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 #define HCLGE_ETHER_MAX_RATE 100000 2784844054SSalil 2884844054SSalil /* hclge_shaper_para_calc: calculate ir parameter for the shaper 2984844054SSalil * @ir: Rate to be config, its unit is Mbps 3084844054SSalil * @shaper_level: the shaper level. eg: port, pg, priority, queueset 3184844054SSalil * @ir_b: IR_B parameter of IR shaper 3284844054SSalil * @ir_u: IR_U parameter of IR shaper 3384844054SSalil * @ir_s: IR_S parameter of IR shaper 3484844054SSalil * 3584844054SSalil * the formula: 3684844054SSalil * 3784844054SSalil * IR_b * (2 ^ IR_u) * 8 3884844054SSalil * IR(Mbps) = ------------------------- * CLOCK(1000Mbps) 3984844054SSalil * Tick * (2 ^ IR_s) 4084844054SSalil * 4184844054SSalil * @return: 0: calculate sucessful, negative: fail 4284844054SSalil */ 4384844054SSalil static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, 4484844054SSalil u8 *ir_b, u8 *ir_u, u8 *ir_s) 4584844054SSalil { 4684844054SSalil const u16 tick_array[HCLGE_SHAPER_LVL_CNT] = { 4784844054SSalil 6 * 256, /* Prioriy level */ 4884844054SSalil 6 * 32, /* Prioriy group level */ 4984844054SSalil 6 * 8, /* Port level */ 5084844054SSalil 6 * 256 /* Qset level */ 5184844054SSalil }; 5284844054SSalil u8 ir_u_calc = 0, ir_s_calc = 0; 5384844054SSalil u32 ir_calc; 5484844054SSalil u32 tick; 5584844054SSalil 5684844054SSalil /* Calc tick */ 5784844054SSalil if (shaper_level >= HCLGE_SHAPER_LVL_CNT) 5884844054SSalil return -EINVAL; 5984844054SSalil 6084844054SSalil tick = tick_array[shaper_level]; 6184844054SSalil 6284844054SSalil /** 6384844054SSalil * Calc the speed if ir_b = 126, ir_u = 0 and ir_s = 0 6484844054SSalil * the formula is changed to: 6584844054SSalil * 126 * 1 * 8 6684844054SSalil * ir_calc = ---------------- * 1000 6784844054SSalil * tick * 1 6884844054SSalil */ 6984844054SSalil ir_calc = (1008000 + (tick >> 1) - 1) / tick; 7084844054SSalil 7184844054SSalil if (ir_calc == ir) { 7284844054SSalil *ir_b = 126; 7384844054SSalil *ir_u = 0; 7484844054SSalil *ir_s = 0; 7584844054SSalil 7684844054SSalil return 0; 7784844054SSalil } else if (ir_calc > ir) { 7884844054SSalil /* Increasing the denominator to select ir_s value */ 7984844054SSalil while (ir_calc > ir) { 8084844054SSalil ir_s_calc++; 8184844054SSalil ir_calc = 1008000 / (tick * (1 << ir_s_calc)); 8284844054SSalil } 8384844054SSalil 8484844054SSalil if (ir_calc == ir) 8584844054SSalil *ir_b = 126; 8684844054SSalil else 8784844054SSalil *ir_b = (ir * tick * (1 << ir_s_calc) + 4000) / 8000; 8884844054SSalil } else { 8984844054SSalil /* Increasing the numerator to select ir_u value */ 9084844054SSalil u32 numerator; 9184844054SSalil 9284844054SSalil while (ir_calc < ir) { 9384844054SSalil ir_u_calc++; 9484844054SSalil numerator = 1008000 * (1 << ir_u_calc); 9584844054SSalil ir_calc = (numerator + (tick >> 1)) / tick; 9684844054SSalil } 9784844054SSalil 9884844054SSalil if (ir_calc == ir) { 9984844054SSalil *ir_b = 126; 10084844054SSalil } else { 10184844054SSalil u32 denominator = (8000 * (1 << --ir_u_calc)); 10284844054SSalil *ir_b = (ir * tick + (denominator >> 1)) / denominator; 10384844054SSalil } 10484844054SSalil } 10584844054SSalil 10684844054SSalil *ir_u = ir_u_calc; 10784844054SSalil *ir_s = ir_s_calc; 10884844054SSalil 10984844054SSalil return 0; 11084844054SSalil } 11184844054SSalil 11264fd2300SPeng Li static int hclge_pfc_stats_get(struct hclge_dev *hdev, 11364fd2300SPeng Li enum hclge_opcode_type opcode, u64 *stats) 11464fd2300SPeng Li { 11564fd2300SPeng Li struct hclge_desc desc[HCLGE_TM_PFC_PKT_GET_CMD_NUM]; 11664fd2300SPeng Li int ret, i, j; 11764fd2300SPeng Li 11864fd2300SPeng Li if (!(opcode == HCLGE_OPC_QUERY_PFC_RX_PKT_CNT || 11964fd2300SPeng Li opcode == HCLGE_OPC_QUERY_PFC_TX_PKT_CNT)) 12064fd2300SPeng Li return -EINVAL; 12164fd2300SPeng Li 12264fd2300SPeng Li for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) { 12364fd2300SPeng Li hclge_cmd_setup_basic_desc(&desc[i], opcode, true); 12464fd2300SPeng Li if (i != (HCLGE_TM_PFC_PKT_GET_CMD_NUM - 1)) 12564fd2300SPeng Li desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); 12664fd2300SPeng Li else 12764fd2300SPeng Li desc[i].flag &= ~cpu_to_le16(HCLGE_CMD_FLAG_NEXT); 12864fd2300SPeng Li } 12964fd2300SPeng Li 13064fd2300SPeng Li ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_TM_PFC_PKT_GET_CMD_NUM); 13120670328SYunsheng Lin if (ret) 13264fd2300SPeng Li return ret; 13364fd2300SPeng Li 13464fd2300SPeng Li for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) { 13564fd2300SPeng Li struct hclge_pfc_stats_cmd *pfc_stats = 13664fd2300SPeng Li (struct hclge_pfc_stats_cmd *)desc[i].data; 13764fd2300SPeng Li 13864fd2300SPeng Li for (j = 0; j < HCLGE_TM_PFC_NUM_GET_PER_CMD; j++) { 13964fd2300SPeng Li u32 index = i * HCLGE_TM_PFC_PKT_GET_CMD_NUM + j; 14064fd2300SPeng Li 14164fd2300SPeng Li if (index < HCLGE_MAX_TC_NUM) 14264fd2300SPeng Li stats[index] = 14364fd2300SPeng Li le64_to_cpu(pfc_stats->pkt_num[j]); 14464fd2300SPeng Li } 14564fd2300SPeng Li } 14664fd2300SPeng Li return 0; 14764fd2300SPeng Li } 14864fd2300SPeng Li 14964fd2300SPeng Li int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats) 15064fd2300SPeng Li { 15164fd2300SPeng Li return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_RX_PKT_CNT, stats); 15264fd2300SPeng Li } 15364fd2300SPeng Li 15464fd2300SPeng Li int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats) 15564fd2300SPeng Li { 15664fd2300SPeng Li return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_TX_PKT_CNT, stats); 15764fd2300SPeng Li } 15864fd2300SPeng Li 15961387774SPeng Li int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx) 16084844054SSalil { 16184844054SSalil struct hclge_desc desc; 16284844054SSalil 16384844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PAUSE_EN, false); 16484844054SSalil 16584844054SSalil desc.data[0] = cpu_to_le32((tx ? HCLGE_TX_MAC_PAUSE_EN_MSK : 0) | 16684844054SSalil (rx ? HCLGE_RX_MAC_PAUSE_EN_MSK : 0)); 16784844054SSalil 16884844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 16984844054SSalil } 17084844054SSalil 1719dc2145dSYunsheng Lin static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, 1729dc2145dSYunsheng Lin u8 pfc_bitmap) 1739dc2145dSYunsheng Lin { 1749dc2145dSYunsheng Lin struct hclge_desc desc; 175d0d72bacSJian Shen struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)desc.data; 1769dc2145dSYunsheng Lin 1779dc2145dSYunsheng Lin hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PFC_PAUSE_EN, false); 1789dc2145dSYunsheng Lin 1799dc2145dSYunsheng Lin pfc->tx_rx_en_bitmap = tx_rx_bitmap; 1809dc2145dSYunsheng Lin pfc->pri_en_bitmap = pfc_bitmap; 1819dc2145dSYunsheng Lin 1829dc2145dSYunsheng Lin return hclge_cmd_send(&hdev->hw, &desc, 1); 1839dc2145dSYunsheng Lin } 1849dc2145dSYunsheng Lin 185e98d7183SFuyun Liang static int hclge_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr, 18618838d0cSFuyun Liang u8 pause_trans_gap, u16 pause_trans_time) 18718838d0cSFuyun Liang { 18818838d0cSFuyun Liang struct hclge_cfg_pause_param_cmd *pause_param; 18918838d0cSFuyun Liang struct hclge_desc desc; 19018838d0cSFuyun Liang 191d0d72bacSJian Shen pause_param = (struct hclge_cfg_pause_param_cmd *)desc.data; 19218838d0cSFuyun Liang 19318838d0cSFuyun Liang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, false); 19418838d0cSFuyun Liang 19518838d0cSFuyun Liang ether_addr_copy(pause_param->mac_addr, addr); 196cd2086bfSFuyun Liang ether_addr_copy(pause_param->mac_addr_extra, addr); 19718838d0cSFuyun Liang pause_param->pause_trans_gap = pause_trans_gap; 19818838d0cSFuyun Liang pause_param->pause_trans_time = cpu_to_le16(pause_trans_time); 19918838d0cSFuyun Liang 20018838d0cSFuyun Liang return hclge_cmd_send(&hdev->hw, &desc, 1); 20118838d0cSFuyun Liang } 20218838d0cSFuyun Liang 203e98d7183SFuyun Liang int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr) 20418838d0cSFuyun Liang { 20518838d0cSFuyun Liang struct hclge_cfg_pause_param_cmd *pause_param; 20618838d0cSFuyun Liang struct hclge_desc desc; 20718838d0cSFuyun Liang u16 trans_time; 20818838d0cSFuyun Liang u8 trans_gap; 20918838d0cSFuyun Liang int ret; 21018838d0cSFuyun Liang 211d0d72bacSJian Shen pause_param = (struct hclge_cfg_pause_param_cmd *)desc.data; 21218838d0cSFuyun Liang 21318838d0cSFuyun Liang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, true); 21418838d0cSFuyun Liang 21518838d0cSFuyun Liang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 21618838d0cSFuyun Liang if (ret) 21718838d0cSFuyun Liang return ret; 21818838d0cSFuyun Liang 21918838d0cSFuyun Liang trans_gap = pause_param->pause_trans_gap; 22018838d0cSFuyun Liang trans_time = le16_to_cpu(pause_param->pause_trans_time); 22118838d0cSFuyun Liang 222e98d7183SFuyun Liang return hclge_pause_param_cfg(hdev, mac_addr, trans_gap, 22318838d0cSFuyun Liang trans_time); 22418838d0cSFuyun Liang } 22518838d0cSFuyun Liang 22684844054SSalil static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id) 22784844054SSalil { 22884844054SSalil u8 tc; 22984844054SSalil 230c5795c53SYunsheng Lin tc = hdev->tm_info.prio_tc[pri_id]; 23184844054SSalil 23284844054SSalil if (tc >= hdev->tm_info.num_tc) 23384844054SSalil return -EINVAL; 23484844054SSalil 23584844054SSalil /** 23684844054SSalil * the register for priority has four bytes, the first bytes includes 23784844054SSalil * priority0 and priority1, the higher 4bit stands for priority1 23884844054SSalil * while the lower 4bit stands for priority0, as below: 23984844054SSalil * first byte: | pri_1 | pri_0 | 24084844054SSalil * second byte: | pri_3 | pri_2 | 24184844054SSalil * third byte: | pri_5 | pri_4 | 24284844054SSalil * fourth byte: | pri_7 | pri_6 | 24384844054SSalil */ 24484844054SSalil pri[pri_id >> 1] |= tc << ((pri_id & 1) * 4); 24584844054SSalil 24684844054SSalil return 0; 24784844054SSalil } 24884844054SSalil 24984844054SSalil static int hclge_up_to_tc_map(struct hclge_dev *hdev) 25084844054SSalil { 25184844054SSalil struct hclge_desc desc; 25284844054SSalil u8 *pri = (u8 *)desc.data; 25384844054SSalil u8 pri_id; 25484844054SSalil int ret; 25584844054SSalil 25684844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PRI_TO_TC_MAPPING, false); 25784844054SSalil 258c5795c53SYunsheng Lin for (pri_id = 0; pri_id < HNAE3_MAX_USER_PRIO; pri_id++) { 25984844054SSalil ret = hclge_fill_pri_array(hdev, pri, pri_id); 26084844054SSalil if (ret) 26184844054SSalil return ret; 26284844054SSalil } 26384844054SSalil 26484844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 26584844054SSalil } 26684844054SSalil 26784844054SSalil static int hclge_tm_pg_to_pri_map_cfg(struct hclge_dev *hdev, 26884844054SSalil u8 pg_id, u8 pri_bit_map) 26984844054SSalil { 27084844054SSalil struct hclge_pg_to_pri_link_cmd *map; 27184844054SSalil struct hclge_desc desc; 27284844054SSalil 27384844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_TO_PRI_LINK, false); 27484844054SSalil 27584844054SSalil map = (struct hclge_pg_to_pri_link_cmd *)desc.data; 27684844054SSalil 27784844054SSalil map->pg_id = pg_id; 27884844054SSalil map->pri_bit_map = pri_bit_map; 27984844054SSalil 28084844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 28184844054SSalil } 28284844054SSalil 28384844054SSalil static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev, 28484844054SSalil u16 qs_id, u8 pri) 28584844054SSalil { 28684844054SSalil struct hclge_qs_to_pri_link_cmd *map; 28784844054SSalil struct hclge_desc desc; 28884844054SSalil 28984844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_TO_PRI_LINK, false); 29084844054SSalil 29184844054SSalil map = (struct hclge_qs_to_pri_link_cmd *)desc.data; 29284844054SSalil 29384844054SSalil map->qs_id = cpu_to_le16(qs_id); 29484844054SSalil map->priority = pri; 29584844054SSalil map->link_vld = HCLGE_TM_QS_PRI_LINK_VLD_MSK; 29684844054SSalil 29784844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 29884844054SSalil } 29984844054SSalil 30084844054SSalil static int hclge_tm_q_to_qs_map_cfg(struct hclge_dev *hdev, 30132c7fbc8SJian Shen u16 q_id, u16 qs_id) 30284844054SSalil { 30384844054SSalil struct hclge_nq_to_qs_link_cmd *map; 30484844054SSalil struct hclge_desc desc; 30584844054SSalil 30684844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NQ_TO_QS_LINK, false); 30784844054SSalil 30884844054SSalil map = (struct hclge_nq_to_qs_link_cmd *)desc.data; 30984844054SSalil 31084844054SSalil map->nq_id = cpu_to_le16(q_id); 31184844054SSalil map->qset_id = cpu_to_le16(qs_id | HCLGE_TM_Q_QS_LINK_VLD_MSK); 31284844054SSalil 31384844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 31484844054SSalil } 31584844054SSalil 31684844054SSalil static int hclge_tm_pg_weight_cfg(struct hclge_dev *hdev, u8 pg_id, 31784844054SSalil u8 dwrr) 31884844054SSalil { 31984844054SSalil struct hclge_pg_weight_cmd *weight; 32084844054SSalil struct hclge_desc desc; 32184844054SSalil 32284844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_WEIGHT, false); 32384844054SSalil 32484844054SSalil weight = (struct hclge_pg_weight_cmd *)desc.data; 32584844054SSalil 32684844054SSalil weight->pg_id = pg_id; 32784844054SSalil weight->dwrr = dwrr; 32884844054SSalil 32984844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 33084844054SSalil } 33184844054SSalil 33284844054SSalil static int hclge_tm_pri_weight_cfg(struct hclge_dev *hdev, u8 pri_id, 33384844054SSalil u8 dwrr) 33484844054SSalil { 33584844054SSalil struct hclge_priority_weight_cmd *weight; 33684844054SSalil struct hclge_desc desc; 33784844054SSalil 33884844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_WEIGHT, false); 33984844054SSalil 34084844054SSalil weight = (struct hclge_priority_weight_cmd *)desc.data; 34184844054SSalil 34284844054SSalil weight->pri_id = pri_id; 34384844054SSalil weight->dwrr = dwrr; 34484844054SSalil 34584844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 34684844054SSalil } 34784844054SSalil 34884844054SSalil static int hclge_tm_qs_weight_cfg(struct hclge_dev *hdev, u16 qs_id, 34984844054SSalil u8 dwrr) 35084844054SSalil { 35184844054SSalil struct hclge_qs_weight_cmd *weight; 35284844054SSalil struct hclge_desc desc; 35384844054SSalil 35484844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_WEIGHT, false); 35584844054SSalil 35684844054SSalil weight = (struct hclge_qs_weight_cmd *)desc.data; 35784844054SSalil 35884844054SSalil weight->qs_id = cpu_to_le16(qs_id); 35984844054SSalil weight->dwrr = dwrr; 36084844054SSalil 36184844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 36284844054SSalil } 36384844054SSalil 36484844054SSalil static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev, 36584844054SSalil enum hclge_shap_bucket bucket, u8 pg_id, 36684844054SSalil u8 ir_b, u8 ir_u, u8 ir_s, u8 bs_b, u8 bs_s) 36784844054SSalil { 36884844054SSalil struct hclge_pg_shapping_cmd *shap_cfg_cmd; 36984844054SSalil enum hclge_opcode_type opcode; 37084844054SSalil struct hclge_desc desc; 371a90bb9a5SYunsheng Lin u32 shapping_para = 0; 37284844054SSalil 37384844054SSalil opcode = bucket ? HCLGE_OPC_TM_PG_P_SHAPPING : 37484844054SSalil HCLGE_OPC_TM_PG_C_SHAPPING; 37584844054SSalil hclge_cmd_setup_basic_desc(&desc, opcode, false); 37684844054SSalil 37784844054SSalil shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data; 37884844054SSalil 37984844054SSalil shap_cfg_cmd->pg_id = pg_id; 38084844054SSalil 381a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_B, ir_b); 382a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_U, ir_u); 383a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_S, ir_s); 384a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, BS_B, bs_b); 385a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, BS_S, bs_s); 386a90bb9a5SYunsheng Lin 387a90bb9a5SYunsheng Lin shap_cfg_cmd->pg_shapping_para = cpu_to_le32(shapping_para); 38884844054SSalil 38984844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 39084844054SSalil } 39184844054SSalil 3920a5677d3SYunsheng Lin static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev) 3930a5677d3SYunsheng Lin { 3940a5677d3SYunsheng Lin struct hclge_port_shapping_cmd *shap_cfg_cmd; 3950a5677d3SYunsheng Lin struct hclge_desc desc; 3960a5677d3SYunsheng Lin u32 shapping_para = 0; 3970a5677d3SYunsheng Lin u8 ir_u, ir_b, ir_s; 3980a5677d3SYunsheng Lin int ret; 3990a5677d3SYunsheng Lin 4000a5677d3SYunsheng Lin ret = hclge_shaper_para_calc(HCLGE_ETHER_MAX_RATE, 4010a5677d3SYunsheng Lin HCLGE_SHAPER_LVL_PORT, 4020a5677d3SYunsheng Lin &ir_b, &ir_u, &ir_s); 4030a5677d3SYunsheng Lin if (ret) 4040a5677d3SYunsheng Lin return ret; 4050a5677d3SYunsheng Lin 4060a5677d3SYunsheng Lin hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PORT_SHAPPING, false); 4070a5677d3SYunsheng Lin shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data; 4080a5677d3SYunsheng Lin 4090a5677d3SYunsheng Lin hclge_tm_set_field(shapping_para, IR_B, ir_b); 4100a5677d3SYunsheng Lin hclge_tm_set_field(shapping_para, IR_U, ir_u); 4110a5677d3SYunsheng Lin hclge_tm_set_field(shapping_para, IR_S, ir_s); 4120a5677d3SYunsheng Lin hclge_tm_set_field(shapping_para, BS_B, HCLGE_SHAPER_BS_U_DEF); 4130a5677d3SYunsheng Lin hclge_tm_set_field(shapping_para, BS_S, HCLGE_SHAPER_BS_S_DEF); 4140a5677d3SYunsheng Lin 4150a5677d3SYunsheng Lin shap_cfg_cmd->port_shapping_para = cpu_to_le32(shapping_para); 4160a5677d3SYunsheng Lin 4170a5677d3SYunsheng Lin return hclge_cmd_send(&hdev->hw, &desc, 1); 4180a5677d3SYunsheng Lin } 4190a5677d3SYunsheng Lin 42084844054SSalil static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev, 42184844054SSalil enum hclge_shap_bucket bucket, u8 pri_id, 42284844054SSalil u8 ir_b, u8 ir_u, u8 ir_s, 42384844054SSalil u8 bs_b, u8 bs_s) 42484844054SSalil { 42584844054SSalil struct hclge_pri_shapping_cmd *shap_cfg_cmd; 42684844054SSalil enum hclge_opcode_type opcode; 42784844054SSalil struct hclge_desc desc; 428a90bb9a5SYunsheng Lin u32 shapping_para = 0; 42984844054SSalil 43084844054SSalil opcode = bucket ? HCLGE_OPC_TM_PRI_P_SHAPPING : 43184844054SSalil HCLGE_OPC_TM_PRI_C_SHAPPING; 43284844054SSalil 43384844054SSalil hclge_cmd_setup_basic_desc(&desc, opcode, false); 43484844054SSalil 43584844054SSalil shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data; 43684844054SSalil 43784844054SSalil shap_cfg_cmd->pri_id = pri_id; 43884844054SSalil 439a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_B, ir_b); 440a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_U, ir_u); 441a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_S, ir_s); 442a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, BS_B, bs_b); 443a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, BS_S, bs_s); 444a90bb9a5SYunsheng Lin 445a90bb9a5SYunsheng Lin shap_cfg_cmd->pri_shapping_para = cpu_to_le32(shapping_para); 44684844054SSalil 44784844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 44884844054SSalil } 44984844054SSalil 45084844054SSalil static int hclge_tm_pg_schd_mode_cfg(struct hclge_dev *hdev, u8 pg_id) 45184844054SSalil { 45284844054SSalil struct hclge_desc desc; 45384844054SSalil 45484844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_SCH_MODE_CFG, false); 45584844054SSalil 45684844054SSalil if (hdev->tm_info.pg_info[pg_id].pg_sch_mode == HCLGE_SCH_MODE_DWRR) 45784844054SSalil desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK); 45884844054SSalil else 45984844054SSalil desc.data[1] = 0; 46084844054SSalil 46184844054SSalil desc.data[0] = cpu_to_le32(pg_id); 46284844054SSalil 46384844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 46484844054SSalil } 46584844054SSalil 46684844054SSalil static int hclge_tm_pri_schd_mode_cfg(struct hclge_dev *hdev, u8 pri_id) 46784844054SSalil { 46884844054SSalil struct hclge_desc desc; 46984844054SSalil 47084844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_SCH_MODE_CFG, false); 47184844054SSalil 47284844054SSalil if (hdev->tm_info.tc_info[pri_id].tc_sch_mode == HCLGE_SCH_MODE_DWRR) 47384844054SSalil desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK); 47484844054SSalil else 47584844054SSalil desc.data[1] = 0; 47684844054SSalil 47784844054SSalil desc.data[0] = cpu_to_le32(pri_id); 47884844054SSalil 47984844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 48084844054SSalil } 48184844054SSalil 482cc9bb43aSYunsheng Lin static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id, u8 mode) 48384844054SSalil { 48484844054SSalil struct hclge_desc desc; 48584844054SSalil 48684844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_SCH_MODE_CFG, false); 48784844054SSalil 488cc9bb43aSYunsheng Lin if (mode == HCLGE_SCH_MODE_DWRR) 48984844054SSalil desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK); 49084844054SSalil else 49184844054SSalil desc.data[1] = 0; 49284844054SSalil 49384844054SSalil desc.data[0] = cpu_to_le32(qs_id); 49484844054SSalil 49584844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 49684844054SSalil } 49784844054SSalil 49867bf2541SYunsheng Lin static int hclge_tm_qs_bp_cfg(struct hclge_dev *hdev, u8 tc, u8 grp_id, 49967bf2541SYunsheng Lin u32 bit_map) 50084844054SSalil { 50184844054SSalil struct hclge_bp_to_qs_map_cmd *bp_to_qs_map_cmd; 50284844054SSalil struct hclge_desc desc; 50384844054SSalil 50484844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_BP_TO_QSET_MAPPING, 50584844054SSalil false); 50684844054SSalil 50784844054SSalil bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data; 50884844054SSalil 50984844054SSalil bp_to_qs_map_cmd->tc_id = tc; 51067bf2541SYunsheng Lin bp_to_qs_map_cmd->qs_group_id = grp_id; 51167bf2541SYunsheng Lin bp_to_qs_map_cmd->qs_bit_map = cpu_to_le32(bit_map); 51284844054SSalil 51384844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 51484844054SSalil } 51584844054SSalil 51684844054SSalil static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) 51784844054SSalil { 51884844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 51984844054SSalil struct hclge_dev *hdev = vport->back; 520672ad0edSHuazhong Tan u16 max_rss_size; 52184844054SSalil u8 i; 52284844054SSalil 52384844054SSalil vport->bw_limit = hdev->tm_info.pg_info[0].bw_limit; 524672ad0edSHuazhong Tan kinfo->num_tc = min_t(u16, vport->alloc_tqps, hdev->tm_info.num_tc); 525672ad0edSHuazhong Tan max_rss_size = min_t(u16, hdev->rss_size_max, 526672ad0edSHuazhong Tan vport->alloc_tqps / kinfo->num_tc); 527672ad0edSHuazhong Tan 528672ad0edSHuazhong Tan if (kinfo->req_rss_size != kinfo->rss_size && kinfo->req_rss_size && 529672ad0edSHuazhong Tan kinfo->req_rss_size <= max_rss_size) { 530672ad0edSHuazhong Tan dev_info(&hdev->pdev->dev, "rss changes from %d to %d\n", 531672ad0edSHuazhong Tan kinfo->rss_size, kinfo->req_rss_size); 532672ad0edSHuazhong Tan kinfo->rss_size = kinfo->req_rss_size; 533672ad0edSHuazhong Tan } else if (kinfo->rss_size > max_rss_size || 534672ad0edSHuazhong Tan (!kinfo->req_rss_size && kinfo->rss_size < max_rss_size)) { 535672ad0edSHuazhong Tan dev_info(&hdev->pdev->dev, "rss changes from %d to %d\n", 536672ad0edSHuazhong Tan kinfo->rss_size, max_rss_size); 537672ad0edSHuazhong Tan kinfo->rss_size = max_rss_size; 538672ad0edSHuazhong Tan } 539672ad0edSHuazhong Tan 540672ad0edSHuazhong Tan kinfo->num_tqps = kinfo->num_tc * kinfo->rss_size; 54184844054SSalil vport->qs_offset = hdev->tm_info.num_tc * vport->vport_id; 54284844054SSalil vport->dwrr = 100; /* 100 percent as init */ 54368ece54eSYunsheng Lin vport->alloc_rss_size = kinfo->rss_size; 54484844054SSalil 545af958827SHuazhong Tan for (i = 0; i < HNAE3_MAX_TC; i++) { 54684844054SSalil if (hdev->hw_tc_map & BIT(i)) { 54784844054SSalil kinfo->tc_info[i].enable = true; 54884844054SSalil kinfo->tc_info[i].tqp_offset = i * kinfo->rss_size; 54984844054SSalil kinfo->tc_info[i].tqp_count = kinfo->rss_size; 55084844054SSalil kinfo->tc_info[i].tc = i; 55184844054SSalil } else { 55284844054SSalil /* Set to default queue if TC is disable */ 55384844054SSalil kinfo->tc_info[i].enable = false; 55484844054SSalil kinfo->tc_info[i].tqp_offset = 0; 55584844054SSalil kinfo->tc_info[i].tqp_count = 1; 55684844054SSalil kinfo->tc_info[i].tc = 0; 55784844054SSalil } 55884844054SSalil } 559c5795c53SYunsheng Lin 560c5795c53SYunsheng Lin memcpy(kinfo->prio_tc, hdev->tm_info.prio_tc, 561c5795c53SYunsheng Lin FIELD_SIZEOF(struct hnae3_knic_private_info, prio_tc)); 56284844054SSalil } 56384844054SSalil 56484844054SSalil static void hclge_tm_vport_info_update(struct hclge_dev *hdev) 56584844054SSalil { 56684844054SSalil struct hclge_vport *vport = hdev->vport; 56784844054SSalil u32 i; 56884844054SSalil 56984844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 57084844054SSalil hclge_tm_vport_tc_info_update(vport); 57184844054SSalil 57284844054SSalil vport++; 57384844054SSalil } 57484844054SSalil } 57584844054SSalil 57684844054SSalil static void hclge_tm_tc_info_init(struct hclge_dev *hdev) 57784844054SSalil { 57884844054SSalil u8 i; 57984844054SSalil 58084844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 58184844054SSalil hdev->tm_info.tc_info[i].tc_id = i; 58284844054SSalil hdev->tm_info.tc_info[i].tc_sch_mode = HCLGE_SCH_MODE_DWRR; 58384844054SSalil hdev->tm_info.tc_info[i].pgid = 0; 58484844054SSalil hdev->tm_info.tc_info[i].bw_limit = 58584844054SSalil hdev->tm_info.pg_info[0].bw_limit; 58684844054SSalil } 58784844054SSalil 588c5795c53SYunsheng Lin for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) 589c5795c53SYunsheng Lin hdev->tm_info.prio_tc[i] = 590c5795c53SYunsheng Lin (i >= hdev->tm_info.num_tc) ? 0 : i; 591c5795c53SYunsheng Lin 5927979a223SYunsheng Lin /* DCB is enabled if we have more than 1 TC */ 5937979a223SYunsheng Lin if (hdev->tm_info.num_tc > 1) 5947979a223SYunsheng Lin hdev->flag |= HCLGE_FLAG_DCB_ENABLE; 5957979a223SYunsheng Lin else 59684844054SSalil hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE; 59784844054SSalil } 59884844054SSalil 59984844054SSalil static void hclge_tm_pg_info_init(struct hclge_dev *hdev) 60084844054SSalil { 60184844054SSalil u8 i; 60284844054SSalil 60384844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 60484844054SSalil int k; 60584844054SSalil 60684844054SSalil hdev->tm_info.pg_dwrr[i] = i ? 0 : 100; 60784844054SSalil 60884844054SSalil hdev->tm_info.pg_info[i].pg_id = i; 60984844054SSalil hdev->tm_info.pg_info[i].pg_sch_mode = HCLGE_SCH_MODE_DWRR; 61084844054SSalil 61184844054SSalil hdev->tm_info.pg_info[i].bw_limit = HCLGE_ETHER_MAX_RATE; 61284844054SSalil 61384844054SSalil if (i != 0) 61484844054SSalil continue; 61584844054SSalil 61684844054SSalil hdev->tm_info.pg_info[i].tc_bit_map = hdev->hw_tc_map; 61784844054SSalil for (k = 0; k < hdev->tm_info.num_tc; k++) 61884844054SSalil hdev->tm_info.pg_info[i].tc_dwrr[k] = 100; 61984844054SSalil } 62084844054SSalil } 62184844054SSalil 6227979a223SYunsheng Lin static void hclge_pfc_info_init(struct hclge_dev *hdev) 6237979a223SYunsheng Lin { 6247979a223SYunsheng Lin if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) { 6257979a223SYunsheng Lin if (hdev->fc_mode_last_time == HCLGE_FC_PFC) 6267979a223SYunsheng Lin dev_warn(&hdev->pdev->dev, 6277979a223SYunsheng Lin "DCB is disable, but last mode is FC_PFC\n"); 6287979a223SYunsheng Lin 6297979a223SYunsheng Lin hdev->tm_info.fc_mode = hdev->fc_mode_last_time; 6307979a223SYunsheng Lin } else if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) { 6317979a223SYunsheng Lin /* fc_mode_last_time record the last fc_mode when 6327979a223SYunsheng Lin * DCB is enabled, so that fc_mode can be set to 6337979a223SYunsheng Lin * the correct value when DCB is disabled. 6347979a223SYunsheng Lin */ 6357979a223SYunsheng Lin hdev->fc_mode_last_time = hdev->tm_info.fc_mode; 6367979a223SYunsheng Lin hdev->tm_info.fc_mode = HCLGE_FC_PFC; 6377979a223SYunsheng Lin } 6387979a223SYunsheng Lin } 6397979a223SYunsheng Lin 64084844054SSalil static int hclge_tm_schd_info_init(struct hclge_dev *hdev) 64184844054SSalil { 64284844054SSalil if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) && 64384844054SSalil (hdev->tm_info.num_pg != 1)) 64484844054SSalil return -EINVAL; 64584844054SSalil 64684844054SSalil hclge_tm_pg_info_init(hdev); 64784844054SSalil 64884844054SSalil hclge_tm_tc_info_init(hdev); 64984844054SSalil 65084844054SSalil hclge_tm_vport_info_update(hdev); 65184844054SSalil 6527979a223SYunsheng Lin hclge_pfc_info_init(hdev); 65384844054SSalil 65484844054SSalil return 0; 65584844054SSalil } 65684844054SSalil 65784844054SSalil static int hclge_tm_pg_to_pri_map(struct hclge_dev *hdev) 65884844054SSalil { 65984844054SSalil int ret; 66084844054SSalil u32 i; 66184844054SSalil 66284844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 66384844054SSalil return 0; 66484844054SSalil 66584844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 66684844054SSalil /* Cfg mapping */ 66784844054SSalil ret = hclge_tm_pg_to_pri_map_cfg( 66884844054SSalil hdev, i, hdev->tm_info.pg_info[i].tc_bit_map); 66984844054SSalil if (ret) 67084844054SSalil return ret; 67184844054SSalil } 67284844054SSalil 67384844054SSalil return 0; 67484844054SSalil } 67584844054SSalil 67684844054SSalil static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev) 67784844054SSalil { 67884844054SSalil u8 ir_u, ir_b, ir_s; 67984844054SSalil int ret; 68084844054SSalil u32 i; 68184844054SSalil 68284844054SSalil /* Cfg pg schd */ 68384844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 68484844054SSalil return 0; 68584844054SSalil 68684844054SSalil /* Pg to pri */ 68784844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 68884844054SSalil /* Calc shaper para */ 68984844054SSalil ret = hclge_shaper_para_calc( 69084844054SSalil hdev->tm_info.pg_info[i].bw_limit, 69184844054SSalil HCLGE_SHAPER_LVL_PG, 69284844054SSalil &ir_b, &ir_u, &ir_s); 69384844054SSalil if (ret) 69484844054SSalil return ret; 69584844054SSalil 69684844054SSalil ret = hclge_tm_pg_shapping_cfg(hdev, 69784844054SSalil HCLGE_TM_SHAP_C_BUCKET, i, 69884844054SSalil 0, 0, 0, HCLGE_SHAPER_BS_U_DEF, 69984844054SSalil HCLGE_SHAPER_BS_S_DEF); 70084844054SSalil if (ret) 70184844054SSalil return ret; 70284844054SSalil 70384844054SSalil ret = hclge_tm_pg_shapping_cfg(hdev, 70484844054SSalil HCLGE_TM_SHAP_P_BUCKET, i, 70584844054SSalil ir_b, ir_u, ir_s, 70684844054SSalil HCLGE_SHAPER_BS_U_DEF, 70784844054SSalil HCLGE_SHAPER_BS_S_DEF); 70884844054SSalil if (ret) 70984844054SSalil return ret; 71084844054SSalil } 71184844054SSalil 71284844054SSalil return 0; 71384844054SSalil } 71484844054SSalil 71584844054SSalil static int hclge_tm_pg_dwrr_cfg(struct hclge_dev *hdev) 71684844054SSalil { 71784844054SSalil int ret; 71884844054SSalil u32 i; 71984844054SSalil 72084844054SSalil /* cfg pg schd */ 72184844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 72284844054SSalil return 0; 72384844054SSalil 72484844054SSalil /* pg to prio */ 72584844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 72684844054SSalil /* Cfg dwrr */ 72784844054SSalil ret = hclge_tm_pg_weight_cfg(hdev, i, 72884844054SSalil hdev->tm_info.pg_dwrr[i]); 72984844054SSalil if (ret) 73084844054SSalil return ret; 73184844054SSalil } 73284844054SSalil 73384844054SSalil return 0; 73484844054SSalil } 73584844054SSalil 73684844054SSalil static int hclge_vport_q_to_qs_map(struct hclge_dev *hdev, 73784844054SSalil struct hclge_vport *vport) 73884844054SSalil { 73984844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 74084844054SSalil struct hnae3_queue **tqp = kinfo->tqp; 74184844054SSalil struct hnae3_tc_info *v_tc_info; 74284844054SSalil u32 i, j; 74384844054SSalil int ret; 74484844054SSalil 74584844054SSalil for (i = 0; i < kinfo->num_tc; i++) { 74684844054SSalil v_tc_info = &kinfo->tc_info[i]; 74784844054SSalil for (j = 0; j < v_tc_info->tqp_count; j++) { 74884844054SSalil struct hnae3_queue *q = tqp[v_tc_info->tqp_offset + j]; 74984844054SSalil 75084844054SSalil ret = hclge_tm_q_to_qs_map_cfg(hdev, 75184844054SSalil hclge_get_queue_id(q), 75284844054SSalil vport->qs_offset + i); 75384844054SSalil if (ret) 75484844054SSalil return ret; 75584844054SSalil } 75684844054SSalil } 75784844054SSalil 75884844054SSalil return 0; 75984844054SSalil } 76084844054SSalil 76184844054SSalil static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev) 76284844054SSalil { 76384844054SSalil struct hclge_vport *vport = hdev->vport; 76484844054SSalil int ret; 765cc9bb43aSYunsheng Lin u32 i, k; 76684844054SSalil 76784844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 76884844054SSalil /* Cfg qs -> pri mapping, one by one mapping */ 769cc9bb43aSYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) 77084844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 771cc9bb43aSYunsheng Lin ret = hclge_tm_qs_to_pri_map_cfg( 772cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, i); 77384844054SSalil if (ret) 77484844054SSalil return ret; 77584844054SSalil } 77684844054SSalil } else if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) { 77784844054SSalil /* Cfg qs -> pri mapping, qs = tc, pri = vf, 8 qs -> 1 pri */ 77884844054SSalil for (k = 0; k < hdev->num_alloc_vport; k++) 77984844054SSalil for (i = 0; i < HNAE3_MAX_TC; i++) { 78084844054SSalil ret = hclge_tm_qs_to_pri_map_cfg( 78184844054SSalil hdev, vport[k].qs_offset + i, k); 78284844054SSalil if (ret) 78384844054SSalil return ret; 78484844054SSalil } 78584844054SSalil } else { 78684844054SSalil return -EINVAL; 78784844054SSalil } 78884844054SSalil 78984844054SSalil /* Cfg q -> qs mapping */ 79084844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 79184844054SSalil ret = hclge_vport_q_to_qs_map(hdev, vport); 79284844054SSalil if (ret) 79384844054SSalil return ret; 79484844054SSalil 79584844054SSalil vport++; 79684844054SSalil } 79784844054SSalil 79884844054SSalil return 0; 79984844054SSalil } 80084844054SSalil 80184844054SSalil static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev) 80284844054SSalil { 80384844054SSalil u8 ir_u, ir_b, ir_s; 80484844054SSalil int ret; 80584844054SSalil u32 i; 80684844054SSalil 80784844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 80884844054SSalil ret = hclge_shaper_para_calc( 80984844054SSalil hdev->tm_info.tc_info[i].bw_limit, 81084844054SSalil HCLGE_SHAPER_LVL_PRI, 81184844054SSalil &ir_b, &ir_u, &ir_s); 81284844054SSalil if (ret) 81384844054SSalil return ret; 81484844054SSalil 81584844054SSalil ret = hclge_tm_pri_shapping_cfg( 81684844054SSalil hdev, HCLGE_TM_SHAP_C_BUCKET, i, 81784844054SSalil 0, 0, 0, HCLGE_SHAPER_BS_U_DEF, 81884844054SSalil HCLGE_SHAPER_BS_S_DEF); 81984844054SSalil if (ret) 82084844054SSalil return ret; 82184844054SSalil 82284844054SSalil ret = hclge_tm_pri_shapping_cfg( 82384844054SSalil hdev, HCLGE_TM_SHAP_P_BUCKET, i, 82484844054SSalil ir_b, ir_u, ir_s, HCLGE_SHAPER_BS_U_DEF, 82584844054SSalil HCLGE_SHAPER_BS_S_DEF); 82684844054SSalil if (ret) 82784844054SSalil return ret; 82884844054SSalil } 82984844054SSalil 83084844054SSalil return 0; 83184844054SSalil } 83284844054SSalil 83384844054SSalil static int hclge_tm_pri_vnet_base_shaper_pri_cfg(struct hclge_vport *vport) 83484844054SSalil { 83584844054SSalil struct hclge_dev *hdev = vport->back; 83684844054SSalil u8 ir_u, ir_b, ir_s; 83784844054SSalil int ret; 83884844054SSalil 83984844054SSalil ret = hclge_shaper_para_calc(vport->bw_limit, HCLGE_SHAPER_LVL_VF, 84084844054SSalil &ir_b, &ir_u, &ir_s); 84184844054SSalil if (ret) 84284844054SSalil return ret; 84384844054SSalil 84484844054SSalil ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, 84584844054SSalil vport->vport_id, 84684844054SSalil 0, 0, 0, HCLGE_SHAPER_BS_U_DEF, 84784844054SSalil HCLGE_SHAPER_BS_S_DEF); 84884844054SSalil if (ret) 84984844054SSalil return ret; 85084844054SSalil 85184844054SSalil ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, 85284844054SSalil vport->vport_id, 85384844054SSalil ir_b, ir_u, ir_s, 85484844054SSalil HCLGE_SHAPER_BS_U_DEF, 85584844054SSalil HCLGE_SHAPER_BS_S_DEF); 85684844054SSalil if (ret) 85784844054SSalil return ret; 85884844054SSalil 85984844054SSalil return 0; 86084844054SSalil } 86184844054SSalil 86284844054SSalil static int hclge_tm_pri_vnet_base_shaper_qs_cfg(struct hclge_vport *vport) 86384844054SSalil { 86484844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 86584844054SSalil struct hclge_dev *hdev = vport->back; 86684844054SSalil u8 ir_u, ir_b, ir_s; 86784844054SSalil u32 i; 86884844054SSalil int ret; 86984844054SSalil 87084844054SSalil for (i = 0; i < kinfo->num_tc; i++) { 87184844054SSalil ret = hclge_shaper_para_calc( 87284844054SSalil hdev->tm_info.tc_info[i].bw_limit, 87384844054SSalil HCLGE_SHAPER_LVL_QSET, 87484844054SSalil &ir_b, &ir_u, &ir_s); 87584844054SSalil if (ret) 87684844054SSalil return ret; 87784844054SSalil } 87884844054SSalil 87984844054SSalil return 0; 88084844054SSalil } 88184844054SSalil 88284844054SSalil static int hclge_tm_pri_vnet_base_shaper_cfg(struct hclge_dev *hdev) 88384844054SSalil { 88484844054SSalil struct hclge_vport *vport = hdev->vport; 88584844054SSalil int ret; 88684844054SSalil u32 i; 88784844054SSalil 88884844054SSalil /* Need config vport shaper */ 88984844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 89084844054SSalil ret = hclge_tm_pri_vnet_base_shaper_pri_cfg(vport); 89184844054SSalil if (ret) 89284844054SSalil return ret; 89384844054SSalil 89484844054SSalil ret = hclge_tm_pri_vnet_base_shaper_qs_cfg(vport); 89584844054SSalil if (ret) 89684844054SSalil return ret; 89784844054SSalil 89884844054SSalil vport++; 89984844054SSalil } 90084844054SSalil 90184844054SSalil return 0; 90284844054SSalil } 90384844054SSalil 90484844054SSalil static int hclge_tm_pri_shaper_cfg(struct hclge_dev *hdev) 90584844054SSalil { 90684844054SSalil int ret; 90784844054SSalil 90884844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 90984844054SSalil ret = hclge_tm_pri_tc_base_shaper_cfg(hdev); 91084844054SSalil if (ret) 91184844054SSalil return ret; 91284844054SSalil } else { 91384844054SSalil ret = hclge_tm_pri_vnet_base_shaper_cfg(hdev); 91484844054SSalil if (ret) 91584844054SSalil return ret; 91684844054SSalil } 91784844054SSalil 91884844054SSalil return 0; 91984844054SSalil } 92084844054SSalil 92184844054SSalil static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev) 92284844054SSalil { 923cc9bb43aSYunsheng Lin struct hclge_vport *vport = hdev->vport; 92484844054SSalil struct hclge_pg_info *pg_info; 92584844054SSalil u8 dwrr; 92684844054SSalil int ret; 927cc9bb43aSYunsheng Lin u32 i, k; 92884844054SSalil 92984844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 93084844054SSalil pg_info = 93184844054SSalil &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; 93284844054SSalil dwrr = pg_info->tc_dwrr[i]; 93384844054SSalil 93484844054SSalil ret = hclge_tm_pri_weight_cfg(hdev, i, dwrr); 93584844054SSalil if (ret) 93684844054SSalil return ret; 93784844054SSalil 938cc9bb43aSYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 939cc9bb43aSYunsheng Lin ret = hclge_tm_qs_weight_cfg( 940cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, 941cc9bb43aSYunsheng Lin vport[k].dwrr); 94284844054SSalil if (ret) 94384844054SSalil return ret; 94484844054SSalil } 945cc9bb43aSYunsheng Lin } 94684844054SSalil 94784844054SSalil return 0; 94884844054SSalil } 94984844054SSalil 950330baff5SYunsheng Lin static int hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev *hdev) 951330baff5SYunsheng Lin { 952330baff5SYunsheng Lin #define DEFAULT_TC_WEIGHT 1 953330baff5SYunsheng Lin #define DEFAULT_TC_OFFSET 14 954330baff5SYunsheng Lin 955330baff5SYunsheng Lin struct hclge_ets_tc_weight_cmd *ets_weight; 956330baff5SYunsheng Lin struct hclge_desc desc; 957330baff5SYunsheng Lin int i; 958330baff5SYunsheng Lin 959330baff5SYunsheng Lin hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_ETS_TC_WEIGHT, false); 960330baff5SYunsheng Lin ets_weight = (struct hclge_ets_tc_weight_cmd *)desc.data; 961330baff5SYunsheng Lin 962330baff5SYunsheng Lin for (i = 0; i < HNAE3_MAX_TC; i++) { 963330baff5SYunsheng Lin struct hclge_pg_info *pg_info; 964330baff5SYunsheng Lin 965330baff5SYunsheng Lin ets_weight->tc_weight[i] = DEFAULT_TC_WEIGHT; 966330baff5SYunsheng Lin 967330baff5SYunsheng Lin if (!(hdev->hw_tc_map & BIT(i))) 968330baff5SYunsheng Lin continue; 969330baff5SYunsheng Lin 970330baff5SYunsheng Lin pg_info = 971330baff5SYunsheng Lin &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; 972330baff5SYunsheng Lin ets_weight->tc_weight[i] = pg_info->tc_dwrr[i]; 973330baff5SYunsheng Lin } 974330baff5SYunsheng Lin 975330baff5SYunsheng Lin ets_weight->weight_offset = DEFAULT_TC_OFFSET; 976330baff5SYunsheng Lin 977330baff5SYunsheng Lin return hclge_cmd_send(&hdev->hw, &desc, 1); 978330baff5SYunsheng Lin } 979330baff5SYunsheng Lin 98084844054SSalil static int hclge_tm_pri_vnet_base_dwrr_pri_cfg(struct hclge_vport *vport) 98184844054SSalil { 98284844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 98384844054SSalil struct hclge_dev *hdev = vport->back; 98484844054SSalil int ret; 98584844054SSalil u8 i; 98684844054SSalil 98784844054SSalil /* Vf dwrr */ 98884844054SSalil ret = hclge_tm_pri_weight_cfg(hdev, vport->vport_id, vport->dwrr); 98984844054SSalil if (ret) 99084844054SSalil return ret; 99184844054SSalil 99284844054SSalil /* Qset dwrr */ 99384844054SSalil for (i = 0; i < kinfo->num_tc; i++) { 99484844054SSalil ret = hclge_tm_qs_weight_cfg( 99584844054SSalil hdev, vport->qs_offset + i, 99684844054SSalil hdev->tm_info.pg_info[0].tc_dwrr[i]); 99784844054SSalil if (ret) 99884844054SSalil return ret; 99984844054SSalil } 100084844054SSalil 100184844054SSalil return 0; 100284844054SSalil } 100384844054SSalil 100484844054SSalil static int hclge_tm_pri_vnet_base_dwrr_cfg(struct hclge_dev *hdev) 100584844054SSalil { 100684844054SSalil struct hclge_vport *vport = hdev->vport; 100784844054SSalil int ret; 100884844054SSalil u32 i; 100984844054SSalil 101084844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 101184844054SSalil ret = hclge_tm_pri_vnet_base_dwrr_pri_cfg(vport); 101284844054SSalil if (ret) 101384844054SSalil return ret; 101484844054SSalil 101584844054SSalil vport++; 101684844054SSalil } 101784844054SSalil 101884844054SSalil return 0; 101984844054SSalil } 102084844054SSalil 102184844054SSalil static int hclge_tm_pri_dwrr_cfg(struct hclge_dev *hdev) 102284844054SSalil { 102384844054SSalil int ret; 102484844054SSalil 102584844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 102684844054SSalil ret = hclge_tm_pri_tc_base_dwrr_cfg(hdev); 102784844054SSalil if (ret) 102884844054SSalil return ret; 1029330baff5SYunsheng Lin 1030330baff5SYunsheng Lin if (!hnae3_dev_dcb_supported(hdev)) 1031330baff5SYunsheng Lin return 0; 1032330baff5SYunsheng Lin 1033330baff5SYunsheng Lin ret = hclge_tm_ets_tc_dwrr_cfg(hdev); 1034330baff5SYunsheng Lin if (ret == -EOPNOTSUPP) { 1035330baff5SYunsheng Lin dev_warn(&hdev->pdev->dev, 1036330baff5SYunsheng Lin "fw %08x does't support ets tc weight cmd\n", 1037330baff5SYunsheng Lin hdev->fw_version); 1038330baff5SYunsheng Lin ret = 0; 1039330baff5SYunsheng Lin } 1040330baff5SYunsheng Lin 1041330baff5SYunsheng Lin return ret; 104284844054SSalil } else { 104384844054SSalil ret = hclge_tm_pri_vnet_base_dwrr_cfg(hdev); 104484844054SSalil if (ret) 104584844054SSalil return ret; 104684844054SSalil } 104784844054SSalil 104884844054SSalil return 0; 104984844054SSalil } 105084844054SSalil 10519e5157baSYunsheng Lin static int hclge_tm_map_cfg(struct hclge_dev *hdev) 105284844054SSalil { 105384844054SSalil int ret; 105484844054SSalil 105577f255c1SYunsheng Lin ret = hclge_up_to_tc_map(hdev); 105677f255c1SYunsheng Lin if (ret) 105777f255c1SYunsheng Lin return ret; 105877f255c1SYunsheng Lin 105984844054SSalil ret = hclge_tm_pg_to_pri_map(hdev); 106084844054SSalil if (ret) 106184844054SSalil return ret; 106284844054SSalil 106384844054SSalil return hclge_tm_pri_q_qs_cfg(hdev); 106484844054SSalil } 106584844054SSalil 106684844054SSalil static int hclge_tm_shaper_cfg(struct hclge_dev *hdev) 106784844054SSalil { 106884844054SSalil int ret; 106984844054SSalil 10700a5677d3SYunsheng Lin ret = hclge_tm_port_shaper_cfg(hdev); 10710a5677d3SYunsheng Lin if (ret) 10720a5677d3SYunsheng Lin return ret; 10730a5677d3SYunsheng Lin 107484844054SSalil ret = hclge_tm_pg_shaper_cfg(hdev); 107584844054SSalil if (ret) 107684844054SSalil return ret; 107784844054SSalil 107884844054SSalil return hclge_tm_pri_shaper_cfg(hdev); 107984844054SSalil } 108084844054SSalil 108184844054SSalil int hclge_tm_dwrr_cfg(struct hclge_dev *hdev) 108284844054SSalil { 108384844054SSalil int ret; 108484844054SSalil 108584844054SSalil ret = hclge_tm_pg_dwrr_cfg(hdev); 108684844054SSalil if (ret) 108784844054SSalil return ret; 108884844054SSalil 108984844054SSalil return hclge_tm_pri_dwrr_cfg(hdev); 109084844054SSalil } 109184844054SSalil 109284844054SSalil static int hclge_tm_lvl2_schd_mode_cfg(struct hclge_dev *hdev) 109384844054SSalil { 109484844054SSalil int ret; 109584844054SSalil u8 i; 109684844054SSalil 109784844054SSalil /* Only being config on TC-Based scheduler mode */ 109884844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) 109984844054SSalil return 0; 110084844054SSalil 110184844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 110284844054SSalil ret = hclge_tm_pg_schd_mode_cfg(hdev, i); 110384844054SSalil if (ret) 110484844054SSalil return ret; 110584844054SSalil } 110684844054SSalil 110784844054SSalil return 0; 110884844054SSalil } 110984844054SSalil 111084844054SSalil static int hclge_tm_schd_mode_vnet_base_cfg(struct hclge_vport *vport) 111184844054SSalil { 111284844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 111384844054SSalil struct hclge_dev *hdev = vport->back; 111484844054SSalil int ret; 111584844054SSalil u8 i; 111684844054SSalil 111784844054SSalil ret = hclge_tm_pri_schd_mode_cfg(hdev, vport->vport_id); 111884844054SSalil if (ret) 111984844054SSalil return ret; 112084844054SSalil 112184844054SSalil for (i = 0; i < kinfo->num_tc; i++) { 1122cc9bb43aSYunsheng Lin u8 sch_mode = hdev->tm_info.tc_info[i].tc_sch_mode; 1123cc9bb43aSYunsheng Lin 1124cc9bb43aSYunsheng Lin ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i, 1125cc9bb43aSYunsheng Lin sch_mode); 112684844054SSalil if (ret) 112784844054SSalil return ret; 112884844054SSalil } 112984844054SSalil 113084844054SSalil return 0; 113184844054SSalil } 113284844054SSalil 113384844054SSalil static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev *hdev) 113484844054SSalil { 113584844054SSalil struct hclge_vport *vport = hdev->vport; 113684844054SSalil int ret; 1137cc9bb43aSYunsheng Lin u8 i, k; 113884844054SSalil 113984844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 114084844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 114184844054SSalil ret = hclge_tm_pri_schd_mode_cfg(hdev, i); 114284844054SSalil if (ret) 114384844054SSalil return ret; 114484844054SSalil 1145cc9bb43aSYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 1146cc9bb43aSYunsheng Lin ret = hclge_tm_qs_schd_mode_cfg( 1147cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, 1148cc9bb43aSYunsheng Lin HCLGE_SCH_MODE_DWRR); 114984844054SSalil if (ret) 115084844054SSalil return ret; 115184844054SSalil } 1152cc9bb43aSYunsheng Lin } 115384844054SSalil } else { 115484844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 115584844054SSalil ret = hclge_tm_schd_mode_vnet_base_cfg(vport); 115684844054SSalil if (ret) 115784844054SSalil return ret; 115884844054SSalil 115984844054SSalil vport++; 116084844054SSalil } 116184844054SSalil } 116284844054SSalil 116384844054SSalil return 0; 116484844054SSalil } 116584844054SSalil 11669e5157baSYunsheng Lin static int hclge_tm_schd_mode_hw(struct hclge_dev *hdev) 116784844054SSalil { 116884844054SSalil int ret; 116984844054SSalil 117084844054SSalil ret = hclge_tm_lvl2_schd_mode_cfg(hdev); 117184844054SSalil if (ret) 117284844054SSalil return ret; 117384844054SSalil 117484844054SSalil return hclge_tm_lvl34_schd_mode_cfg(hdev); 117584844054SSalil } 117684844054SSalil 11779e5157baSYunsheng Lin int hclge_tm_schd_setup_hw(struct hclge_dev *hdev) 117884844054SSalil { 117984844054SSalil int ret; 118084844054SSalil 118184844054SSalil /* Cfg tm mapping */ 118284844054SSalil ret = hclge_tm_map_cfg(hdev); 118384844054SSalil if (ret) 118484844054SSalil return ret; 118584844054SSalil 118684844054SSalil /* Cfg tm shaper */ 118784844054SSalil ret = hclge_tm_shaper_cfg(hdev); 118884844054SSalil if (ret) 118984844054SSalil return ret; 119084844054SSalil 119184844054SSalil /* Cfg dwrr */ 119284844054SSalil ret = hclge_tm_dwrr_cfg(hdev); 119384844054SSalil if (ret) 119484844054SSalil return ret; 119584844054SSalil 119684844054SSalil /* Cfg schd mode for each level schd */ 119784844054SSalil return hclge_tm_schd_mode_hw(hdev); 119884844054SSalil } 119984844054SSalil 1200e98d7183SFuyun Liang static int hclge_pause_param_setup_hw(struct hclge_dev *hdev) 120118838d0cSFuyun Liang { 120218838d0cSFuyun Liang struct hclge_mac *mac = &hdev->hw.mac; 120318838d0cSFuyun Liang 1204e98d7183SFuyun Liang return hclge_pause_param_cfg(hdev, mac->mac_addr, 120518838d0cSFuyun Liang HCLGE_DEFAULT_PAUSE_TRANS_GAP, 120618838d0cSFuyun Liang HCLGE_DEFAULT_PAUSE_TRANS_TIME); 120718838d0cSFuyun Liang } 120818838d0cSFuyun Liang 12099dc2145dSYunsheng Lin static int hclge_pfc_setup_hw(struct hclge_dev *hdev) 12109dc2145dSYunsheng Lin { 12119dc2145dSYunsheng Lin u8 enable_bitmap = 0; 12129dc2145dSYunsheng Lin 12139dc2145dSYunsheng Lin if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) 12149dc2145dSYunsheng Lin enable_bitmap = HCLGE_TX_MAC_PAUSE_EN_MSK | 12159dc2145dSYunsheng Lin HCLGE_RX_MAC_PAUSE_EN_MSK; 12169dc2145dSYunsheng Lin 12179dc2145dSYunsheng Lin return hclge_pfc_pause_en_cfg(hdev, enable_bitmap, 12189dc2145dSYunsheng Lin hdev->tm_info.hw_pfc_map); 12199dc2145dSYunsheng Lin } 12209dc2145dSYunsheng Lin 122167bf2541SYunsheng Lin /* Each Tc has a 1024 queue sets to backpress, it divides to 122267bf2541SYunsheng Lin * 32 group, each group contains 32 queue sets, which can be 122367bf2541SYunsheng Lin * represented by u32 bitmap. 122467bf2541SYunsheng Lin */ 122567bf2541SYunsheng Lin static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc) 122667bf2541SYunsheng Lin { 1227e8ccbb7dSYunsheng Lin int i; 122867bf2541SYunsheng Lin 122967bf2541SYunsheng Lin for (i = 0; i < HCLGE_BP_GRP_NUM; i++) { 1230e8ccbb7dSYunsheng Lin u32 qs_bitmap = 0; 1231e8ccbb7dSYunsheng Lin int k, ret; 123267bf2541SYunsheng Lin 123367bf2541SYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 1234e8ccbb7dSYunsheng Lin struct hclge_vport *vport = &hdev->vport[k]; 123567bf2541SYunsheng Lin u16 qs_id = vport->qs_offset + tc; 123667bf2541SYunsheng Lin u8 grp, sub_grp; 123767bf2541SYunsheng Lin 1238e4e87715SPeng Li grp = hnae3_get_field(qs_id, HCLGE_BP_GRP_ID_M, 123967bf2541SYunsheng Lin HCLGE_BP_GRP_ID_S); 1240e4e87715SPeng Li sub_grp = hnae3_get_field(qs_id, HCLGE_BP_SUB_GRP_ID_M, 124167bf2541SYunsheng Lin HCLGE_BP_SUB_GRP_ID_S); 124267bf2541SYunsheng Lin if (i == grp) 124367bf2541SYunsheng Lin qs_bitmap |= (1 << sub_grp); 124467bf2541SYunsheng Lin } 124567bf2541SYunsheng Lin 124667bf2541SYunsheng Lin ret = hclge_tm_qs_bp_cfg(hdev, tc, i, qs_bitmap); 124767bf2541SYunsheng Lin if (ret) 124867bf2541SYunsheng Lin return ret; 124967bf2541SYunsheng Lin } 125067bf2541SYunsheng Lin 125167bf2541SYunsheng Lin return 0; 125267bf2541SYunsheng Lin } 125367bf2541SYunsheng Lin 12549dc2145dSYunsheng Lin static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) 12559dc2145dSYunsheng Lin { 12569dc2145dSYunsheng Lin bool tx_en, rx_en; 12579dc2145dSYunsheng Lin 12589dc2145dSYunsheng Lin switch (hdev->tm_info.fc_mode) { 12599dc2145dSYunsheng Lin case HCLGE_FC_NONE: 12609dc2145dSYunsheng Lin tx_en = false; 12619dc2145dSYunsheng Lin rx_en = false; 12629dc2145dSYunsheng Lin break; 12639dc2145dSYunsheng Lin case HCLGE_FC_RX_PAUSE: 12649dc2145dSYunsheng Lin tx_en = false; 12659dc2145dSYunsheng Lin rx_en = true; 12669dc2145dSYunsheng Lin break; 12679dc2145dSYunsheng Lin case HCLGE_FC_TX_PAUSE: 12689dc2145dSYunsheng Lin tx_en = true; 12699dc2145dSYunsheng Lin rx_en = false; 12709dc2145dSYunsheng Lin break; 12719dc2145dSYunsheng Lin case HCLGE_FC_FULL: 12729dc2145dSYunsheng Lin tx_en = true; 12739dc2145dSYunsheng Lin rx_en = true; 12749dc2145dSYunsheng Lin break; 12756d0ec65cSYunsheng Lin case HCLGE_FC_PFC: 12766d0ec65cSYunsheng Lin tx_en = false; 12776d0ec65cSYunsheng Lin rx_en = false; 12786d0ec65cSYunsheng Lin break; 12799dc2145dSYunsheng Lin default: 12809dc2145dSYunsheng Lin tx_en = true; 12819dc2145dSYunsheng Lin rx_en = true; 12829dc2145dSYunsheng Lin } 12839dc2145dSYunsheng Lin 12849dc2145dSYunsheng Lin return hclge_mac_pause_en_cfg(hdev, tx_en, rx_en); 12859dc2145dSYunsheng Lin } 12869dc2145dSYunsheng Lin 128773fc9c48SHuazhong Tan static int hclge_tm_bp_setup(struct hclge_dev *hdev) 128873fc9c48SHuazhong Tan { 128973fc9c48SHuazhong Tan int ret = 0; 129073fc9c48SHuazhong Tan int i; 129173fc9c48SHuazhong Tan 129273fc9c48SHuazhong Tan for (i = 0; i < hdev->tm_info.num_tc; i++) { 129373fc9c48SHuazhong Tan ret = hclge_bp_setup_hw(hdev, i); 129473fc9c48SHuazhong Tan if (ret) 129573fc9c48SHuazhong Tan return ret; 129673fc9c48SHuazhong Tan } 129773fc9c48SHuazhong Tan 129873fc9c48SHuazhong Tan return ret; 129973fc9c48SHuazhong Tan } 130073fc9c48SHuazhong Tan 130144e59e37SYunsheng Lin int hclge_pause_setup_hw(struct hclge_dev *hdev, bool init) 130284844054SSalil { 130384844054SSalil int ret; 130484844054SSalil 1305e98d7183SFuyun Liang ret = hclge_pause_param_setup_hw(hdev); 130618838d0cSFuyun Liang if (ret) 130718838d0cSFuyun Liang return ret; 130818838d0cSFuyun Liang 13096d0ec65cSYunsheng Lin ret = hclge_mac_pause_setup_hw(hdev); 13106d0ec65cSYunsheng Lin if (ret) 13116d0ec65cSYunsheng Lin return ret; 131284844054SSalil 13139dc2145dSYunsheng Lin /* Only DCB-supported dev supports qset back pressure and pfc cmd */ 13142daf4a65SYunsheng Lin if (!hnae3_dev_dcb_supported(hdev)) 13152daf4a65SYunsheng Lin return 0; 13162daf4a65SYunsheng Lin 131744e59e37SYunsheng Lin /* GE MAC does not support PFC, when driver is initializing and MAC 131844e59e37SYunsheng Lin * is in GE Mode, ignore the error here, otherwise initialization 131944e59e37SYunsheng Lin * will fail. 132044e59e37SYunsheng Lin */ 13219dc2145dSYunsheng Lin ret = hclge_pfc_setup_hw(hdev); 132244e59e37SYunsheng Lin if (init && ret == -EOPNOTSUPP) 132344e59e37SYunsheng Lin dev_warn(&hdev->pdev->dev, "GE MAC does not support pfc\n"); 132444e59e37SYunsheng Lin else 132544e59e37SYunsheng Lin return ret; 13269dc2145dSYunsheng Lin 132773fc9c48SHuazhong Tan return hclge_tm_bp_setup(hdev); 132877f255c1SYunsheng Lin } 132977f255c1SYunsheng Lin 1330e432abfbSYunsheng Lin void hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc) 133177f255c1SYunsheng Lin { 133277f255c1SYunsheng Lin struct hclge_vport *vport = hdev->vport; 133377f255c1SYunsheng Lin struct hnae3_knic_private_info *kinfo; 133477f255c1SYunsheng Lin u32 i, k; 133577f255c1SYunsheng Lin 133677f255c1SYunsheng Lin for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) { 133777f255c1SYunsheng Lin hdev->tm_info.prio_tc[i] = prio_tc[i]; 133877f255c1SYunsheng Lin 133977f255c1SYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 134077f255c1SYunsheng Lin kinfo = &vport[k].nic.kinfo; 134177f255c1SYunsheng Lin kinfo->prio_tc[i] = prio_tc[i]; 134277f255c1SYunsheng Lin } 134377f255c1SYunsheng Lin } 134477f255c1SYunsheng Lin } 134577f255c1SYunsheng Lin 1346e432abfbSYunsheng Lin void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc) 134777f255c1SYunsheng Lin { 134877f255c1SYunsheng Lin u8 i, bit_map = 0; 134977f255c1SYunsheng Lin 135077f255c1SYunsheng Lin hdev->tm_info.num_tc = num_tc; 135177f255c1SYunsheng Lin 135277f255c1SYunsheng Lin for (i = 0; i < hdev->tm_info.num_tc; i++) 135377f255c1SYunsheng Lin bit_map |= BIT(i); 135477f255c1SYunsheng Lin 135577f255c1SYunsheng Lin if (!bit_map) { 135677f255c1SYunsheng Lin bit_map = 1; 135777f255c1SYunsheng Lin hdev->tm_info.num_tc = 1; 135877f255c1SYunsheng Lin } 135977f255c1SYunsheng Lin 136077f255c1SYunsheng Lin hdev->hw_tc_map = bit_map; 136177f255c1SYunsheng Lin 136277f255c1SYunsheng Lin hclge_tm_schd_info_init(hdev); 136384844054SSalil } 136484844054SSalil 136544e59e37SYunsheng Lin int hclge_tm_init_hw(struct hclge_dev *hdev, bool init) 136684844054SSalil { 136784844054SSalil int ret; 136884844054SSalil 136984844054SSalil if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) && 137084844054SSalil (hdev->tx_sch_mode != HCLGE_FLAG_VNET_BASE_SCH_MODE)) 137184844054SSalil return -ENOTSUPP; 137284844054SSalil 137384844054SSalil ret = hclge_tm_schd_setup_hw(hdev); 137484844054SSalil if (ret) 137584844054SSalil return ret; 137684844054SSalil 137744e59e37SYunsheng Lin ret = hclge_pause_setup_hw(hdev, init); 137884844054SSalil if (ret) 137984844054SSalil return ret; 138084844054SSalil 138184844054SSalil return 0; 138284844054SSalil } 138384844054SSalil 138484844054SSalil int hclge_tm_schd_init(struct hclge_dev *hdev) 138584844054SSalil { 13867979a223SYunsheng Lin int ret; 138784844054SSalil 13887979a223SYunsheng Lin /* fc_mode is HCLGE_FC_FULL on reset */ 13897979a223SYunsheng Lin hdev->tm_info.fc_mode = HCLGE_FC_FULL; 13907979a223SYunsheng Lin hdev->fc_mode_last_time = hdev->tm_info.fc_mode; 13917979a223SYunsheng Lin 13927979a223SYunsheng Lin ret = hclge_tm_schd_info_init(hdev); 139384844054SSalil if (ret) 139484844054SSalil return ret; 139584844054SSalil 139644e59e37SYunsheng Lin return hclge_tm_init_hw(hdev, true); 139784844054SSalil } 1398672ad0edSHuazhong Tan 1399672ad0edSHuazhong Tan int hclge_tm_vport_map_update(struct hclge_dev *hdev) 1400672ad0edSHuazhong Tan { 1401672ad0edSHuazhong Tan struct hclge_vport *vport = hdev->vport; 1402672ad0edSHuazhong Tan int ret; 1403672ad0edSHuazhong Tan 1404672ad0edSHuazhong Tan hclge_tm_vport_tc_info_update(vport); 1405672ad0edSHuazhong Tan 1406672ad0edSHuazhong Tan ret = hclge_vport_q_to_qs_map(hdev, vport); 1407672ad0edSHuazhong Tan if (ret) 1408672ad0edSHuazhong Tan return ret; 1409672ad0edSHuazhong Tan 1410672ad0edSHuazhong Tan if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) 1411672ad0edSHuazhong Tan return 0; 1412672ad0edSHuazhong Tan 1413672ad0edSHuazhong Tan return hclge_tm_bp_setup(hdev); 1414672ad0edSHuazhong Tan } 1415