1d71d8381SJian Shen // SPDX-License-Identifier: GPL-2.0+ 2d71d8381SJian Shen // Copyright (c) 2016-2017 Hisilicon Limited. 384844054SSalil 484844054SSalil #include <linux/etherdevice.h> 584844054SSalil 684844054SSalil #include "hclge_cmd.h" 784844054SSalil #include "hclge_main.h" 884844054SSalil #include "hclge_tm.h" 984844054SSalil 1084844054SSalil enum hclge_shaper_level { 1184844054SSalil HCLGE_SHAPER_LVL_PRI = 0, 1284844054SSalil HCLGE_SHAPER_LVL_PG = 1, 1384844054SSalil HCLGE_SHAPER_LVL_PORT = 2, 1484844054SSalil HCLGE_SHAPER_LVL_QSET = 3, 1584844054SSalil HCLGE_SHAPER_LVL_CNT = 4, 1684844054SSalil HCLGE_SHAPER_LVL_VF = 0, 1784844054SSalil HCLGE_SHAPER_LVL_PF = 1, 1884844054SSalil }; 1984844054SSalil 2064fd2300SPeng Li #define HCLGE_TM_PFC_PKT_GET_CMD_NUM 3 2164fd2300SPeng Li #define HCLGE_TM_PFC_NUM_GET_PER_CMD 3 2264fd2300SPeng Li 233a7d5958SPeng Li #define HCLGE_SHAPER_BS_U_DEF 5 243a7d5958SPeng Li #define HCLGE_SHAPER_BS_S_DEF 20 2584844054SSalil 2684844054SSalil /* hclge_shaper_para_calc: calculate ir parameter for the shaper 2784844054SSalil * @ir: Rate to be config, its unit is Mbps 2884844054SSalil * @shaper_level: the shaper level. eg: port, pg, priority, queueset 29ff7e4d0dSHuazhong Tan * @ir_para: parameters of IR shaper 30d9c7d20dSGuangbin Huang * @max_tm_rate: max tm rate is available to config 3184844054SSalil * 3284844054SSalil * the formula: 3384844054SSalil * 3484844054SSalil * IR_b * (2 ^ IR_u) * 8 3584844054SSalil * IR(Mbps) = ------------------------- * CLOCK(1000Mbps) 3684844054SSalil * Tick * (2 ^ IR_s) 3784844054SSalil * 3884844054SSalil * @return: 0: calculate sucessful, negative: fail 3984844054SSalil */ 4084844054SSalil static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, 41ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para *ir_para, 42d9c7d20dSGuangbin Huang u32 max_tm_rate) 4384844054SSalil { 449d2a1ceaSPeng Li #define DEFAULT_SHAPER_IR_B 126 45b37ce587SYufeng Mo #define DIVISOR_CLK (1000 * 8) 469d2a1ceaSPeng Li #define DEFAULT_DIVISOR_IR_B (DEFAULT_SHAPER_IR_B * DIVISOR_CLK) 47b37ce587SYufeng Mo 483ea7af9eSColin Ian King static const u16 tick_array[HCLGE_SHAPER_LVL_CNT] = { 4984844054SSalil 6 * 256, /* Prioriy level */ 5084844054SSalil 6 * 32, /* Prioriy group level */ 5184844054SSalil 6 * 8, /* Port level */ 5284844054SSalil 6 * 256 /* Qset level */ 5384844054SSalil }; 549b2f3477SWeihang Li u8 ir_u_calc = 0; 559b2f3477SWeihang Li u8 ir_s_calc = 0; 5684844054SSalil u32 ir_calc; 5784844054SSalil u32 tick; 5884844054SSalil 5984844054SSalil /* Calc tick */ 6004f25edbSYunsheng Lin if (shaper_level >= HCLGE_SHAPER_LVL_CNT || 61d9c7d20dSGuangbin Huang ir > max_tm_rate) 6284844054SSalil return -EINVAL; 6384844054SSalil 6484844054SSalil tick = tick_array[shaper_level]; 6584844054SSalil 6684844054SSalil /** 6784844054SSalil * Calc the speed if ir_b = 126, ir_u = 0 and ir_s = 0 6884844054SSalil * the formula is changed to: 6984844054SSalil * 126 * 1 * 8 7084844054SSalil * ir_calc = ---------------- * 1000 7184844054SSalil * tick * 1 7284844054SSalil */ 739d2a1ceaSPeng Li ir_calc = (DEFAULT_DIVISOR_IR_B + (tick >> 1) - 1) / tick; 7484844054SSalil 7584844054SSalil if (ir_calc == ir) { 769d2a1ceaSPeng Li ir_para->ir_b = DEFAULT_SHAPER_IR_B; 77ff7e4d0dSHuazhong Tan ir_para->ir_u = 0; 78ff7e4d0dSHuazhong Tan ir_para->ir_s = 0; 7984844054SSalil 8084844054SSalil return 0; 8184844054SSalil } else if (ir_calc > ir) { 8284844054SSalil /* Increasing the denominator to select ir_s value */ 831a92497dSYonglong Liu while (ir_calc >= ir && ir) { 8484844054SSalil ir_s_calc++; 859d2a1ceaSPeng Li ir_calc = DEFAULT_DIVISOR_IR_B / 869d2a1ceaSPeng Li (tick * (1 << ir_s_calc)); 8784844054SSalil } 8884844054SSalil 89ff7e4d0dSHuazhong Tan ir_para->ir_b = (ir * tick * (1 << ir_s_calc) + 90ff7e4d0dSHuazhong Tan (DIVISOR_CLK >> 1)) / DIVISOR_CLK; 9184844054SSalil } else { 9284844054SSalil /* Increasing the numerator to select ir_u value */ 9384844054SSalil u32 numerator; 9484844054SSalil 9584844054SSalil while (ir_calc < ir) { 9684844054SSalil ir_u_calc++; 979d2a1ceaSPeng Li numerator = DEFAULT_DIVISOR_IR_B * (1 << ir_u_calc); 9884844054SSalil ir_calc = (numerator + (tick >> 1)) / tick; 9984844054SSalil } 10084844054SSalil 10184844054SSalil if (ir_calc == ir) { 1029d2a1ceaSPeng Li ir_para->ir_b = DEFAULT_SHAPER_IR_B; 10384844054SSalil } else { 1041a92497dSYonglong Liu u32 denominator = DIVISOR_CLK * (1 << --ir_u_calc); 105ff7e4d0dSHuazhong Tan ir_para->ir_b = (ir * tick + (denominator >> 1)) / 106ff7e4d0dSHuazhong Tan denominator; 10784844054SSalil } 10884844054SSalil } 10984844054SSalil 110ff7e4d0dSHuazhong Tan ir_para->ir_u = ir_u_calc; 111ff7e4d0dSHuazhong Tan ir_para->ir_s = ir_s_calc; 11284844054SSalil 11384844054SSalil return 0; 11484844054SSalil } 11584844054SSalil 11664fd2300SPeng Li static int hclge_pfc_stats_get(struct hclge_dev *hdev, 11764fd2300SPeng Li enum hclge_opcode_type opcode, u64 *stats) 11864fd2300SPeng Li { 11964fd2300SPeng Li struct hclge_desc desc[HCLGE_TM_PFC_PKT_GET_CMD_NUM]; 12064fd2300SPeng Li int ret, i, j; 12164fd2300SPeng Li 12264fd2300SPeng Li if (!(opcode == HCLGE_OPC_QUERY_PFC_RX_PKT_CNT || 12364fd2300SPeng Li opcode == HCLGE_OPC_QUERY_PFC_TX_PKT_CNT)) 12464fd2300SPeng Li return -EINVAL; 12564fd2300SPeng Li 12663cbf7a9SYufeng Mo for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM - 1; i++) { 12764fd2300SPeng Li hclge_cmd_setup_basic_desc(&desc[i], opcode, true); 12864fd2300SPeng Li desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); 12964fd2300SPeng Li } 13064fd2300SPeng Li 13163cbf7a9SYufeng Mo hclge_cmd_setup_basic_desc(&desc[i], opcode, true); 13263cbf7a9SYufeng Mo 13364fd2300SPeng Li ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_TM_PFC_PKT_GET_CMD_NUM); 13420670328SYunsheng Lin if (ret) 13564fd2300SPeng Li return ret; 13664fd2300SPeng Li 13764fd2300SPeng Li for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) { 13864fd2300SPeng Li struct hclge_pfc_stats_cmd *pfc_stats = 13964fd2300SPeng Li (struct hclge_pfc_stats_cmd *)desc[i].data; 14064fd2300SPeng Li 14164fd2300SPeng Li for (j = 0; j < HCLGE_TM_PFC_NUM_GET_PER_CMD; j++) { 14264fd2300SPeng Li u32 index = i * HCLGE_TM_PFC_PKT_GET_CMD_NUM + j; 14364fd2300SPeng Li 14464fd2300SPeng Li if (index < HCLGE_MAX_TC_NUM) 14564fd2300SPeng Li stats[index] = 14664fd2300SPeng Li le64_to_cpu(pfc_stats->pkt_num[j]); 14764fd2300SPeng Li } 14864fd2300SPeng Li } 14964fd2300SPeng Li return 0; 15064fd2300SPeng Li } 15164fd2300SPeng Li 15264fd2300SPeng Li int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats) 15364fd2300SPeng Li { 15464fd2300SPeng Li return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_RX_PKT_CNT, stats); 15564fd2300SPeng Li } 15664fd2300SPeng Li 15764fd2300SPeng Li int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats) 15864fd2300SPeng Li { 15964fd2300SPeng Li return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_TX_PKT_CNT, stats); 16064fd2300SPeng Li } 16164fd2300SPeng Li 16261387774SPeng Li int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx) 16384844054SSalil { 16484844054SSalil struct hclge_desc desc; 16584844054SSalil 16684844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PAUSE_EN, false); 16784844054SSalil 16884844054SSalil desc.data[0] = cpu_to_le32((tx ? HCLGE_TX_MAC_PAUSE_EN_MSK : 0) | 16984844054SSalil (rx ? HCLGE_RX_MAC_PAUSE_EN_MSK : 0)); 17084844054SSalil 17184844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 17284844054SSalil } 17384844054SSalil 1749dc2145dSYunsheng Lin static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, 1759dc2145dSYunsheng Lin u8 pfc_bitmap) 1769dc2145dSYunsheng Lin { 1779dc2145dSYunsheng Lin struct hclge_desc desc; 178d0d72bacSJian Shen struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)desc.data; 1799dc2145dSYunsheng Lin 1809dc2145dSYunsheng Lin hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PFC_PAUSE_EN, false); 1819dc2145dSYunsheng Lin 1829dc2145dSYunsheng Lin pfc->tx_rx_en_bitmap = tx_rx_bitmap; 1839dc2145dSYunsheng Lin pfc->pri_en_bitmap = pfc_bitmap; 1849dc2145dSYunsheng Lin 1859dc2145dSYunsheng Lin return hclge_cmd_send(&hdev->hw, &desc, 1); 1869dc2145dSYunsheng Lin } 1879dc2145dSYunsheng Lin 188e98d7183SFuyun Liang static int hclge_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr, 18918838d0cSFuyun Liang u8 pause_trans_gap, u16 pause_trans_time) 19018838d0cSFuyun Liang { 19118838d0cSFuyun Liang struct hclge_cfg_pause_param_cmd *pause_param; 19218838d0cSFuyun Liang struct hclge_desc desc; 19318838d0cSFuyun Liang 194d0d72bacSJian Shen pause_param = (struct hclge_cfg_pause_param_cmd *)desc.data; 19518838d0cSFuyun Liang 19618838d0cSFuyun Liang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, false); 19718838d0cSFuyun Liang 19818838d0cSFuyun Liang ether_addr_copy(pause_param->mac_addr, addr); 199cd2086bfSFuyun Liang ether_addr_copy(pause_param->mac_addr_extra, addr); 20018838d0cSFuyun Liang pause_param->pause_trans_gap = pause_trans_gap; 20118838d0cSFuyun Liang pause_param->pause_trans_time = cpu_to_le16(pause_trans_time); 20218838d0cSFuyun Liang 20318838d0cSFuyun Liang return hclge_cmd_send(&hdev->hw, &desc, 1); 20418838d0cSFuyun Liang } 20518838d0cSFuyun Liang 206e98d7183SFuyun Liang int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr) 20718838d0cSFuyun Liang { 20818838d0cSFuyun Liang struct hclge_cfg_pause_param_cmd *pause_param; 20918838d0cSFuyun Liang struct hclge_desc desc; 21018838d0cSFuyun Liang u16 trans_time; 21118838d0cSFuyun Liang u8 trans_gap; 21218838d0cSFuyun Liang int ret; 21318838d0cSFuyun Liang 214d0d72bacSJian Shen pause_param = (struct hclge_cfg_pause_param_cmd *)desc.data; 21518838d0cSFuyun Liang 21618838d0cSFuyun Liang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, true); 21718838d0cSFuyun Liang 21818838d0cSFuyun Liang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 21918838d0cSFuyun Liang if (ret) 22018838d0cSFuyun Liang return ret; 22118838d0cSFuyun Liang 22218838d0cSFuyun Liang trans_gap = pause_param->pause_trans_gap; 22318838d0cSFuyun Liang trans_time = le16_to_cpu(pause_param->pause_trans_time); 22418838d0cSFuyun Liang 2259b2f3477SWeihang Li return hclge_pause_param_cfg(hdev, mac_addr, trans_gap, trans_time); 22618838d0cSFuyun Liang } 22718838d0cSFuyun Liang 22884844054SSalil static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id) 22984844054SSalil { 23084844054SSalil u8 tc; 23184844054SSalil 232c5795c53SYunsheng Lin tc = hdev->tm_info.prio_tc[pri_id]; 23384844054SSalil 23484844054SSalil if (tc >= hdev->tm_info.num_tc) 23584844054SSalil return -EINVAL; 23684844054SSalil 23784844054SSalil /** 23884844054SSalil * the register for priority has four bytes, the first bytes includes 23984844054SSalil * priority0 and priority1, the higher 4bit stands for priority1 24084844054SSalil * while the lower 4bit stands for priority0, as below: 24184844054SSalil * first byte: | pri_1 | pri_0 | 24284844054SSalil * second byte: | pri_3 | pri_2 | 24384844054SSalil * third byte: | pri_5 | pri_4 | 24484844054SSalil * fourth byte: | pri_7 | pri_6 | 24584844054SSalil */ 24684844054SSalil pri[pri_id >> 1] |= tc << ((pri_id & 1) * 4); 24784844054SSalil 24884844054SSalil return 0; 24984844054SSalil } 25084844054SSalil 25184844054SSalil static int hclge_up_to_tc_map(struct hclge_dev *hdev) 25284844054SSalil { 25384844054SSalil struct hclge_desc desc; 25484844054SSalil u8 *pri = (u8 *)desc.data; 25584844054SSalil u8 pri_id; 25684844054SSalil int ret; 25784844054SSalil 25884844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PRI_TO_TC_MAPPING, false); 25984844054SSalil 260c5795c53SYunsheng Lin for (pri_id = 0; pri_id < HNAE3_MAX_USER_PRIO; pri_id++) { 26184844054SSalil ret = hclge_fill_pri_array(hdev, pri, pri_id); 26284844054SSalil if (ret) 26384844054SSalil return ret; 26484844054SSalil } 26584844054SSalil 26684844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 26784844054SSalil } 26884844054SSalil 26984844054SSalil static int hclge_tm_pg_to_pri_map_cfg(struct hclge_dev *hdev, 27084844054SSalil u8 pg_id, u8 pri_bit_map) 27184844054SSalil { 27284844054SSalil struct hclge_pg_to_pri_link_cmd *map; 27384844054SSalil struct hclge_desc desc; 27484844054SSalil 27584844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_TO_PRI_LINK, false); 27684844054SSalil 27784844054SSalil map = (struct hclge_pg_to_pri_link_cmd *)desc.data; 27884844054SSalil 27984844054SSalil map->pg_id = pg_id; 28084844054SSalil map->pri_bit_map = pri_bit_map; 28184844054SSalil 28284844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 28384844054SSalil } 28484844054SSalil 28584844054SSalil static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev, 28684844054SSalil u16 qs_id, u8 pri) 28784844054SSalil { 28884844054SSalil struct hclge_qs_to_pri_link_cmd *map; 28984844054SSalil struct hclge_desc desc; 29084844054SSalil 29184844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_TO_PRI_LINK, false); 29284844054SSalil 29384844054SSalil map = (struct hclge_qs_to_pri_link_cmd *)desc.data; 29484844054SSalil 29584844054SSalil map->qs_id = cpu_to_le16(qs_id); 29684844054SSalil map->priority = pri; 29784844054SSalil map->link_vld = HCLGE_TM_QS_PRI_LINK_VLD_MSK; 29884844054SSalil 29984844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 30084844054SSalil } 30184844054SSalil 30284844054SSalil static int hclge_tm_q_to_qs_map_cfg(struct hclge_dev *hdev, 30332c7fbc8SJian Shen u16 q_id, u16 qs_id) 30484844054SSalil { 30584844054SSalil struct hclge_nq_to_qs_link_cmd *map; 30684844054SSalil struct hclge_desc desc; 3079a5ef4aaSYonglong Liu u16 qs_id_l; 3089a5ef4aaSYonglong Liu u16 qs_id_h; 30984844054SSalil 31084844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NQ_TO_QS_LINK, false); 31184844054SSalil 31284844054SSalil map = (struct hclge_nq_to_qs_link_cmd *)desc.data; 31384844054SSalil 31484844054SSalil map->nq_id = cpu_to_le16(q_id); 3159a5ef4aaSYonglong Liu 3169a5ef4aaSYonglong Liu /* convert qs_id to the following format to support qset_id >= 1024 3179a5ef4aaSYonglong Liu * qs_id: | 15 | 14 ~ 10 | 9 ~ 0 | 3189a5ef4aaSYonglong Liu * / / \ \ 3199a5ef4aaSYonglong Liu * / / \ \ 3209a5ef4aaSYonglong Liu * qset_id: | 15 ~ 11 | 10 | 9 ~ 0 | 3219a5ef4aaSYonglong Liu * | qs_id_h | vld | qs_id_l | 3229a5ef4aaSYonglong Liu */ 3239a5ef4aaSYonglong Liu qs_id_l = hnae3_get_field(qs_id, HCLGE_TM_QS_ID_L_MSK, 3249a5ef4aaSYonglong Liu HCLGE_TM_QS_ID_L_S); 3259a5ef4aaSYonglong Liu qs_id_h = hnae3_get_field(qs_id, HCLGE_TM_QS_ID_H_MSK, 3269a5ef4aaSYonglong Liu HCLGE_TM_QS_ID_H_S); 3279a5ef4aaSYonglong Liu hnae3_set_field(qs_id, HCLGE_TM_QS_ID_L_MSK, HCLGE_TM_QS_ID_L_S, 3289a5ef4aaSYonglong Liu qs_id_l); 3299a5ef4aaSYonglong Liu hnae3_set_field(qs_id, HCLGE_TM_QS_ID_H_EXT_MSK, HCLGE_TM_QS_ID_H_EXT_S, 3309a5ef4aaSYonglong Liu qs_id_h); 33184844054SSalil map->qset_id = cpu_to_le16(qs_id | HCLGE_TM_Q_QS_LINK_VLD_MSK); 33284844054SSalil 33384844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 33484844054SSalil } 33584844054SSalil 33684844054SSalil static int hclge_tm_pg_weight_cfg(struct hclge_dev *hdev, u8 pg_id, 33784844054SSalil u8 dwrr) 33884844054SSalil { 33984844054SSalil struct hclge_pg_weight_cmd *weight; 34084844054SSalil struct hclge_desc desc; 34184844054SSalil 34284844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_WEIGHT, false); 34384844054SSalil 34484844054SSalil weight = (struct hclge_pg_weight_cmd *)desc.data; 34584844054SSalil 34684844054SSalil weight->pg_id = pg_id; 34784844054SSalil weight->dwrr = dwrr; 34884844054SSalil 34984844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 35084844054SSalil } 35184844054SSalil 35284844054SSalil static int hclge_tm_pri_weight_cfg(struct hclge_dev *hdev, u8 pri_id, 35384844054SSalil u8 dwrr) 35484844054SSalil { 35584844054SSalil struct hclge_priority_weight_cmd *weight; 35684844054SSalil struct hclge_desc desc; 35784844054SSalil 35884844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_WEIGHT, false); 35984844054SSalil 36084844054SSalil weight = (struct hclge_priority_weight_cmd *)desc.data; 36184844054SSalil 36284844054SSalil weight->pri_id = pri_id; 36384844054SSalil weight->dwrr = dwrr; 36484844054SSalil 36584844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 36684844054SSalil } 36784844054SSalil 36884844054SSalil static int hclge_tm_qs_weight_cfg(struct hclge_dev *hdev, u16 qs_id, 36984844054SSalil u8 dwrr) 37084844054SSalil { 37184844054SSalil struct hclge_qs_weight_cmd *weight; 37284844054SSalil struct hclge_desc desc; 37384844054SSalil 37484844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_WEIGHT, false); 37584844054SSalil 37684844054SSalil weight = (struct hclge_qs_weight_cmd *)desc.data; 37784844054SSalil 37884844054SSalil weight->qs_id = cpu_to_le16(qs_id); 37984844054SSalil weight->dwrr = dwrr; 38084844054SSalil 38184844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 38284844054SSalil } 38384844054SSalil 38463cbf7a9SYufeng Mo static u32 hclge_tm_get_shapping_para(u8 ir_b, u8 ir_u, u8 ir_s, 38563cbf7a9SYufeng Mo u8 bs_b, u8 bs_s) 38663cbf7a9SYufeng Mo { 38763cbf7a9SYufeng Mo u32 shapping_para = 0; 38863cbf7a9SYufeng Mo 38963cbf7a9SYufeng Mo hclge_tm_set_field(shapping_para, IR_B, ir_b); 39063cbf7a9SYufeng Mo hclge_tm_set_field(shapping_para, IR_U, ir_u); 39163cbf7a9SYufeng Mo hclge_tm_set_field(shapping_para, IR_S, ir_s); 39263cbf7a9SYufeng Mo hclge_tm_set_field(shapping_para, BS_B, bs_b); 39363cbf7a9SYufeng Mo hclge_tm_set_field(shapping_para, BS_S, bs_s); 39463cbf7a9SYufeng Mo 39563cbf7a9SYufeng Mo return shapping_para; 39663cbf7a9SYufeng Mo } 39763cbf7a9SYufeng Mo 39884844054SSalil static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev, 39984844054SSalil enum hclge_shap_bucket bucket, u8 pg_id, 400e364ad30SYonglong Liu u32 shapping_para, u32 rate) 40184844054SSalil { 40284844054SSalil struct hclge_pg_shapping_cmd *shap_cfg_cmd; 40384844054SSalil enum hclge_opcode_type opcode; 40484844054SSalil struct hclge_desc desc; 40584844054SSalil 40684844054SSalil opcode = bucket ? HCLGE_OPC_TM_PG_P_SHAPPING : 40784844054SSalil HCLGE_OPC_TM_PG_C_SHAPPING; 40884844054SSalil hclge_cmd_setup_basic_desc(&desc, opcode, false); 40984844054SSalil 41084844054SSalil shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data; 41184844054SSalil 41284844054SSalil shap_cfg_cmd->pg_id = pg_id; 41384844054SSalil 414a90bb9a5SYunsheng Lin shap_cfg_cmd->pg_shapping_para = cpu_to_le32(shapping_para); 41584844054SSalil 416e364ad30SYonglong Liu hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1); 417e364ad30SYonglong Liu 418e364ad30SYonglong Liu shap_cfg_cmd->pg_rate = cpu_to_le32(rate); 419e364ad30SYonglong Liu 42084844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 42184844054SSalil } 42284844054SSalil 4230a5677d3SYunsheng Lin static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev) 4240a5677d3SYunsheng Lin { 4250a5677d3SYunsheng Lin struct hclge_port_shapping_cmd *shap_cfg_cmd; 426ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para ir_para; 4270a5677d3SYunsheng Lin struct hclge_desc desc; 428cdd332acSGuojia Liao u32 shapping_para; 4290a5677d3SYunsheng Lin int ret; 4300a5677d3SYunsheng Lin 431ff7e4d0dSHuazhong Tan ret = hclge_shaper_para_calc(hdev->hw.mac.speed, HCLGE_SHAPER_LVL_PORT, 432ff7e4d0dSHuazhong Tan &ir_para, 433d9c7d20dSGuangbin Huang hdev->ae_dev->dev_specs.max_tm_rate); 4340a5677d3SYunsheng Lin if (ret) 4350a5677d3SYunsheng Lin return ret; 4360a5677d3SYunsheng Lin 4370a5677d3SYunsheng Lin hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PORT_SHAPPING, false); 4380a5677d3SYunsheng Lin shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data; 4390a5677d3SYunsheng Lin 440ff7e4d0dSHuazhong Tan shapping_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u, 441ff7e4d0dSHuazhong Tan ir_para.ir_s, 44263cbf7a9SYufeng Mo HCLGE_SHAPER_BS_U_DEF, 44363cbf7a9SYufeng Mo HCLGE_SHAPER_BS_S_DEF); 4440a5677d3SYunsheng Lin 4450a5677d3SYunsheng Lin shap_cfg_cmd->port_shapping_para = cpu_to_le32(shapping_para); 4460a5677d3SYunsheng Lin 447e364ad30SYonglong Liu hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1); 448e364ad30SYonglong Liu 449e364ad30SYonglong Liu shap_cfg_cmd->port_rate = cpu_to_le32(hdev->hw.mac.speed); 450e364ad30SYonglong Liu 4510a5677d3SYunsheng Lin return hclge_cmd_send(&hdev->hw, &desc, 1); 4520a5677d3SYunsheng Lin } 4530a5677d3SYunsheng Lin 45484844054SSalil static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev, 45584844054SSalil enum hclge_shap_bucket bucket, u8 pri_id, 456e364ad30SYonglong Liu u32 shapping_para, u32 rate) 45784844054SSalil { 45884844054SSalil struct hclge_pri_shapping_cmd *shap_cfg_cmd; 45984844054SSalil enum hclge_opcode_type opcode; 46084844054SSalil struct hclge_desc desc; 46184844054SSalil 46284844054SSalil opcode = bucket ? HCLGE_OPC_TM_PRI_P_SHAPPING : 46384844054SSalil HCLGE_OPC_TM_PRI_C_SHAPPING; 46484844054SSalil 46584844054SSalil hclge_cmd_setup_basic_desc(&desc, opcode, false); 46684844054SSalil 46784844054SSalil shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data; 46884844054SSalil 46984844054SSalil shap_cfg_cmd->pri_id = pri_id; 47084844054SSalil 471a90bb9a5SYunsheng Lin shap_cfg_cmd->pri_shapping_para = cpu_to_le32(shapping_para); 47284844054SSalil 473e364ad30SYonglong Liu hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1); 474e364ad30SYonglong Liu 475e364ad30SYonglong Liu shap_cfg_cmd->pri_rate = cpu_to_le32(rate); 476e364ad30SYonglong Liu 47784844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 47884844054SSalil } 47984844054SSalil 48084844054SSalil static int hclge_tm_pg_schd_mode_cfg(struct hclge_dev *hdev, u8 pg_id) 48184844054SSalil { 48284844054SSalil struct hclge_desc desc; 48384844054SSalil 48484844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_SCH_MODE_CFG, false); 48584844054SSalil 48684844054SSalil if (hdev->tm_info.pg_info[pg_id].pg_sch_mode == HCLGE_SCH_MODE_DWRR) 48784844054SSalil desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK); 48884844054SSalil else 48984844054SSalil desc.data[1] = 0; 49084844054SSalil 49184844054SSalil desc.data[0] = cpu_to_le32(pg_id); 49284844054SSalil 49384844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 49484844054SSalil } 49584844054SSalil 49684844054SSalil static int hclge_tm_pri_schd_mode_cfg(struct hclge_dev *hdev, u8 pri_id) 49784844054SSalil { 49884844054SSalil struct hclge_desc desc; 49984844054SSalil 50084844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_SCH_MODE_CFG, false); 50184844054SSalil 50284844054SSalil if (hdev->tm_info.tc_info[pri_id].tc_sch_mode == HCLGE_SCH_MODE_DWRR) 50384844054SSalil desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK); 50484844054SSalil else 50584844054SSalil desc.data[1] = 0; 50684844054SSalil 50784844054SSalil desc.data[0] = cpu_to_le32(pri_id); 50884844054SSalil 50984844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 51084844054SSalil } 51184844054SSalil 512cc9bb43aSYunsheng Lin static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id, u8 mode) 51384844054SSalil { 51484844054SSalil struct hclge_desc desc; 51584844054SSalil 51684844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_SCH_MODE_CFG, false); 51784844054SSalil 518cc9bb43aSYunsheng Lin if (mode == HCLGE_SCH_MODE_DWRR) 51984844054SSalil desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK); 52084844054SSalil else 52184844054SSalil desc.data[1] = 0; 52284844054SSalil 52384844054SSalil desc.data[0] = cpu_to_le32(qs_id); 52484844054SSalil 52584844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 52684844054SSalil } 52784844054SSalil 52867bf2541SYunsheng Lin static int hclge_tm_qs_bp_cfg(struct hclge_dev *hdev, u8 tc, u8 grp_id, 52967bf2541SYunsheng Lin u32 bit_map) 53084844054SSalil { 53184844054SSalil struct hclge_bp_to_qs_map_cmd *bp_to_qs_map_cmd; 53284844054SSalil struct hclge_desc desc; 53384844054SSalil 53484844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_BP_TO_QSET_MAPPING, 53584844054SSalil false); 53684844054SSalil 53784844054SSalil bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data; 53884844054SSalil 53984844054SSalil bp_to_qs_map_cmd->tc_id = tc; 54067bf2541SYunsheng Lin bp_to_qs_map_cmd->qs_group_id = grp_id; 54167bf2541SYunsheng Lin bp_to_qs_map_cmd->qs_bit_map = cpu_to_le32(bit_map); 54284844054SSalil 54384844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 54484844054SSalil } 54584844054SSalil 546ee9e4424SYonglong Liu int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate) 547ee9e4424SYonglong Liu { 548ee9e4424SYonglong Liu struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 549ee9e4424SYonglong Liu struct hclge_qs_shapping_cmd *shap_cfg_cmd; 550ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para ir_para; 551ee9e4424SYonglong Liu struct hclge_dev *hdev = vport->back; 552ee9e4424SYonglong Liu struct hclge_desc desc; 553ee9e4424SYonglong Liu u32 shaper_para; 554ee9e4424SYonglong Liu int ret, i; 555ee9e4424SYonglong Liu 556ee9e4424SYonglong Liu if (!max_tx_rate) 557d9c7d20dSGuangbin Huang max_tx_rate = hdev->ae_dev->dev_specs.max_tm_rate; 558ee9e4424SYonglong Liu 559ee9e4424SYonglong Liu ret = hclge_shaper_para_calc(max_tx_rate, HCLGE_SHAPER_LVL_QSET, 560ff7e4d0dSHuazhong Tan &ir_para, 561d9c7d20dSGuangbin Huang hdev->ae_dev->dev_specs.max_tm_rate); 562ee9e4424SYonglong Liu if (ret) 563ee9e4424SYonglong Liu return ret; 564ee9e4424SYonglong Liu 565ff7e4d0dSHuazhong Tan shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u, 566ff7e4d0dSHuazhong Tan ir_para.ir_s, 567ee9e4424SYonglong Liu HCLGE_SHAPER_BS_U_DEF, 568ee9e4424SYonglong Liu HCLGE_SHAPER_BS_S_DEF); 569ee9e4424SYonglong Liu 57035244430SJian Shen for (i = 0; i < kinfo->tc_info.num_tc; i++) { 571ee9e4424SYonglong Liu hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QCN_SHAPPING_CFG, 572ee9e4424SYonglong Liu false); 573ee9e4424SYonglong Liu 574ee9e4424SYonglong Liu shap_cfg_cmd = (struct hclge_qs_shapping_cmd *)desc.data; 575ee9e4424SYonglong Liu shap_cfg_cmd->qs_id = cpu_to_le16(vport->qs_offset + i); 576ee9e4424SYonglong Liu shap_cfg_cmd->qs_shapping_para = cpu_to_le32(shaper_para); 577ee9e4424SYonglong Liu 578e364ad30SYonglong Liu hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1); 579e364ad30SYonglong Liu shap_cfg_cmd->qs_rate = cpu_to_le32(max_tx_rate); 580e364ad30SYonglong Liu 581ee9e4424SYonglong Liu ret = hclge_cmd_send(&hdev->hw, &desc, 1); 582ee9e4424SYonglong Liu if (ret) { 583ee9e4424SYonglong Liu dev_err(&hdev->pdev->dev, 584311c0aaaSJiaran Zhang "vport%u, qs%u failed to set tx_rate:%d, ret=%d\n", 585ee9e4424SYonglong Liu vport->vport_id, shap_cfg_cmd->qs_id, 586ee9e4424SYonglong Liu max_tx_rate, ret); 587ee9e4424SYonglong Liu return ret; 588ee9e4424SYonglong Liu } 589ee9e4424SYonglong Liu } 590ee9e4424SYonglong Liu 591ee9e4424SYonglong Liu return 0; 592ee9e4424SYonglong Liu } 593ee9e4424SYonglong Liu 5945a5c9091SJian Shen static u16 hclge_vport_get_max_rss_size(struct hclge_vport *vport) 5955a5c9091SJian Shen { 5965a5c9091SJian Shen struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 5975a5c9091SJian Shen struct hnae3_tc_info *tc_info = &kinfo->tc_info; 5985a5c9091SJian Shen struct hclge_dev *hdev = vport->back; 5995a5c9091SJian Shen u16 max_rss_size = 0; 6005a5c9091SJian Shen int i; 6015a5c9091SJian Shen 6025a5c9091SJian Shen if (!tc_info->mqprio_active) 6035a5c9091SJian Shen return vport->alloc_tqps / tc_info->num_tc; 6045a5c9091SJian Shen 6055a5c9091SJian Shen for (i = 0; i < HNAE3_MAX_TC; i++) { 6065a5c9091SJian Shen if (!(hdev->hw_tc_map & BIT(i)) || i >= tc_info->num_tc) 6075a5c9091SJian Shen continue; 6085a5c9091SJian Shen if (max_rss_size < tc_info->tqp_count[i]) 6095a5c9091SJian Shen max_rss_size = tc_info->tqp_count[i]; 6105a5c9091SJian Shen } 6115a5c9091SJian Shen 6125a5c9091SJian Shen return max_rss_size; 6135a5c9091SJian Shen } 6145a5c9091SJian Shen 6155a5c9091SJian Shen static u16 hclge_vport_get_tqp_num(struct hclge_vport *vport) 6165a5c9091SJian Shen { 6175a5c9091SJian Shen struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 6185a5c9091SJian Shen struct hnae3_tc_info *tc_info = &kinfo->tc_info; 6195a5c9091SJian Shen struct hclge_dev *hdev = vport->back; 6205a5c9091SJian Shen int sum = 0; 6215a5c9091SJian Shen int i; 6225a5c9091SJian Shen 6235a5c9091SJian Shen if (!tc_info->mqprio_active) 6245a5c9091SJian Shen return kinfo->rss_size * tc_info->num_tc; 6255a5c9091SJian Shen 6265a5c9091SJian Shen for (i = 0; i < HNAE3_MAX_TC; i++) { 6275a5c9091SJian Shen if (hdev->hw_tc_map & BIT(i) && i < tc_info->num_tc) 6285a5c9091SJian Shen sum += tc_info->tqp_count[i]; 6295a5c9091SJian Shen } 6305a5c9091SJian Shen 6315a5c9091SJian Shen return sum; 6325a5c9091SJian Shen } 6335a5c9091SJian Shen 634b1261897SGuojia Liao static void hclge_tm_update_kinfo_rss_size(struct hclge_vport *vport) 63584844054SSalil { 63684844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 63784844054SSalil struct hclge_dev *hdev = vport->back; 638f1c2e66dSGuojia Liao u16 vport_max_rss_size; 639672ad0edSHuazhong Tan u16 max_rss_size; 64084844054SSalil 641de67a690SYunsheng Lin /* TC configuration is shared by PF/VF in one port, only allow 642de67a690SYunsheng Lin * one tc for VF for simplicity. VF's vport_id is non zero. 643de67a690SYunsheng Lin */ 644693e4415SGuoJia Liao if (vport->vport_id) { 645693e4415SGuoJia Liao kinfo->tc_info.num_tc = 1; 646693e4415SGuoJia Liao vport->qs_offset = HNAE3_MAX_TC + 647693e4415SGuoJia Liao vport->vport_id - HCLGE_VF_VPORT_START_NUM; 648693e4415SGuoJia Liao vport_max_rss_size = hdev->vf_rss_size_max; 649693e4415SGuoJia Liao } else { 650693e4415SGuoJia Liao kinfo->tc_info.num_tc = 651de67a690SYunsheng Lin min_t(u16, vport->alloc_tqps, hdev->tm_info.num_tc); 652693e4415SGuoJia Liao vport->qs_offset = 0; 653693e4415SGuoJia Liao vport_max_rss_size = hdev->pf_rss_size_max; 654693e4415SGuoJia Liao } 655de67a690SYunsheng Lin 656f1c2e66dSGuojia Liao max_rss_size = min_t(u16, vport_max_rss_size, 6575a5c9091SJian Shen hclge_vport_get_max_rss_size(vport)); 658672ad0edSHuazhong Tan 6599b2f3477SWeihang Li /* Set to user value, no larger than max_rss_size. */ 660672ad0edSHuazhong Tan if (kinfo->req_rss_size != kinfo->rss_size && kinfo->req_rss_size && 661672ad0edSHuazhong Tan kinfo->req_rss_size <= max_rss_size) { 662adcf738bSGuojia Liao dev_info(&hdev->pdev->dev, "rss changes from %u to %u\n", 663672ad0edSHuazhong Tan kinfo->rss_size, kinfo->req_rss_size); 664672ad0edSHuazhong Tan kinfo->rss_size = kinfo->req_rss_size; 665672ad0edSHuazhong Tan } else if (kinfo->rss_size > max_rss_size || 666672ad0edSHuazhong Tan (!kinfo->req_rss_size && kinfo->rss_size < max_rss_size)) { 6679b2f3477SWeihang Li /* Set to the maximum specification value (max_rss_size). */ 668672ad0edSHuazhong Tan kinfo->rss_size = max_rss_size; 669672ad0edSHuazhong Tan } 670b1261897SGuojia Liao } 671672ad0edSHuazhong Tan 672b1261897SGuojia Liao static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) 673b1261897SGuojia Liao { 674b1261897SGuojia Liao struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 675b1261897SGuojia Liao struct hclge_dev *hdev = vport->back; 676b1261897SGuojia Liao u8 i; 677b1261897SGuojia Liao 678b1261897SGuojia Liao hclge_tm_update_kinfo_rss_size(vport); 6795a5c9091SJian Shen kinfo->num_tqps = hclge_vport_get_tqp_num(vport); 68084844054SSalil vport->dwrr = 100; /* 100 percent as init */ 68168ece54eSYunsheng Lin vport->alloc_rss_size = kinfo->rss_size; 682de67a690SYunsheng Lin vport->bw_limit = hdev->tm_info.pg_info[0].bw_limit; 68384844054SSalil 6845a5c9091SJian Shen /* when enable mqprio, the tc_info has been updated. */ 6855a5c9091SJian Shen if (kinfo->tc_info.mqprio_active) 6865a5c9091SJian Shen return; 6875a5c9091SJian Shen 688af958827SHuazhong Tan for (i = 0; i < HNAE3_MAX_TC; i++) { 68935244430SJian Shen if (hdev->hw_tc_map & BIT(i) && i < kinfo->tc_info.num_tc) { 69035244430SJian Shen kinfo->tc_info.tqp_offset[i] = i * kinfo->rss_size; 69135244430SJian Shen kinfo->tc_info.tqp_count[i] = kinfo->rss_size; 69284844054SSalil } else { 69384844054SSalil /* Set to default queue if TC is disable */ 69435244430SJian Shen kinfo->tc_info.tqp_offset[i] = 0; 69535244430SJian Shen kinfo->tc_info.tqp_count[i] = 1; 69684844054SSalil } 69784844054SSalil } 698c5795c53SYunsheng Lin 69935244430SJian Shen memcpy(kinfo->tc_info.prio_tc, hdev->tm_info.prio_tc, 70035244430SJian Shen sizeof_field(struct hnae3_tc_info, prio_tc)); 70184844054SSalil } 70284844054SSalil 70384844054SSalil static void hclge_tm_vport_info_update(struct hclge_dev *hdev) 70484844054SSalil { 70584844054SSalil struct hclge_vport *vport = hdev->vport; 70684844054SSalil u32 i; 70784844054SSalil 70884844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 70984844054SSalil hclge_tm_vport_tc_info_update(vport); 71084844054SSalil 71184844054SSalil vport++; 71284844054SSalil } 71384844054SSalil } 71484844054SSalil 71584844054SSalil static void hclge_tm_tc_info_init(struct hclge_dev *hdev) 71684844054SSalil { 71784844054SSalil u8 i; 71884844054SSalil 71984844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 72084844054SSalil hdev->tm_info.tc_info[i].tc_id = i; 72184844054SSalil hdev->tm_info.tc_info[i].tc_sch_mode = HCLGE_SCH_MODE_DWRR; 72284844054SSalil hdev->tm_info.tc_info[i].pgid = 0; 72384844054SSalil hdev->tm_info.tc_info[i].bw_limit = 72484844054SSalil hdev->tm_info.pg_info[0].bw_limit; 72584844054SSalil } 72684844054SSalil 727c5795c53SYunsheng Lin for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) 728c5795c53SYunsheng Lin hdev->tm_info.prio_tc[i] = 729c5795c53SYunsheng Lin (i >= hdev->tm_info.num_tc) ? 0 : i; 73084844054SSalil } 73184844054SSalil 73284844054SSalil static void hclge_tm_pg_info_init(struct hclge_dev *hdev) 73384844054SSalil { 734b37ce587SYufeng Mo #define BW_PERCENT 100 735b37ce587SYufeng Mo 73684844054SSalil u8 i; 73784844054SSalil 73884844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 73984844054SSalil int k; 74084844054SSalil 741b37ce587SYufeng Mo hdev->tm_info.pg_dwrr[i] = i ? 0 : BW_PERCENT; 74284844054SSalil 74384844054SSalil hdev->tm_info.pg_info[i].pg_id = i; 74484844054SSalil hdev->tm_info.pg_info[i].pg_sch_mode = HCLGE_SCH_MODE_DWRR; 74584844054SSalil 746d9c7d20dSGuangbin Huang hdev->tm_info.pg_info[i].bw_limit = 747d9c7d20dSGuangbin Huang hdev->ae_dev->dev_specs.max_tm_rate; 74884844054SSalil 74984844054SSalil if (i != 0) 75084844054SSalil continue; 75184844054SSalil 75284844054SSalil hdev->tm_info.pg_info[i].tc_bit_map = hdev->hw_tc_map; 75384844054SSalil for (k = 0; k < hdev->tm_info.num_tc; k++) 754b37ce587SYufeng Mo hdev->tm_info.pg_info[i].tc_dwrr[k] = BW_PERCENT; 75584844054SSalil } 75684844054SSalil } 75784844054SSalil 758d78e5b6aSYonglong Liu static void hclge_update_fc_mode_by_dcb_flag(struct hclge_dev *hdev) 7597979a223SYunsheng Lin { 760*0472e95fSJian Shen if (hdev->tm_info.num_tc == 1 && !hdev->tm_info.pfc_en) { 7617979a223SYunsheng Lin if (hdev->fc_mode_last_time == HCLGE_FC_PFC) 7627979a223SYunsheng Lin dev_warn(&hdev->pdev->dev, 763*0472e95fSJian Shen "Only 1 tc used, but last mode is FC_PFC\n"); 7647979a223SYunsheng Lin 7657979a223SYunsheng Lin hdev->tm_info.fc_mode = hdev->fc_mode_last_time; 7667979a223SYunsheng Lin } else if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) { 7677979a223SYunsheng Lin /* fc_mode_last_time record the last fc_mode when 7687979a223SYunsheng Lin * DCB is enabled, so that fc_mode can be set to 7697979a223SYunsheng Lin * the correct value when DCB is disabled. 7707979a223SYunsheng Lin */ 7717979a223SYunsheng Lin hdev->fc_mode_last_time = hdev->tm_info.fc_mode; 7727979a223SYunsheng Lin hdev->tm_info.fc_mode = HCLGE_FC_PFC; 7737979a223SYunsheng Lin } 7747979a223SYunsheng Lin } 7757979a223SYunsheng Lin 776d78e5b6aSYonglong Liu static void hclge_update_fc_mode(struct hclge_dev *hdev) 777d78e5b6aSYonglong Liu { 778d78e5b6aSYonglong Liu if (!hdev->tm_info.pfc_en) { 779d78e5b6aSYonglong Liu hdev->tm_info.fc_mode = hdev->fc_mode_last_time; 780d78e5b6aSYonglong Liu return; 781d78e5b6aSYonglong Liu } 782d78e5b6aSYonglong Liu 783d78e5b6aSYonglong Liu if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) { 784d78e5b6aSYonglong Liu hdev->fc_mode_last_time = hdev->tm_info.fc_mode; 785d78e5b6aSYonglong Liu hdev->tm_info.fc_mode = HCLGE_FC_PFC; 786d78e5b6aSYonglong Liu } 787d78e5b6aSYonglong Liu } 788d78e5b6aSYonglong Liu 789*0472e95fSJian Shen void hclge_tm_pfc_info_update(struct hclge_dev *hdev) 790d78e5b6aSYonglong Liu { 791d78e5b6aSYonglong Liu if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) 792d78e5b6aSYonglong Liu hclge_update_fc_mode(hdev); 793d78e5b6aSYonglong Liu else 794d78e5b6aSYonglong Liu hclge_update_fc_mode_by_dcb_flag(hdev); 795d78e5b6aSYonglong Liu } 796d78e5b6aSYonglong Liu 797b6872fd3SYunsheng Lin static void hclge_tm_schd_info_init(struct hclge_dev *hdev) 79884844054SSalil { 79984844054SSalil hclge_tm_pg_info_init(hdev); 80084844054SSalil 80184844054SSalil hclge_tm_tc_info_init(hdev); 80284844054SSalil 80384844054SSalil hclge_tm_vport_info_update(hdev); 80484844054SSalil 805*0472e95fSJian Shen hclge_tm_pfc_info_update(hdev); 80684844054SSalil } 80784844054SSalil 80884844054SSalil static int hclge_tm_pg_to_pri_map(struct hclge_dev *hdev) 80984844054SSalil { 81084844054SSalil int ret; 81184844054SSalil u32 i; 81284844054SSalil 81384844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 81484844054SSalil return 0; 81584844054SSalil 81684844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 81784844054SSalil /* Cfg mapping */ 81884844054SSalil ret = hclge_tm_pg_to_pri_map_cfg( 81984844054SSalil hdev, i, hdev->tm_info.pg_info[i].tc_bit_map); 82084844054SSalil if (ret) 82184844054SSalil return ret; 82284844054SSalil } 82384844054SSalil 82484844054SSalil return 0; 82584844054SSalil } 82684844054SSalil 82784844054SSalil static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev) 82884844054SSalil { 829d9c7d20dSGuangbin Huang u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; 830ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para ir_para; 83163cbf7a9SYufeng Mo u32 shaper_para; 83284844054SSalil int ret; 83384844054SSalil u32 i; 83484844054SSalil 83584844054SSalil /* Cfg pg schd */ 83684844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 83784844054SSalil return 0; 83884844054SSalil 83984844054SSalil /* Pg to pri */ 84084844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 841e364ad30SYonglong Liu u32 rate = hdev->tm_info.pg_info[i].bw_limit; 842e364ad30SYonglong Liu 84384844054SSalil /* Calc shaper para */ 844e364ad30SYonglong Liu ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PG, 845ff7e4d0dSHuazhong Tan &ir_para, max_tm_rate); 84684844054SSalil if (ret) 84784844054SSalil return ret; 84884844054SSalil 84963cbf7a9SYufeng Mo shaper_para = hclge_tm_get_shapping_para(0, 0, 0, 85063cbf7a9SYufeng Mo HCLGE_SHAPER_BS_U_DEF, 85163cbf7a9SYufeng Mo HCLGE_SHAPER_BS_S_DEF); 85284844054SSalil ret = hclge_tm_pg_shapping_cfg(hdev, 85384844054SSalil HCLGE_TM_SHAP_C_BUCKET, i, 854e364ad30SYonglong Liu shaper_para, rate); 85584844054SSalil if (ret) 85684844054SSalil return ret; 85784844054SSalil 858ff7e4d0dSHuazhong Tan shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, 859ff7e4d0dSHuazhong Tan ir_para.ir_u, 860ff7e4d0dSHuazhong Tan ir_para.ir_s, 86184844054SSalil HCLGE_SHAPER_BS_U_DEF, 86284844054SSalil HCLGE_SHAPER_BS_S_DEF); 86363cbf7a9SYufeng Mo ret = hclge_tm_pg_shapping_cfg(hdev, 86463cbf7a9SYufeng Mo HCLGE_TM_SHAP_P_BUCKET, i, 865e364ad30SYonglong Liu shaper_para, rate); 86684844054SSalil if (ret) 86784844054SSalil return ret; 86884844054SSalil } 86984844054SSalil 87084844054SSalil return 0; 87184844054SSalil } 87284844054SSalil 87384844054SSalil static int hclge_tm_pg_dwrr_cfg(struct hclge_dev *hdev) 87484844054SSalil { 87584844054SSalil int ret; 87684844054SSalil u32 i; 87784844054SSalil 87884844054SSalil /* cfg pg schd */ 87984844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 88084844054SSalil return 0; 88184844054SSalil 88284844054SSalil /* pg to prio */ 88384844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 88484844054SSalil /* Cfg dwrr */ 8859b2f3477SWeihang Li ret = hclge_tm_pg_weight_cfg(hdev, i, hdev->tm_info.pg_dwrr[i]); 88684844054SSalil if (ret) 88784844054SSalil return ret; 88884844054SSalil } 88984844054SSalil 89084844054SSalil return 0; 89184844054SSalil } 89284844054SSalil 89384844054SSalil static int hclge_vport_q_to_qs_map(struct hclge_dev *hdev, 89484844054SSalil struct hclge_vport *vport) 89584844054SSalil { 89684844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 89735244430SJian Shen struct hnae3_tc_info *tc_info = &kinfo->tc_info; 89884844054SSalil struct hnae3_queue **tqp = kinfo->tqp; 89984844054SSalil u32 i, j; 90084844054SSalil int ret; 90184844054SSalil 90235244430SJian Shen for (i = 0; i < tc_info->num_tc; i++) { 90335244430SJian Shen for (j = 0; j < tc_info->tqp_count[i]; j++) { 90435244430SJian Shen struct hnae3_queue *q = tqp[tc_info->tqp_offset[i] + j]; 90584844054SSalil 90684844054SSalil ret = hclge_tm_q_to_qs_map_cfg(hdev, 90784844054SSalil hclge_get_queue_id(q), 90884844054SSalil vport->qs_offset + i); 90984844054SSalil if (ret) 91084844054SSalil return ret; 91184844054SSalil } 91284844054SSalil } 91384844054SSalil 91484844054SSalil return 0; 91584844054SSalil } 91684844054SSalil 91784844054SSalil static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev) 91884844054SSalil { 91984844054SSalil struct hclge_vport *vport = hdev->vport; 92084844054SSalil int ret; 921cc9bb43aSYunsheng Lin u32 i, k; 92284844054SSalil 92384844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 92484844054SSalil /* Cfg qs -> pri mapping, one by one mapping */ 925de67a690SYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 926de67a690SYunsheng Lin struct hnae3_knic_private_info *kinfo = 927de67a690SYunsheng Lin &vport[k].nic.kinfo; 928de67a690SYunsheng Lin 92935244430SJian Shen for (i = 0; i < kinfo->tc_info.num_tc; i++) { 930cc9bb43aSYunsheng Lin ret = hclge_tm_qs_to_pri_map_cfg( 931cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, i); 93284844054SSalil if (ret) 93384844054SSalil return ret; 93484844054SSalil } 935de67a690SYunsheng Lin } 93684844054SSalil } else if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) { 93784844054SSalil /* Cfg qs -> pri mapping, qs = tc, pri = vf, 8 qs -> 1 pri */ 93884844054SSalil for (k = 0; k < hdev->num_alloc_vport; k++) 93984844054SSalil for (i = 0; i < HNAE3_MAX_TC; i++) { 94084844054SSalil ret = hclge_tm_qs_to_pri_map_cfg( 94184844054SSalil hdev, vport[k].qs_offset + i, k); 94284844054SSalil if (ret) 94384844054SSalil return ret; 94484844054SSalil } 94584844054SSalil } else { 94684844054SSalil return -EINVAL; 94784844054SSalil } 94884844054SSalil 94984844054SSalil /* Cfg q -> qs mapping */ 95084844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 95184844054SSalil ret = hclge_vport_q_to_qs_map(hdev, vport); 95284844054SSalil if (ret) 95384844054SSalil return ret; 95484844054SSalil 95584844054SSalil vport++; 95684844054SSalil } 95784844054SSalil 95884844054SSalil return 0; 95984844054SSalil } 96084844054SSalil 96184844054SSalil static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev) 96284844054SSalil { 963d9c7d20dSGuangbin Huang u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; 964ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para ir_para; 96563cbf7a9SYufeng Mo u32 shaper_para; 96684844054SSalil int ret; 96784844054SSalil u32 i; 96884844054SSalil 96984844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 970e364ad30SYonglong Liu u32 rate = hdev->tm_info.tc_info[i].bw_limit; 971e364ad30SYonglong Liu 972e364ad30SYonglong Liu ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PRI, 973ff7e4d0dSHuazhong Tan &ir_para, max_tm_rate); 97484844054SSalil if (ret) 97584844054SSalil return ret; 97684844054SSalil 97763cbf7a9SYufeng Mo shaper_para = hclge_tm_get_shapping_para(0, 0, 0, 97863cbf7a9SYufeng Mo HCLGE_SHAPER_BS_U_DEF, 97984844054SSalil HCLGE_SHAPER_BS_S_DEF); 98063cbf7a9SYufeng Mo ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, i, 981e364ad30SYonglong Liu shaper_para, rate); 98284844054SSalil if (ret) 98384844054SSalil return ret; 98484844054SSalil 985ff7e4d0dSHuazhong Tan shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, 986ff7e4d0dSHuazhong Tan ir_para.ir_u, 987ff7e4d0dSHuazhong Tan ir_para.ir_s, 98863cbf7a9SYufeng Mo HCLGE_SHAPER_BS_U_DEF, 98984844054SSalil HCLGE_SHAPER_BS_S_DEF); 99063cbf7a9SYufeng Mo ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, i, 991e364ad30SYonglong Liu shaper_para, rate); 99284844054SSalil if (ret) 99384844054SSalil return ret; 99484844054SSalil } 99584844054SSalil 99684844054SSalil return 0; 99784844054SSalil } 99884844054SSalil 99984844054SSalil static int hclge_tm_pri_vnet_base_shaper_pri_cfg(struct hclge_vport *vport) 100084844054SSalil { 100184844054SSalil struct hclge_dev *hdev = vport->back; 1002ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para ir_para; 100363cbf7a9SYufeng Mo u32 shaper_para; 100484844054SSalil int ret; 100584844054SSalil 100684844054SSalil ret = hclge_shaper_para_calc(vport->bw_limit, HCLGE_SHAPER_LVL_VF, 1007ff7e4d0dSHuazhong Tan &ir_para, 1008d9c7d20dSGuangbin Huang hdev->ae_dev->dev_specs.max_tm_rate); 100984844054SSalil if (ret) 101084844054SSalil return ret; 101184844054SSalil 101263cbf7a9SYufeng Mo shaper_para = hclge_tm_get_shapping_para(0, 0, 0, 101363cbf7a9SYufeng Mo HCLGE_SHAPER_BS_U_DEF, 101484844054SSalil HCLGE_SHAPER_BS_S_DEF); 101563cbf7a9SYufeng Mo ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, 1016e364ad30SYonglong Liu vport->vport_id, shaper_para, 1017e364ad30SYonglong Liu vport->bw_limit); 101884844054SSalil if (ret) 101984844054SSalil return ret; 102084844054SSalil 1021ff7e4d0dSHuazhong Tan shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u, 1022ff7e4d0dSHuazhong Tan ir_para.ir_s, 102384844054SSalil HCLGE_SHAPER_BS_U_DEF, 102484844054SSalil HCLGE_SHAPER_BS_S_DEF); 102563cbf7a9SYufeng Mo ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, 1026e364ad30SYonglong Liu vport->vport_id, shaper_para, 1027e364ad30SYonglong Liu vport->bw_limit); 102884844054SSalil if (ret) 102984844054SSalil return ret; 103084844054SSalil 103184844054SSalil return 0; 103284844054SSalil } 103384844054SSalil 103484844054SSalil static int hclge_tm_pri_vnet_base_shaper_qs_cfg(struct hclge_vport *vport) 103584844054SSalil { 103684844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 103784844054SSalil struct hclge_dev *hdev = vport->back; 1038d9c7d20dSGuangbin Huang u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; 1039ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para ir_para; 104084844054SSalil u32 i; 104184844054SSalil int ret; 104284844054SSalil 104335244430SJian Shen for (i = 0; i < kinfo->tc_info.num_tc; i++) { 1044ff7e4d0dSHuazhong Tan ret = hclge_shaper_para_calc(hdev->tm_info.tc_info[i].bw_limit, 104584844054SSalil HCLGE_SHAPER_LVL_QSET, 1046ff7e4d0dSHuazhong Tan &ir_para, max_tm_rate); 104784844054SSalil if (ret) 104884844054SSalil return ret; 104984844054SSalil } 105084844054SSalil 105184844054SSalil return 0; 105284844054SSalil } 105384844054SSalil 105484844054SSalil static int hclge_tm_pri_vnet_base_shaper_cfg(struct hclge_dev *hdev) 105584844054SSalil { 105684844054SSalil struct hclge_vport *vport = hdev->vport; 105784844054SSalil int ret; 105884844054SSalil u32 i; 105984844054SSalil 106084844054SSalil /* Need config vport shaper */ 106184844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 106284844054SSalil ret = hclge_tm_pri_vnet_base_shaper_pri_cfg(vport); 106384844054SSalil if (ret) 106484844054SSalil return ret; 106584844054SSalil 106684844054SSalil ret = hclge_tm_pri_vnet_base_shaper_qs_cfg(vport); 106784844054SSalil if (ret) 106884844054SSalil return ret; 106984844054SSalil 107084844054SSalil vport++; 107184844054SSalil } 107284844054SSalil 107384844054SSalil return 0; 107484844054SSalil } 107584844054SSalil 107684844054SSalil static int hclge_tm_pri_shaper_cfg(struct hclge_dev *hdev) 107784844054SSalil { 107884844054SSalil int ret; 107984844054SSalil 108084844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 108184844054SSalil ret = hclge_tm_pri_tc_base_shaper_cfg(hdev); 108284844054SSalil if (ret) 108384844054SSalil return ret; 108484844054SSalil } else { 108584844054SSalil ret = hclge_tm_pri_vnet_base_shaper_cfg(hdev); 108684844054SSalil if (ret) 108784844054SSalil return ret; 108884844054SSalil } 108984844054SSalil 109084844054SSalil return 0; 109184844054SSalil } 109284844054SSalil 109384844054SSalil static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev) 109484844054SSalil { 1095cc9bb43aSYunsheng Lin struct hclge_vport *vport = hdev->vport; 109684844054SSalil struct hclge_pg_info *pg_info; 109784844054SSalil u8 dwrr; 109884844054SSalil int ret; 1099cc9bb43aSYunsheng Lin u32 i, k; 110084844054SSalil 110184844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 110284844054SSalil pg_info = 110384844054SSalil &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; 110484844054SSalil dwrr = pg_info->tc_dwrr[i]; 110584844054SSalil 110684844054SSalil ret = hclge_tm_pri_weight_cfg(hdev, i, dwrr); 110784844054SSalil if (ret) 110884844054SSalil return ret; 110984844054SSalil 1110cc9bb43aSYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 1111cc9bb43aSYunsheng Lin ret = hclge_tm_qs_weight_cfg( 1112cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, 1113cc9bb43aSYunsheng Lin vport[k].dwrr); 111484844054SSalil if (ret) 111584844054SSalil return ret; 111684844054SSalil } 1117cc9bb43aSYunsheng Lin } 111884844054SSalil 111984844054SSalil return 0; 112084844054SSalil } 112184844054SSalil 1122330baff5SYunsheng Lin static int hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev *hdev) 1123330baff5SYunsheng Lin { 1124330baff5SYunsheng Lin #define DEFAULT_TC_WEIGHT 1 1125330baff5SYunsheng Lin #define DEFAULT_TC_OFFSET 14 1126330baff5SYunsheng Lin 1127330baff5SYunsheng Lin struct hclge_ets_tc_weight_cmd *ets_weight; 1128330baff5SYunsheng Lin struct hclge_desc desc; 1129ebaf1908SWeihang Li unsigned int i; 1130330baff5SYunsheng Lin 1131330baff5SYunsheng Lin hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_ETS_TC_WEIGHT, false); 1132330baff5SYunsheng Lin ets_weight = (struct hclge_ets_tc_weight_cmd *)desc.data; 1133330baff5SYunsheng Lin 1134330baff5SYunsheng Lin for (i = 0; i < HNAE3_MAX_TC; i++) { 1135330baff5SYunsheng Lin struct hclge_pg_info *pg_info; 1136330baff5SYunsheng Lin 1137330baff5SYunsheng Lin ets_weight->tc_weight[i] = DEFAULT_TC_WEIGHT; 1138330baff5SYunsheng Lin 1139330baff5SYunsheng Lin if (!(hdev->hw_tc_map & BIT(i))) 1140330baff5SYunsheng Lin continue; 1141330baff5SYunsheng Lin 1142330baff5SYunsheng Lin pg_info = 1143330baff5SYunsheng Lin &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; 1144330baff5SYunsheng Lin ets_weight->tc_weight[i] = pg_info->tc_dwrr[i]; 1145330baff5SYunsheng Lin } 1146330baff5SYunsheng Lin 1147330baff5SYunsheng Lin ets_weight->weight_offset = DEFAULT_TC_OFFSET; 1148330baff5SYunsheng Lin 1149330baff5SYunsheng Lin return hclge_cmd_send(&hdev->hw, &desc, 1); 1150330baff5SYunsheng Lin } 1151330baff5SYunsheng Lin 115284844054SSalil static int hclge_tm_pri_vnet_base_dwrr_pri_cfg(struct hclge_vport *vport) 115384844054SSalil { 115484844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 115584844054SSalil struct hclge_dev *hdev = vport->back; 115684844054SSalil int ret; 115784844054SSalil u8 i; 115884844054SSalil 115984844054SSalil /* Vf dwrr */ 116084844054SSalil ret = hclge_tm_pri_weight_cfg(hdev, vport->vport_id, vport->dwrr); 116184844054SSalil if (ret) 116284844054SSalil return ret; 116384844054SSalil 116484844054SSalil /* Qset dwrr */ 116535244430SJian Shen for (i = 0; i < kinfo->tc_info.num_tc; i++) { 116684844054SSalil ret = hclge_tm_qs_weight_cfg( 116784844054SSalil hdev, vport->qs_offset + i, 116884844054SSalil hdev->tm_info.pg_info[0].tc_dwrr[i]); 116984844054SSalil if (ret) 117084844054SSalil return ret; 117184844054SSalil } 117284844054SSalil 117384844054SSalil return 0; 117484844054SSalil } 117584844054SSalil 117684844054SSalil static int hclge_tm_pri_vnet_base_dwrr_cfg(struct hclge_dev *hdev) 117784844054SSalil { 117884844054SSalil struct hclge_vport *vport = hdev->vport; 117984844054SSalil int ret; 118084844054SSalil u32 i; 118184844054SSalil 118284844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 118384844054SSalil ret = hclge_tm_pri_vnet_base_dwrr_pri_cfg(vport); 118484844054SSalil if (ret) 118584844054SSalil return ret; 118684844054SSalil 118784844054SSalil vport++; 118884844054SSalil } 118984844054SSalil 119084844054SSalil return 0; 119184844054SSalil } 119284844054SSalil 119384844054SSalil static int hclge_tm_pri_dwrr_cfg(struct hclge_dev *hdev) 119484844054SSalil { 119584844054SSalil int ret; 119684844054SSalil 119784844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 119884844054SSalil ret = hclge_tm_pri_tc_base_dwrr_cfg(hdev); 119984844054SSalil if (ret) 120084844054SSalil return ret; 1201330baff5SYunsheng Lin 1202330baff5SYunsheng Lin if (!hnae3_dev_dcb_supported(hdev)) 1203330baff5SYunsheng Lin return 0; 1204330baff5SYunsheng Lin 1205330baff5SYunsheng Lin ret = hclge_tm_ets_tc_dwrr_cfg(hdev); 1206330baff5SYunsheng Lin if (ret == -EOPNOTSUPP) { 1207330baff5SYunsheng Lin dev_warn(&hdev->pdev->dev, 1208330baff5SYunsheng Lin "fw %08x does't support ets tc weight cmd\n", 1209330baff5SYunsheng Lin hdev->fw_version); 1210330baff5SYunsheng Lin ret = 0; 1211330baff5SYunsheng Lin } 1212330baff5SYunsheng Lin 1213330baff5SYunsheng Lin return ret; 121484844054SSalil } else { 121584844054SSalil ret = hclge_tm_pri_vnet_base_dwrr_cfg(hdev); 121684844054SSalil if (ret) 121784844054SSalil return ret; 121884844054SSalil } 121984844054SSalil 122084844054SSalil return 0; 122184844054SSalil } 122284844054SSalil 12239e5157baSYunsheng Lin static int hclge_tm_map_cfg(struct hclge_dev *hdev) 122484844054SSalil { 122584844054SSalil int ret; 122684844054SSalil 122777f255c1SYunsheng Lin ret = hclge_up_to_tc_map(hdev); 122877f255c1SYunsheng Lin if (ret) 122977f255c1SYunsheng Lin return ret; 123077f255c1SYunsheng Lin 123184844054SSalil ret = hclge_tm_pg_to_pri_map(hdev); 123284844054SSalil if (ret) 123384844054SSalil return ret; 123484844054SSalil 123584844054SSalil return hclge_tm_pri_q_qs_cfg(hdev); 123684844054SSalil } 123784844054SSalil 123884844054SSalil static int hclge_tm_shaper_cfg(struct hclge_dev *hdev) 123984844054SSalil { 124084844054SSalil int ret; 124184844054SSalil 12420a5677d3SYunsheng Lin ret = hclge_tm_port_shaper_cfg(hdev); 12430a5677d3SYunsheng Lin if (ret) 12440a5677d3SYunsheng Lin return ret; 12450a5677d3SYunsheng Lin 124684844054SSalil ret = hclge_tm_pg_shaper_cfg(hdev); 124784844054SSalil if (ret) 124884844054SSalil return ret; 124984844054SSalil 125084844054SSalil return hclge_tm_pri_shaper_cfg(hdev); 125184844054SSalil } 125284844054SSalil 125384844054SSalil int hclge_tm_dwrr_cfg(struct hclge_dev *hdev) 125484844054SSalil { 125584844054SSalil int ret; 125684844054SSalil 125784844054SSalil ret = hclge_tm_pg_dwrr_cfg(hdev); 125884844054SSalil if (ret) 125984844054SSalil return ret; 126084844054SSalil 126184844054SSalil return hclge_tm_pri_dwrr_cfg(hdev); 126284844054SSalil } 126384844054SSalil 126484844054SSalil static int hclge_tm_lvl2_schd_mode_cfg(struct hclge_dev *hdev) 126584844054SSalil { 126684844054SSalil int ret; 126784844054SSalil u8 i; 126884844054SSalil 126984844054SSalil /* Only being config on TC-Based scheduler mode */ 127084844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) 127184844054SSalil return 0; 127284844054SSalil 127384844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 127484844054SSalil ret = hclge_tm_pg_schd_mode_cfg(hdev, i); 127584844054SSalil if (ret) 127684844054SSalil return ret; 127784844054SSalil } 127884844054SSalil 127984844054SSalil return 0; 128084844054SSalil } 128184844054SSalil 128284844054SSalil static int hclge_tm_schd_mode_vnet_base_cfg(struct hclge_vport *vport) 128384844054SSalil { 128484844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 128584844054SSalil struct hclge_dev *hdev = vport->back; 128684844054SSalil int ret; 128784844054SSalil u8 i; 128884844054SSalil 128904f25edbSYunsheng Lin if (vport->vport_id >= HNAE3_MAX_TC) 129004f25edbSYunsheng Lin return -EINVAL; 129104f25edbSYunsheng Lin 129284844054SSalil ret = hclge_tm_pri_schd_mode_cfg(hdev, vport->vport_id); 129384844054SSalil if (ret) 129484844054SSalil return ret; 129584844054SSalil 129635244430SJian Shen for (i = 0; i < kinfo->tc_info.num_tc; i++) { 1297cc9bb43aSYunsheng Lin u8 sch_mode = hdev->tm_info.tc_info[i].tc_sch_mode; 1298cc9bb43aSYunsheng Lin 1299cc9bb43aSYunsheng Lin ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i, 1300cc9bb43aSYunsheng Lin sch_mode); 130184844054SSalil if (ret) 130284844054SSalil return ret; 130384844054SSalil } 130484844054SSalil 130584844054SSalil return 0; 130684844054SSalil } 130784844054SSalil 130884844054SSalil static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev *hdev) 130984844054SSalil { 131084844054SSalil struct hclge_vport *vport = hdev->vport; 131184844054SSalil int ret; 1312cc9bb43aSYunsheng Lin u8 i, k; 131384844054SSalil 131484844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 131584844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 131684844054SSalil ret = hclge_tm_pri_schd_mode_cfg(hdev, i); 131784844054SSalil if (ret) 131884844054SSalil return ret; 131984844054SSalil 1320cc9bb43aSYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 1321cc9bb43aSYunsheng Lin ret = hclge_tm_qs_schd_mode_cfg( 1322cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, 1323cc9bb43aSYunsheng Lin HCLGE_SCH_MODE_DWRR); 132484844054SSalil if (ret) 132584844054SSalil return ret; 132684844054SSalil } 1327cc9bb43aSYunsheng Lin } 132884844054SSalil } else { 132984844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 133084844054SSalil ret = hclge_tm_schd_mode_vnet_base_cfg(vport); 133184844054SSalil if (ret) 133284844054SSalil return ret; 133384844054SSalil 133484844054SSalil vport++; 133584844054SSalil } 133684844054SSalil } 133784844054SSalil 133884844054SSalil return 0; 133984844054SSalil } 134084844054SSalil 13419e5157baSYunsheng Lin static int hclge_tm_schd_mode_hw(struct hclge_dev *hdev) 134284844054SSalil { 134384844054SSalil int ret; 134484844054SSalil 134584844054SSalil ret = hclge_tm_lvl2_schd_mode_cfg(hdev); 134684844054SSalil if (ret) 134784844054SSalil return ret; 134884844054SSalil 134984844054SSalil return hclge_tm_lvl34_schd_mode_cfg(hdev); 135084844054SSalil } 135184844054SSalil 13529e5157baSYunsheng Lin int hclge_tm_schd_setup_hw(struct hclge_dev *hdev) 135384844054SSalil { 135484844054SSalil int ret; 135584844054SSalil 135684844054SSalil /* Cfg tm mapping */ 135784844054SSalil ret = hclge_tm_map_cfg(hdev); 135884844054SSalil if (ret) 135984844054SSalil return ret; 136084844054SSalil 136184844054SSalil /* Cfg tm shaper */ 136284844054SSalil ret = hclge_tm_shaper_cfg(hdev); 136384844054SSalil if (ret) 136484844054SSalil return ret; 136584844054SSalil 136684844054SSalil /* Cfg dwrr */ 136784844054SSalil ret = hclge_tm_dwrr_cfg(hdev); 136884844054SSalil if (ret) 136984844054SSalil return ret; 137084844054SSalil 137184844054SSalil /* Cfg schd mode for each level schd */ 137284844054SSalil return hclge_tm_schd_mode_hw(hdev); 137384844054SSalil } 137484844054SSalil 1375e98d7183SFuyun Liang static int hclge_pause_param_setup_hw(struct hclge_dev *hdev) 137618838d0cSFuyun Liang { 137718838d0cSFuyun Liang struct hclge_mac *mac = &hdev->hw.mac; 137818838d0cSFuyun Liang 1379e98d7183SFuyun Liang return hclge_pause_param_cfg(hdev, mac->mac_addr, 138018838d0cSFuyun Liang HCLGE_DEFAULT_PAUSE_TRANS_GAP, 138118838d0cSFuyun Liang HCLGE_DEFAULT_PAUSE_TRANS_TIME); 138218838d0cSFuyun Liang } 138318838d0cSFuyun Liang 13849dc2145dSYunsheng Lin static int hclge_pfc_setup_hw(struct hclge_dev *hdev) 13859dc2145dSYunsheng Lin { 13869dc2145dSYunsheng Lin u8 enable_bitmap = 0; 13879dc2145dSYunsheng Lin 13889dc2145dSYunsheng Lin if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) 13899dc2145dSYunsheng Lin enable_bitmap = HCLGE_TX_MAC_PAUSE_EN_MSK | 13909dc2145dSYunsheng Lin HCLGE_RX_MAC_PAUSE_EN_MSK; 13919dc2145dSYunsheng Lin 13929dc2145dSYunsheng Lin return hclge_pfc_pause_en_cfg(hdev, enable_bitmap, 1393d3ad430aSYunsheng Lin hdev->tm_info.pfc_en); 13949dc2145dSYunsheng Lin } 13959dc2145dSYunsheng Lin 13969a5ef4aaSYonglong Liu /* for the queues that use for backpress, divides to several groups, 13979a5ef4aaSYonglong Liu * each group contains 32 queue sets, which can be represented by u32 bitmap. 139867bf2541SYunsheng Lin */ 139967bf2541SYunsheng Lin static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc) 140067bf2541SYunsheng Lin { 14019a5ef4aaSYonglong Liu u16 grp_id_shift = HCLGE_BP_GRP_ID_S; 14029a5ef4aaSYonglong Liu u16 grp_id_mask = HCLGE_BP_GRP_ID_M; 14039a5ef4aaSYonglong Liu u8 grp_num = HCLGE_BP_GRP_NUM; 1404e8ccbb7dSYunsheng Lin int i; 140567bf2541SYunsheng Lin 14069a5ef4aaSYonglong Liu if (hdev->num_tqps > HCLGE_TQP_MAX_SIZE_DEV_V2) { 14079a5ef4aaSYonglong Liu grp_num = HCLGE_BP_EXT_GRP_NUM; 14089a5ef4aaSYonglong Liu grp_id_mask = HCLGE_BP_EXT_GRP_ID_M; 14099a5ef4aaSYonglong Liu grp_id_shift = HCLGE_BP_EXT_GRP_ID_S; 14109a5ef4aaSYonglong Liu } 14119a5ef4aaSYonglong Liu 14129a5ef4aaSYonglong Liu for (i = 0; i < grp_num; i++) { 1413e8ccbb7dSYunsheng Lin u32 qs_bitmap = 0; 1414e8ccbb7dSYunsheng Lin int k, ret; 141567bf2541SYunsheng Lin 141667bf2541SYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 1417e8ccbb7dSYunsheng Lin struct hclge_vport *vport = &hdev->vport[k]; 141867bf2541SYunsheng Lin u16 qs_id = vport->qs_offset + tc; 141967bf2541SYunsheng Lin u8 grp, sub_grp; 142067bf2541SYunsheng Lin 14219a5ef4aaSYonglong Liu grp = hnae3_get_field(qs_id, grp_id_mask, grp_id_shift); 1422e4e87715SPeng Li sub_grp = hnae3_get_field(qs_id, HCLGE_BP_SUB_GRP_ID_M, 142367bf2541SYunsheng Lin HCLGE_BP_SUB_GRP_ID_S); 142467bf2541SYunsheng Lin if (i == grp) 142567bf2541SYunsheng Lin qs_bitmap |= (1 << sub_grp); 142667bf2541SYunsheng Lin } 142767bf2541SYunsheng Lin 142867bf2541SYunsheng Lin ret = hclge_tm_qs_bp_cfg(hdev, tc, i, qs_bitmap); 142967bf2541SYunsheng Lin if (ret) 143067bf2541SYunsheng Lin return ret; 143167bf2541SYunsheng Lin } 143267bf2541SYunsheng Lin 143367bf2541SYunsheng Lin return 0; 143467bf2541SYunsheng Lin } 143567bf2541SYunsheng Lin 14369dc2145dSYunsheng Lin static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) 14379dc2145dSYunsheng Lin { 14389dc2145dSYunsheng Lin bool tx_en, rx_en; 14399dc2145dSYunsheng Lin 14409dc2145dSYunsheng Lin switch (hdev->tm_info.fc_mode) { 14419dc2145dSYunsheng Lin case HCLGE_FC_NONE: 14429dc2145dSYunsheng Lin tx_en = false; 14439dc2145dSYunsheng Lin rx_en = false; 14449dc2145dSYunsheng Lin break; 14459dc2145dSYunsheng Lin case HCLGE_FC_RX_PAUSE: 14469dc2145dSYunsheng Lin tx_en = false; 14479dc2145dSYunsheng Lin rx_en = true; 14489dc2145dSYunsheng Lin break; 14499dc2145dSYunsheng Lin case HCLGE_FC_TX_PAUSE: 14509dc2145dSYunsheng Lin tx_en = true; 14519dc2145dSYunsheng Lin rx_en = false; 14529dc2145dSYunsheng Lin break; 14539dc2145dSYunsheng Lin case HCLGE_FC_FULL: 14549dc2145dSYunsheng Lin tx_en = true; 14559dc2145dSYunsheng Lin rx_en = true; 14569dc2145dSYunsheng Lin break; 14576d0ec65cSYunsheng Lin case HCLGE_FC_PFC: 14586d0ec65cSYunsheng Lin tx_en = false; 14596d0ec65cSYunsheng Lin rx_en = false; 14606d0ec65cSYunsheng Lin break; 14619dc2145dSYunsheng Lin default: 14629dc2145dSYunsheng Lin tx_en = true; 14639dc2145dSYunsheng Lin rx_en = true; 14649dc2145dSYunsheng Lin } 14659dc2145dSYunsheng Lin 14669dc2145dSYunsheng Lin return hclge_mac_pause_en_cfg(hdev, tx_en, rx_en); 14679dc2145dSYunsheng Lin } 14689dc2145dSYunsheng Lin 146973fc9c48SHuazhong Tan static int hclge_tm_bp_setup(struct hclge_dev *hdev) 147073fc9c48SHuazhong Tan { 14719d8d5a36SYufeng Mo int ret; 147273fc9c48SHuazhong Tan int i; 147373fc9c48SHuazhong Tan 147473fc9c48SHuazhong Tan for (i = 0; i < hdev->tm_info.num_tc; i++) { 147573fc9c48SHuazhong Tan ret = hclge_bp_setup_hw(hdev, i); 147673fc9c48SHuazhong Tan if (ret) 147773fc9c48SHuazhong Tan return ret; 147873fc9c48SHuazhong Tan } 147973fc9c48SHuazhong Tan 1480ee7a3764SDan Carpenter return 0; 148173fc9c48SHuazhong Tan } 148273fc9c48SHuazhong Tan 148344e59e37SYunsheng Lin int hclge_pause_setup_hw(struct hclge_dev *hdev, bool init) 148484844054SSalil { 148584844054SSalil int ret; 148684844054SSalil 1487e98d7183SFuyun Liang ret = hclge_pause_param_setup_hw(hdev); 148818838d0cSFuyun Liang if (ret) 148918838d0cSFuyun Liang return ret; 149018838d0cSFuyun Liang 14916d0ec65cSYunsheng Lin ret = hclge_mac_pause_setup_hw(hdev); 14926d0ec65cSYunsheng Lin if (ret) 14936d0ec65cSYunsheng Lin return ret; 149484844054SSalil 14959dc2145dSYunsheng Lin /* Only DCB-supported dev supports qset back pressure and pfc cmd */ 14962daf4a65SYunsheng Lin if (!hnae3_dev_dcb_supported(hdev)) 14972daf4a65SYunsheng Lin return 0; 14982daf4a65SYunsheng Lin 149944e59e37SYunsheng Lin /* GE MAC does not support PFC, when driver is initializing and MAC 150044e59e37SYunsheng Lin * is in GE Mode, ignore the error here, otherwise initialization 150144e59e37SYunsheng Lin * will fail. 150244e59e37SYunsheng Lin */ 15039dc2145dSYunsheng Lin ret = hclge_pfc_setup_hw(hdev); 150444e59e37SYunsheng Lin if (init && ret == -EOPNOTSUPP) 150544e59e37SYunsheng Lin dev_warn(&hdev->pdev->dev, "GE MAC does not support pfc\n"); 1506fba2efdaSHuazhong Tan else if (ret) { 1507fba2efdaSHuazhong Tan dev_err(&hdev->pdev->dev, "config pfc failed! ret = %d\n", 1508fba2efdaSHuazhong Tan ret); 150944e59e37SYunsheng Lin return ret; 1510fba2efdaSHuazhong Tan } 15119dc2145dSYunsheng Lin 151273fc9c48SHuazhong Tan return hclge_tm_bp_setup(hdev); 151377f255c1SYunsheng Lin } 151477f255c1SYunsheng Lin 1515e432abfbSYunsheng Lin void hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc) 151677f255c1SYunsheng Lin { 151777f255c1SYunsheng Lin struct hclge_vport *vport = hdev->vport; 151877f255c1SYunsheng Lin struct hnae3_knic_private_info *kinfo; 151977f255c1SYunsheng Lin u32 i, k; 152077f255c1SYunsheng Lin 152177f255c1SYunsheng Lin for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) { 152277f255c1SYunsheng Lin hdev->tm_info.prio_tc[i] = prio_tc[i]; 152377f255c1SYunsheng Lin 152477f255c1SYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 152577f255c1SYunsheng Lin kinfo = &vport[k].nic.kinfo; 152635244430SJian Shen kinfo->tc_info.prio_tc[i] = prio_tc[i]; 152777f255c1SYunsheng Lin } 152877f255c1SYunsheng Lin } 152977f255c1SYunsheng Lin } 153077f255c1SYunsheng Lin 1531e432abfbSYunsheng Lin void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc) 153277f255c1SYunsheng Lin { 15339b2f3477SWeihang Li u8 bit_map = 0; 15349b2f3477SWeihang Li u8 i; 153577f255c1SYunsheng Lin 153677f255c1SYunsheng Lin hdev->tm_info.num_tc = num_tc; 153777f255c1SYunsheng Lin 153877f255c1SYunsheng Lin for (i = 0; i < hdev->tm_info.num_tc; i++) 153977f255c1SYunsheng Lin bit_map |= BIT(i); 154077f255c1SYunsheng Lin 154177f255c1SYunsheng Lin if (!bit_map) { 154277f255c1SYunsheng Lin bit_map = 1; 154377f255c1SYunsheng Lin hdev->tm_info.num_tc = 1; 154477f255c1SYunsheng Lin } 154577f255c1SYunsheng Lin 154677f255c1SYunsheng Lin hdev->hw_tc_map = bit_map; 154777f255c1SYunsheng Lin 154877f255c1SYunsheng Lin hclge_tm_schd_info_init(hdev); 154984844054SSalil } 155084844054SSalil 155144e59e37SYunsheng Lin int hclge_tm_init_hw(struct hclge_dev *hdev, bool init) 155284844054SSalil { 155384844054SSalil int ret; 155484844054SSalil 155584844054SSalil if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) && 155684844054SSalil (hdev->tx_sch_mode != HCLGE_FLAG_VNET_BASE_SCH_MODE)) 155784844054SSalil return -ENOTSUPP; 155884844054SSalil 155984844054SSalil ret = hclge_tm_schd_setup_hw(hdev); 156084844054SSalil if (ret) 156184844054SSalil return ret; 156284844054SSalil 156344e59e37SYunsheng Lin ret = hclge_pause_setup_hw(hdev, init); 156484844054SSalil if (ret) 156584844054SSalil return ret; 156684844054SSalil 156784844054SSalil return 0; 156884844054SSalil } 156984844054SSalil 157084844054SSalil int hclge_tm_schd_init(struct hclge_dev *hdev) 157184844054SSalil { 15727979a223SYunsheng Lin /* fc_mode is HCLGE_FC_FULL on reset */ 15737979a223SYunsheng Lin hdev->tm_info.fc_mode = HCLGE_FC_FULL; 15747979a223SYunsheng Lin hdev->fc_mode_last_time = hdev->tm_info.fc_mode; 15757979a223SYunsheng Lin 1576b6872fd3SYunsheng Lin if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE && 1577b6872fd3SYunsheng Lin hdev->tm_info.num_pg != 1) 1578b6872fd3SYunsheng Lin return -EINVAL; 1579b6872fd3SYunsheng Lin 1580b6872fd3SYunsheng Lin hclge_tm_schd_info_init(hdev); 158184844054SSalil 158244e59e37SYunsheng Lin return hclge_tm_init_hw(hdev, true); 158384844054SSalil } 1584672ad0edSHuazhong Tan 1585672ad0edSHuazhong Tan int hclge_tm_vport_map_update(struct hclge_dev *hdev) 1586672ad0edSHuazhong Tan { 1587672ad0edSHuazhong Tan struct hclge_vport *vport = hdev->vport; 1588672ad0edSHuazhong Tan int ret; 1589672ad0edSHuazhong Tan 1590672ad0edSHuazhong Tan hclge_tm_vport_tc_info_update(vport); 1591672ad0edSHuazhong Tan 1592672ad0edSHuazhong Tan ret = hclge_vport_q_to_qs_map(hdev, vport); 1593672ad0edSHuazhong Tan if (ret) 1594672ad0edSHuazhong Tan return ret; 1595672ad0edSHuazhong Tan 1596*0472e95fSJian Shen if (hdev->tm_info.num_tc == 1 && !hdev->tm_info.pfc_en) 1597672ad0edSHuazhong Tan return 0; 1598672ad0edSHuazhong Tan 1599672ad0edSHuazhong Tan return hclge_tm_bp_setup(hdev); 1600672ad0edSHuazhong Tan } 16012bbad0aaSGuangbin Huang 16022bbad0aaSGuangbin Huang int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num) 16032bbad0aaSGuangbin Huang { 16042bbad0aaSGuangbin Huang struct hclge_tm_nodes_cmd *nodes; 16052bbad0aaSGuangbin Huang struct hclge_desc desc; 16062bbad0aaSGuangbin Huang int ret; 16072bbad0aaSGuangbin Huang 16082bbad0aaSGuangbin Huang if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) { 16092bbad0aaSGuangbin Huang /* Each PF has 8 qsets and each VF has 1 qset */ 16102bbad0aaSGuangbin Huang *qset_num = HCLGE_TM_PF_MAX_QSET_NUM + pci_num_vf(hdev->pdev); 16112bbad0aaSGuangbin Huang return 0; 16122bbad0aaSGuangbin Huang } 16132bbad0aaSGuangbin Huang 16142bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NODES, true); 16152bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 16162bbad0aaSGuangbin Huang if (ret) { 16172bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 16182bbad0aaSGuangbin Huang "failed to get qset num, ret = %d\n", ret); 16192bbad0aaSGuangbin Huang return ret; 16202bbad0aaSGuangbin Huang } 16212bbad0aaSGuangbin Huang 16222bbad0aaSGuangbin Huang nodes = (struct hclge_tm_nodes_cmd *)desc.data; 16232bbad0aaSGuangbin Huang *qset_num = le16_to_cpu(nodes->qset_num); 16242bbad0aaSGuangbin Huang return 0; 16252bbad0aaSGuangbin Huang } 16262bbad0aaSGuangbin Huang 16272bbad0aaSGuangbin Huang int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num) 16282bbad0aaSGuangbin Huang { 16292bbad0aaSGuangbin Huang struct hclge_tm_nodes_cmd *nodes; 16302bbad0aaSGuangbin Huang struct hclge_desc desc; 16312bbad0aaSGuangbin Huang int ret; 16322bbad0aaSGuangbin Huang 16332bbad0aaSGuangbin Huang if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) { 16342bbad0aaSGuangbin Huang *pri_num = HCLGE_TM_PF_MAX_PRI_NUM; 16352bbad0aaSGuangbin Huang return 0; 16362bbad0aaSGuangbin Huang } 16372bbad0aaSGuangbin Huang 16382bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NODES, true); 16392bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 16402bbad0aaSGuangbin Huang if (ret) { 16412bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 16422bbad0aaSGuangbin Huang "failed to get pri num, ret = %d\n", ret); 16432bbad0aaSGuangbin Huang return ret; 16442bbad0aaSGuangbin Huang } 16452bbad0aaSGuangbin Huang 16462bbad0aaSGuangbin Huang nodes = (struct hclge_tm_nodes_cmd *)desc.data; 16472bbad0aaSGuangbin Huang *pri_num = nodes->pri_num; 16482bbad0aaSGuangbin Huang return 0; 16492bbad0aaSGuangbin Huang } 16502bbad0aaSGuangbin Huang 16512bbad0aaSGuangbin Huang int hclge_tm_get_qset_map_pri(struct hclge_dev *hdev, u16 qset_id, u8 *priority, 16522bbad0aaSGuangbin Huang u8 *link_vld) 16532bbad0aaSGuangbin Huang { 16542bbad0aaSGuangbin Huang struct hclge_qs_to_pri_link_cmd *map; 16552bbad0aaSGuangbin Huang struct hclge_desc desc; 16562bbad0aaSGuangbin Huang int ret; 16572bbad0aaSGuangbin Huang 16582bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_TO_PRI_LINK, true); 16592bbad0aaSGuangbin Huang map = (struct hclge_qs_to_pri_link_cmd *)desc.data; 16602bbad0aaSGuangbin Huang map->qs_id = cpu_to_le16(qset_id); 16612bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 16622bbad0aaSGuangbin Huang if (ret) { 16632bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 16642bbad0aaSGuangbin Huang "failed to get qset map priority, ret = %d\n", ret); 16652bbad0aaSGuangbin Huang return ret; 16662bbad0aaSGuangbin Huang } 16672bbad0aaSGuangbin Huang 16682bbad0aaSGuangbin Huang *priority = map->priority; 16692bbad0aaSGuangbin Huang *link_vld = map->link_vld; 16702bbad0aaSGuangbin Huang return 0; 16712bbad0aaSGuangbin Huang } 16722bbad0aaSGuangbin Huang 16732bbad0aaSGuangbin Huang int hclge_tm_get_qset_sch_mode(struct hclge_dev *hdev, u16 qset_id, u8 *mode) 16742bbad0aaSGuangbin Huang { 16752bbad0aaSGuangbin Huang struct hclge_qs_sch_mode_cfg_cmd *qs_sch_mode; 16762bbad0aaSGuangbin Huang struct hclge_desc desc; 16772bbad0aaSGuangbin Huang int ret; 16782bbad0aaSGuangbin Huang 16792bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_SCH_MODE_CFG, true); 16802bbad0aaSGuangbin Huang qs_sch_mode = (struct hclge_qs_sch_mode_cfg_cmd *)desc.data; 16812bbad0aaSGuangbin Huang qs_sch_mode->qs_id = cpu_to_le16(qset_id); 16822bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 16832bbad0aaSGuangbin Huang if (ret) { 16842bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 16852bbad0aaSGuangbin Huang "failed to get qset sch mode, ret = %d\n", ret); 16862bbad0aaSGuangbin Huang return ret; 16872bbad0aaSGuangbin Huang } 16882bbad0aaSGuangbin Huang 16892bbad0aaSGuangbin Huang *mode = qs_sch_mode->sch_mode; 16902bbad0aaSGuangbin Huang return 0; 16912bbad0aaSGuangbin Huang } 16922bbad0aaSGuangbin Huang 16932bbad0aaSGuangbin Huang int hclge_tm_get_qset_weight(struct hclge_dev *hdev, u16 qset_id, u8 *weight) 16942bbad0aaSGuangbin Huang { 16952bbad0aaSGuangbin Huang struct hclge_qs_weight_cmd *qs_weight; 16962bbad0aaSGuangbin Huang struct hclge_desc desc; 16972bbad0aaSGuangbin Huang int ret; 16982bbad0aaSGuangbin Huang 16992bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_WEIGHT, true); 17002bbad0aaSGuangbin Huang qs_weight = (struct hclge_qs_weight_cmd *)desc.data; 17012bbad0aaSGuangbin Huang qs_weight->qs_id = cpu_to_le16(qset_id); 17022bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 17032bbad0aaSGuangbin Huang if (ret) { 17042bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 17052bbad0aaSGuangbin Huang "failed to get qset weight, ret = %d\n", ret); 17062bbad0aaSGuangbin Huang return ret; 17072bbad0aaSGuangbin Huang } 17082bbad0aaSGuangbin Huang 17092bbad0aaSGuangbin Huang *weight = qs_weight->dwrr; 17102bbad0aaSGuangbin Huang return 0; 17112bbad0aaSGuangbin Huang } 17122bbad0aaSGuangbin Huang 1713484e1ed1SGuangbin Huang int hclge_tm_get_qset_shaper(struct hclge_dev *hdev, u16 qset_id, 1714484e1ed1SGuangbin Huang struct hclge_tm_shaper_para *para) 1715484e1ed1SGuangbin Huang { 1716484e1ed1SGuangbin Huang struct hclge_qs_shapping_cmd *shap_cfg_cmd; 1717484e1ed1SGuangbin Huang struct hclge_desc desc; 1718484e1ed1SGuangbin Huang u32 shapping_para; 1719484e1ed1SGuangbin Huang int ret; 1720484e1ed1SGuangbin Huang 1721484e1ed1SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QCN_SHAPPING_CFG, true); 1722484e1ed1SGuangbin Huang shap_cfg_cmd = (struct hclge_qs_shapping_cmd *)desc.data; 1723484e1ed1SGuangbin Huang shap_cfg_cmd->qs_id = cpu_to_le16(qset_id); 1724484e1ed1SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1725484e1ed1SGuangbin Huang if (ret) { 1726484e1ed1SGuangbin Huang dev_err(&hdev->pdev->dev, 1727484e1ed1SGuangbin Huang "failed to get qset %u shaper, ret = %d\n", qset_id, 1728484e1ed1SGuangbin Huang ret); 1729484e1ed1SGuangbin Huang return ret; 1730484e1ed1SGuangbin Huang } 1731484e1ed1SGuangbin Huang 1732484e1ed1SGuangbin Huang shapping_para = le32_to_cpu(shap_cfg_cmd->qs_shapping_para); 1733484e1ed1SGuangbin Huang para->ir_b = hclge_tm_get_field(shapping_para, IR_B); 1734484e1ed1SGuangbin Huang para->ir_u = hclge_tm_get_field(shapping_para, IR_U); 1735484e1ed1SGuangbin Huang para->ir_s = hclge_tm_get_field(shapping_para, IR_S); 1736484e1ed1SGuangbin Huang para->bs_b = hclge_tm_get_field(shapping_para, BS_B); 1737484e1ed1SGuangbin Huang para->bs_s = hclge_tm_get_field(shapping_para, BS_S); 1738484e1ed1SGuangbin Huang para->flag = shap_cfg_cmd->flag; 1739484e1ed1SGuangbin Huang para->rate = le32_to_cpu(shap_cfg_cmd->qs_rate); 1740484e1ed1SGuangbin Huang return 0; 1741484e1ed1SGuangbin Huang } 1742484e1ed1SGuangbin Huang 17432bbad0aaSGuangbin Huang int hclge_tm_get_pri_sch_mode(struct hclge_dev *hdev, u8 pri_id, u8 *mode) 17442bbad0aaSGuangbin Huang { 17452bbad0aaSGuangbin Huang struct hclge_pri_sch_mode_cfg_cmd *pri_sch_mode; 17462bbad0aaSGuangbin Huang struct hclge_desc desc; 17472bbad0aaSGuangbin Huang int ret; 17482bbad0aaSGuangbin Huang 17492bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_SCH_MODE_CFG, true); 17502bbad0aaSGuangbin Huang pri_sch_mode = (struct hclge_pri_sch_mode_cfg_cmd *)desc.data; 17512bbad0aaSGuangbin Huang pri_sch_mode->pri_id = pri_id; 17522bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 17532bbad0aaSGuangbin Huang if (ret) { 17542bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 17552bbad0aaSGuangbin Huang "failed to get priority sch mode, ret = %d\n", ret); 17562bbad0aaSGuangbin Huang return ret; 17572bbad0aaSGuangbin Huang } 17582bbad0aaSGuangbin Huang 17592bbad0aaSGuangbin Huang *mode = pri_sch_mode->sch_mode; 17602bbad0aaSGuangbin Huang return 0; 17612bbad0aaSGuangbin Huang } 17622bbad0aaSGuangbin Huang 17632bbad0aaSGuangbin Huang int hclge_tm_get_pri_weight(struct hclge_dev *hdev, u8 pri_id, u8 *weight) 17642bbad0aaSGuangbin Huang { 17652bbad0aaSGuangbin Huang struct hclge_priority_weight_cmd *priority_weight; 17662bbad0aaSGuangbin Huang struct hclge_desc desc; 17672bbad0aaSGuangbin Huang int ret; 17682bbad0aaSGuangbin Huang 17692bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_WEIGHT, true); 17702bbad0aaSGuangbin Huang priority_weight = (struct hclge_priority_weight_cmd *)desc.data; 17712bbad0aaSGuangbin Huang priority_weight->pri_id = pri_id; 17722bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 17732bbad0aaSGuangbin Huang if (ret) { 17742bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 17752bbad0aaSGuangbin Huang "failed to get priority weight, ret = %d\n", ret); 17762bbad0aaSGuangbin Huang return ret; 17772bbad0aaSGuangbin Huang } 17782bbad0aaSGuangbin Huang 17792bbad0aaSGuangbin Huang *weight = priority_weight->dwrr; 17802bbad0aaSGuangbin Huang return 0; 17812bbad0aaSGuangbin Huang } 17822bbad0aaSGuangbin Huang 17832bbad0aaSGuangbin Huang int hclge_tm_get_pri_shaper(struct hclge_dev *hdev, u8 pri_id, 17842bbad0aaSGuangbin Huang enum hclge_opcode_type cmd, 1785cad7c215SGuangbin Huang struct hclge_tm_shaper_para *para) 17862bbad0aaSGuangbin Huang { 17872bbad0aaSGuangbin Huang struct hclge_pri_shapping_cmd *shap_cfg_cmd; 17882bbad0aaSGuangbin Huang struct hclge_desc desc; 17892bbad0aaSGuangbin Huang u32 shapping_para; 17902bbad0aaSGuangbin Huang int ret; 17912bbad0aaSGuangbin Huang 17922bbad0aaSGuangbin Huang if (cmd != HCLGE_OPC_TM_PRI_C_SHAPPING && 17932bbad0aaSGuangbin Huang cmd != HCLGE_OPC_TM_PRI_P_SHAPPING) 17942bbad0aaSGuangbin Huang return -EINVAL; 17952bbad0aaSGuangbin Huang 17962bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, cmd, true); 17972bbad0aaSGuangbin Huang shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data; 17982bbad0aaSGuangbin Huang shap_cfg_cmd->pri_id = pri_id; 17992bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 18002bbad0aaSGuangbin Huang if (ret) { 18012bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 18022bbad0aaSGuangbin Huang "failed to get priority shaper(%#x), ret = %d\n", 18032bbad0aaSGuangbin Huang cmd, ret); 18042bbad0aaSGuangbin Huang return ret; 18052bbad0aaSGuangbin Huang } 18062bbad0aaSGuangbin Huang 18072bbad0aaSGuangbin Huang shapping_para = le32_to_cpu(shap_cfg_cmd->pri_shapping_para); 18082bbad0aaSGuangbin Huang para->ir_b = hclge_tm_get_field(shapping_para, IR_B); 18092bbad0aaSGuangbin Huang para->ir_u = hclge_tm_get_field(shapping_para, IR_U); 18102bbad0aaSGuangbin Huang para->ir_s = hclge_tm_get_field(shapping_para, IR_S); 18112bbad0aaSGuangbin Huang para->bs_b = hclge_tm_get_field(shapping_para, BS_B); 18122bbad0aaSGuangbin Huang para->bs_s = hclge_tm_get_field(shapping_para, BS_S); 18132bbad0aaSGuangbin Huang para->flag = shap_cfg_cmd->flag; 18142bbad0aaSGuangbin Huang para->rate = le32_to_cpu(shap_cfg_cmd->pri_rate); 18152bbad0aaSGuangbin Huang return 0; 18162bbad0aaSGuangbin Huang } 18177679f28eSGuangbin Huang 18187679f28eSGuangbin Huang int hclge_tm_get_q_to_qs_map(struct hclge_dev *hdev, u16 q_id, u16 *qset_id) 18197679f28eSGuangbin Huang { 18207679f28eSGuangbin Huang struct hclge_nq_to_qs_link_cmd *map; 18217679f28eSGuangbin Huang struct hclge_desc desc; 18227679f28eSGuangbin Huang u16 qs_id_l; 18237679f28eSGuangbin Huang u16 qs_id_h; 18247679f28eSGuangbin Huang int ret; 18257679f28eSGuangbin Huang 18267679f28eSGuangbin Huang map = (struct hclge_nq_to_qs_link_cmd *)desc.data; 18277679f28eSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NQ_TO_QS_LINK, true); 18287679f28eSGuangbin Huang map->nq_id = cpu_to_le16(q_id); 18297679f28eSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 18307679f28eSGuangbin Huang if (ret) { 18317679f28eSGuangbin Huang dev_err(&hdev->pdev->dev, 18327679f28eSGuangbin Huang "failed to get queue to qset map, ret = %d\n", ret); 18337679f28eSGuangbin Huang return ret; 18347679f28eSGuangbin Huang } 18357679f28eSGuangbin Huang *qset_id = le16_to_cpu(map->qset_id); 18367679f28eSGuangbin Huang 18377679f28eSGuangbin Huang /* convert qset_id to the following format, drop the vld bit 18387679f28eSGuangbin Huang * | qs_id_h | vld | qs_id_l | 18397679f28eSGuangbin Huang * qset_id: | 15 ~ 11 | 10 | 9 ~ 0 | 18407679f28eSGuangbin Huang * \ \ / / 18417679f28eSGuangbin Huang * \ \ / / 18427679f28eSGuangbin Huang * qset_id: | 15 | 14 ~ 10 | 9 ~ 0 | 18437679f28eSGuangbin Huang */ 18447679f28eSGuangbin Huang qs_id_l = hnae3_get_field(*qset_id, HCLGE_TM_QS_ID_L_MSK, 18457679f28eSGuangbin Huang HCLGE_TM_QS_ID_L_S); 18467679f28eSGuangbin Huang qs_id_h = hnae3_get_field(*qset_id, HCLGE_TM_QS_ID_H_EXT_MSK, 18477679f28eSGuangbin Huang HCLGE_TM_QS_ID_H_EXT_S); 18487679f28eSGuangbin Huang *qset_id = 0; 18497679f28eSGuangbin Huang hnae3_set_field(*qset_id, HCLGE_TM_QS_ID_L_MSK, HCLGE_TM_QS_ID_L_S, 18507679f28eSGuangbin Huang qs_id_l); 18517679f28eSGuangbin Huang hnae3_set_field(*qset_id, HCLGE_TM_QS_ID_H_MSK, HCLGE_TM_QS_ID_H_S, 18527679f28eSGuangbin Huang qs_id_h); 18537679f28eSGuangbin Huang return 0; 18547679f28eSGuangbin Huang } 18557679f28eSGuangbin Huang 18567679f28eSGuangbin Huang int hclge_tm_get_q_to_tc(struct hclge_dev *hdev, u16 q_id, u8 *tc_id) 18577679f28eSGuangbin Huang { 18587679f28eSGuangbin Huang #define HCLGE_TM_TC_MASK 0x7 18597679f28eSGuangbin Huang 18607679f28eSGuangbin Huang struct hclge_tqp_tx_queue_tc_cmd *tc; 18617679f28eSGuangbin Huang struct hclge_desc desc; 18627679f28eSGuangbin Huang int ret; 18637679f28eSGuangbin Huang 18647679f28eSGuangbin Huang tc = (struct hclge_tqp_tx_queue_tc_cmd *)desc.data; 18657679f28eSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TQP_TX_QUEUE_TC, true); 18667679f28eSGuangbin Huang tc->queue_id = cpu_to_le16(q_id); 18677679f28eSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 18687679f28eSGuangbin Huang if (ret) { 18697679f28eSGuangbin Huang dev_err(&hdev->pdev->dev, 18707679f28eSGuangbin Huang "failed to get queue to tc map, ret = %d\n", ret); 18717679f28eSGuangbin Huang return ret; 18727679f28eSGuangbin Huang } 18737679f28eSGuangbin Huang 18747679f28eSGuangbin Huang *tc_id = tc->tc_id & HCLGE_TM_TC_MASK; 18757679f28eSGuangbin Huang return 0; 18767679f28eSGuangbin Huang } 1877cad7c215SGuangbin Huang 1878cad7c215SGuangbin Huang int hclge_tm_get_pg_to_pri_map(struct hclge_dev *hdev, u8 pg_id, 1879cad7c215SGuangbin Huang u8 *pri_bit_map) 1880cad7c215SGuangbin Huang { 1881cad7c215SGuangbin Huang struct hclge_pg_to_pri_link_cmd *map; 1882cad7c215SGuangbin Huang struct hclge_desc desc; 1883cad7c215SGuangbin Huang int ret; 1884cad7c215SGuangbin Huang 1885cad7c215SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_TO_PRI_LINK, true); 1886cad7c215SGuangbin Huang map = (struct hclge_pg_to_pri_link_cmd *)desc.data; 1887cad7c215SGuangbin Huang map->pg_id = pg_id; 1888cad7c215SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1889cad7c215SGuangbin Huang if (ret) { 1890cad7c215SGuangbin Huang dev_err(&hdev->pdev->dev, 1891cad7c215SGuangbin Huang "failed to get pg to pri map, ret = %d\n", ret); 1892cad7c215SGuangbin Huang return ret; 1893cad7c215SGuangbin Huang } 1894cad7c215SGuangbin Huang 1895cad7c215SGuangbin Huang *pri_bit_map = map->pri_bit_map; 1896cad7c215SGuangbin Huang return 0; 1897cad7c215SGuangbin Huang } 1898cad7c215SGuangbin Huang 1899cad7c215SGuangbin Huang int hclge_tm_get_pg_weight(struct hclge_dev *hdev, u8 pg_id, u8 *weight) 1900cad7c215SGuangbin Huang { 1901cad7c215SGuangbin Huang struct hclge_pg_weight_cmd *pg_weight_cmd; 1902cad7c215SGuangbin Huang struct hclge_desc desc; 1903cad7c215SGuangbin Huang int ret; 1904cad7c215SGuangbin Huang 1905cad7c215SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_WEIGHT, true); 1906cad7c215SGuangbin Huang pg_weight_cmd = (struct hclge_pg_weight_cmd *)desc.data; 1907cad7c215SGuangbin Huang pg_weight_cmd->pg_id = pg_id; 1908cad7c215SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1909cad7c215SGuangbin Huang if (ret) { 1910cad7c215SGuangbin Huang dev_err(&hdev->pdev->dev, 1911cad7c215SGuangbin Huang "failed to get pg weight, ret = %d\n", ret); 1912cad7c215SGuangbin Huang return ret; 1913cad7c215SGuangbin Huang } 1914cad7c215SGuangbin Huang 1915cad7c215SGuangbin Huang *weight = pg_weight_cmd->dwrr; 1916cad7c215SGuangbin Huang return 0; 1917cad7c215SGuangbin Huang } 1918cad7c215SGuangbin Huang 1919cad7c215SGuangbin Huang int hclge_tm_get_pg_sch_mode(struct hclge_dev *hdev, u8 pg_id, u8 *mode) 1920cad7c215SGuangbin Huang { 1921cad7c215SGuangbin Huang struct hclge_desc desc; 1922cad7c215SGuangbin Huang int ret; 1923cad7c215SGuangbin Huang 1924cad7c215SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_SCH_MODE_CFG, true); 1925cad7c215SGuangbin Huang desc.data[0] = cpu_to_le32(pg_id); 1926cad7c215SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1927cad7c215SGuangbin Huang if (ret) { 1928cad7c215SGuangbin Huang dev_err(&hdev->pdev->dev, 1929cad7c215SGuangbin Huang "failed to get pg sch mode, ret = %d\n", ret); 1930cad7c215SGuangbin Huang return ret; 1931cad7c215SGuangbin Huang } 1932cad7c215SGuangbin Huang 1933cad7c215SGuangbin Huang *mode = (u8)le32_to_cpu(desc.data[1]); 1934cad7c215SGuangbin Huang return 0; 1935cad7c215SGuangbin Huang } 1936cad7c215SGuangbin Huang 1937cad7c215SGuangbin Huang int hclge_tm_get_pg_shaper(struct hclge_dev *hdev, u8 pg_id, 1938cad7c215SGuangbin Huang enum hclge_opcode_type cmd, 1939cad7c215SGuangbin Huang struct hclge_tm_shaper_para *para) 1940cad7c215SGuangbin Huang { 1941cad7c215SGuangbin Huang struct hclge_pg_shapping_cmd *shap_cfg_cmd; 1942cad7c215SGuangbin Huang struct hclge_desc desc; 1943cad7c215SGuangbin Huang u32 shapping_para; 1944cad7c215SGuangbin Huang int ret; 1945cad7c215SGuangbin Huang 1946cad7c215SGuangbin Huang if (cmd != HCLGE_OPC_TM_PG_C_SHAPPING && 1947cad7c215SGuangbin Huang cmd != HCLGE_OPC_TM_PG_P_SHAPPING) 1948cad7c215SGuangbin Huang return -EINVAL; 1949cad7c215SGuangbin Huang 1950cad7c215SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, cmd, true); 1951cad7c215SGuangbin Huang shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data; 1952cad7c215SGuangbin Huang shap_cfg_cmd->pg_id = pg_id; 1953cad7c215SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1954cad7c215SGuangbin Huang if (ret) { 1955cad7c215SGuangbin Huang dev_err(&hdev->pdev->dev, 1956cad7c215SGuangbin Huang "failed to get pg shaper(%#x), ret = %d\n", 1957cad7c215SGuangbin Huang cmd, ret); 1958cad7c215SGuangbin Huang return ret; 1959cad7c215SGuangbin Huang } 1960cad7c215SGuangbin Huang 1961cad7c215SGuangbin Huang shapping_para = le32_to_cpu(shap_cfg_cmd->pg_shapping_para); 1962cad7c215SGuangbin Huang para->ir_b = hclge_tm_get_field(shapping_para, IR_B); 1963cad7c215SGuangbin Huang para->ir_u = hclge_tm_get_field(shapping_para, IR_U); 1964cad7c215SGuangbin Huang para->ir_s = hclge_tm_get_field(shapping_para, IR_S); 1965cad7c215SGuangbin Huang para->bs_b = hclge_tm_get_field(shapping_para, BS_B); 1966cad7c215SGuangbin Huang para->bs_s = hclge_tm_get_field(shapping_para, BS_S); 1967cad7c215SGuangbin Huang para->flag = shap_cfg_cmd->flag; 1968cad7c215SGuangbin Huang para->rate = le32_to_cpu(shap_cfg_cmd->pg_rate); 1969cad7c215SGuangbin Huang return 0; 1970cad7c215SGuangbin Huang } 1971cad7c215SGuangbin Huang 1972cad7c215SGuangbin Huang int hclge_tm_get_port_shaper(struct hclge_dev *hdev, 1973cad7c215SGuangbin Huang struct hclge_tm_shaper_para *para) 1974cad7c215SGuangbin Huang { 1975cad7c215SGuangbin Huang struct hclge_port_shapping_cmd *port_shap_cfg_cmd; 1976cad7c215SGuangbin Huang struct hclge_desc desc; 1977cad7c215SGuangbin Huang u32 shapping_para; 1978cad7c215SGuangbin Huang int ret; 1979cad7c215SGuangbin Huang 1980cad7c215SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PORT_SHAPPING, true); 1981cad7c215SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1982cad7c215SGuangbin Huang if (ret) { 1983cad7c215SGuangbin Huang dev_err(&hdev->pdev->dev, 1984cad7c215SGuangbin Huang "failed to get port shaper, ret = %d\n", ret); 1985cad7c215SGuangbin Huang return ret; 1986cad7c215SGuangbin Huang } 1987cad7c215SGuangbin Huang 1988cad7c215SGuangbin Huang port_shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data; 1989cad7c215SGuangbin Huang shapping_para = le32_to_cpu(port_shap_cfg_cmd->port_shapping_para); 1990cad7c215SGuangbin Huang para->ir_b = hclge_tm_get_field(shapping_para, IR_B); 1991cad7c215SGuangbin Huang para->ir_u = hclge_tm_get_field(shapping_para, IR_U); 1992cad7c215SGuangbin Huang para->ir_s = hclge_tm_get_field(shapping_para, IR_S); 1993cad7c215SGuangbin Huang para->bs_b = hclge_tm_get_field(shapping_para, BS_B); 1994cad7c215SGuangbin Huang para->bs_s = hclge_tm_get_field(shapping_para, BS_S); 1995cad7c215SGuangbin Huang para->flag = port_shap_cfg_cmd->flag; 1996cad7c215SGuangbin Huang para->rate = le32_to_cpu(port_shap_cfg_cmd->port_rate); 1997cad7c215SGuangbin Huang 1998cad7c215SGuangbin Huang return 0; 1999cad7c215SGuangbin Huang } 2000