1329159Shselasky/* 2329159Shselasky * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 3329159Shselasky * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. 4329159Shselasky * All rights reserved. 5329159Shselasky * 6329159Shselasky * This software is available to you under a choice of one of two 7329159Shselasky * licenses. You may choose to be licensed under the terms of the GNU 8329159Shselasky * General Public License (GPL) Version 2, available from the file 9329159Shselasky * COPYING in the main directory of this source tree, or the 10329159Shselasky * OpenIB.org BSD license below: 11329159Shselasky * 12329159Shselasky * Redistribution and use in source and binary forms, with or 13329159Shselasky * without modification, are permitted provided that the following 14329159Shselasky * conditions are met: 15329159Shselasky * 16329159Shselasky * - Redistributions of source code must retain the above 17329159Shselasky * copyright notice, this list of conditions and the following 18329159Shselasky * disclaimer. 19329159Shselasky * 20329159Shselasky * - Redistributions in binary form must reproduce the above 21329159Shselasky * copyright notice, this list of conditions and the following 22329159Shselasky * disclaimer in the documentation and/or other materials 23329159Shselasky * provided with the distribution. 24329159Shselasky * 25329159Shselasky * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 26329159Shselasky * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 27329159Shselasky * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 28329159Shselasky * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 29329159Shselasky * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 30329159Shselasky * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 31329159Shselasky * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 32329159Shselasky * SOFTWARE. 33329159Shselasky */ 34329159Shselasky 35329159Shselasky#include <linux/kernel.h> 36329159Shselasky#include "fw_qos.h" 37329159Shselasky#include "fw.h" 38329159Shselasky 39329159Shselaskyenum { 40329159Shselasky /* allocate vpp opcode modifiers */ 41329159Shselasky MLX4_ALLOCATE_VPP_ALLOCATE = 0x0, 42329159Shselasky MLX4_ALLOCATE_VPP_QUERY = 0x1 43329159Shselasky}; 44329159Shselasky 45329159Shselaskyenum { 46329159Shselasky /* set vport qos opcode modifiers */ 47329159Shselasky MLX4_SET_VPORT_QOS_SET = 0x0, 48329159Shselasky MLX4_SET_VPORT_QOS_QUERY = 0x1 49329159Shselasky}; 50329159Shselasky 51329159Shselaskystruct mlx4_set_port_prio2tc_context { 52329159Shselasky u8 prio2tc[4]; 53329159Shselasky}; 54329159Shselasky 55329159Shselaskystruct mlx4_port_scheduler_tc_cfg_be { 56329159Shselasky __be16 pg; 57329159Shselasky __be16 bw_precentage; 58329159Shselasky __be16 max_bw_units; /* 3-100Mbps, 4-1Gbps, other values - reserved */ 59329159Shselasky __be16 max_bw_value; 60329159Shselasky}; 61329159Shselasky 62329159Shselaskystruct mlx4_set_port_scheduler_context { 63329159Shselasky struct mlx4_port_scheduler_tc_cfg_be tc[MLX4_NUM_TC]; 64329159Shselasky}; 65329159Shselasky 66329159Shselasky/* Granular Qos (per VF) section */ 67329159Shselaskystruct mlx4_alloc_vpp_param { 68329159Shselasky __be32 availible_vpp; 69329159Shselasky __be32 vpp_p_up[MLX4_NUM_UP]; 70329159Shselasky}; 71329159Shselasky 72329159Shselaskystruct mlx4_prio_qos_param { 73329159Shselasky __be32 bw_share; 74329159Shselasky __be32 max_avg_bw; 75329159Shselasky __be32 reserved; 76329159Shselasky __be32 enable; 77329159Shselasky __be32 reserved1[4]; 78329159Shselasky}; 79329159Shselasky 80329159Shselaskystruct mlx4_set_vport_context { 81329159Shselasky __be32 reserved[8]; 82329159Shselasky struct mlx4_prio_qos_param qos_p_up[MLX4_NUM_UP]; 83329159Shselasky}; 84329159Shselasky 85329159Shselaskyint mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc) 86329159Shselasky{ 87329159Shselasky struct mlx4_cmd_mailbox *mailbox; 88329159Shselasky struct mlx4_set_port_prio2tc_context *context; 89329159Shselasky int err; 90329159Shselasky u32 in_mod; 91329159Shselasky int i; 92329159Shselasky 93329159Shselasky mailbox = mlx4_alloc_cmd_mailbox(dev); 94329159Shselasky if (IS_ERR(mailbox)) 95329159Shselasky return PTR_ERR(mailbox); 96329159Shselasky 97329159Shselasky context = mailbox->buf; 98329159Shselasky 99329159Shselasky for (i = 0; i < MLX4_NUM_UP; i += 2) 100329159Shselasky context->prio2tc[i >> 1] = prio2tc[i] << 4 | prio2tc[i + 1]; 101329159Shselasky 102329159Shselasky in_mod = MLX4_SET_PORT_PRIO2TC << 8 | port; 103329159Shselasky err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 104329159Shselasky MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 105329159Shselasky 106329159Shselasky mlx4_free_cmd_mailbox(dev, mailbox); 107329159Shselasky return err; 108329159Shselasky} 109329159ShselaskyEXPORT_SYMBOL(mlx4_SET_PORT_PRIO2TC); 110329159Shselasky 111329159Shselaskyint mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw, 112329159Shselasky u8 *pg, u16 *ratelimit) 113329159Shselasky{ 114329159Shselasky struct mlx4_cmd_mailbox *mailbox; 115329159Shselasky struct mlx4_set_port_scheduler_context *context; 116329159Shselasky int err; 117329159Shselasky u32 in_mod; 118329159Shselasky int i; 119329159Shselasky 120329159Shselasky mailbox = mlx4_alloc_cmd_mailbox(dev); 121329159Shselasky if (IS_ERR(mailbox)) 122329159Shselasky return PTR_ERR(mailbox); 123329159Shselasky 124329159Shselasky context = mailbox->buf; 125329159Shselasky 126329159Shselasky for (i = 0; i < MLX4_NUM_TC; i++) { 127329159Shselasky struct mlx4_port_scheduler_tc_cfg_be *tc = &context->tc[i]; 128329159Shselasky u16 r; 129329159Shselasky 130329159Shselasky if (ratelimit && ratelimit[i]) { 131329159Shselasky if (ratelimit[i] <= MLX4_MAX_100M_UNITS_VAL) { 132329159Shselasky r = ratelimit[i]; 133329159Shselasky tc->max_bw_units = 134329159Shselasky htons(MLX4_RATELIMIT_100M_UNITS); 135329159Shselasky } else { 136329159Shselasky r = ratelimit[i] / 10; 137329159Shselasky tc->max_bw_units = 138329159Shselasky htons(MLX4_RATELIMIT_1G_UNITS); 139329159Shselasky } 140329159Shselasky tc->max_bw_value = htons(r); 141329159Shselasky } else { 142329159Shselasky tc->max_bw_value = htons(MLX4_RATELIMIT_DEFAULT); 143329159Shselasky tc->max_bw_units = htons(MLX4_RATELIMIT_1G_UNITS); 144329159Shselasky } 145329159Shselasky 146329159Shselasky tc->pg = htons(pg[i]); 147329159Shselasky tc->bw_precentage = htons(tc_tx_bw[i]); 148329159Shselasky } 149329159Shselasky 150329159Shselasky in_mod = MLX4_SET_PORT_SCHEDULER << 8 | port; 151329159Shselasky err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 152329159Shselasky MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 153329159Shselasky 154329159Shselasky mlx4_free_cmd_mailbox(dev, mailbox); 155329159Shselasky return err; 156329159Shselasky} 157329159ShselaskyEXPORT_SYMBOL(mlx4_SET_PORT_SCHEDULER); 158329159Shselasky 159329159Shselaskyint mlx4_ALLOCATE_VPP_get(struct mlx4_dev *dev, u8 port, 160329159Shselasky u16 *availible_vpp, u8 *vpp_p_up) 161329159Shselasky{ 162329159Shselasky int i; 163329159Shselasky int err; 164329159Shselasky struct mlx4_cmd_mailbox *mailbox; 165329159Shselasky struct mlx4_alloc_vpp_param *out_param; 166329159Shselasky 167329159Shselasky mailbox = mlx4_alloc_cmd_mailbox(dev); 168329159Shselasky if (IS_ERR(mailbox)) 169329159Shselasky return PTR_ERR(mailbox); 170329159Shselasky 171329159Shselasky out_param = mailbox->buf; 172329159Shselasky 173329159Shselasky err = mlx4_cmd_box(dev, 0, mailbox->dma, port, 174329159Shselasky MLX4_ALLOCATE_VPP_QUERY, 175329159Shselasky MLX4_CMD_ALLOCATE_VPP, 176329159Shselasky MLX4_CMD_TIME_CLASS_A, 177329159Shselasky MLX4_CMD_NATIVE); 178329159Shselasky if (err) 179329159Shselasky goto out; 180329159Shselasky 181329159Shselasky /* Total number of supported VPPs */ 182329159Shselasky *availible_vpp = (u16)be32_to_cpu(out_param->availible_vpp); 183329159Shselasky 184329159Shselasky for (i = 0; i < MLX4_NUM_UP; i++) 185329159Shselasky vpp_p_up[i] = (u8)be32_to_cpu(out_param->vpp_p_up[i]); 186329159Shselasky 187329159Shselaskyout: 188329159Shselasky mlx4_free_cmd_mailbox(dev, mailbox); 189329159Shselasky 190329159Shselasky return err; 191329159Shselasky} 192329159ShselaskyEXPORT_SYMBOL(mlx4_ALLOCATE_VPP_get); 193329159Shselasky 194329159Shselaskyint mlx4_ALLOCATE_VPP_set(struct mlx4_dev *dev, u8 port, u8 *vpp_p_up) 195329159Shselasky{ 196329159Shselasky int i; 197329159Shselasky int err; 198329159Shselasky struct mlx4_cmd_mailbox *mailbox; 199329159Shselasky struct mlx4_alloc_vpp_param *in_param; 200329159Shselasky 201329159Shselasky mailbox = mlx4_alloc_cmd_mailbox(dev); 202329159Shselasky if (IS_ERR(mailbox)) 203329159Shselasky return PTR_ERR(mailbox); 204329159Shselasky 205329159Shselasky in_param = mailbox->buf; 206329159Shselasky 207329159Shselasky for (i = 0; i < MLX4_NUM_UP; i++) 208329159Shselasky in_param->vpp_p_up[i] = cpu_to_be32(vpp_p_up[i]); 209329159Shselasky 210329159Shselasky err = mlx4_cmd(dev, mailbox->dma, port, 211329159Shselasky MLX4_ALLOCATE_VPP_ALLOCATE, 212329159Shselasky MLX4_CMD_ALLOCATE_VPP, 213329159Shselasky MLX4_CMD_TIME_CLASS_A, 214329159Shselasky MLX4_CMD_NATIVE); 215329159Shselasky 216329159Shselasky mlx4_free_cmd_mailbox(dev, mailbox); 217329159Shselasky return err; 218329159Shselasky} 219329159ShselaskyEXPORT_SYMBOL(mlx4_ALLOCATE_VPP_set); 220329159Shselasky 221329159Shselaskyint mlx4_SET_VPORT_QOS_get(struct mlx4_dev *dev, u8 port, u8 vport, 222329159Shselasky struct mlx4_vport_qos_param *out_param) 223329159Shselasky{ 224329159Shselasky int i; 225329159Shselasky int err; 226329159Shselasky struct mlx4_cmd_mailbox *mailbox; 227329159Shselasky struct mlx4_set_vport_context *ctx; 228329159Shselasky 229329159Shselasky mailbox = mlx4_alloc_cmd_mailbox(dev); 230329159Shselasky if (IS_ERR(mailbox)) 231329159Shselasky return PTR_ERR(mailbox); 232329159Shselasky 233329159Shselasky ctx = mailbox->buf; 234329159Shselasky 235329159Shselasky err = mlx4_cmd_box(dev, 0, mailbox->dma, (vport << 8) | port, 236329159Shselasky MLX4_SET_VPORT_QOS_QUERY, 237329159Shselasky MLX4_CMD_SET_VPORT_QOS, 238329159Shselasky MLX4_CMD_TIME_CLASS_A, 239329159Shselasky MLX4_CMD_NATIVE); 240329159Shselasky if (err) 241329159Shselasky goto out; 242329159Shselasky 243329159Shselasky for (i = 0; i < MLX4_NUM_UP; i++) { 244329159Shselasky out_param[i].bw_share = be32_to_cpu(ctx->qos_p_up[i].bw_share); 245329159Shselasky out_param[i].max_avg_bw = 246329159Shselasky be32_to_cpu(ctx->qos_p_up[i].max_avg_bw); 247329159Shselasky out_param[i].enable = 248329159Shselasky !!(be32_to_cpu(ctx->qos_p_up[i].enable) & 31); 249329159Shselasky } 250329159Shselasky 251329159Shselaskyout: 252329159Shselasky mlx4_free_cmd_mailbox(dev, mailbox); 253329159Shselasky 254329159Shselasky return err; 255329159Shselasky} 256329159ShselaskyEXPORT_SYMBOL(mlx4_SET_VPORT_QOS_get); 257329159Shselasky 258329159Shselaskyint mlx4_SET_VPORT_QOS_set(struct mlx4_dev *dev, u8 port, u8 vport, 259329159Shselasky struct mlx4_vport_qos_param *in_param) 260329159Shselasky{ 261329159Shselasky int i; 262329159Shselasky int err; 263329159Shselasky struct mlx4_cmd_mailbox *mailbox; 264329159Shselasky struct mlx4_set_vport_context *ctx; 265329159Shselasky 266329159Shselasky mailbox = mlx4_alloc_cmd_mailbox(dev); 267329159Shselasky if (IS_ERR(mailbox)) 268329159Shselasky return PTR_ERR(mailbox); 269329159Shselasky 270329159Shselasky ctx = mailbox->buf; 271329159Shselasky 272329159Shselasky for (i = 0; i < MLX4_NUM_UP; i++) { 273329159Shselasky ctx->qos_p_up[i].bw_share = cpu_to_be32(in_param[i].bw_share); 274329159Shselasky ctx->qos_p_up[i].max_avg_bw = 275329159Shselasky cpu_to_be32(in_param[i].max_avg_bw); 276329159Shselasky ctx->qos_p_up[i].enable = 277329159Shselasky cpu_to_be32(in_param[i].enable << 31); 278329159Shselasky } 279329159Shselasky 280329159Shselasky err = mlx4_cmd(dev, mailbox->dma, (vport << 8) | port, 281329159Shselasky MLX4_SET_VPORT_QOS_SET, 282329159Shselasky MLX4_CMD_SET_VPORT_QOS, 283329159Shselasky MLX4_CMD_TIME_CLASS_A, 284329159Shselasky MLX4_CMD_NATIVE); 285329159Shselasky 286329159Shselasky mlx4_free_cmd_mailbox(dev, mailbox); 287329159Shselasky return err; 288329159Shselasky} 289329159ShselaskyEXPORT_SYMBOL(mlx4_SET_VPORT_QOS_set); 290