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, 584adcf738bSGuojia Liao "vf%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 set_bit(i, &kinfo->tc_info.tc_en); 69135244430SJian Shen kinfo->tc_info.tqp_offset[i] = i * kinfo->rss_size; 69235244430SJian Shen kinfo->tc_info.tqp_count[i] = kinfo->rss_size; 69384844054SSalil } else { 69484844054SSalil /* Set to default queue if TC is disable */ 69535244430SJian Shen clear_bit(i, &kinfo->tc_info.tc_en); 69635244430SJian Shen kinfo->tc_info.tqp_offset[i] = 0; 69735244430SJian Shen kinfo->tc_info.tqp_count[i] = 1; 69884844054SSalil } 69984844054SSalil } 700c5795c53SYunsheng Lin 70135244430SJian Shen memcpy(kinfo->tc_info.prio_tc, hdev->tm_info.prio_tc, 70235244430SJian Shen sizeof_field(struct hnae3_tc_info, prio_tc)); 70384844054SSalil } 70484844054SSalil 70584844054SSalil static void hclge_tm_vport_info_update(struct hclge_dev *hdev) 70684844054SSalil { 70784844054SSalil struct hclge_vport *vport = hdev->vport; 70884844054SSalil u32 i; 70984844054SSalil 71084844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 71184844054SSalil hclge_tm_vport_tc_info_update(vport); 71284844054SSalil 71384844054SSalil vport++; 71484844054SSalil } 71584844054SSalil } 71684844054SSalil 71784844054SSalil static void hclge_tm_tc_info_init(struct hclge_dev *hdev) 71884844054SSalil { 71984844054SSalil u8 i; 72084844054SSalil 72184844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 72284844054SSalil hdev->tm_info.tc_info[i].tc_id = i; 72384844054SSalil hdev->tm_info.tc_info[i].tc_sch_mode = HCLGE_SCH_MODE_DWRR; 72484844054SSalil hdev->tm_info.tc_info[i].pgid = 0; 72584844054SSalil hdev->tm_info.tc_info[i].bw_limit = 72684844054SSalil hdev->tm_info.pg_info[0].bw_limit; 72784844054SSalil } 72884844054SSalil 729c5795c53SYunsheng Lin for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) 730c5795c53SYunsheng Lin hdev->tm_info.prio_tc[i] = 731c5795c53SYunsheng Lin (i >= hdev->tm_info.num_tc) ? 0 : i; 732c5795c53SYunsheng Lin 733ae179b2fSYunsheng Lin /* DCB is enabled if we have more than 1 TC or pfc_en is 734ae179b2fSYunsheng Lin * non-zero. 735ae179b2fSYunsheng Lin */ 736ae179b2fSYunsheng Lin if (hdev->tm_info.num_tc > 1 || hdev->tm_info.pfc_en) 7377979a223SYunsheng Lin hdev->flag |= HCLGE_FLAG_DCB_ENABLE; 7387979a223SYunsheng Lin else 73984844054SSalil hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE; 74084844054SSalil } 74184844054SSalil 74284844054SSalil static void hclge_tm_pg_info_init(struct hclge_dev *hdev) 74384844054SSalil { 744b37ce587SYufeng Mo #define BW_PERCENT 100 745b37ce587SYufeng Mo 74684844054SSalil u8 i; 74784844054SSalil 74884844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 74984844054SSalil int k; 75084844054SSalil 751b37ce587SYufeng Mo hdev->tm_info.pg_dwrr[i] = i ? 0 : BW_PERCENT; 75284844054SSalil 75384844054SSalil hdev->tm_info.pg_info[i].pg_id = i; 75484844054SSalil hdev->tm_info.pg_info[i].pg_sch_mode = HCLGE_SCH_MODE_DWRR; 75584844054SSalil 756d9c7d20dSGuangbin Huang hdev->tm_info.pg_info[i].bw_limit = 757d9c7d20dSGuangbin Huang hdev->ae_dev->dev_specs.max_tm_rate; 75884844054SSalil 75984844054SSalil if (i != 0) 76084844054SSalil continue; 76184844054SSalil 76284844054SSalil hdev->tm_info.pg_info[i].tc_bit_map = hdev->hw_tc_map; 76384844054SSalil for (k = 0; k < hdev->tm_info.num_tc; k++) 764b37ce587SYufeng Mo hdev->tm_info.pg_info[i].tc_dwrr[k] = BW_PERCENT; 76584844054SSalil } 76684844054SSalil } 76784844054SSalil 768d78e5b6aSYonglong Liu static void hclge_update_fc_mode_by_dcb_flag(struct hclge_dev *hdev) 7697979a223SYunsheng Lin { 7707979a223SYunsheng Lin if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) { 7717979a223SYunsheng Lin if (hdev->fc_mode_last_time == HCLGE_FC_PFC) 7727979a223SYunsheng Lin dev_warn(&hdev->pdev->dev, 7737979a223SYunsheng Lin "DCB is disable, but last mode is FC_PFC\n"); 7747979a223SYunsheng Lin 7757979a223SYunsheng Lin hdev->tm_info.fc_mode = hdev->fc_mode_last_time; 7767979a223SYunsheng Lin } else if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) { 7777979a223SYunsheng Lin /* fc_mode_last_time record the last fc_mode when 7787979a223SYunsheng Lin * DCB is enabled, so that fc_mode can be set to 7797979a223SYunsheng Lin * the correct value when DCB is disabled. 7807979a223SYunsheng Lin */ 7817979a223SYunsheng Lin hdev->fc_mode_last_time = hdev->tm_info.fc_mode; 7827979a223SYunsheng Lin hdev->tm_info.fc_mode = HCLGE_FC_PFC; 7837979a223SYunsheng Lin } 7847979a223SYunsheng Lin } 7857979a223SYunsheng Lin 786d78e5b6aSYonglong Liu static void hclge_update_fc_mode(struct hclge_dev *hdev) 787d78e5b6aSYonglong Liu { 788d78e5b6aSYonglong Liu if (!hdev->tm_info.pfc_en) { 789d78e5b6aSYonglong Liu hdev->tm_info.fc_mode = hdev->fc_mode_last_time; 790d78e5b6aSYonglong Liu return; 791d78e5b6aSYonglong Liu } 792d78e5b6aSYonglong Liu 793d78e5b6aSYonglong Liu if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) { 794d78e5b6aSYonglong Liu hdev->fc_mode_last_time = hdev->tm_info.fc_mode; 795d78e5b6aSYonglong Liu hdev->tm_info.fc_mode = HCLGE_FC_PFC; 796d78e5b6aSYonglong Liu } 797d78e5b6aSYonglong Liu } 798d78e5b6aSYonglong Liu 799d78e5b6aSYonglong Liu static void hclge_pfc_info_init(struct hclge_dev *hdev) 800d78e5b6aSYonglong Liu { 801d78e5b6aSYonglong Liu if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) 802d78e5b6aSYonglong Liu hclge_update_fc_mode(hdev); 803d78e5b6aSYonglong Liu else 804d78e5b6aSYonglong Liu hclge_update_fc_mode_by_dcb_flag(hdev); 805d78e5b6aSYonglong Liu } 806d78e5b6aSYonglong Liu 807b6872fd3SYunsheng Lin static void hclge_tm_schd_info_init(struct hclge_dev *hdev) 80884844054SSalil { 80984844054SSalil hclge_tm_pg_info_init(hdev); 81084844054SSalil 81184844054SSalil hclge_tm_tc_info_init(hdev); 81284844054SSalil 81384844054SSalil hclge_tm_vport_info_update(hdev); 81484844054SSalil 8157979a223SYunsheng Lin hclge_pfc_info_init(hdev); 81684844054SSalil } 81784844054SSalil 81884844054SSalil static int hclge_tm_pg_to_pri_map(struct hclge_dev *hdev) 81984844054SSalil { 82084844054SSalil int ret; 82184844054SSalil u32 i; 82284844054SSalil 82384844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 82484844054SSalil return 0; 82584844054SSalil 82684844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 82784844054SSalil /* Cfg mapping */ 82884844054SSalil ret = hclge_tm_pg_to_pri_map_cfg( 82984844054SSalil hdev, i, hdev->tm_info.pg_info[i].tc_bit_map); 83084844054SSalil if (ret) 83184844054SSalil return ret; 83284844054SSalil } 83384844054SSalil 83484844054SSalil return 0; 83584844054SSalil } 83684844054SSalil 83784844054SSalil static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev) 83884844054SSalil { 839d9c7d20dSGuangbin Huang u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; 840ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para ir_para; 84163cbf7a9SYufeng Mo u32 shaper_para; 84284844054SSalil int ret; 84384844054SSalil u32 i; 84484844054SSalil 84584844054SSalil /* Cfg pg schd */ 84684844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 84784844054SSalil return 0; 84884844054SSalil 84984844054SSalil /* Pg to pri */ 85084844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 851e364ad30SYonglong Liu u32 rate = hdev->tm_info.pg_info[i].bw_limit; 852e364ad30SYonglong Liu 85384844054SSalil /* Calc shaper para */ 854e364ad30SYonglong Liu ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PG, 855ff7e4d0dSHuazhong Tan &ir_para, max_tm_rate); 85684844054SSalil if (ret) 85784844054SSalil return ret; 85884844054SSalil 85963cbf7a9SYufeng Mo shaper_para = hclge_tm_get_shapping_para(0, 0, 0, 86063cbf7a9SYufeng Mo HCLGE_SHAPER_BS_U_DEF, 86163cbf7a9SYufeng Mo HCLGE_SHAPER_BS_S_DEF); 86284844054SSalil ret = hclge_tm_pg_shapping_cfg(hdev, 86384844054SSalil HCLGE_TM_SHAP_C_BUCKET, i, 864e364ad30SYonglong Liu shaper_para, rate); 86584844054SSalil if (ret) 86684844054SSalil return ret; 86784844054SSalil 868ff7e4d0dSHuazhong Tan shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, 869ff7e4d0dSHuazhong Tan ir_para.ir_u, 870ff7e4d0dSHuazhong Tan ir_para.ir_s, 87184844054SSalil HCLGE_SHAPER_BS_U_DEF, 87284844054SSalil HCLGE_SHAPER_BS_S_DEF); 87363cbf7a9SYufeng Mo ret = hclge_tm_pg_shapping_cfg(hdev, 87463cbf7a9SYufeng Mo HCLGE_TM_SHAP_P_BUCKET, i, 875e364ad30SYonglong Liu shaper_para, rate); 87684844054SSalil if (ret) 87784844054SSalil return ret; 87884844054SSalil } 87984844054SSalil 88084844054SSalil return 0; 88184844054SSalil } 88284844054SSalil 88384844054SSalil static int hclge_tm_pg_dwrr_cfg(struct hclge_dev *hdev) 88484844054SSalil { 88584844054SSalil int ret; 88684844054SSalil u32 i; 88784844054SSalil 88884844054SSalil /* cfg pg schd */ 88984844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 89084844054SSalil return 0; 89184844054SSalil 89284844054SSalil /* pg to prio */ 89384844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 89484844054SSalil /* Cfg dwrr */ 8959b2f3477SWeihang Li ret = hclge_tm_pg_weight_cfg(hdev, i, hdev->tm_info.pg_dwrr[i]); 89684844054SSalil if (ret) 89784844054SSalil return ret; 89884844054SSalil } 89984844054SSalil 90084844054SSalil return 0; 90184844054SSalil } 90284844054SSalil 90384844054SSalil static int hclge_vport_q_to_qs_map(struct hclge_dev *hdev, 90484844054SSalil struct hclge_vport *vport) 90584844054SSalil { 90684844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 90735244430SJian Shen struct hnae3_tc_info *tc_info = &kinfo->tc_info; 90884844054SSalil struct hnae3_queue **tqp = kinfo->tqp; 90984844054SSalil u32 i, j; 91084844054SSalil int ret; 91184844054SSalil 91235244430SJian Shen for (i = 0; i < tc_info->num_tc; i++) { 91335244430SJian Shen for (j = 0; j < tc_info->tqp_count[i]; j++) { 91435244430SJian Shen struct hnae3_queue *q = tqp[tc_info->tqp_offset[i] + j]; 91584844054SSalil 91684844054SSalil ret = hclge_tm_q_to_qs_map_cfg(hdev, 91784844054SSalil hclge_get_queue_id(q), 91884844054SSalil vport->qs_offset + i); 91984844054SSalil if (ret) 92084844054SSalil return ret; 92184844054SSalil } 92284844054SSalil } 92384844054SSalil 92484844054SSalil return 0; 92584844054SSalil } 92684844054SSalil 92784844054SSalil static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev) 92884844054SSalil { 92984844054SSalil struct hclge_vport *vport = hdev->vport; 93084844054SSalil int ret; 931cc9bb43aSYunsheng Lin u32 i, k; 93284844054SSalil 93384844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 93484844054SSalil /* Cfg qs -> pri mapping, one by one mapping */ 935de67a690SYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 936de67a690SYunsheng Lin struct hnae3_knic_private_info *kinfo = 937de67a690SYunsheng Lin &vport[k].nic.kinfo; 938de67a690SYunsheng Lin 93935244430SJian Shen for (i = 0; i < kinfo->tc_info.num_tc; i++) { 940cc9bb43aSYunsheng Lin ret = hclge_tm_qs_to_pri_map_cfg( 941cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, i); 94284844054SSalil if (ret) 94384844054SSalil return ret; 94484844054SSalil } 945de67a690SYunsheng Lin } 94684844054SSalil } else if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) { 94784844054SSalil /* Cfg qs -> pri mapping, qs = tc, pri = vf, 8 qs -> 1 pri */ 94884844054SSalil for (k = 0; k < hdev->num_alloc_vport; k++) 94984844054SSalil for (i = 0; i < HNAE3_MAX_TC; i++) { 95084844054SSalil ret = hclge_tm_qs_to_pri_map_cfg( 95184844054SSalil hdev, vport[k].qs_offset + i, k); 95284844054SSalil if (ret) 95384844054SSalil return ret; 95484844054SSalil } 95584844054SSalil } else { 95684844054SSalil return -EINVAL; 95784844054SSalil } 95884844054SSalil 95984844054SSalil /* Cfg q -> qs mapping */ 96084844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 96184844054SSalil ret = hclge_vport_q_to_qs_map(hdev, vport); 96284844054SSalil if (ret) 96384844054SSalil return ret; 96484844054SSalil 96584844054SSalil vport++; 96684844054SSalil } 96784844054SSalil 96884844054SSalil return 0; 96984844054SSalil } 97084844054SSalil 97184844054SSalil static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev) 97284844054SSalil { 973d9c7d20dSGuangbin Huang u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; 974ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para ir_para; 97563cbf7a9SYufeng Mo u32 shaper_para; 97684844054SSalil int ret; 97784844054SSalil u32 i; 97884844054SSalil 97984844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 980e364ad30SYonglong Liu u32 rate = hdev->tm_info.tc_info[i].bw_limit; 981e364ad30SYonglong Liu 982e364ad30SYonglong Liu ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PRI, 983ff7e4d0dSHuazhong Tan &ir_para, max_tm_rate); 98484844054SSalil if (ret) 98584844054SSalil return ret; 98684844054SSalil 98763cbf7a9SYufeng Mo shaper_para = hclge_tm_get_shapping_para(0, 0, 0, 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_C_BUCKET, i, 991e364ad30SYonglong Liu shaper_para, rate); 99284844054SSalil if (ret) 99384844054SSalil return ret; 99484844054SSalil 995ff7e4d0dSHuazhong Tan shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, 996ff7e4d0dSHuazhong Tan ir_para.ir_u, 997ff7e4d0dSHuazhong Tan ir_para.ir_s, 99863cbf7a9SYufeng Mo HCLGE_SHAPER_BS_U_DEF, 99984844054SSalil HCLGE_SHAPER_BS_S_DEF); 100063cbf7a9SYufeng Mo ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, i, 1001e364ad30SYonglong Liu shaper_para, rate); 100284844054SSalil if (ret) 100384844054SSalil return ret; 100484844054SSalil } 100584844054SSalil 100684844054SSalil return 0; 100784844054SSalil } 100884844054SSalil 100984844054SSalil static int hclge_tm_pri_vnet_base_shaper_pri_cfg(struct hclge_vport *vport) 101084844054SSalil { 101184844054SSalil struct hclge_dev *hdev = vport->back; 1012ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para ir_para; 101363cbf7a9SYufeng Mo u32 shaper_para; 101484844054SSalil int ret; 101584844054SSalil 101684844054SSalil ret = hclge_shaper_para_calc(vport->bw_limit, HCLGE_SHAPER_LVL_VF, 1017ff7e4d0dSHuazhong Tan &ir_para, 1018d9c7d20dSGuangbin Huang hdev->ae_dev->dev_specs.max_tm_rate); 101984844054SSalil if (ret) 102084844054SSalil return ret; 102184844054SSalil 102263cbf7a9SYufeng Mo shaper_para = hclge_tm_get_shapping_para(0, 0, 0, 102363cbf7a9SYufeng Mo HCLGE_SHAPER_BS_U_DEF, 102484844054SSalil HCLGE_SHAPER_BS_S_DEF); 102563cbf7a9SYufeng Mo ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, 1026e364ad30SYonglong Liu vport->vport_id, shaper_para, 1027e364ad30SYonglong Liu vport->bw_limit); 102884844054SSalil if (ret) 102984844054SSalil return ret; 103084844054SSalil 1031ff7e4d0dSHuazhong Tan shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u, 1032ff7e4d0dSHuazhong Tan ir_para.ir_s, 103384844054SSalil HCLGE_SHAPER_BS_U_DEF, 103484844054SSalil HCLGE_SHAPER_BS_S_DEF); 103563cbf7a9SYufeng Mo ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, 1036e364ad30SYonglong Liu vport->vport_id, shaper_para, 1037e364ad30SYonglong Liu vport->bw_limit); 103884844054SSalil if (ret) 103984844054SSalil return ret; 104084844054SSalil 104184844054SSalil return 0; 104284844054SSalil } 104384844054SSalil 104484844054SSalil static int hclge_tm_pri_vnet_base_shaper_qs_cfg(struct hclge_vport *vport) 104584844054SSalil { 104684844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 104784844054SSalil struct hclge_dev *hdev = vport->back; 1048d9c7d20dSGuangbin Huang u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate; 1049ff7e4d0dSHuazhong Tan struct hclge_shaper_ir_para ir_para; 105084844054SSalil u32 i; 105184844054SSalil int ret; 105284844054SSalil 105335244430SJian Shen for (i = 0; i < kinfo->tc_info.num_tc; i++) { 1054ff7e4d0dSHuazhong Tan ret = hclge_shaper_para_calc(hdev->tm_info.tc_info[i].bw_limit, 105584844054SSalil HCLGE_SHAPER_LVL_QSET, 1056ff7e4d0dSHuazhong Tan &ir_para, max_tm_rate); 105784844054SSalil if (ret) 105884844054SSalil return ret; 105984844054SSalil } 106084844054SSalil 106184844054SSalil return 0; 106284844054SSalil } 106384844054SSalil 106484844054SSalil static int hclge_tm_pri_vnet_base_shaper_cfg(struct hclge_dev *hdev) 106584844054SSalil { 106684844054SSalil struct hclge_vport *vport = hdev->vport; 106784844054SSalil int ret; 106884844054SSalil u32 i; 106984844054SSalil 107084844054SSalil /* Need config vport shaper */ 107184844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 107284844054SSalil ret = hclge_tm_pri_vnet_base_shaper_pri_cfg(vport); 107384844054SSalil if (ret) 107484844054SSalil return ret; 107584844054SSalil 107684844054SSalil ret = hclge_tm_pri_vnet_base_shaper_qs_cfg(vport); 107784844054SSalil if (ret) 107884844054SSalil return ret; 107984844054SSalil 108084844054SSalil vport++; 108184844054SSalil } 108284844054SSalil 108384844054SSalil return 0; 108484844054SSalil } 108584844054SSalil 108684844054SSalil static int hclge_tm_pri_shaper_cfg(struct hclge_dev *hdev) 108784844054SSalil { 108884844054SSalil int ret; 108984844054SSalil 109084844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 109184844054SSalil ret = hclge_tm_pri_tc_base_shaper_cfg(hdev); 109284844054SSalil if (ret) 109384844054SSalil return ret; 109484844054SSalil } else { 109584844054SSalil ret = hclge_tm_pri_vnet_base_shaper_cfg(hdev); 109684844054SSalil if (ret) 109784844054SSalil return ret; 109884844054SSalil } 109984844054SSalil 110084844054SSalil return 0; 110184844054SSalil } 110284844054SSalil 110384844054SSalil static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev) 110484844054SSalil { 1105cc9bb43aSYunsheng Lin struct hclge_vport *vport = hdev->vport; 110684844054SSalil struct hclge_pg_info *pg_info; 110784844054SSalil u8 dwrr; 110884844054SSalil int ret; 1109cc9bb43aSYunsheng Lin u32 i, k; 111084844054SSalil 111184844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 111284844054SSalil pg_info = 111384844054SSalil &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; 111484844054SSalil dwrr = pg_info->tc_dwrr[i]; 111584844054SSalil 111684844054SSalil ret = hclge_tm_pri_weight_cfg(hdev, i, dwrr); 111784844054SSalil if (ret) 111884844054SSalil return ret; 111984844054SSalil 1120cc9bb43aSYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 1121cc9bb43aSYunsheng Lin ret = hclge_tm_qs_weight_cfg( 1122cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, 1123cc9bb43aSYunsheng Lin vport[k].dwrr); 112484844054SSalil if (ret) 112584844054SSalil return ret; 112684844054SSalil } 1127cc9bb43aSYunsheng Lin } 112884844054SSalil 112984844054SSalil return 0; 113084844054SSalil } 113184844054SSalil 1132330baff5SYunsheng Lin static int hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev *hdev) 1133330baff5SYunsheng Lin { 1134330baff5SYunsheng Lin #define DEFAULT_TC_WEIGHT 1 1135330baff5SYunsheng Lin #define DEFAULT_TC_OFFSET 14 1136330baff5SYunsheng Lin 1137330baff5SYunsheng Lin struct hclge_ets_tc_weight_cmd *ets_weight; 1138330baff5SYunsheng Lin struct hclge_desc desc; 1139ebaf1908SWeihang Li unsigned int i; 1140330baff5SYunsheng Lin 1141330baff5SYunsheng Lin hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_ETS_TC_WEIGHT, false); 1142330baff5SYunsheng Lin ets_weight = (struct hclge_ets_tc_weight_cmd *)desc.data; 1143330baff5SYunsheng Lin 1144330baff5SYunsheng Lin for (i = 0; i < HNAE3_MAX_TC; i++) { 1145330baff5SYunsheng Lin struct hclge_pg_info *pg_info; 1146330baff5SYunsheng Lin 1147330baff5SYunsheng Lin ets_weight->tc_weight[i] = DEFAULT_TC_WEIGHT; 1148330baff5SYunsheng Lin 1149330baff5SYunsheng Lin if (!(hdev->hw_tc_map & BIT(i))) 1150330baff5SYunsheng Lin continue; 1151330baff5SYunsheng Lin 1152330baff5SYunsheng Lin pg_info = 1153330baff5SYunsheng Lin &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; 1154330baff5SYunsheng Lin ets_weight->tc_weight[i] = pg_info->tc_dwrr[i]; 1155330baff5SYunsheng Lin } 1156330baff5SYunsheng Lin 1157330baff5SYunsheng Lin ets_weight->weight_offset = DEFAULT_TC_OFFSET; 1158330baff5SYunsheng Lin 1159330baff5SYunsheng Lin return hclge_cmd_send(&hdev->hw, &desc, 1); 1160330baff5SYunsheng Lin } 1161330baff5SYunsheng Lin 116284844054SSalil static int hclge_tm_pri_vnet_base_dwrr_pri_cfg(struct hclge_vport *vport) 116384844054SSalil { 116484844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 116584844054SSalil struct hclge_dev *hdev = vport->back; 116684844054SSalil int ret; 116784844054SSalil u8 i; 116884844054SSalil 116984844054SSalil /* Vf dwrr */ 117084844054SSalil ret = hclge_tm_pri_weight_cfg(hdev, vport->vport_id, vport->dwrr); 117184844054SSalil if (ret) 117284844054SSalil return ret; 117384844054SSalil 117484844054SSalil /* Qset dwrr */ 117535244430SJian Shen for (i = 0; i < kinfo->tc_info.num_tc; i++) { 117684844054SSalil ret = hclge_tm_qs_weight_cfg( 117784844054SSalil hdev, vport->qs_offset + i, 117884844054SSalil hdev->tm_info.pg_info[0].tc_dwrr[i]); 117984844054SSalil if (ret) 118084844054SSalil return ret; 118184844054SSalil } 118284844054SSalil 118384844054SSalil return 0; 118484844054SSalil } 118584844054SSalil 118684844054SSalil static int hclge_tm_pri_vnet_base_dwrr_cfg(struct hclge_dev *hdev) 118784844054SSalil { 118884844054SSalil struct hclge_vport *vport = hdev->vport; 118984844054SSalil int ret; 119084844054SSalil u32 i; 119184844054SSalil 119284844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 119384844054SSalil ret = hclge_tm_pri_vnet_base_dwrr_pri_cfg(vport); 119484844054SSalil if (ret) 119584844054SSalil return ret; 119684844054SSalil 119784844054SSalil vport++; 119884844054SSalil } 119984844054SSalil 120084844054SSalil return 0; 120184844054SSalil } 120284844054SSalil 120384844054SSalil static int hclge_tm_pri_dwrr_cfg(struct hclge_dev *hdev) 120484844054SSalil { 120584844054SSalil int ret; 120684844054SSalil 120784844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 120884844054SSalil ret = hclge_tm_pri_tc_base_dwrr_cfg(hdev); 120984844054SSalil if (ret) 121084844054SSalil return ret; 1211330baff5SYunsheng Lin 1212330baff5SYunsheng Lin if (!hnae3_dev_dcb_supported(hdev)) 1213330baff5SYunsheng Lin return 0; 1214330baff5SYunsheng Lin 1215330baff5SYunsheng Lin ret = hclge_tm_ets_tc_dwrr_cfg(hdev); 1216330baff5SYunsheng Lin if (ret == -EOPNOTSUPP) { 1217330baff5SYunsheng Lin dev_warn(&hdev->pdev->dev, 1218330baff5SYunsheng Lin "fw %08x does't support ets tc weight cmd\n", 1219330baff5SYunsheng Lin hdev->fw_version); 1220330baff5SYunsheng Lin ret = 0; 1221330baff5SYunsheng Lin } 1222330baff5SYunsheng Lin 1223330baff5SYunsheng Lin return ret; 122484844054SSalil } else { 122584844054SSalil ret = hclge_tm_pri_vnet_base_dwrr_cfg(hdev); 122684844054SSalil if (ret) 122784844054SSalil return ret; 122884844054SSalil } 122984844054SSalil 123084844054SSalil return 0; 123184844054SSalil } 123284844054SSalil 12339e5157baSYunsheng Lin static int hclge_tm_map_cfg(struct hclge_dev *hdev) 123484844054SSalil { 123584844054SSalil int ret; 123684844054SSalil 123777f255c1SYunsheng Lin ret = hclge_up_to_tc_map(hdev); 123877f255c1SYunsheng Lin if (ret) 123977f255c1SYunsheng Lin return ret; 124077f255c1SYunsheng Lin 124184844054SSalil ret = hclge_tm_pg_to_pri_map(hdev); 124284844054SSalil if (ret) 124384844054SSalil return ret; 124484844054SSalil 124584844054SSalil return hclge_tm_pri_q_qs_cfg(hdev); 124684844054SSalil } 124784844054SSalil 124884844054SSalil static int hclge_tm_shaper_cfg(struct hclge_dev *hdev) 124984844054SSalil { 125084844054SSalil int ret; 125184844054SSalil 12520a5677d3SYunsheng Lin ret = hclge_tm_port_shaper_cfg(hdev); 12530a5677d3SYunsheng Lin if (ret) 12540a5677d3SYunsheng Lin return ret; 12550a5677d3SYunsheng Lin 125684844054SSalil ret = hclge_tm_pg_shaper_cfg(hdev); 125784844054SSalil if (ret) 125884844054SSalil return ret; 125984844054SSalil 126084844054SSalil return hclge_tm_pri_shaper_cfg(hdev); 126184844054SSalil } 126284844054SSalil 126384844054SSalil int hclge_tm_dwrr_cfg(struct hclge_dev *hdev) 126484844054SSalil { 126584844054SSalil int ret; 126684844054SSalil 126784844054SSalil ret = hclge_tm_pg_dwrr_cfg(hdev); 126884844054SSalil if (ret) 126984844054SSalil return ret; 127084844054SSalil 127184844054SSalil return hclge_tm_pri_dwrr_cfg(hdev); 127284844054SSalil } 127384844054SSalil 127484844054SSalil static int hclge_tm_lvl2_schd_mode_cfg(struct hclge_dev *hdev) 127584844054SSalil { 127684844054SSalil int ret; 127784844054SSalil u8 i; 127884844054SSalil 127984844054SSalil /* Only being config on TC-Based scheduler mode */ 128084844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) 128184844054SSalil return 0; 128284844054SSalil 128384844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 128484844054SSalil ret = hclge_tm_pg_schd_mode_cfg(hdev, i); 128584844054SSalil if (ret) 128684844054SSalil return ret; 128784844054SSalil } 128884844054SSalil 128984844054SSalil return 0; 129084844054SSalil } 129184844054SSalil 129284844054SSalil static int hclge_tm_schd_mode_vnet_base_cfg(struct hclge_vport *vport) 129384844054SSalil { 129484844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 129584844054SSalil struct hclge_dev *hdev = vport->back; 129684844054SSalil int ret; 129784844054SSalil u8 i; 129884844054SSalil 129904f25edbSYunsheng Lin if (vport->vport_id >= HNAE3_MAX_TC) 130004f25edbSYunsheng Lin return -EINVAL; 130104f25edbSYunsheng Lin 130284844054SSalil ret = hclge_tm_pri_schd_mode_cfg(hdev, vport->vport_id); 130384844054SSalil if (ret) 130484844054SSalil return ret; 130584844054SSalil 130635244430SJian Shen for (i = 0; i < kinfo->tc_info.num_tc; i++) { 1307cc9bb43aSYunsheng Lin u8 sch_mode = hdev->tm_info.tc_info[i].tc_sch_mode; 1308cc9bb43aSYunsheng Lin 1309cc9bb43aSYunsheng Lin ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i, 1310cc9bb43aSYunsheng Lin sch_mode); 131184844054SSalil if (ret) 131284844054SSalil return ret; 131384844054SSalil } 131484844054SSalil 131584844054SSalil return 0; 131684844054SSalil } 131784844054SSalil 131884844054SSalil static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev *hdev) 131984844054SSalil { 132084844054SSalil struct hclge_vport *vport = hdev->vport; 132184844054SSalil int ret; 1322cc9bb43aSYunsheng Lin u8 i, k; 132384844054SSalil 132484844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 132584844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 132684844054SSalil ret = hclge_tm_pri_schd_mode_cfg(hdev, i); 132784844054SSalil if (ret) 132884844054SSalil return ret; 132984844054SSalil 1330cc9bb43aSYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 1331cc9bb43aSYunsheng Lin ret = hclge_tm_qs_schd_mode_cfg( 1332cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, 1333cc9bb43aSYunsheng Lin HCLGE_SCH_MODE_DWRR); 133484844054SSalil if (ret) 133584844054SSalil return ret; 133684844054SSalil } 1337cc9bb43aSYunsheng Lin } 133884844054SSalil } else { 133984844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 134084844054SSalil ret = hclge_tm_schd_mode_vnet_base_cfg(vport); 134184844054SSalil if (ret) 134284844054SSalil return ret; 134384844054SSalil 134484844054SSalil vport++; 134584844054SSalil } 134684844054SSalil } 134784844054SSalil 134884844054SSalil return 0; 134984844054SSalil } 135084844054SSalil 13519e5157baSYunsheng Lin static int hclge_tm_schd_mode_hw(struct hclge_dev *hdev) 135284844054SSalil { 135384844054SSalil int ret; 135484844054SSalil 135584844054SSalil ret = hclge_tm_lvl2_schd_mode_cfg(hdev); 135684844054SSalil if (ret) 135784844054SSalil return ret; 135884844054SSalil 135984844054SSalil return hclge_tm_lvl34_schd_mode_cfg(hdev); 136084844054SSalil } 136184844054SSalil 13629e5157baSYunsheng Lin int hclge_tm_schd_setup_hw(struct hclge_dev *hdev) 136384844054SSalil { 136484844054SSalil int ret; 136584844054SSalil 136684844054SSalil /* Cfg tm mapping */ 136784844054SSalil ret = hclge_tm_map_cfg(hdev); 136884844054SSalil if (ret) 136984844054SSalil return ret; 137084844054SSalil 137184844054SSalil /* Cfg tm shaper */ 137284844054SSalil ret = hclge_tm_shaper_cfg(hdev); 137384844054SSalil if (ret) 137484844054SSalil return ret; 137584844054SSalil 137684844054SSalil /* Cfg dwrr */ 137784844054SSalil ret = hclge_tm_dwrr_cfg(hdev); 137884844054SSalil if (ret) 137984844054SSalil return ret; 138084844054SSalil 138184844054SSalil /* Cfg schd mode for each level schd */ 138284844054SSalil return hclge_tm_schd_mode_hw(hdev); 138384844054SSalil } 138484844054SSalil 1385e98d7183SFuyun Liang static int hclge_pause_param_setup_hw(struct hclge_dev *hdev) 138618838d0cSFuyun Liang { 138718838d0cSFuyun Liang struct hclge_mac *mac = &hdev->hw.mac; 138818838d0cSFuyun Liang 1389e98d7183SFuyun Liang return hclge_pause_param_cfg(hdev, mac->mac_addr, 139018838d0cSFuyun Liang HCLGE_DEFAULT_PAUSE_TRANS_GAP, 139118838d0cSFuyun Liang HCLGE_DEFAULT_PAUSE_TRANS_TIME); 139218838d0cSFuyun Liang } 139318838d0cSFuyun Liang 13949dc2145dSYunsheng Lin static int hclge_pfc_setup_hw(struct hclge_dev *hdev) 13959dc2145dSYunsheng Lin { 13969dc2145dSYunsheng Lin u8 enable_bitmap = 0; 13979dc2145dSYunsheng Lin 13989dc2145dSYunsheng Lin if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) 13999dc2145dSYunsheng Lin enable_bitmap = HCLGE_TX_MAC_PAUSE_EN_MSK | 14009dc2145dSYunsheng Lin HCLGE_RX_MAC_PAUSE_EN_MSK; 14019dc2145dSYunsheng Lin 14029dc2145dSYunsheng Lin return hclge_pfc_pause_en_cfg(hdev, enable_bitmap, 1403d3ad430aSYunsheng Lin hdev->tm_info.pfc_en); 14049dc2145dSYunsheng Lin } 14059dc2145dSYunsheng Lin 14069a5ef4aaSYonglong Liu /* for the queues that use for backpress, divides to several groups, 14079a5ef4aaSYonglong Liu * each group contains 32 queue sets, which can be represented by u32 bitmap. 140867bf2541SYunsheng Lin */ 140967bf2541SYunsheng Lin static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc) 141067bf2541SYunsheng Lin { 14119a5ef4aaSYonglong Liu u16 grp_id_shift = HCLGE_BP_GRP_ID_S; 14129a5ef4aaSYonglong Liu u16 grp_id_mask = HCLGE_BP_GRP_ID_M; 14139a5ef4aaSYonglong Liu u8 grp_num = HCLGE_BP_GRP_NUM; 1414e8ccbb7dSYunsheng Lin int i; 141567bf2541SYunsheng Lin 14169a5ef4aaSYonglong Liu if (hdev->num_tqps > HCLGE_TQP_MAX_SIZE_DEV_V2) { 14179a5ef4aaSYonglong Liu grp_num = HCLGE_BP_EXT_GRP_NUM; 14189a5ef4aaSYonglong Liu grp_id_mask = HCLGE_BP_EXT_GRP_ID_M; 14199a5ef4aaSYonglong Liu grp_id_shift = HCLGE_BP_EXT_GRP_ID_S; 14209a5ef4aaSYonglong Liu } 14219a5ef4aaSYonglong Liu 14229a5ef4aaSYonglong Liu for (i = 0; i < grp_num; i++) { 1423e8ccbb7dSYunsheng Lin u32 qs_bitmap = 0; 1424e8ccbb7dSYunsheng Lin int k, ret; 142567bf2541SYunsheng Lin 142667bf2541SYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 1427e8ccbb7dSYunsheng Lin struct hclge_vport *vport = &hdev->vport[k]; 142867bf2541SYunsheng Lin u16 qs_id = vport->qs_offset + tc; 142967bf2541SYunsheng Lin u8 grp, sub_grp; 143067bf2541SYunsheng Lin 14319a5ef4aaSYonglong Liu grp = hnae3_get_field(qs_id, grp_id_mask, grp_id_shift); 1432e4e87715SPeng Li sub_grp = hnae3_get_field(qs_id, HCLGE_BP_SUB_GRP_ID_M, 143367bf2541SYunsheng Lin HCLGE_BP_SUB_GRP_ID_S); 143467bf2541SYunsheng Lin if (i == grp) 143567bf2541SYunsheng Lin qs_bitmap |= (1 << sub_grp); 143667bf2541SYunsheng Lin } 143767bf2541SYunsheng Lin 143867bf2541SYunsheng Lin ret = hclge_tm_qs_bp_cfg(hdev, tc, i, qs_bitmap); 143967bf2541SYunsheng Lin if (ret) 144067bf2541SYunsheng Lin return ret; 144167bf2541SYunsheng Lin } 144267bf2541SYunsheng Lin 144367bf2541SYunsheng Lin return 0; 144467bf2541SYunsheng Lin } 144567bf2541SYunsheng Lin 14469dc2145dSYunsheng Lin static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) 14479dc2145dSYunsheng Lin { 14489dc2145dSYunsheng Lin bool tx_en, rx_en; 14499dc2145dSYunsheng Lin 14509dc2145dSYunsheng Lin switch (hdev->tm_info.fc_mode) { 14519dc2145dSYunsheng Lin case HCLGE_FC_NONE: 14529dc2145dSYunsheng Lin tx_en = false; 14539dc2145dSYunsheng Lin rx_en = false; 14549dc2145dSYunsheng Lin break; 14559dc2145dSYunsheng Lin case HCLGE_FC_RX_PAUSE: 14569dc2145dSYunsheng Lin tx_en = false; 14579dc2145dSYunsheng Lin rx_en = true; 14589dc2145dSYunsheng Lin break; 14599dc2145dSYunsheng Lin case HCLGE_FC_TX_PAUSE: 14609dc2145dSYunsheng Lin tx_en = true; 14619dc2145dSYunsheng Lin rx_en = false; 14629dc2145dSYunsheng Lin break; 14639dc2145dSYunsheng Lin case HCLGE_FC_FULL: 14649dc2145dSYunsheng Lin tx_en = true; 14659dc2145dSYunsheng Lin rx_en = true; 14669dc2145dSYunsheng Lin break; 14676d0ec65cSYunsheng Lin case HCLGE_FC_PFC: 14686d0ec65cSYunsheng Lin tx_en = false; 14696d0ec65cSYunsheng Lin rx_en = false; 14706d0ec65cSYunsheng Lin break; 14719dc2145dSYunsheng Lin default: 14729dc2145dSYunsheng Lin tx_en = true; 14739dc2145dSYunsheng Lin rx_en = true; 14749dc2145dSYunsheng Lin } 14759dc2145dSYunsheng Lin 14769dc2145dSYunsheng Lin return hclge_mac_pause_en_cfg(hdev, tx_en, rx_en); 14779dc2145dSYunsheng Lin } 14789dc2145dSYunsheng Lin 147973fc9c48SHuazhong Tan static int hclge_tm_bp_setup(struct hclge_dev *hdev) 148073fc9c48SHuazhong Tan { 14819d8d5a36SYufeng Mo int ret; 148273fc9c48SHuazhong Tan int i; 148373fc9c48SHuazhong Tan 148473fc9c48SHuazhong Tan for (i = 0; i < hdev->tm_info.num_tc; i++) { 148573fc9c48SHuazhong Tan ret = hclge_bp_setup_hw(hdev, i); 148673fc9c48SHuazhong Tan if (ret) 148773fc9c48SHuazhong Tan return ret; 148873fc9c48SHuazhong Tan } 148973fc9c48SHuazhong Tan 1490ee7a3764SDan Carpenter return 0; 149173fc9c48SHuazhong Tan } 149273fc9c48SHuazhong Tan 149344e59e37SYunsheng Lin int hclge_pause_setup_hw(struct hclge_dev *hdev, bool init) 149484844054SSalil { 149584844054SSalil int ret; 149684844054SSalil 1497e98d7183SFuyun Liang ret = hclge_pause_param_setup_hw(hdev); 149818838d0cSFuyun Liang if (ret) 149918838d0cSFuyun Liang return ret; 150018838d0cSFuyun Liang 15016d0ec65cSYunsheng Lin ret = hclge_mac_pause_setup_hw(hdev); 15026d0ec65cSYunsheng Lin if (ret) 15036d0ec65cSYunsheng Lin return ret; 150484844054SSalil 15059dc2145dSYunsheng Lin /* Only DCB-supported dev supports qset back pressure and pfc cmd */ 15062daf4a65SYunsheng Lin if (!hnae3_dev_dcb_supported(hdev)) 15072daf4a65SYunsheng Lin return 0; 15082daf4a65SYunsheng Lin 150944e59e37SYunsheng Lin /* GE MAC does not support PFC, when driver is initializing and MAC 151044e59e37SYunsheng Lin * is in GE Mode, ignore the error here, otherwise initialization 151144e59e37SYunsheng Lin * will fail. 151244e59e37SYunsheng Lin */ 15139dc2145dSYunsheng Lin ret = hclge_pfc_setup_hw(hdev); 151444e59e37SYunsheng Lin if (init && ret == -EOPNOTSUPP) 151544e59e37SYunsheng Lin dev_warn(&hdev->pdev->dev, "GE MAC does not support pfc\n"); 1516fba2efdaSHuazhong Tan else if (ret) { 1517fba2efdaSHuazhong Tan dev_err(&hdev->pdev->dev, "config pfc failed! ret = %d\n", 1518fba2efdaSHuazhong Tan ret); 151944e59e37SYunsheng Lin return ret; 1520fba2efdaSHuazhong Tan } 15219dc2145dSYunsheng Lin 152273fc9c48SHuazhong Tan return hclge_tm_bp_setup(hdev); 152377f255c1SYunsheng Lin } 152477f255c1SYunsheng Lin 1525e432abfbSYunsheng Lin void hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc) 152677f255c1SYunsheng Lin { 152777f255c1SYunsheng Lin struct hclge_vport *vport = hdev->vport; 152877f255c1SYunsheng Lin struct hnae3_knic_private_info *kinfo; 152977f255c1SYunsheng Lin u32 i, k; 153077f255c1SYunsheng Lin 153177f255c1SYunsheng Lin for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) { 153277f255c1SYunsheng Lin hdev->tm_info.prio_tc[i] = prio_tc[i]; 153377f255c1SYunsheng Lin 153477f255c1SYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 153577f255c1SYunsheng Lin kinfo = &vport[k].nic.kinfo; 153635244430SJian Shen kinfo->tc_info.prio_tc[i] = prio_tc[i]; 153777f255c1SYunsheng Lin } 153877f255c1SYunsheng Lin } 153977f255c1SYunsheng Lin } 154077f255c1SYunsheng Lin 1541e432abfbSYunsheng Lin void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc) 154277f255c1SYunsheng Lin { 15439b2f3477SWeihang Li u8 bit_map = 0; 15449b2f3477SWeihang Li u8 i; 154577f255c1SYunsheng Lin 154677f255c1SYunsheng Lin hdev->tm_info.num_tc = num_tc; 154777f255c1SYunsheng Lin 154877f255c1SYunsheng Lin for (i = 0; i < hdev->tm_info.num_tc; i++) 154977f255c1SYunsheng Lin bit_map |= BIT(i); 155077f255c1SYunsheng Lin 155177f255c1SYunsheng Lin if (!bit_map) { 155277f255c1SYunsheng Lin bit_map = 1; 155377f255c1SYunsheng Lin hdev->tm_info.num_tc = 1; 155477f255c1SYunsheng Lin } 155577f255c1SYunsheng Lin 155677f255c1SYunsheng Lin hdev->hw_tc_map = bit_map; 155777f255c1SYunsheng Lin 155877f255c1SYunsheng Lin hclge_tm_schd_info_init(hdev); 155984844054SSalil } 156084844054SSalil 1561ae179b2fSYunsheng Lin void hclge_tm_pfc_info_update(struct hclge_dev *hdev) 1562ae179b2fSYunsheng Lin { 1563ae179b2fSYunsheng Lin /* DCB is enabled if we have more than 1 TC or pfc_en is 1564ae179b2fSYunsheng Lin * non-zero. 1565ae179b2fSYunsheng Lin */ 1566ae179b2fSYunsheng Lin if (hdev->tm_info.num_tc > 1 || hdev->tm_info.pfc_en) 1567ae179b2fSYunsheng Lin hdev->flag |= HCLGE_FLAG_DCB_ENABLE; 1568ae179b2fSYunsheng Lin else 1569ae179b2fSYunsheng Lin hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE; 1570ae179b2fSYunsheng Lin 1571ae179b2fSYunsheng Lin hclge_pfc_info_init(hdev); 1572ae179b2fSYunsheng Lin } 1573ae179b2fSYunsheng Lin 157444e59e37SYunsheng Lin int hclge_tm_init_hw(struct hclge_dev *hdev, bool init) 157584844054SSalil { 157684844054SSalil int ret; 157784844054SSalil 157884844054SSalil if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) && 157984844054SSalil (hdev->tx_sch_mode != HCLGE_FLAG_VNET_BASE_SCH_MODE)) 158084844054SSalil return -ENOTSUPP; 158184844054SSalil 158284844054SSalil ret = hclge_tm_schd_setup_hw(hdev); 158384844054SSalil if (ret) 158484844054SSalil return ret; 158584844054SSalil 158644e59e37SYunsheng Lin ret = hclge_pause_setup_hw(hdev, init); 158784844054SSalil if (ret) 158884844054SSalil return ret; 158984844054SSalil 159084844054SSalil return 0; 159184844054SSalil } 159284844054SSalil 159384844054SSalil int hclge_tm_schd_init(struct hclge_dev *hdev) 159484844054SSalil { 15957979a223SYunsheng Lin /* fc_mode is HCLGE_FC_FULL on reset */ 15967979a223SYunsheng Lin hdev->tm_info.fc_mode = HCLGE_FC_FULL; 15977979a223SYunsheng Lin hdev->fc_mode_last_time = hdev->tm_info.fc_mode; 15987979a223SYunsheng Lin 1599b6872fd3SYunsheng Lin if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE && 1600b6872fd3SYunsheng Lin hdev->tm_info.num_pg != 1) 1601b6872fd3SYunsheng Lin return -EINVAL; 1602b6872fd3SYunsheng Lin 1603b6872fd3SYunsheng Lin hclge_tm_schd_info_init(hdev); 160484844054SSalil 160544e59e37SYunsheng Lin return hclge_tm_init_hw(hdev, true); 160684844054SSalil } 1607672ad0edSHuazhong Tan 1608672ad0edSHuazhong Tan int hclge_tm_vport_map_update(struct hclge_dev *hdev) 1609672ad0edSHuazhong Tan { 1610672ad0edSHuazhong Tan struct hclge_vport *vport = hdev->vport; 1611672ad0edSHuazhong Tan int ret; 1612672ad0edSHuazhong Tan 1613672ad0edSHuazhong Tan hclge_tm_vport_tc_info_update(vport); 1614672ad0edSHuazhong Tan 1615672ad0edSHuazhong Tan ret = hclge_vport_q_to_qs_map(hdev, vport); 1616672ad0edSHuazhong Tan if (ret) 1617672ad0edSHuazhong Tan return ret; 1618672ad0edSHuazhong Tan 1619672ad0edSHuazhong Tan if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) 1620672ad0edSHuazhong Tan return 0; 1621672ad0edSHuazhong Tan 1622672ad0edSHuazhong Tan return hclge_tm_bp_setup(hdev); 1623672ad0edSHuazhong Tan } 16242bbad0aaSGuangbin Huang 16252bbad0aaSGuangbin Huang int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num) 16262bbad0aaSGuangbin Huang { 16272bbad0aaSGuangbin Huang struct hclge_tm_nodes_cmd *nodes; 16282bbad0aaSGuangbin Huang struct hclge_desc desc; 16292bbad0aaSGuangbin Huang int ret; 16302bbad0aaSGuangbin Huang 16312bbad0aaSGuangbin Huang if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) { 16322bbad0aaSGuangbin Huang /* Each PF has 8 qsets and each VF has 1 qset */ 16332bbad0aaSGuangbin Huang *qset_num = HCLGE_TM_PF_MAX_QSET_NUM + pci_num_vf(hdev->pdev); 16342bbad0aaSGuangbin Huang return 0; 16352bbad0aaSGuangbin Huang } 16362bbad0aaSGuangbin Huang 16372bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NODES, true); 16382bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 16392bbad0aaSGuangbin Huang if (ret) { 16402bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 16412bbad0aaSGuangbin Huang "failed to get qset num, ret = %d\n", ret); 16422bbad0aaSGuangbin Huang return ret; 16432bbad0aaSGuangbin Huang } 16442bbad0aaSGuangbin Huang 16452bbad0aaSGuangbin Huang nodes = (struct hclge_tm_nodes_cmd *)desc.data; 16462bbad0aaSGuangbin Huang *qset_num = le16_to_cpu(nodes->qset_num); 16472bbad0aaSGuangbin Huang return 0; 16482bbad0aaSGuangbin Huang } 16492bbad0aaSGuangbin Huang 16502bbad0aaSGuangbin Huang int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num) 16512bbad0aaSGuangbin Huang { 16522bbad0aaSGuangbin Huang struct hclge_tm_nodes_cmd *nodes; 16532bbad0aaSGuangbin Huang struct hclge_desc desc; 16542bbad0aaSGuangbin Huang int ret; 16552bbad0aaSGuangbin Huang 16562bbad0aaSGuangbin Huang if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) { 16572bbad0aaSGuangbin Huang *pri_num = HCLGE_TM_PF_MAX_PRI_NUM; 16582bbad0aaSGuangbin Huang return 0; 16592bbad0aaSGuangbin Huang } 16602bbad0aaSGuangbin Huang 16612bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NODES, true); 16622bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 16632bbad0aaSGuangbin Huang if (ret) { 16642bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 16652bbad0aaSGuangbin Huang "failed to get pri num, ret = %d\n", ret); 16662bbad0aaSGuangbin Huang return ret; 16672bbad0aaSGuangbin Huang } 16682bbad0aaSGuangbin Huang 16692bbad0aaSGuangbin Huang nodes = (struct hclge_tm_nodes_cmd *)desc.data; 16702bbad0aaSGuangbin Huang *pri_num = nodes->pri_num; 16712bbad0aaSGuangbin Huang return 0; 16722bbad0aaSGuangbin Huang } 16732bbad0aaSGuangbin Huang 16742bbad0aaSGuangbin Huang int hclge_tm_get_qset_map_pri(struct hclge_dev *hdev, u16 qset_id, u8 *priority, 16752bbad0aaSGuangbin Huang u8 *link_vld) 16762bbad0aaSGuangbin Huang { 16772bbad0aaSGuangbin Huang struct hclge_qs_to_pri_link_cmd *map; 16782bbad0aaSGuangbin Huang struct hclge_desc desc; 16792bbad0aaSGuangbin Huang int ret; 16802bbad0aaSGuangbin Huang 16812bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_TO_PRI_LINK, true); 16822bbad0aaSGuangbin Huang map = (struct hclge_qs_to_pri_link_cmd *)desc.data; 16832bbad0aaSGuangbin Huang map->qs_id = cpu_to_le16(qset_id); 16842bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 16852bbad0aaSGuangbin Huang if (ret) { 16862bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 16872bbad0aaSGuangbin Huang "failed to get qset map priority, ret = %d\n", ret); 16882bbad0aaSGuangbin Huang return ret; 16892bbad0aaSGuangbin Huang } 16902bbad0aaSGuangbin Huang 16912bbad0aaSGuangbin Huang *priority = map->priority; 16922bbad0aaSGuangbin Huang *link_vld = map->link_vld; 16932bbad0aaSGuangbin Huang return 0; 16942bbad0aaSGuangbin Huang } 16952bbad0aaSGuangbin Huang 16962bbad0aaSGuangbin Huang int hclge_tm_get_qset_sch_mode(struct hclge_dev *hdev, u16 qset_id, u8 *mode) 16972bbad0aaSGuangbin Huang { 16982bbad0aaSGuangbin Huang struct hclge_qs_sch_mode_cfg_cmd *qs_sch_mode; 16992bbad0aaSGuangbin Huang struct hclge_desc desc; 17002bbad0aaSGuangbin Huang int ret; 17012bbad0aaSGuangbin Huang 17022bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_SCH_MODE_CFG, true); 17032bbad0aaSGuangbin Huang qs_sch_mode = (struct hclge_qs_sch_mode_cfg_cmd *)desc.data; 17042bbad0aaSGuangbin Huang qs_sch_mode->qs_id = cpu_to_le16(qset_id); 17052bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 17062bbad0aaSGuangbin Huang if (ret) { 17072bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 17082bbad0aaSGuangbin Huang "failed to get qset sch mode, ret = %d\n", ret); 17092bbad0aaSGuangbin Huang return ret; 17102bbad0aaSGuangbin Huang } 17112bbad0aaSGuangbin Huang 17122bbad0aaSGuangbin Huang *mode = qs_sch_mode->sch_mode; 17132bbad0aaSGuangbin Huang return 0; 17142bbad0aaSGuangbin Huang } 17152bbad0aaSGuangbin Huang 17162bbad0aaSGuangbin Huang int hclge_tm_get_qset_weight(struct hclge_dev *hdev, u16 qset_id, u8 *weight) 17172bbad0aaSGuangbin Huang { 17182bbad0aaSGuangbin Huang struct hclge_qs_weight_cmd *qs_weight; 17192bbad0aaSGuangbin Huang struct hclge_desc desc; 17202bbad0aaSGuangbin Huang int ret; 17212bbad0aaSGuangbin Huang 17222bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_WEIGHT, true); 17232bbad0aaSGuangbin Huang qs_weight = (struct hclge_qs_weight_cmd *)desc.data; 17242bbad0aaSGuangbin Huang qs_weight->qs_id = cpu_to_le16(qset_id); 17252bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 17262bbad0aaSGuangbin Huang if (ret) { 17272bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 17282bbad0aaSGuangbin Huang "failed to get qset weight, ret = %d\n", ret); 17292bbad0aaSGuangbin Huang return ret; 17302bbad0aaSGuangbin Huang } 17312bbad0aaSGuangbin Huang 17322bbad0aaSGuangbin Huang *weight = qs_weight->dwrr; 17332bbad0aaSGuangbin Huang return 0; 17342bbad0aaSGuangbin Huang } 17352bbad0aaSGuangbin Huang 17362bbad0aaSGuangbin Huang int hclge_tm_get_pri_sch_mode(struct hclge_dev *hdev, u8 pri_id, u8 *mode) 17372bbad0aaSGuangbin Huang { 17382bbad0aaSGuangbin Huang struct hclge_pri_sch_mode_cfg_cmd *pri_sch_mode; 17392bbad0aaSGuangbin Huang struct hclge_desc desc; 17402bbad0aaSGuangbin Huang int ret; 17412bbad0aaSGuangbin Huang 17422bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_SCH_MODE_CFG, true); 17432bbad0aaSGuangbin Huang pri_sch_mode = (struct hclge_pri_sch_mode_cfg_cmd *)desc.data; 17442bbad0aaSGuangbin Huang pri_sch_mode->pri_id = pri_id; 17452bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 17462bbad0aaSGuangbin Huang if (ret) { 17472bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 17482bbad0aaSGuangbin Huang "failed to get priority sch mode, ret = %d\n", ret); 17492bbad0aaSGuangbin Huang return ret; 17502bbad0aaSGuangbin Huang } 17512bbad0aaSGuangbin Huang 17522bbad0aaSGuangbin Huang *mode = pri_sch_mode->sch_mode; 17532bbad0aaSGuangbin Huang return 0; 17542bbad0aaSGuangbin Huang } 17552bbad0aaSGuangbin Huang 17562bbad0aaSGuangbin Huang int hclge_tm_get_pri_weight(struct hclge_dev *hdev, u8 pri_id, u8 *weight) 17572bbad0aaSGuangbin Huang { 17582bbad0aaSGuangbin Huang struct hclge_priority_weight_cmd *priority_weight; 17592bbad0aaSGuangbin Huang struct hclge_desc desc; 17602bbad0aaSGuangbin Huang int ret; 17612bbad0aaSGuangbin Huang 17622bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_WEIGHT, true); 17632bbad0aaSGuangbin Huang priority_weight = (struct hclge_priority_weight_cmd *)desc.data; 17642bbad0aaSGuangbin Huang priority_weight->pri_id = pri_id; 17652bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 17662bbad0aaSGuangbin Huang if (ret) { 17672bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 17682bbad0aaSGuangbin Huang "failed to get priority weight, ret = %d\n", ret); 17692bbad0aaSGuangbin Huang return ret; 17702bbad0aaSGuangbin Huang } 17712bbad0aaSGuangbin Huang 17722bbad0aaSGuangbin Huang *weight = priority_weight->dwrr; 17732bbad0aaSGuangbin Huang return 0; 17742bbad0aaSGuangbin Huang } 17752bbad0aaSGuangbin Huang 17762bbad0aaSGuangbin Huang int hclge_tm_get_pri_shaper(struct hclge_dev *hdev, u8 pri_id, 17772bbad0aaSGuangbin Huang enum hclge_opcode_type cmd, 1778*cad7c215SGuangbin Huang struct hclge_tm_shaper_para *para) 17792bbad0aaSGuangbin Huang { 17802bbad0aaSGuangbin Huang struct hclge_pri_shapping_cmd *shap_cfg_cmd; 17812bbad0aaSGuangbin Huang struct hclge_desc desc; 17822bbad0aaSGuangbin Huang u32 shapping_para; 17832bbad0aaSGuangbin Huang int ret; 17842bbad0aaSGuangbin Huang 17852bbad0aaSGuangbin Huang if (cmd != HCLGE_OPC_TM_PRI_C_SHAPPING && 17862bbad0aaSGuangbin Huang cmd != HCLGE_OPC_TM_PRI_P_SHAPPING) 17872bbad0aaSGuangbin Huang return -EINVAL; 17882bbad0aaSGuangbin Huang 17892bbad0aaSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, cmd, true); 17902bbad0aaSGuangbin Huang shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data; 17912bbad0aaSGuangbin Huang shap_cfg_cmd->pri_id = pri_id; 17922bbad0aaSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 17932bbad0aaSGuangbin Huang if (ret) { 17942bbad0aaSGuangbin Huang dev_err(&hdev->pdev->dev, 17952bbad0aaSGuangbin Huang "failed to get priority shaper(%#x), ret = %d\n", 17962bbad0aaSGuangbin Huang cmd, ret); 17972bbad0aaSGuangbin Huang return ret; 17982bbad0aaSGuangbin Huang } 17992bbad0aaSGuangbin Huang 18002bbad0aaSGuangbin Huang shapping_para = le32_to_cpu(shap_cfg_cmd->pri_shapping_para); 18012bbad0aaSGuangbin Huang para->ir_b = hclge_tm_get_field(shapping_para, IR_B); 18022bbad0aaSGuangbin Huang para->ir_u = hclge_tm_get_field(shapping_para, IR_U); 18032bbad0aaSGuangbin Huang para->ir_s = hclge_tm_get_field(shapping_para, IR_S); 18042bbad0aaSGuangbin Huang para->bs_b = hclge_tm_get_field(shapping_para, BS_B); 18052bbad0aaSGuangbin Huang para->bs_s = hclge_tm_get_field(shapping_para, BS_S); 18062bbad0aaSGuangbin Huang para->flag = shap_cfg_cmd->flag; 18072bbad0aaSGuangbin Huang para->rate = le32_to_cpu(shap_cfg_cmd->pri_rate); 18082bbad0aaSGuangbin Huang return 0; 18092bbad0aaSGuangbin Huang } 18107679f28eSGuangbin Huang 18117679f28eSGuangbin Huang int hclge_tm_get_q_to_qs_map(struct hclge_dev *hdev, u16 q_id, u16 *qset_id) 18127679f28eSGuangbin Huang { 18137679f28eSGuangbin Huang struct hclge_nq_to_qs_link_cmd *map; 18147679f28eSGuangbin Huang struct hclge_desc desc; 18157679f28eSGuangbin Huang u16 qs_id_l; 18167679f28eSGuangbin Huang u16 qs_id_h; 18177679f28eSGuangbin Huang int ret; 18187679f28eSGuangbin Huang 18197679f28eSGuangbin Huang map = (struct hclge_nq_to_qs_link_cmd *)desc.data; 18207679f28eSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NQ_TO_QS_LINK, true); 18217679f28eSGuangbin Huang map->nq_id = cpu_to_le16(q_id); 18227679f28eSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 18237679f28eSGuangbin Huang if (ret) { 18247679f28eSGuangbin Huang dev_err(&hdev->pdev->dev, 18257679f28eSGuangbin Huang "failed to get queue to qset map, ret = %d\n", ret); 18267679f28eSGuangbin Huang return ret; 18277679f28eSGuangbin Huang } 18287679f28eSGuangbin Huang *qset_id = le16_to_cpu(map->qset_id); 18297679f28eSGuangbin Huang 18307679f28eSGuangbin Huang /* convert qset_id to the following format, drop the vld bit 18317679f28eSGuangbin Huang * | qs_id_h | vld | qs_id_l | 18327679f28eSGuangbin Huang * qset_id: | 15 ~ 11 | 10 | 9 ~ 0 | 18337679f28eSGuangbin Huang * \ \ / / 18347679f28eSGuangbin Huang * \ \ / / 18357679f28eSGuangbin Huang * qset_id: | 15 | 14 ~ 10 | 9 ~ 0 | 18367679f28eSGuangbin Huang */ 18377679f28eSGuangbin Huang qs_id_l = hnae3_get_field(*qset_id, HCLGE_TM_QS_ID_L_MSK, 18387679f28eSGuangbin Huang HCLGE_TM_QS_ID_L_S); 18397679f28eSGuangbin Huang qs_id_h = hnae3_get_field(*qset_id, HCLGE_TM_QS_ID_H_EXT_MSK, 18407679f28eSGuangbin Huang HCLGE_TM_QS_ID_H_EXT_S); 18417679f28eSGuangbin Huang *qset_id = 0; 18427679f28eSGuangbin Huang hnae3_set_field(*qset_id, HCLGE_TM_QS_ID_L_MSK, HCLGE_TM_QS_ID_L_S, 18437679f28eSGuangbin Huang qs_id_l); 18447679f28eSGuangbin Huang hnae3_set_field(*qset_id, HCLGE_TM_QS_ID_H_MSK, HCLGE_TM_QS_ID_H_S, 18457679f28eSGuangbin Huang qs_id_h); 18467679f28eSGuangbin Huang return 0; 18477679f28eSGuangbin Huang } 18487679f28eSGuangbin Huang 18497679f28eSGuangbin Huang int hclge_tm_get_q_to_tc(struct hclge_dev *hdev, u16 q_id, u8 *tc_id) 18507679f28eSGuangbin Huang { 18517679f28eSGuangbin Huang #define HCLGE_TM_TC_MASK 0x7 18527679f28eSGuangbin Huang 18537679f28eSGuangbin Huang struct hclge_tqp_tx_queue_tc_cmd *tc; 18547679f28eSGuangbin Huang struct hclge_desc desc; 18557679f28eSGuangbin Huang int ret; 18567679f28eSGuangbin Huang 18577679f28eSGuangbin Huang tc = (struct hclge_tqp_tx_queue_tc_cmd *)desc.data; 18587679f28eSGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TQP_TX_QUEUE_TC, true); 18597679f28eSGuangbin Huang tc->queue_id = cpu_to_le16(q_id); 18607679f28eSGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 18617679f28eSGuangbin Huang if (ret) { 18627679f28eSGuangbin Huang dev_err(&hdev->pdev->dev, 18637679f28eSGuangbin Huang "failed to get queue to tc map, ret = %d\n", ret); 18647679f28eSGuangbin Huang return ret; 18657679f28eSGuangbin Huang } 18667679f28eSGuangbin Huang 18677679f28eSGuangbin Huang *tc_id = tc->tc_id & HCLGE_TM_TC_MASK; 18687679f28eSGuangbin Huang return 0; 18697679f28eSGuangbin Huang } 1870*cad7c215SGuangbin Huang 1871*cad7c215SGuangbin Huang int hclge_tm_get_pg_to_pri_map(struct hclge_dev *hdev, u8 pg_id, 1872*cad7c215SGuangbin Huang u8 *pri_bit_map) 1873*cad7c215SGuangbin Huang { 1874*cad7c215SGuangbin Huang struct hclge_pg_to_pri_link_cmd *map; 1875*cad7c215SGuangbin Huang struct hclge_desc desc; 1876*cad7c215SGuangbin Huang int ret; 1877*cad7c215SGuangbin Huang 1878*cad7c215SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_TO_PRI_LINK, true); 1879*cad7c215SGuangbin Huang map = (struct hclge_pg_to_pri_link_cmd *)desc.data; 1880*cad7c215SGuangbin Huang map->pg_id = pg_id; 1881*cad7c215SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1882*cad7c215SGuangbin Huang if (ret) { 1883*cad7c215SGuangbin Huang dev_err(&hdev->pdev->dev, 1884*cad7c215SGuangbin Huang "failed to get pg to pri map, ret = %d\n", ret); 1885*cad7c215SGuangbin Huang return ret; 1886*cad7c215SGuangbin Huang } 1887*cad7c215SGuangbin Huang 1888*cad7c215SGuangbin Huang *pri_bit_map = map->pri_bit_map; 1889*cad7c215SGuangbin Huang return 0; 1890*cad7c215SGuangbin Huang } 1891*cad7c215SGuangbin Huang 1892*cad7c215SGuangbin Huang int hclge_tm_get_pg_weight(struct hclge_dev *hdev, u8 pg_id, u8 *weight) 1893*cad7c215SGuangbin Huang { 1894*cad7c215SGuangbin Huang struct hclge_pg_weight_cmd *pg_weight_cmd; 1895*cad7c215SGuangbin Huang struct hclge_desc desc; 1896*cad7c215SGuangbin Huang int ret; 1897*cad7c215SGuangbin Huang 1898*cad7c215SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_WEIGHT, true); 1899*cad7c215SGuangbin Huang pg_weight_cmd = (struct hclge_pg_weight_cmd *)desc.data; 1900*cad7c215SGuangbin Huang pg_weight_cmd->pg_id = pg_id; 1901*cad7c215SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1902*cad7c215SGuangbin Huang if (ret) { 1903*cad7c215SGuangbin Huang dev_err(&hdev->pdev->dev, 1904*cad7c215SGuangbin Huang "failed to get pg weight, ret = %d\n", ret); 1905*cad7c215SGuangbin Huang return ret; 1906*cad7c215SGuangbin Huang } 1907*cad7c215SGuangbin Huang 1908*cad7c215SGuangbin Huang *weight = pg_weight_cmd->dwrr; 1909*cad7c215SGuangbin Huang return 0; 1910*cad7c215SGuangbin Huang } 1911*cad7c215SGuangbin Huang 1912*cad7c215SGuangbin Huang int hclge_tm_get_pg_sch_mode(struct hclge_dev *hdev, u8 pg_id, u8 *mode) 1913*cad7c215SGuangbin Huang { 1914*cad7c215SGuangbin Huang struct hclge_desc desc; 1915*cad7c215SGuangbin Huang int ret; 1916*cad7c215SGuangbin Huang 1917*cad7c215SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_SCH_MODE_CFG, true); 1918*cad7c215SGuangbin Huang desc.data[0] = cpu_to_le32(pg_id); 1919*cad7c215SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1920*cad7c215SGuangbin Huang if (ret) { 1921*cad7c215SGuangbin Huang dev_err(&hdev->pdev->dev, 1922*cad7c215SGuangbin Huang "failed to get pg sch mode, ret = %d\n", ret); 1923*cad7c215SGuangbin Huang return ret; 1924*cad7c215SGuangbin Huang } 1925*cad7c215SGuangbin Huang 1926*cad7c215SGuangbin Huang *mode = (u8)le32_to_cpu(desc.data[1]); 1927*cad7c215SGuangbin Huang return 0; 1928*cad7c215SGuangbin Huang } 1929*cad7c215SGuangbin Huang 1930*cad7c215SGuangbin Huang int hclge_tm_get_pg_shaper(struct hclge_dev *hdev, u8 pg_id, 1931*cad7c215SGuangbin Huang enum hclge_opcode_type cmd, 1932*cad7c215SGuangbin Huang struct hclge_tm_shaper_para *para) 1933*cad7c215SGuangbin Huang { 1934*cad7c215SGuangbin Huang struct hclge_pg_shapping_cmd *shap_cfg_cmd; 1935*cad7c215SGuangbin Huang struct hclge_desc desc; 1936*cad7c215SGuangbin Huang u32 shapping_para; 1937*cad7c215SGuangbin Huang int ret; 1938*cad7c215SGuangbin Huang 1939*cad7c215SGuangbin Huang if (cmd != HCLGE_OPC_TM_PG_C_SHAPPING && 1940*cad7c215SGuangbin Huang cmd != HCLGE_OPC_TM_PG_P_SHAPPING) 1941*cad7c215SGuangbin Huang return -EINVAL; 1942*cad7c215SGuangbin Huang 1943*cad7c215SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, cmd, true); 1944*cad7c215SGuangbin Huang shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data; 1945*cad7c215SGuangbin Huang shap_cfg_cmd->pg_id = pg_id; 1946*cad7c215SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1947*cad7c215SGuangbin Huang if (ret) { 1948*cad7c215SGuangbin Huang dev_err(&hdev->pdev->dev, 1949*cad7c215SGuangbin Huang "failed to get pg shaper(%#x), ret = %d\n", 1950*cad7c215SGuangbin Huang cmd, ret); 1951*cad7c215SGuangbin Huang return ret; 1952*cad7c215SGuangbin Huang } 1953*cad7c215SGuangbin Huang 1954*cad7c215SGuangbin Huang shapping_para = le32_to_cpu(shap_cfg_cmd->pg_shapping_para); 1955*cad7c215SGuangbin Huang para->ir_b = hclge_tm_get_field(shapping_para, IR_B); 1956*cad7c215SGuangbin Huang para->ir_u = hclge_tm_get_field(shapping_para, IR_U); 1957*cad7c215SGuangbin Huang para->ir_s = hclge_tm_get_field(shapping_para, IR_S); 1958*cad7c215SGuangbin Huang para->bs_b = hclge_tm_get_field(shapping_para, BS_B); 1959*cad7c215SGuangbin Huang para->bs_s = hclge_tm_get_field(shapping_para, BS_S); 1960*cad7c215SGuangbin Huang para->flag = shap_cfg_cmd->flag; 1961*cad7c215SGuangbin Huang para->rate = le32_to_cpu(shap_cfg_cmd->pg_rate); 1962*cad7c215SGuangbin Huang return 0; 1963*cad7c215SGuangbin Huang } 1964*cad7c215SGuangbin Huang 1965*cad7c215SGuangbin Huang int hclge_tm_get_port_shaper(struct hclge_dev *hdev, 1966*cad7c215SGuangbin Huang struct hclge_tm_shaper_para *para) 1967*cad7c215SGuangbin Huang { 1968*cad7c215SGuangbin Huang struct hclge_port_shapping_cmd *port_shap_cfg_cmd; 1969*cad7c215SGuangbin Huang struct hclge_desc desc; 1970*cad7c215SGuangbin Huang u32 shapping_para; 1971*cad7c215SGuangbin Huang int ret; 1972*cad7c215SGuangbin Huang 1973*cad7c215SGuangbin Huang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PORT_SHAPPING, true); 1974*cad7c215SGuangbin Huang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 1975*cad7c215SGuangbin Huang if (ret) { 1976*cad7c215SGuangbin Huang dev_err(&hdev->pdev->dev, 1977*cad7c215SGuangbin Huang "failed to get port shaper, ret = %d\n", ret); 1978*cad7c215SGuangbin Huang return ret; 1979*cad7c215SGuangbin Huang } 1980*cad7c215SGuangbin Huang 1981*cad7c215SGuangbin Huang port_shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data; 1982*cad7c215SGuangbin Huang shapping_para = le32_to_cpu(port_shap_cfg_cmd->port_shapping_para); 1983*cad7c215SGuangbin Huang para->ir_b = hclge_tm_get_field(shapping_para, IR_B); 1984*cad7c215SGuangbin Huang para->ir_u = hclge_tm_get_field(shapping_para, IR_U); 1985*cad7c215SGuangbin Huang para->ir_s = hclge_tm_get_field(shapping_para, IR_S); 1986*cad7c215SGuangbin Huang para->bs_b = hclge_tm_get_field(shapping_para, BS_B); 1987*cad7c215SGuangbin Huang para->bs_s = hclge_tm_get_field(shapping_para, BS_S); 1988*cad7c215SGuangbin Huang para->flag = port_shap_cfg_cmd->flag; 1989*cad7c215SGuangbin Huang para->rate = le32_to_cpu(port_shap_cfg_cmd->port_rate); 1990*cad7c215SGuangbin Huang 1991*cad7c215SGuangbin Huang return 0; 1992*cad7c215SGuangbin Huang } 1993