18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. 38c2ecf20Sopenharmony_ci * Copyright (c) 2005, 2006, 2007, 2008 Mellanox Technologies. 48c2ecf20Sopenharmony_ci * All rights reserved. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * This software is available to you under a choice of one of two 78c2ecf20Sopenharmony_ci * licenses. You may choose to be licensed under the terms of the GNU 88c2ecf20Sopenharmony_ci * General Public License (GPL) Version 2, available from the file 98c2ecf20Sopenharmony_ci * COPYING in the main directory of this source tree, or the 108c2ecf20Sopenharmony_ci * OpenIB.org BSD license below: 118c2ecf20Sopenharmony_ci * 128c2ecf20Sopenharmony_ci * Redistribution and use in source and binary forms, with or 138c2ecf20Sopenharmony_ci * without modification, are permitted provided that the following 148c2ecf20Sopenharmony_ci * conditions are met: 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * - Redistributions of source code must retain the above 178c2ecf20Sopenharmony_ci * copyright notice, this list of conditions and the following 188c2ecf20Sopenharmony_ci * disclaimer. 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * - Redistributions in binary form must reproduce the above 218c2ecf20Sopenharmony_ci * copyright notice, this list of conditions and the following 228c2ecf20Sopenharmony_ci * disclaimer in the documentation and/or other materials 238c2ecf20Sopenharmony_ci * provided with the distribution. 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 268c2ecf20Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 278c2ecf20Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 288c2ecf20Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 298c2ecf20Sopenharmony_ci * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 308c2ecf20Sopenharmony_ci * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 318c2ecf20Sopenharmony_ci * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 328c2ecf20Sopenharmony_ci * SOFTWARE. 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_ci#include <linux/export.h> 368c2ecf20Sopenharmony_ci#include "fw_qos.h" 378c2ecf20Sopenharmony_ci#include "fw.h" 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_cienum { 408c2ecf20Sopenharmony_ci /* allocate vpp opcode modifiers */ 418c2ecf20Sopenharmony_ci MLX4_ALLOCATE_VPP_ALLOCATE = 0x0, 428c2ecf20Sopenharmony_ci MLX4_ALLOCATE_VPP_QUERY = 0x1 438c2ecf20Sopenharmony_ci}; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cienum { 468c2ecf20Sopenharmony_ci /* set vport qos opcode modifiers */ 478c2ecf20Sopenharmony_ci MLX4_SET_VPORT_QOS_SET = 0x0, 488c2ecf20Sopenharmony_ci MLX4_SET_VPORT_QOS_QUERY = 0x1 498c2ecf20Sopenharmony_ci}; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistruct mlx4_set_port_prio2tc_context { 528c2ecf20Sopenharmony_ci u8 prio2tc[4]; 538c2ecf20Sopenharmony_ci}; 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistruct mlx4_port_scheduler_tc_cfg_be { 568c2ecf20Sopenharmony_ci __be16 pg; 578c2ecf20Sopenharmony_ci __be16 bw_precentage; 588c2ecf20Sopenharmony_ci __be16 max_bw_units; /* 3-100Mbps, 4-1Gbps, other values - reserved */ 598c2ecf20Sopenharmony_ci __be16 max_bw_value; 608c2ecf20Sopenharmony_ci}; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_cistruct mlx4_set_port_scheduler_context { 638c2ecf20Sopenharmony_ci struct mlx4_port_scheduler_tc_cfg_be tc[MLX4_NUM_TC]; 648c2ecf20Sopenharmony_ci}; 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci/* Granular Qos (per VF) section */ 678c2ecf20Sopenharmony_cistruct mlx4_alloc_vpp_param { 688c2ecf20Sopenharmony_ci __be32 available_vpp; 698c2ecf20Sopenharmony_ci __be32 vpp_p_up[MLX4_NUM_UP]; 708c2ecf20Sopenharmony_ci}; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_cistruct mlx4_prio_qos_param { 738c2ecf20Sopenharmony_ci __be32 bw_share; 748c2ecf20Sopenharmony_ci __be32 max_avg_bw; 758c2ecf20Sopenharmony_ci __be32 reserved; 768c2ecf20Sopenharmony_ci __be32 enable; 778c2ecf20Sopenharmony_ci __be32 reserved1[4]; 788c2ecf20Sopenharmony_ci}; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_cistruct mlx4_set_vport_context { 818c2ecf20Sopenharmony_ci __be32 reserved[8]; 828c2ecf20Sopenharmony_ci struct mlx4_prio_qos_param qos_p_up[MLX4_NUM_UP]; 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ciint mlx4_SET_PORT_PRIO2TC(struct mlx4_dev *dev, u8 port, u8 *prio2tc) 868c2ecf20Sopenharmony_ci{ 878c2ecf20Sopenharmony_ci struct mlx4_cmd_mailbox *mailbox; 888c2ecf20Sopenharmony_ci struct mlx4_set_port_prio2tc_context *context; 898c2ecf20Sopenharmony_ci int err; 908c2ecf20Sopenharmony_ci u32 in_mod; 918c2ecf20Sopenharmony_ci int i; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci mailbox = mlx4_alloc_cmd_mailbox(dev); 948c2ecf20Sopenharmony_ci if (IS_ERR(mailbox)) 958c2ecf20Sopenharmony_ci return PTR_ERR(mailbox); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci context = mailbox->buf; 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci for (i = 0; i < MLX4_NUM_UP; i += 2) 1008c2ecf20Sopenharmony_ci context->prio2tc[i >> 1] = prio2tc[i] << 4 | prio2tc[i + 1]; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci in_mod = MLX4_SET_PORT_PRIO2TC << 8 | port; 1038c2ecf20Sopenharmony_ci err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 1048c2ecf20Sopenharmony_ci MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci mlx4_free_cmd_mailbox(dev, mailbox); 1078c2ecf20Sopenharmony_ci return err; 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ciEXPORT_SYMBOL(mlx4_SET_PORT_PRIO2TC); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ciint mlx4_SET_PORT_SCHEDULER(struct mlx4_dev *dev, u8 port, u8 *tc_tx_bw, 1128c2ecf20Sopenharmony_ci u8 *pg, u16 *ratelimit) 1138c2ecf20Sopenharmony_ci{ 1148c2ecf20Sopenharmony_ci struct mlx4_cmd_mailbox *mailbox; 1158c2ecf20Sopenharmony_ci struct mlx4_set_port_scheduler_context *context; 1168c2ecf20Sopenharmony_ci int err; 1178c2ecf20Sopenharmony_ci u32 in_mod; 1188c2ecf20Sopenharmony_ci int i; 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci mailbox = mlx4_alloc_cmd_mailbox(dev); 1218c2ecf20Sopenharmony_ci if (IS_ERR(mailbox)) 1228c2ecf20Sopenharmony_ci return PTR_ERR(mailbox); 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci context = mailbox->buf; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci for (i = 0; i < MLX4_NUM_TC; i++) { 1278c2ecf20Sopenharmony_ci struct mlx4_port_scheduler_tc_cfg_be *tc = &context->tc[i]; 1288c2ecf20Sopenharmony_ci u16 r; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci if (ratelimit && ratelimit[i]) { 1318c2ecf20Sopenharmony_ci if (ratelimit[i] <= MLX4_MAX_100M_UNITS_VAL) { 1328c2ecf20Sopenharmony_ci r = ratelimit[i]; 1338c2ecf20Sopenharmony_ci tc->max_bw_units = 1348c2ecf20Sopenharmony_ci htons(MLX4_RATELIMIT_100M_UNITS); 1358c2ecf20Sopenharmony_ci } else { 1368c2ecf20Sopenharmony_ci r = ratelimit[i] / 10; 1378c2ecf20Sopenharmony_ci tc->max_bw_units = 1388c2ecf20Sopenharmony_ci htons(MLX4_RATELIMIT_1G_UNITS); 1398c2ecf20Sopenharmony_ci } 1408c2ecf20Sopenharmony_ci tc->max_bw_value = htons(r); 1418c2ecf20Sopenharmony_ci } else { 1428c2ecf20Sopenharmony_ci tc->max_bw_value = htons(MLX4_RATELIMIT_DEFAULT); 1438c2ecf20Sopenharmony_ci tc->max_bw_units = htons(MLX4_RATELIMIT_1G_UNITS); 1448c2ecf20Sopenharmony_ci } 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci tc->pg = htons(pg[i]); 1478c2ecf20Sopenharmony_ci tc->bw_precentage = htons(tc_tx_bw[i]); 1488c2ecf20Sopenharmony_ci } 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci in_mod = MLX4_SET_PORT_SCHEDULER << 8 | port; 1518c2ecf20Sopenharmony_ci err = mlx4_cmd(dev, mailbox->dma, in_mod, 1, MLX4_CMD_SET_PORT, 1528c2ecf20Sopenharmony_ci MLX4_CMD_TIME_CLASS_B, MLX4_CMD_NATIVE); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci mlx4_free_cmd_mailbox(dev, mailbox); 1558c2ecf20Sopenharmony_ci return err; 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ciEXPORT_SYMBOL(mlx4_SET_PORT_SCHEDULER); 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ciint mlx4_ALLOCATE_VPP_get(struct mlx4_dev *dev, u8 port, 1608c2ecf20Sopenharmony_ci u16 *available_vpp, u8 *vpp_p_up) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci int i; 1638c2ecf20Sopenharmony_ci int err; 1648c2ecf20Sopenharmony_ci struct mlx4_cmd_mailbox *mailbox; 1658c2ecf20Sopenharmony_ci struct mlx4_alloc_vpp_param *out_param; 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci mailbox = mlx4_alloc_cmd_mailbox(dev); 1688c2ecf20Sopenharmony_ci if (IS_ERR(mailbox)) 1698c2ecf20Sopenharmony_ci return PTR_ERR(mailbox); 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci out_param = mailbox->buf; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci err = mlx4_cmd_box(dev, 0, mailbox->dma, port, 1748c2ecf20Sopenharmony_ci MLX4_ALLOCATE_VPP_QUERY, 1758c2ecf20Sopenharmony_ci MLX4_CMD_ALLOCATE_VPP, 1768c2ecf20Sopenharmony_ci MLX4_CMD_TIME_CLASS_A, 1778c2ecf20Sopenharmony_ci MLX4_CMD_NATIVE); 1788c2ecf20Sopenharmony_ci if (err) 1798c2ecf20Sopenharmony_ci goto out; 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci /* Total number of supported VPPs */ 1828c2ecf20Sopenharmony_ci *available_vpp = (u16)be32_to_cpu(out_param->available_vpp); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci for (i = 0; i < MLX4_NUM_UP; i++) 1858c2ecf20Sopenharmony_ci vpp_p_up[i] = (u8)be32_to_cpu(out_param->vpp_p_up[i]); 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ciout: 1888c2ecf20Sopenharmony_ci mlx4_free_cmd_mailbox(dev, mailbox); 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci return err; 1918c2ecf20Sopenharmony_ci} 1928c2ecf20Sopenharmony_ciEXPORT_SYMBOL(mlx4_ALLOCATE_VPP_get); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ciint mlx4_ALLOCATE_VPP_set(struct mlx4_dev *dev, u8 port, u8 *vpp_p_up) 1958c2ecf20Sopenharmony_ci{ 1968c2ecf20Sopenharmony_ci int i; 1978c2ecf20Sopenharmony_ci int err; 1988c2ecf20Sopenharmony_ci struct mlx4_cmd_mailbox *mailbox; 1998c2ecf20Sopenharmony_ci struct mlx4_alloc_vpp_param *in_param; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci mailbox = mlx4_alloc_cmd_mailbox(dev); 2028c2ecf20Sopenharmony_ci if (IS_ERR(mailbox)) 2038c2ecf20Sopenharmony_ci return PTR_ERR(mailbox); 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci in_param = mailbox->buf; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci for (i = 0; i < MLX4_NUM_UP; i++) 2088c2ecf20Sopenharmony_ci in_param->vpp_p_up[i] = cpu_to_be32(vpp_p_up[i]); 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci err = mlx4_cmd(dev, mailbox->dma, port, 2118c2ecf20Sopenharmony_ci MLX4_ALLOCATE_VPP_ALLOCATE, 2128c2ecf20Sopenharmony_ci MLX4_CMD_ALLOCATE_VPP, 2138c2ecf20Sopenharmony_ci MLX4_CMD_TIME_CLASS_A, 2148c2ecf20Sopenharmony_ci MLX4_CMD_NATIVE); 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci mlx4_free_cmd_mailbox(dev, mailbox); 2178c2ecf20Sopenharmony_ci return err; 2188c2ecf20Sopenharmony_ci} 2198c2ecf20Sopenharmony_ciEXPORT_SYMBOL(mlx4_ALLOCATE_VPP_set); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ciint mlx4_SET_VPORT_QOS_get(struct mlx4_dev *dev, u8 port, u8 vport, 2228c2ecf20Sopenharmony_ci struct mlx4_vport_qos_param *out_param) 2238c2ecf20Sopenharmony_ci{ 2248c2ecf20Sopenharmony_ci int i; 2258c2ecf20Sopenharmony_ci int err; 2268c2ecf20Sopenharmony_ci struct mlx4_cmd_mailbox *mailbox; 2278c2ecf20Sopenharmony_ci struct mlx4_set_vport_context *ctx; 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ci mailbox = mlx4_alloc_cmd_mailbox(dev); 2308c2ecf20Sopenharmony_ci if (IS_ERR(mailbox)) 2318c2ecf20Sopenharmony_ci return PTR_ERR(mailbox); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci ctx = mailbox->buf; 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci err = mlx4_cmd_box(dev, 0, mailbox->dma, (vport << 8) | port, 2368c2ecf20Sopenharmony_ci MLX4_SET_VPORT_QOS_QUERY, 2378c2ecf20Sopenharmony_ci MLX4_CMD_SET_VPORT_QOS, 2388c2ecf20Sopenharmony_ci MLX4_CMD_TIME_CLASS_A, 2398c2ecf20Sopenharmony_ci MLX4_CMD_NATIVE); 2408c2ecf20Sopenharmony_ci if (err) 2418c2ecf20Sopenharmony_ci goto out; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci for (i = 0; i < MLX4_NUM_UP; i++) { 2448c2ecf20Sopenharmony_ci out_param[i].bw_share = be32_to_cpu(ctx->qos_p_up[i].bw_share); 2458c2ecf20Sopenharmony_ci out_param[i].max_avg_bw = 2468c2ecf20Sopenharmony_ci be32_to_cpu(ctx->qos_p_up[i].max_avg_bw); 2478c2ecf20Sopenharmony_ci out_param[i].enable = 2488c2ecf20Sopenharmony_ci !!(be32_to_cpu(ctx->qos_p_up[i].enable) & 31); 2498c2ecf20Sopenharmony_ci } 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_ciout: 2528c2ecf20Sopenharmony_ci mlx4_free_cmd_mailbox(dev, mailbox); 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci return err; 2558c2ecf20Sopenharmony_ci} 2568c2ecf20Sopenharmony_ciEXPORT_SYMBOL(mlx4_SET_VPORT_QOS_get); 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ciint mlx4_SET_VPORT_QOS_set(struct mlx4_dev *dev, u8 port, u8 vport, 2598c2ecf20Sopenharmony_ci struct mlx4_vport_qos_param *in_param) 2608c2ecf20Sopenharmony_ci{ 2618c2ecf20Sopenharmony_ci int i; 2628c2ecf20Sopenharmony_ci int err; 2638c2ecf20Sopenharmony_ci struct mlx4_cmd_mailbox *mailbox; 2648c2ecf20Sopenharmony_ci struct mlx4_set_vport_context *ctx; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci mailbox = mlx4_alloc_cmd_mailbox(dev); 2678c2ecf20Sopenharmony_ci if (IS_ERR(mailbox)) 2688c2ecf20Sopenharmony_ci return PTR_ERR(mailbox); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci ctx = mailbox->buf; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci for (i = 0; i < MLX4_NUM_UP; i++) { 2738c2ecf20Sopenharmony_ci ctx->qos_p_up[i].bw_share = cpu_to_be32(in_param[i].bw_share); 2748c2ecf20Sopenharmony_ci ctx->qos_p_up[i].max_avg_bw = 2758c2ecf20Sopenharmony_ci cpu_to_be32(in_param[i].max_avg_bw); 2768c2ecf20Sopenharmony_ci ctx->qos_p_up[i].enable = 2778c2ecf20Sopenharmony_ci cpu_to_be32(in_param[i].enable << 31); 2788c2ecf20Sopenharmony_ci } 2798c2ecf20Sopenharmony_ci 2808c2ecf20Sopenharmony_ci err = mlx4_cmd(dev, mailbox->dma, (vport << 8) | port, 2818c2ecf20Sopenharmony_ci MLX4_SET_VPORT_QOS_SET, 2828c2ecf20Sopenharmony_ci MLX4_CMD_SET_VPORT_QOS, 2838c2ecf20Sopenharmony_ci MLX4_CMD_TIME_CLASS_A, 2848c2ecf20Sopenharmony_ci MLX4_CMD_NATIVE); 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_ci mlx4_free_cmd_mailbox(dev, mailbox); 2878c2ecf20Sopenharmony_ci return err; 2888c2ecf20Sopenharmony_ci} 2898c2ecf20Sopenharmony_ciEXPORT_SYMBOL(mlx4_SET_VPORT_QOS_set); 290