184844054SSalil /* 284844054SSalil * Copyright (c) 2016~2017 Hisilicon Limited. 384844054SSalil * 484844054SSalil * This program is free software; you can redistribute it and/or modify 584844054SSalil * it under the terms of the GNU General Public License as published by 684844054SSalil * the Free Software Foundation; either version 2 of the License, or 784844054SSalil * (at your option) any later version. 884844054SSalil */ 984844054SSalil 1084844054SSalil #include <linux/etherdevice.h> 1184844054SSalil 1284844054SSalil #include "hclge_cmd.h" 1384844054SSalil #include "hclge_main.h" 1484844054SSalil #include "hclge_tm.h" 1584844054SSalil 1684844054SSalil enum hclge_shaper_level { 1784844054SSalil HCLGE_SHAPER_LVL_PRI = 0, 1884844054SSalil HCLGE_SHAPER_LVL_PG = 1, 1984844054SSalil HCLGE_SHAPER_LVL_PORT = 2, 2084844054SSalil HCLGE_SHAPER_LVL_QSET = 3, 2184844054SSalil HCLGE_SHAPER_LVL_CNT = 4, 2284844054SSalil HCLGE_SHAPER_LVL_VF = 0, 2384844054SSalil HCLGE_SHAPER_LVL_PF = 1, 2484844054SSalil }; 2584844054SSalil 2664fd2300SPeng Li #define HCLGE_TM_PFC_PKT_GET_CMD_NUM 3 2764fd2300SPeng Li #define HCLGE_TM_PFC_NUM_GET_PER_CMD 3 2864fd2300SPeng Li 293a7d5958SPeng Li #define HCLGE_SHAPER_BS_U_DEF 5 303a7d5958SPeng Li #define HCLGE_SHAPER_BS_S_DEF 20 3184844054SSalil 3284844054SSalil #define HCLGE_ETHER_MAX_RATE 100000 3384844054SSalil 3484844054SSalil /* hclge_shaper_para_calc: calculate ir parameter for the shaper 3584844054SSalil * @ir: Rate to be config, its unit is Mbps 3684844054SSalil * @shaper_level: the shaper level. eg: port, pg, priority, queueset 3784844054SSalil * @ir_b: IR_B parameter of IR shaper 3884844054SSalil * @ir_u: IR_U parameter of IR shaper 3984844054SSalil * @ir_s: IR_S parameter of IR shaper 4084844054SSalil * 4184844054SSalil * the formula: 4284844054SSalil * 4384844054SSalil * IR_b * (2 ^ IR_u) * 8 4484844054SSalil * IR(Mbps) = ------------------------- * CLOCK(1000Mbps) 4584844054SSalil * Tick * (2 ^ IR_s) 4684844054SSalil * 4784844054SSalil * @return: 0: calculate sucessful, negative: fail 4884844054SSalil */ 4984844054SSalil static int hclge_shaper_para_calc(u32 ir, u8 shaper_level, 5084844054SSalil u8 *ir_b, u8 *ir_u, u8 *ir_s) 5184844054SSalil { 5284844054SSalil const u16 tick_array[HCLGE_SHAPER_LVL_CNT] = { 5384844054SSalil 6 * 256, /* Prioriy level */ 5484844054SSalil 6 * 32, /* Prioriy group level */ 5584844054SSalil 6 * 8, /* Port level */ 5684844054SSalil 6 * 256 /* Qset level */ 5784844054SSalil }; 5884844054SSalil u8 ir_u_calc = 0, ir_s_calc = 0; 5984844054SSalil u32 ir_calc; 6084844054SSalil u32 tick; 6184844054SSalil 6284844054SSalil /* Calc tick */ 6384844054SSalil if (shaper_level >= HCLGE_SHAPER_LVL_CNT) 6484844054SSalil return -EINVAL; 6584844054SSalil 6684844054SSalil tick = tick_array[shaper_level]; 6784844054SSalil 6884844054SSalil /** 6984844054SSalil * Calc the speed if ir_b = 126, ir_u = 0 and ir_s = 0 7084844054SSalil * the formula is changed to: 7184844054SSalil * 126 * 1 * 8 7284844054SSalil * ir_calc = ---------------- * 1000 7384844054SSalil * tick * 1 7484844054SSalil */ 7584844054SSalil ir_calc = (1008000 + (tick >> 1) - 1) / tick; 7684844054SSalil 7784844054SSalil if (ir_calc == ir) { 7884844054SSalil *ir_b = 126; 7984844054SSalil *ir_u = 0; 8084844054SSalil *ir_s = 0; 8184844054SSalil 8284844054SSalil return 0; 8384844054SSalil } else if (ir_calc > ir) { 8484844054SSalil /* Increasing the denominator to select ir_s value */ 8584844054SSalil while (ir_calc > ir) { 8684844054SSalil ir_s_calc++; 8784844054SSalil ir_calc = 1008000 / (tick * (1 << ir_s_calc)); 8884844054SSalil } 8984844054SSalil 9084844054SSalil if (ir_calc == ir) 9184844054SSalil *ir_b = 126; 9284844054SSalil else 9384844054SSalil *ir_b = (ir * tick * (1 << ir_s_calc) + 4000) / 8000; 9484844054SSalil } else { 9584844054SSalil /* Increasing the numerator to select ir_u value */ 9684844054SSalil u32 numerator; 9784844054SSalil 9884844054SSalil while (ir_calc < ir) { 9984844054SSalil ir_u_calc++; 10084844054SSalil numerator = 1008000 * (1 << ir_u_calc); 10184844054SSalil ir_calc = (numerator + (tick >> 1)) / tick; 10284844054SSalil } 10384844054SSalil 10484844054SSalil if (ir_calc == ir) { 10584844054SSalil *ir_b = 126; 10684844054SSalil } else { 10784844054SSalil u32 denominator = (8000 * (1 << --ir_u_calc)); 10884844054SSalil *ir_b = (ir * tick + (denominator >> 1)) / denominator; 10984844054SSalil } 11084844054SSalil } 11184844054SSalil 11284844054SSalil *ir_u = ir_u_calc; 11384844054SSalil *ir_s = ir_s_calc; 11484844054SSalil 11584844054SSalil return 0; 11684844054SSalil } 11784844054SSalil 11864fd2300SPeng Li static int hclge_pfc_stats_get(struct hclge_dev *hdev, 11964fd2300SPeng Li enum hclge_opcode_type opcode, u64 *stats) 12064fd2300SPeng Li { 12164fd2300SPeng Li struct hclge_desc desc[HCLGE_TM_PFC_PKT_GET_CMD_NUM]; 12264fd2300SPeng Li int ret, i, j; 12364fd2300SPeng Li 12464fd2300SPeng Li if (!(opcode == HCLGE_OPC_QUERY_PFC_RX_PKT_CNT || 12564fd2300SPeng Li opcode == HCLGE_OPC_QUERY_PFC_TX_PKT_CNT)) 12664fd2300SPeng Li return -EINVAL; 12764fd2300SPeng Li 12864fd2300SPeng Li for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) { 12964fd2300SPeng Li hclge_cmd_setup_basic_desc(&desc[i], opcode, true); 13064fd2300SPeng Li if (i != (HCLGE_TM_PFC_PKT_GET_CMD_NUM - 1)) 13164fd2300SPeng Li desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT); 13264fd2300SPeng Li else 13364fd2300SPeng Li desc[i].flag &= ~cpu_to_le16(HCLGE_CMD_FLAG_NEXT); 13464fd2300SPeng Li } 13564fd2300SPeng Li 13664fd2300SPeng Li ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_TM_PFC_PKT_GET_CMD_NUM); 13720670328SYunsheng Lin if (ret) 13864fd2300SPeng Li return ret; 13964fd2300SPeng Li 14064fd2300SPeng Li for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) { 14164fd2300SPeng Li struct hclge_pfc_stats_cmd *pfc_stats = 14264fd2300SPeng Li (struct hclge_pfc_stats_cmd *)desc[i].data; 14364fd2300SPeng Li 14464fd2300SPeng Li for (j = 0; j < HCLGE_TM_PFC_NUM_GET_PER_CMD; j++) { 14564fd2300SPeng Li u32 index = i * HCLGE_TM_PFC_PKT_GET_CMD_NUM + j; 14664fd2300SPeng Li 14764fd2300SPeng Li if (index < HCLGE_MAX_TC_NUM) 14864fd2300SPeng Li stats[index] = 14964fd2300SPeng Li le64_to_cpu(pfc_stats->pkt_num[j]); 15064fd2300SPeng Li } 15164fd2300SPeng Li } 15264fd2300SPeng Li return 0; 15364fd2300SPeng Li } 15464fd2300SPeng Li 15564fd2300SPeng Li int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats) 15664fd2300SPeng Li { 15764fd2300SPeng Li return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_RX_PKT_CNT, stats); 15864fd2300SPeng Li } 15964fd2300SPeng Li 16064fd2300SPeng Li int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats) 16164fd2300SPeng Li { 16264fd2300SPeng Li return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_TX_PKT_CNT, stats); 16364fd2300SPeng Li } 16464fd2300SPeng Li 16561387774SPeng Li int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx) 16684844054SSalil { 16784844054SSalil struct hclge_desc desc; 16884844054SSalil 16984844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PAUSE_EN, false); 17084844054SSalil 17184844054SSalil desc.data[0] = cpu_to_le32((tx ? HCLGE_TX_MAC_PAUSE_EN_MSK : 0) | 17284844054SSalil (rx ? HCLGE_RX_MAC_PAUSE_EN_MSK : 0)); 17384844054SSalil 17484844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 17584844054SSalil } 17684844054SSalil 1779dc2145dSYunsheng Lin static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap, 1789dc2145dSYunsheng Lin u8 pfc_bitmap) 1799dc2145dSYunsheng Lin { 1809dc2145dSYunsheng Lin struct hclge_desc desc; 1819dc2145dSYunsheng Lin struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)&desc.data; 1829dc2145dSYunsheng Lin 1839dc2145dSYunsheng Lin hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PFC_PAUSE_EN, false); 1849dc2145dSYunsheng Lin 1859dc2145dSYunsheng Lin pfc->tx_rx_en_bitmap = tx_rx_bitmap; 1869dc2145dSYunsheng Lin pfc->pri_en_bitmap = pfc_bitmap; 1879dc2145dSYunsheng Lin 1889dc2145dSYunsheng Lin return hclge_cmd_send(&hdev->hw, &desc, 1); 1899dc2145dSYunsheng Lin } 1909dc2145dSYunsheng Lin 191e98d7183SFuyun Liang static int hclge_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr, 19218838d0cSFuyun Liang u8 pause_trans_gap, u16 pause_trans_time) 19318838d0cSFuyun Liang { 19418838d0cSFuyun Liang struct hclge_cfg_pause_param_cmd *pause_param; 19518838d0cSFuyun Liang struct hclge_desc desc; 19618838d0cSFuyun Liang 19718838d0cSFuyun Liang pause_param = (struct hclge_cfg_pause_param_cmd *)&desc.data; 19818838d0cSFuyun Liang 19918838d0cSFuyun Liang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, false); 20018838d0cSFuyun Liang 20118838d0cSFuyun Liang ether_addr_copy(pause_param->mac_addr, addr); 20218838d0cSFuyun Liang pause_param->pause_trans_gap = pause_trans_gap; 20318838d0cSFuyun Liang pause_param->pause_trans_time = cpu_to_le16(pause_trans_time); 20418838d0cSFuyun Liang 20518838d0cSFuyun Liang return hclge_cmd_send(&hdev->hw, &desc, 1); 20618838d0cSFuyun Liang } 20718838d0cSFuyun Liang 208e98d7183SFuyun Liang int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr) 20918838d0cSFuyun Liang { 21018838d0cSFuyun Liang struct hclge_cfg_pause_param_cmd *pause_param; 21118838d0cSFuyun Liang struct hclge_desc desc; 21218838d0cSFuyun Liang u16 trans_time; 21318838d0cSFuyun Liang u8 trans_gap; 21418838d0cSFuyun Liang int ret; 21518838d0cSFuyun Liang 21618838d0cSFuyun Liang pause_param = (struct hclge_cfg_pause_param_cmd *)&desc.data; 21718838d0cSFuyun Liang 21818838d0cSFuyun Liang hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, true); 21918838d0cSFuyun Liang 22018838d0cSFuyun Liang ret = hclge_cmd_send(&hdev->hw, &desc, 1); 22118838d0cSFuyun Liang if (ret) 22218838d0cSFuyun Liang return ret; 22318838d0cSFuyun Liang 22418838d0cSFuyun Liang trans_gap = pause_param->pause_trans_gap; 22518838d0cSFuyun Liang trans_time = le16_to_cpu(pause_param->pause_trans_time); 22618838d0cSFuyun Liang 227e98d7183SFuyun Liang return hclge_pause_param_cfg(hdev, mac_addr, trans_gap, 22818838d0cSFuyun Liang trans_time); 22918838d0cSFuyun Liang } 23018838d0cSFuyun Liang 23184844054SSalil static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id) 23284844054SSalil { 23384844054SSalil u8 tc; 23484844054SSalil 235c5795c53SYunsheng Lin tc = hdev->tm_info.prio_tc[pri_id]; 23684844054SSalil 23784844054SSalil if (tc >= hdev->tm_info.num_tc) 23884844054SSalil return -EINVAL; 23984844054SSalil 24084844054SSalil /** 24184844054SSalil * the register for priority has four bytes, the first bytes includes 24284844054SSalil * priority0 and priority1, the higher 4bit stands for priority1 24384844054SSalil * while the lower 4bit stands for priority0, as below: 24484844054SSalil * first byte: | pri_1 | pri_0 | 24584844054SSalil * second byte: | pri_3 | pri_2 | 24684844054SSalil * third byte: | pri_5 | pri_4 | 24784844054SSalil * fourth byte: | pri_7 | pri_6 | 24884844054SSalil */ 24984844054SSalil pri[pri_id >> 1] |= tc << ((pri_id & 1) * 4); 25084844054SSalil 25184844054SSalil return 0; 25284844054SSalil } 25384844054SSalil 25484844054SSalil static int hclge_up_to_tc_map(struct hclge_dev *hdev) 25584844054SSalil { 25684844054SSalil struct hclge_desc desc; 25784844054SSalil u8 *pri = (u8 *)desc.data; 25884844054SSalil u8 pri_id; 25984844054SSalil int ret; 26084844054SSalil 26184844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PRI_TO_TC_MAPPING, false); 26284844054SSalil 263c5795c53SYunsheng Lin for (pri_id = 0; pri_id < HNAE3_MAX_USER_PRIO; pri_id++) { 26484844054SSalil ret = hclge_fill_pri_array(hdev, pri, pri_id); 26584844054SSalil if (ret) 26684844054SSalil return ret; 26784844054SSalil } 26884844054SSalil 26984844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 27084844054SSalil } 27184844054SSalil 27284844054SSalil static int hclge_tm_pg_to_pri_map_cfg(struct hclge_dev *hdev, 27384844054SSalil u8 pg_id, u8 pri_bit_map) 27484844054SSalil { 27584844054SSalil struct hclge_pg_to_pri_link_cmd *map; 27684844054SSalil struct hclge_desc desc; 27784844054SSalil 27884844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_TO_PRI_LINK, false); 27984844054SSalil 28084844054SSalil map = (struct hclge_pg_to_pri_link_cmd *)desc.data; 28184844054SSalil 28284844054SSalil map->pg_id = pg_id; 28384844054SSalil map->pri_bit_map = pri_bit_map; 28484844054SSalil 28584844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 28684844054SSalil } 28784844054SSalil 28884844054SSalil static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev, 28984844054SSalil u16 qs_id, u8 pri) 29084844054SSalil { 29184844054SSalil struct hclge_qs_to_pri_link_cmd *map; 29284844054SSalil struct hclge_desc desc; 29384844054SSalil 29484844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_TO_PRI_LINK, false); 29584844054SSalil 29684844054SSalil map = (struct hclge_qs_to_pri_link_cmd *)desc.data; 29784844054SSalil 29884844054SSalil map->qs_id = cpu_to_le16(qs_id); 29984844054SSalil map->priority = pri; 30084844054SSalil map->link_vld = HCLGE_TM_QS_PRI_LINK_VLD_MSK; 30184844054SSalil 30284844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 30384844054SSalil } 30484844054SSalil 30584844054SSalil static int hclge_tm_q_to_qs_map_cfg(struct hclge_dev *hdev, 30684844054SSalil u8 q_id, u16 qs_id) 30784844054SSalil { 30884844054SSalil struct hclge_nq_to_qs_link_cmd *map; 30984844054SSalil struct hclge_desc desc; 31084844054SSalil 31184844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NQ_TO_QS_LINK, false); 31284844054SSalil 31384844054SSalil map = (struct hclge_nq_to_qs_link_cmd *)desc.data; 31484844054SSalil 31584844054SSalil map->nq_id = cpu_to_le16(q_id); 31684844054SSalil map->qset_id = cpu_to_le16(qs_id | HCLGE_TM_Q_QS_LINK_VLD_MSK); 31784844054SSalil 31884844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 31984844054SSalil } 32084844054SSalil 32184844054SSalil static int hclge_tm_pg_weight_cfg(struct hclge_dev *hdev, u8 pg_id, 32284844054SSalil u8 dwrr) 32384844054SSalil { 32484844054SSalil struct hclge_pg_weight_cmd *weight; 32584844054SSalil struct hclge_desc desc; 32684844054SSalil 32784844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_WEIGHT, false); 32884844054SSalil 32984844054SSalil weight = (struct hclge_pg_weight_cmd *)desc.data; 33084844054SSalil 33184844054SSalil weight->pg_id = pg_id; 33284844054SSalil weight->dwrr = dwrr; 33384844054SSalil 33484844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 33584844054SSalil } 33684844054SSalil 33784844054SSalil static int hclge_tm_pri_weight_cfg(struct hclge_dev *hdev, u8 pri_id, 33884844054SSalil u8 dwrr) 33984844054SSalil { 34084844054SSalil struct hclge_priority_weight_cmd *weight; 34184844054SSalil struct hclge_desc desc; 34284844054SSalil 34384844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_WEIGHT, false); 34484844054SSalil 34584844054SSalil weight = (struct hclge_priority_weight_cmd *)desc.data; 34684844054SSalil 34784844054SSalil weight->pri_id = pri_id; 34884844054SSalil weight->dwrr = dwrr; 34984844054SSalil 35084844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 35184844054SSalil } 35284844054SSalil 35384844054SSalil static int hclge_tm_qs_weight_cfg(struct hclge_dev *hdev, u16 qs_id, 35484844054SSalil u8 dwrr) 35584844054SSalil { 35684844054SSalil struct hclge_qs_weight_cmd *weight; 35784844054SSalil struct hclge_desc desc; 35884844054SSalil 35984844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_WEIGHT, false); 36084844054SSalil 36184844054SSalil weight = (struct hclge_qs_weight_cmd *)desc.data; 36284844054SSalil 36384844054SSalil weight->qs_id = cpu_to_le16(qs_id); 36484844054SSalil weight->dwrr = dwrr; 36584844054SSalil 36684844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 36784844054SSalil } 36884844054SSalil 36984844054SSalil static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev, 37084844054SSalil enum hclge_shap_bucket bucket, u8 pg_id, 37184844054SSalil u8 ir_b, u8 ir_u, u8 ir_s, u8 bs_b, u8 bs_s) 37284844054SSalil { 37384844054SSalil struct hclge_pg_shapping_cmd *shap_cfg_cmd; 37484844054SSalil enum hclge_opcode_type opcode; 37584844054SSalil struct hclge_desc desc; 376a90bb9a5SYunsheng Lin u32 shapping_para = 0; 37784844054SSalil 37884844054SSalil opcode = bucket ? HCLGE_OPC_TM_PG_P_SHAPPING : 37984844054SSalil HCLGE_OPC_TM_PG_C_SHAPPING; 38084844054SSalil hclge_cmd_setup_basic_desc(&desc, opcode, false); 38184844054SSalil 38284844054SSalil shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data; 38384844054SSalil 38484844054SSalil shap_cfg_cmd->pg_id = pg_id; 38584844054SSalil 386a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_B, ir_b); 387a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_U, ir_u); 388a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_S, ir_s); 389a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, BS_B, bs_b); 390a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, BS_S, bs_s); 391a90bb9a5SYunsheng Lin 392a90bb9a5SYunsheng Lin shap_cfg_cmd->pg_shapping_para = cpu_to_le32(shapping_para); 39384844054SSalil 39484844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 39584844054SSalil } 39684844054SSalil 3970a5677d3SYunsheng Lin static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev) 3980a5677d3SYunsheng Lin { 3990a5677d3SYunsheng Lin struct hclge_port_shapping_cmd *shap_cfg_cmd; 4000a5677d3SYunsheng Lin struct hclge_desc desc; 4010a5677d3SYunsheng Lin u32 shapping_para = 0; 4020a5677d3SYunsheng Lin u8 ir_u, ir_b, ir_s; 4030a5677d3SYunsheng Lin int ret; 4040a5677d3SYunsheng Lin 4050a5677d3SYunsheng Lin ret = hclge_shaper_para_calc(HCLGE_ETHER_MAX_RATE, 4060a5677d3SYunsheng Lin HCLGE_SHAPER_LVL_PORT, 4070a5677d3SYunsheng Lin &ir_b, &ir_u, &ir_s); 4080a5677d3SYunsheng Lin if (ret) 4090a5677d3SYunsheng Lin return ret; 4100a5677d3SYunsheng Lin 4110a5677d3SYunsheng Lin hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PORT_SHAPPING, false); 4120a5677d3SYunsheng Lin shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data; 4130a5677d3SYunsheng Lin 4140a5677d3SYunsheng Lin hclge_tm_set_field(shapping_para, IR_B, ir_b); 4150a5677d3SYunsheng Lin hclge_tm_set_field(shapping_para, IR_U, ir_u); 4160a5677d3SYunsheng Lin hclge_tm_set_field(shapping_para, IR_S, ir_s); 4170a5677d3SYunsheng Lin hclge_tm_set_field(shapping_para, BS_B, HCLGE_SHAPER_BS_U_DEF); 4180a5677d3SYunsheng Lin hclge_tm_set_field(shapping_para, BS_S, HCLGE_SHAPER_BS_S_DEF); 4190a5677d3SYunsheng Lin 4200a5677d3SYunsheng Lin shap_cfg_cmd->port_shapping_para = cpu_to_le32(shapping_para); 4210a5677d3SYunsheng Lin 4220a5677d3SYunsheng Lin return hclge_cmd_send(&hdev->hw, &desc, 1); 4230a5677d3SYunsheng Lin } 4240a5677d3SYunsheng Lin 42584844054SSalil static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev, 42684844054SSalil enum hclge_shap_bucket bucket, u8 pri_id, 42784844054SSalil u8 ir_b, u8 ir_u, u8 ir_s, 42884844054SSalil u8 bs_b, u8 bs_s) 42984844054SSalil { 43084844054SSalil struct hclge_pri_shapping_cmd *shap_cfg_cmd; 43184844054SSalil enum hclge_opcode_type opcode; 43284844054SSalil struct hclge_desc desc; 433a90bb9a5SYunsheng Lin u32 shapping_para = 0; 43484844054SSalil 43584844054SSalil opcode = bucket ? HCLGE_OPC_TM_PRI_P_SHAPPING : 43684844054SSalil HCLGE_OPC_TM_PRI_C_SHAPPING; 43784844054SSalil 43884844054SSalil hclge_cmd_setup_basic_desc(&desc, opcode, false); 43984844054SSalil 44084844054SSalil shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data; 44184844054SSalil 44284844054SSalil shap_cfg_cmd->pri_id = pri_id; 44384844054SSalil 444a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_B, ir_b); 445a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_U, ir_u); 446a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, IR_S, ir_s); 447a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, BS_B, bs_b); 448a90bb9a5SYunsheng Lin hclge_tm_set_field(shapping_para, BS_S, bs_s); 449a90bb9a5SYunsheng Lin 450a90bb9a5SYunsheng Lin shap_cfg_cmd->pri_shapping_para = cpu_to_le32(shapping_para); 45184844054SSalil 45284844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 45384844054SSalil } 45484844054SSalil 45584844054SSalil static int hclge_tm_pg_schd_mode_cfg(struct hclge_dev *hdev, u8 pg_id) 45684844054SSalil { 45784844054SSalil struct hclge_desc desc; 45884844054SSalil 45984844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_SCH_MODE_CFG, false); 46084844054SSalil 46184844054SSalil if (hdev->tm_info.pg_info[pg_id].pg_sch_mode == HCLGE_SCH_MODE_DWRR) 46284844054SSalil desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK); 46384844054SSalil else 46484844054SSalil desc.data[1] = 0; 46584844054SSalil 46684844054SSalil desc.data[0] = cpu_to_le32(pg_id); 46784844054SSalil 46884844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 46984844054SSalil } 47084844054SSalil 47184844054SSalil static int hclge_tm_pri_schd_mode_cfg(struct hclge_dev *hdev, u8 pri_id) 47284844054SSalil { 47384844054SSalil struct hclge_desc desc; 47484844054SSalil 47584844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_SCH_MODE_CFG, false); 47684844054SSalil 47784844054SSalil if (hdev->tm_info.tc_info[pri_id].tc_sch_mode == HCLGE_SCH_MODE_DWRR) 47884844054SSalil desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK); 47984844054SSalil else 48084844054SSalil desc.data[1] = 0; 48184844054SSalil 48284844054SSalil desc.data[0] = cpu_to_le32(pri_id); 48384844054SSalil 48484844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 48584844054SSalil } 48684844054SSalil 487cc9bb43aSYunsheng Lin static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id, u8 mode) 48884844054SSalil { 48984844054SSalil struct hclge_desc desc; 49084844054SSalil 49184844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_SCH_MODE_CFG, false); 49284844054SSalil 493cc9bb43aSYunsheng Lin if (mode == HCLGE_SCH_MODE_DWRR) 49484844054SSalil desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK); 49584844054SSalil else 49684844054SSalil desc.data[1] = 0; 49784844054SSalil 49884844054SSalil desc.data[0] = cpu_to_le32(qs_id); 49984844054SSalil 50084844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 50184844054SSalil } 50284844054SSalil 50367bf2541SYunsheng Lin static int hclge_tm_qs_bp_cfg(struct hclge_dev *hdev, u8 tc, u8 grp_id, 50467bf2541SYunsheng Lin u32 bit_map) 50584844054SSalil { 50684844054SSalil struct hclge_bp_to_qs_map_cmd *bp_to_qs_map_cmd; 50784844054SSalil struct hclge_desc desc; 50884844054SSalil 50984844054SSalil hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_BP_TO_QSET_MAPPING, 51084844054SSalil false); 51184844054SSalil 51284844054SSalil bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data; 51384844054SSalil 51484844054SSalil bp_to_qs_map_cmd->tc_id = tc; 51567bf2541SYunsheng Lin bp_to_qs_map_cmd->qs_group_id = grp_id; 51667bf2541SYunsheng Lin bp_to_qs_map_cmd->qs_bit_map = cpu_to_le32(bit_map); 51784844054SSalil 51884844054SSalil return hclge_cmd_send(&hdev->hw, &desc, 1); 51984844054SSalil } 52084844054SSalil 52184844054SSalil static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport) 52284844054SSalil { 52384844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 52484844054SSalil struct hclge_dev *hdev = vport->back; 52584844054SSalil u8 i; 52684844054SSalil 52784844054SSalil vport->bw_limit = hdev->tm_info.pg_info[0].bw_limit; 52884844054SSalil kinfo->num_tc = 52984844054SSalil min_t(u16, kinfo->num_tqps, hdev->tm_info.num_tc); 53084844054SSalil kinfo->rss_size 53184844054SSalil = min_t(u16, hdev->rss_size_max, 53284844054SSalil kinfo->num_tqps / kinfo->num_tc); 53384844054SSalil vport->qs_offset = hdev->tm_info.num_tc * vport->vport_id; 53484844054SSalil vport->dwrr = 100; /* 100 percent as init */ 53568ece54eSYunsheng Lin vport->alloc_rss_size = kinfo->rss_size; 53684844054SSalil 53784844054SSalil for (i = 0; i < kinfo->num_tc; i++) { 53884844054SSalil if (hdev->hw_tc_map & BIT(i)) { 53984844054SSalil kinfo->tc_info[i].enable = true; 54084844054SSalil kinfo->tc_info[i].tqp_offset = i * kinfo->rss_size; 54184844054SSalil kinfo->tc_info[i].tqp_count = kinfo->rss_size; 54284844054SSalil kinfo->tc_info[i].tc = i; 54384844054SSalil } else { 54484844054SSalil /* Set to default queue if TC is disable */ 54584844054SSalil kinfo->tc_info[i].enable = false; 54684844054SSalil kinfo->tc_info[i].tqp_offset = 0; 54784844054SSalil kinfo->tc_info[i].tqp_count = 1; 54884844054SSalil kinfo->tc_info[i].tc = 0; 54984844054SSalil } 55084844054SSalil } 551c5795c53SYunsheng Lin 552c5795c53SYunsheng Lin memcpy(kinfo->prio_tc, hdev->tm_info.prio_tc, 553c5795c53SYunsheng Lin FIELD_SIZEOF(struct hnae3_knic_private_info, prio_tc)); 55484844054SSalil } 55584844054SSalil 55684844054SSalil static void hclge_tm_vport_info_update(struct hclge_dev *hdev) 55784844054SSalil { 55884844054SSalil struct hclge_vport *vport = hdev->vport; 55984844054SSalil u32 i; 56084844054SSalil 56184844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 56284844054SSalil hclge_tm_vport_tc_info_update(vport); 56384844054SSalil 56484844054SSalil vport++; 56584844054SSalil } 56684844054SSalil } 56784844054SSalil 56884844054SSalil static void hclge_tm_tc_info_init(struct hclge_dev *hdev) 56984844054SSalil { 57084844054SSalil u8 i; 57184844054SSalil 57284844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 57384844054SSalil hdev->tm_info.tc_info[i].tc_id = i; 57484844054SSalil hdev->tm_info.tc_info[i].tc_sch_mode = HCLGE_SCH_MODE_DWRR; 57584844054SSalil hdev->tm_info.tc_info[i].pgid = 0; 57684844054SSalil hdev->tm_info.tc_info[i].bw_limit = 57784844054SSalil hdev->tm_info.pg_info[0].bw_limit; 57884844054SSalil } 57984844054SSalil 580c5795c53SYunsheng Lin for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) 581c5795c53SYunsheng Lin hdev->tm_info.prio_tc[i] = 582c5795c53SYunsheng Lin (i >= hdev->tm_info.num_tc) ? 0 : i; 583c5795c53SYunsheng Lin 5847979a223SYunsheng Lin /* DCB is enabled if we have more than 1 TC */ 5857979a223SYunsheng Lin if (hdev->tm_info.num_tc > 1) 5867979a223SYunsheng Lin hdev->flag |= HCLGE_FLAG_DCB_ENABLE; 5877979a223SYunsheng Lin else 58884844054SSalil hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE; 58984844054SSalil } 59084844054SSalil 59184844054SSalil static void hclge_tm_pg_info_init(struct hclge_dev *hdev) 59284844054SSalil { 59384844054SSalil u8 i; 59484844054SSalil 59584844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 59684844054SSalil int k; 59784844054SSalil 59884844054SSalil hdev->tm_info.pg_dwrr[i] = i ? 0 : 100; 59984844054SSalil 60084844054SSalil hdev->tm_info.pg_info[i].pg_id = i; 60184844054SSalil hdev->tm_info.pg_info[i].pg_sch_mode = HCLGE_SCH_MODE_DWRR; 60284844054SSalil 60384844054SSalil hdev->tm_info.pg_info[i].bw_limit = HCLGE_ETHER_MAX_RATE; 60484844054SSalil 60584844054SSalil if (i != 0) 60684844054SSalil continue; 60784844054SSalil 60884844054SSalil hdev->tm_info.pg_info[i].tc_bit_map = hdev->hw_tc_map; 60984844054SSalil for (k = 0; k < hdev->tm_info.num_tc; k++) 61084844054SSalil hdev->tm_info.pg_info[i].tc_dwrr[k] = 100; 61184844054SSalil } 61284844054SSalil } 61384844054SSalil 6147979a223SYunsheng Lin static void hclge_pfc_info_init(struct hclge_dev *hdev) 6157979a223SYunsheng Lin { 6167979a223SYunsheng Lin if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) { 6177979a223SYunsheng Lin if (hdev->fc_mode_last_time == HCLGE_FC_PFC) 6187979a223SYunsheng Lin dev_warn(&hdev->pdev->dev, 6197979a223SYunsheng Lin "DCB is disable, but last mode is FC_PFC\n"); 6207979a223SYunsheng Lin 6217979a223SYunsheng Lin hdev->tm_info.fc_mode = hdev->fc_mode_last_time; 6227979a223SYunsheng Lin } else if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) { 6237979a223SYunsheng Lin /* fc_mode_last_time record the last fc_mode when 6247979a223SYunsheng Lin * DCB is enabled, so that fc_mode can be set to 6257979a223SYunsheng Lin * the correct value when DCB is disabled. 6267979a223SYunsheng Lin */ 6277979a223SYunsheng Lin hdev->fc_mode_last_time = hdev->tm_info.fc_mode; 6287979a223SYunsheng Lin hdev->tm_info.fc_mode = HCLGE_FC_PFC; 6297979a223SYunsheng Lin } 6307979a223SYunsheng Lin } 6317979a223SYunsheng Lin 63284844054SSalil static int hclge_tm_schd_info_init(struct hclge_dev *hdev) 63384844054SSalil { 63484844054SSalil if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) && 63584844054SSalil (hdev->tm_info.num_pg != 1)) 63684844054SSalil return -EINVAL; 63784844054SSalil 63884844054SSalil hclge_tm_pg_info_init(hdev); 63984844054SSalil 64084844054SSalil hclge_tm_tc_info_init(hdev); 64184844054SSalil 64284844054SSalil hclge_tm_vport_info_update(hdev); 64384844054SSalil 6447979a223SYunsheng Lin hclge_pfc_info_init(hdev); 64584844054SSalil 64684844054SSalil return 0; 64784844054SSalil } 64884844054SSalil 64984844054SSalil static int hclge_tm_pg_to_pri_map(struct hclge_dev *hdev) 65084844054SSalil { 65184844054SSalil int ret; 65284844054SSalil u32 i; 65384844054SSalil 65484844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 65584844054SSalil return 0; 65684844054SSalil 65784844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 65884844054SSalil /* Cfg mapping */ 65984844054SSalil ret = hclge_tm_pg_to_pri_map_cfg( 66084844054SSalil hdev, i, hdev->tm_info.pg_info[i].tc_bit_map); 66184844054SSalil if (ret) 66284844054SSalil return ret; 66384844054SSalil } 66484844054SSalil 66584844054SSalil return 0; 66684844054SSalil } 66784844054SSalil 66884844054SSalil static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev) 66984844054SSalil { 67084844054SSalil u8 ir_u, ir_b, ir_s; 67184844054SSalil int ret; 67284844054SSalil u32 i; 67384844054SSalil 67484844054SSalil /* Cfg pg schd */ 67584844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 67684844054SSalil return 0; 67784844054SSalil 67884844054SSalil /* Pg to pri */ 67984844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 68084844054SSalil /* Calc shaper para */ 68184844054SSalil ret = hclge_shaper_para_calc( 68284844054SSalil hdev->tm_info.pg_info[i].bw_limit, 68384844054SSalil HCLGE_SHAPER_LVL_PG, 68484844054SSalil &ir_b, &ir_u, &ir_s); 68584844054SSalil if (ret) 68684844054SSalil return ret; 68784844054SSalil 68884844054SSalil ret = hclge_tm_pg_shapping_cfg(hdev, 68984844054SSalil HCLGE_TM_SHAP_C_BUCKET, i, 69084844054SSalil 0, 0, 0, HCLGE_SHAPER_BS_U_DEF, 69184844054SSalil HCLGE_SHAPER_BS_S_DEF); 69284844054SSalil if (ret) 69384844054SSalil return ret; 69484844054SSalil 69584844054SSalil ret = hclge_tm_pg_shapping_cfg(hdev, 69684844054SSalil HCLGE_TM_SHAP_P_BUCKET, i, 69784844054SSalil ir_b, ir_u, ir_s, 69884844054SSalil HCLGE_SHAPER_BS_U_DEF, 69984844054SSalil HCLGE_SHAPER_BS_S_DEF); 70084844054SSalil if (ret) 70184844054SSalil return ret; 70284844054SSalil } 70384844054SSalil 70484844054SSalil return 0; 70584844054SSalil } 70684844054SSalil 70784844054SSalil static int hclge_tm_pg_dwrr_cfg(struct hclge_dev *hdev) 70884844054SSalil { 70984844054SSalil int ret; 71084844054SSalil u32 i; 71184844054SSalil 71284844054SSalil /* cfg pg schd */ 71384844054SSalil if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) 71484844054SSalil return 0; 71584844054SSalil 71684844054SSalil /* pg to prio */ 71784844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 71884844054SSalil /* Cfg dwrr */ 71984844054SSalil ret = hclge_tm_pg_weight_cfg(hdev, i, 72084844054SSalil hdev->tm_info.pg_dwrr[i]); 72184844054SSalil if (ret) 72284844054SSalil return ret; 72384844054SSalil } 72484844054SSalil 72584844054SSalil return 0; 72684844054SSalil } 72784844054SSalil 72884844054SSalil static int hclge_vport_q_to_qs_map(struct hclge_dev *hdev, 72984844054SSalil struct hclge_vport *vport) 73084844054SSalil { 73184844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 73284844054SSalil struct hnae3_queue **tqp = kinfo->tqp; 73384844054SSalil struct hnae3_tc_info *v_tc_info; 73484844054SSalil u32 i, j; 73584844054SSalil int ret; 73684844054SSalil 73784844054SSalil for (i = 0; i < kinfo->num_tc; i++) { 73884844054SSalil v_tc_info = &kinfo->tc_info[i]; 73984844054SSalil for (j = 0; j < v_tc_info->tqp_count; j++) { 74084844054SSalil struct hnae3_queue *q = tqp[v_tc_info->tqp_offset + j]; 74184844054SSalil 74284844054SSalil ret = hclge_tm_q_to_qs_map_cfg(hdev, 74384844054SSalil hclge_get_queue_id(q), 74484844054SSalil vport->qs_offset + i); 74584844054SSalil if (ret) 74684844054SSalil return ret; 74784844054SSalil } 74884844054SSalil } 74984844054SSalil 75084844054SSalil return 0; 75184844054SSalil } 75284844054SSalil 75384844054SSalil static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev) 75484844054SSalil { 75584844054SSalil struct hclge_vport *vport = hdev->vport; 75684844054SSalil int ret; 757cc9bb43aSYunsheng Lin u32 i, k; 75884844054SSalil 75984844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 76084844054SSalil /* Cfg qs -> pri mapping, one by one mapping */ 761cc9bb43aSYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) 76284844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 763cc9bb43aSYunsheng Lin ret = hclge_tm_qs_to_pri_map_cfg( 764cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, i); 76584844054SSalil if (ret) 76684844054SSalil return ret; 76784844054SSalil } 76884844054SSalil } else if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) { 76984844054SSalil /* Cfg qs -> pri mapping, qs = tc, pri = vf, 8 qs -> 1 pri */ 77084844054SSalil for (k = 0; k < hdev->num_alloc_vport; k++) 77184844054SSalil for (i = 0; i < HNAE3_MAX_TC; i++) { 77284844054SSalil ret = hclge_tm_qs_to_pri_map_cfg( 77384844054SSalil hdev, vport[k].qs_offset + i, k); 77484844054SSalil if (ret) 77584844054SSalil return ret; 77684844054SSalil } 77784844054SSalil } else { 77884844054SSalil return -EINVAL; 77984844054SSalil } 78084844054SSalil 78184844054SSalil /* Cfg q -> qs mapping */ 78284844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 78384844054SSalil ret = hclge_vport_q_to_qs_map(hdev, vport); 78484844054SSalil if (ret) 78584844054SSalil return ret; 78684844054SSalil 78784844054SSalil vport++; 78884844054SSalil } 78984844054SSalil 79084844054SSalil return 0; 79184844054SSalil } 79284844054SSalil 79384844054SSalil static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev) 79484844054SSalil { 79584844054SSalil u8 ir_u, ir_b, ir_s; 79684844054SSalil int ret; 79784844054SSalil u32 i; 79884844054SSalil 79984844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 80084844054SSalil ret = hclge_shaper_para_calc( 80184844054SSalil hdev->tm_info.tc_info[i].bw_limit, 80284844054SSalil HCLGE_SHAPER_LVL_PRI, 80384844054SSalil &ir_b, &ir_u, &ir_s); 80484844054SSalil if (ret) 80584844054SSalil return ret; 80684844054SSalil 80784844054SSalil ret = hclge_tm_pri_shapping_cfg( 80884844054SSalil hdev, HCLGE_TM_SHAP_C_BUCKET, i, 80984844054SSalil 0, 0, 0, HCLGE_SHAPER_BS_U_DEF, 81084844054SSalil HCLGE_SHAPER_BS_S_DEF); 81184844054SSalil if (ret) 81284844054SSalil return ret; 81384844054SSalil 81484844054SSalil ret = hclge_tm_pri_shapping_cfg( 81584844054SSalil hdev, HCLGE_TM_SHAP_P_BUCKET, i, 81684844054SSalil ir_b, ir_u, ir_s, HCLGE_SHAPER_BS_U_DEF, 81784844054SSalil HCLGE_SHAPER_BS_S_DEF); 81884844054SSalil if (ret) 81984844054SSalil return ret; 82084844054SSalil } 82184844054SSalil 82284844054SSalil return 0; 82384844054SSalil } 82484844054SSalil 82584844054SSalil static int hclge_tm_pri_vnet_base_shaper_pri_cfg(struct hclge_vport *vport) 82684844054SSalil { 82784844054SSalil struct hclge_dev *hdev = vport->back; 82884844054SSalil u8 ir_u, ir_b, ir_s; 82984844054SSalil int ret; 83084844054SSalil 83184844054SSalil ret = hclge_shaper_para_calc(vport->bw_limit, HCLGE_SHAPER_LVL_VF, 83284844054SSalil &ir_b, &ir_u, &ir_s); 83384844054SSalil if (ret) 83484844054SSalil return ret; 83584844054SSalil 83684844054SSalil ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, 83784844054SSalil vport->vport_id, 83884844054SSalil 0, 0, 0, HCLGE_SHAPER_BS_U_DEF, 83984844054SSalil HCLGE_SHAPER_BS_S_DEF); 84084844054SSalil if (ret) 84184844054SSalil return ret; 84284844054SSalil 84384844054SSalil ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, 84484844054SSalil vport->vport_id, 84584844054SSalil ir_b, ir_u, ir_s, 84684844054SSalil HCLGE_SHAPER_BS_U_DEF, 84784844054SSalil HCLGE_SHAPER_BS_S_DEF); 84884844054SSalil if (ret) 84984844054SSalil return ret; 85084844054SSalil 85184844054SSalil return 0; 85284844054SSalil } 85384844054SSalil 85484844054SSalil static int hclge_tm_pri_vnet_base_shaper_qs_cfg(struct hclge_vport *vport) 85584844054SSalil { 85684844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 85784844054SSalil struct hclge_dev *hdev = vport->back; 85884844054SSalil u8 ir_u, ir_b, ir_s; 85984844054SSalil u32 i; 86084844054SSalil int ret; 86184844054SSalil 86284844054SSalil for (i = 0; i < kinfo->num_tc; i++) { 86384844054SSalil ret = hclge_shaper_para_calc( 86484844054SSalil hdev->tm_info.tc_info[i].bw_limit, 86584844054SSalil HCLGE_SHAPER_LVL_QSET, 86684844054SSalil &ir_b, &ir_u, &ir_s); 86784844054SSalil if (ret) 86884844054SSalil return ret; 86984844054SSalil } 87084844054SSalil 87184844054SSalil return 0; 87284844054SSalil } 87384844054SSalil 87484844054SSalil static int hclge_tm_pri_vnet_base_shaper_cfg(struct hclge_dev *hdev) 87584844054SSalil { 87684844054SSalil struct hclge_vport *vport = hdev->vport; 87784844054SSalil int ret; 87884844054SSalil u32 i; 87984844054SSalil 88084844054SSalil /* Need config vport shaper */ 88184844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 88284844054SSalil ret = hclge_tm_pri_vnet_base_shaper_pri_cfg(vport); 88384844054SSalil if (ret) 88484844054SSalil return ret; 88584844054SSalil 88684844054SSalil ret = hclge_tm_pri_vnet_base_shaper_qs_cfg(vport); 88784844054SSalil if (ret) 88884844054SSalil return ret; 88984844054SSalil 89084844054SSalil vport++; 89184844054SSalil } 89284844054SSalil 89384844054SSalil return 0; 89484844054SSalil } 89584844054SSalil 89684844054SSalil static int hclge_tm_pri_shaper_cfg(struct hclge_dev *hdev) 89784844054SSalil { 89884844054SSalil int ret; 89984844054SSalil 90084844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 90184844054SSalil ret = hclge_tm_pri_tc_base_shaper_cfg(hdev); 90284844054SSalil if (ret) 90384844054SSalil return ret; 90484844054SSalil } else { 90584844054SSalil ret = hclge_tm_pri_vnet_base_shaper_cfg(hdev); 90684844054SSalil if (ret) 90784844054SSalil return ret; 90884844054SSalil } 90984844054SSalil 91084844054SSalil return 0; 91184844054SSalil } 91284844054SSalil 91384844054SSalil static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev) 91484844054SSalil { 915cc9bb43aSYunsheng Lin struct hclge_vport *vport = hdev->vport; 91684844054SSalil struct hclge_pg_info *pg_info; 91784844054SSalil u8 dwrr; 91884844054SSalil int ret; 919cc9bb43aSYunsheng Lin u32 i, k; 92084844054SSalil 92184844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 92284844054SSalil pg_info = 92384844054SSalil &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid]; 92484844054SSalil dwrr = pg_info->tc_dwrr[i]; 92584844054SSalil 92684844054SSalil ret = hclge_tm_pri_weight_cfg(hdev, i, dwrr); 92784844054SSalil if (ret) 92884844054SSalil return ret; 92984844054SSalil 930cc9bb43aSYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 931cc9bb43aSYunsheng Lin ret = hclge_tm_qs_weight_cfg( 932cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, 933cc9bb43aSYunsheng Lin vport[k].dwrr); 93484844054SSalil if (ret) 93584844054SSalil return ret; 93684844054SSalil } 937cc9bb43aSYunsheng Lin } 93884844054SSalil 93984844054SSalil return 0; 94084844054SSalil } 94184844054SSalil 94284844054SSalil static int hclge_tm_pri_vnet_base_dwrr_pri_cfg(struct hclge_vport *vport) 94384844054SSalil { 94484844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 94584844054SSalil struct hclge_dev *hdev = vport->back; 94684844054SSalil int ret; 94784844054SSalil u8 i; 94884844054SSalil 94984844054SSalil /* Vf dwrr */ 95084844054SSalil ret = hclge_tm_pri_weight_cfg(hdev, vport->vport_id, vport->dwrr); 95184844054SSalil if (ret) 95284844054SSalil return ret; 95384844054SSalil 95484844054SSalil /* Qset dwrr */ 95584844054SSalil for (i = 0; i < kinfo->num_tc; i++) { 95684844054SSalil ret = hclge_tm_qs_weight_cfg( 95784844054SSalil hdev, vport->qs_offset + i, 95884844054SSalil hdev->tm_info.pg_info[0].tc_dwrr[i]); 95984844054SSalil if (ret) 96084844054SSalil return ret; 96184844054SSalil } 96284844054SSalil 96384844054SSalil return 0; 96484844054SSalil } 96584844054SSalil 96684844054SSalil static int hclge_tm_pri_vnet_base_dwrr_cfg(struct hclge_dev *hdev) 96784844054SSalil { 96884844054SSalil struct hclge_vport *vport = hdev->vport; 96984844054SSalil int ret; 97084844054SSalil u32 i; 97184844054SSalil 97284844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 97384844054SSalil ret = hclge_tm_pri_vnet_base_dwrr_pri_cfg(vport); 97484844054SSalil if (ret) 97584844054SSalil return ret; 97684844054SSalil 97784844054SSalil vport++; 97884844054SSalil } 97984844054SSalil 98084844054SSalil return 0; 98184844054SSalil } 98284844054SSalil 98384844054SSalil static int hclge_tm_pri_dwrr_cfg(struct hclge_dev *hdev) 98484844054SSalil { 98584844054SSalil int ret; 98684844054SSalil 98784844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 98884844054SSalil ret = hclge_tm_pri_tc_base_dwrr_cfg(hdev); 98984844054SSalil if (ret) 99084844054SSalil return ret; 99184844054SSalil } else { 99284844054SSalil ret = hclge_tm_pri_vnet_base_dwrr_cfg(hdev); 99384844054SSalil if (ret) 99484844054SSalil return ret; 99584844054SSalil } 99684844054SSalil 99784844054SSalil return 0; 99884844054SSalil } 99984844054SSalil 100077f255c1SYunsheng Lin int hclge_tm_map_cfg(struct hclge_dev *hdev) 100184844054SSalil { 100284844054SSalil int ret; 100384844054SSalil 100477f255c1SYunsheng Lin ret = hclge_up_to_tc_map(hdev); 100577f255c1SYunsheng Lin if (ret) 100677f255c1SYunsheng Lin return ret; 100777f255c1SYunsheng Lin 100884844054SSalil ret = hclge_tm_pg_to_pri_map(hdev); 100984844054SSalil if (ret) 101084844054SSalil return ret; 101184844054SSalil 101284844054SSalil return hclge_tm_pri_q_qs_cfg(hdev); 101384844054SSalil } 101484844054SSalil 101584844054SSalil static int hclge_tm_shaper_cfg(struct hclge_dev *hdev) 101684844054SSalil { 101784844054SSalil int ret; 101884844054SSalil 10190a5677d3SYunsheng Lin ret = hclge_tm_port_shaper_cfg(hdev); 10200a5677d3SYunsheng Lin if (ret) 10210a5677d3SYunsheng Lin return ret; 10220a5677d3SYunsheng Lin 102384844054SSalil ret = hclge_tm_pg_shaper_cfg(hdev); 102484844054SSalil if (ret) 102584844054SSalil return ret; 102684844054SSalil 102784844054SSalil return hclge_tm_pri_shaper_cfg(hdev); 102884844054SSalil } 102984844054SSalil 103084844054SSalil int hclge_tm_dwrr_cfg(struct hclge_dev *hdev) 103184844054SSalil { 103284844054SSalil int ret; 103384844054SSalil 103484844054SSalil ret = hclge_tm_pg_dwrr_cfg(hdev); 103584844054SSalil if (ret) 103684844054SSalil return ret; 103784844054SSalil 103884844054SSalil return hclge_tm_pri_dwrr_cfg(hdev); 103984844054SSalil } 104084844054SSalil 104184844054SSalil static int hclge_tm_lvl2_schd_mode_cfg(struct hclge_dev *hdev) 104284844054SSalil { 104384844054SSalil int ret; 104484844054SSalil u8 i; 104584844054SSalil 104684844054SSalil /* Only being config on TC-Based scheduler mode */ 104784844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) 104884844054SSalil return 0; 104984844054SSalil 105084844054SSalil for (i = 0; i < hdev->tm_info.num_pg; i++) { 105184844054SSalil ret = hclge_tm_pg_schd_mode_cfg(hdev, i); 105284844054SSalil if (ret) 105384844054SSalil return ret; 105484844054SSalil } 105584844054SSalil 105684844054SSalil return 0; 105784844054SSalil } 105884844054SSalil 105984844054SSalil static int hclge_tm_schd_mode_vnet_base_cfg(struct hclge_vport *vport) 106084844054SSalil { 106184844054SSalil struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo; 106284844054SSalil struct hclge_dev *hdev = vport->back; 106384844054SSalil int ret; 106484844054SSalil u8 i; 106584844054SSalil 106684844054SSalil ret = hclge_tm_pri_schd_mode_cfg(hdev, vport->vport_id); 106784844054SSalil if (ret) 106884844054SSalil return ret; 106984844054SSalil 107084844054SSalil for (i = 0; i < kinfo->num_tc; i++) { 1071cc9bb43aSYunsheng Lin u8 sch_mode = hdev->tm_info.tc_info[i].tc_sch_mode; 1072cc9bb43aSYunsheng Lin 1073cc9bb43aSYunsheng Lin ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i, 1074cc9bb43aSYunsheng Lin sch_mode); 107584844054SSalil if (ret) 107684844054SSalil return ret; 107784844054SSalil } 107884844054SSalil 107984844054SSalil return 0; 108084844054SSalil } 108184844054SSalil 108284844054SSalil static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev *hdev) 108384844054SSalil { 108484844054SSalil struct hclge_vport *vport = hdev->vport; 108584844054SSalil int ret; 1086cc9bb43aSYunsheng Lin u8 i, k; 108784844054SSalil 108884844054SSalil if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) { 108984844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 109084844054SSalil ret = hclge_tm_pri_schd_mode_cfg(hdev, i); 109184844054SSalil if (ret) 109284844054SSalil return ret; 109384844054SSalil 1094cc9bb43aSYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 1095cc9bb43aSYunsheng Lin ret = hclge_tm_qs_schd_mode_cfg( 1096cc9bb43aSYunsheng Lin hdev, vport[k].qs_offset + i, 1097cc9bb43aSYunsheng Lin HCLGE_SCH_MODE_DWRR); 109884844054SSalil if (ret) 109984844054SSalil return ret; 110084844054SSalil } 1101cc9bb43aSYunsheng Lin } 110284844054SSalil } else { 110384844054SSalil for (i = 0; i < hdev->num_alloc_vport; i++) { 110484844054SSalil ret = hclge_tm_schd_mode_vnet_base_cfg(vport); 110584844054SSalil if (ret) 110684844054SSalil return ret; 110784844054SSalil 110884844054SSalil vport++; 110984844054SSalil } 111084844054SSalil } 111184844054SSalil 111284844054SSalil return 0; 111384844054SSalil } 111484844054SSalil 111577f255c1SYunsheng Lin int hclge_tm_schd_mode_hw(struct hclge_dev *hdev) 111684844054SSalil { 111784844054SSalil int ret; 111884844054SSalil 111984844054SSalil ret = hclge_tm_lvl2_schd_mode_cfg(hdev); 112084844054SSalil if (ret) 112184844054SSalil return ret; 112284844054SSalil 112384844054SSalil return hclge_tm_lvl34_schd_mode_cfg(hdev); 112484844054SSalil } 112584844054SSalil 112684844054SSalil static int hclge_tm_schd_setup_hw(struct hclge_dev *hdev) 112784844054SSalil { 112884844054SSalil int ret; 112984844054SSalil 113084844054SSalil /* Cfg tm mapping */ 113184844054SSalil ret = hclge_tm_map_cfg(hdev); 113284844054SSalil if (ret) 113384844054SSalil return ret; 113484844054SSalil 113584844054SSalil /* Cfg tm shaper */ 113684844054SSalil ret = hclge_tm_shaper_cfg(hdev); 113784844054SSalil if (ret) 113884844054SSalil return ret; 113984844054SSalil 114084844054SSalil /* Cfg dwrr */ 114184844054SSalil ret = hclge_tm_dwrr_cfg(hdev); 114284844054SSalil if (ret) 114384844054SSalil return ret; 114484844054SSalil 114584844054SSalil /* Cfg schd mode for each level schd */ 114684844054SSalil return hclge_tm_schd_mode_hw(hdev); 114784844054SSalil } 114884844054SSalil 1149e98d7183SFuyun Liang static int hclge_pause_param_setup_hw(struct hclge_dev *hdev) 115018838d0cSFuyun Liang { 115118838d0cSFuyun Liang struct hclge_mac *mac = &hdev->hw.mac; 115218838d0cSFuyun Liang 1153e98d7183SFuyun Liang return hclge_pause_param_cfg(hdev, mac->mac_addr, 115418838d0cSFuyun Liang HCLGE_DEFAULT_PAUSE_TRANS_GAP, 115518838d0cSFuyun Liang HCLGE_DEFAULT_PAUSE_TRANS_TIME); 115618838d0cSFuyun Liang } 115718838d0cSFuyun Liang 11589dc2145dSYunsheng Lin static int hclge_pfc_setup_hw(struct hclge_dev *hdev) 11599dc2145dSYunsheng Lin { 11609dc2145dSYunsheng Lin u8 enable_bitmap = 0; 11619dc2145dSYunsheng Lin 11629dc2145dSYunsheng Lin if (hdev->tm_info.fc_mode == HCLGE_FC_PFC) 11639dc2145dSYunsheng Lin enable_bitmap = HCLGE_TX_MAC_PAUSE_EN_MSK | 11649dc2145dSYunsheng Lin HCLGE_RX_MAC_PAUSE_EN_MSK; 11659dc2145dSYunsheng Lin 11669dc2145dSYunsheng Lin return hclge_pfc_pause_en_cfg(hdev, enable_bitmap, 11679dc2145dSYunsheng Lin hdev->tm_info.hw_pfc_map); 11689dc2145dSYunsheng Lin } 11699dc2145dSYunsheng Lin 117067bf2541SYunsheng Lin /* Each Tc has a 1024 queue sets to backpress, it divides to 117167bf2541SYunsheng Lin * 32 group, each group contains 32 queue sets, which can be 117267bf2541SYunsheng Lin * represented by u32 bitmap. 117367bf2541SYunsheng Lin */ 117467bf2541SYunsheng Lin static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc) 117567bf2541SYunsheng Lin { 117667bf2541SYunsheng Lin struct hclge_vport *vport = hdev->vport; 117767bf2541SYunsheng Lin u32 i, k, qs_bitmap; 117867bf2541SYunsheng Lin int ret; 117967bf2541SYunsheng Lin 118067bf2541SYunsheng Lin for (i = 0; i < HCLGE_BP_GRP_NUM; i++) { 118167bf2541SYunsheng Lin qs_bitmap = 0; 118267bf2541SYunsheng Lin 118367bf2541SYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 118467bf2541SYunsheng Lin u16 qs_id = vport->qs_offset + tc; 118567bf2541SYunsheng Lin u8 grp, sub_grp; 118667bf2541SYunsheng Lin 1187e4e87715SPeng Li grp = hnae3_get_field(qs_id, HCLGE_BP_GRP_ID_M, 118867bf2541SYunsheng Lin HCLGE_BP_GRP_ID_S); 1189e4e87715SPeng Li sub_grp = hnae3_get_field(qs_id, HCLGE_BP_SUB_GRP_ID_M, 119067bf2541SYunsheng Lin HCLGE_BP_SUB_GRP_ID_S); 119167bf2541SYunsheng Lin if (i == grp) 119267bf2541SYunsheng Lin qs_bitmap |= (1 << sub_grp); 119367bf2541SYunsheng Lin 119467bf2541SYunsheng Lin vport++; 119567bf2541SYunsheng Lin } 119667bf2541SYunsheng Lin 119767bf2541SYunsheng Lin ret = hclge_tm_qs_bp_cfg(hdev, tc, i, qs_bitmap); 119867bf2541SYunsheng Lin if (ret) 119967bf2541SYunsheng Lin return ret; 120067bf2541SYunsheng Lin } 120167bf2541SYunsheng Lin 120267bf2541SYunsheng Lin return 0; 120367bf2541SYunsheng Lin } 120467bf2541SYunsheng Lin 12059dc2145dSYunsheng Lin static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev) 12069dc2145dSYunsheng Lin { 12079dc2145dSYunsheng Lin bool tx_en, rx_en; 12089dc2145dSYunsheng Lin 12099dc2145dSYunsheng Lin switch (hdev->tm_info.fc_mode) { 12109dc2145dSYunsheng Lin case HCLGE_FC_NONE: 12119dc2145dSYunsheng Lin tx_en = false; 12129dc2145dSYunsheng Lin rx_en = false; 12139dc2145dSYunsheng Lin break; 12149dc2145dSYunsheng Lin case HCLGE_FC_RX_PAUSE: 12159dc2145dSYunsheng Lin tx_en = false; 12169dc2145dSYunsheng Lin rx_en = true; 12179dc2145dSYunsheng Lin break; 12189dc2145dSYunsheng Lin case HCLGE_FC_TX_PAUSE: 12199dc2145dSYunsheng Lin tx_en = true; 12209dc2145dSYunsheng Lin rx_en = false; 12219dc2145dSYunsheng Lin break; 12229dc2145dSYunsheng Lin case HCLGE_FC_FULL: 12239dc2145dSYunsheng Lin tx_en = true; 12249dc2145dSYunsheng Lin rx_en = true; 12259dc2145dSYunsheng Lin break; 12269dc2145dSYunsheng Lin default: 12279dc2145dSYunsheng Lin tx_en = true; 12289dc2145dSYunsheng Lin rx_en = true; 12299dc2145dSYunsheng Lin } 12309dc2145dSYunsheng Lin 12319dc2145dSYunsheng Lin return hclge_mac_pause_en_cfg(hdev, tx_en, rx_en); 12329dc2145dSYunsheng Lin } 12339dc2145dSYunsheng Lin 123484844054SSalil int hclge_pause_setup_hw(struct hclge_dev *hdev) 123584844054SSalil { 123684844054SSalil int ret; 123784844054SSalil u8 i; 123884844054SSalil 1239e98d7183SFuyun Liang ret = hclge_pause_param_setup_hw(hdev); 124018838d0cSFuyun Liang if (ret) 124118838d0cSFuyun Liang return ret; 124218838d0cSFuyun Liang 1243e98d7183SFuyun Liang if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) 1244e98d7183SFuyun Liang return hclge_mac_pause_setup_hw(hdev); 124584844054SSalil 12469dc2145dSYunsheng Lin /* Only DCB-supported dev supports qset back pressure and pfc cmd */ 12472daf4a65SYunsheng Lin if (!hnae3_dev_dcb_supported(hdev)) 12482daf4a65SYunsheng Lin return 0; 12492daf4a65SYunsheng Lin 12509dc2145dSYunsheng Lin /* When MAC is GE Mode, hdev does not support pfc setting */ 12519dc2145dSYunsheng Lin ret = hclge_pfc_setup_hw(hdev); 12529dc2145dSYunsheng Lin if (ret) 12539dc2145dSYunsheng Lin dev_warn(&hdev->pdev->dev, "set pfc pause failed:%d\n", ret); 12549dc2145dSYunsheng Lin 125584844054SSalil for (i = 0; i < hdev->tm_info.num_tc; i++) { 125667bf2541SYunsheng Lin ret = hclge_bp_setup_hw(hdev, i); 125784844054SSalil if (ret) 125884844054SSalil return ret; 125984844054SSalil } 126084844054SSalil 126177f255c1SYunsheng Lin return 0; 126277f255c1SYunsheng Lin } 126377f255c1SYunsheng Lin 126477f255c1SYunsheng Lin int hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc) 126577f255c1SYunsheng Lin { 126677f255c1SYunsheng Lin struct hclge_vport *vport = hdev->vport; 126777f255c1SYunsheng Lin struct hnae3_knic_private_info *kinfo; 126877f255c1SYunsheng Lin u32 i, k; 126977f255c1SYunsheng Lin 127077f255c1SYunsheng Lin for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) { 127177f255c1SYunsheng Lin if (prio_tc[i] >= hdev->tm_info.num_tc) 127277f255c1SYunsheng Lin return -EINVAL; 127377f255c1SYunsheng Lin hdev->tm_info.prio_tc[i] = prio_tc[i]; 127477f255c1SYunsheng Lin 127577f255c1SYunsheng Lin for (k = 0; k < hdev->num_alloc_vport; k++) { 127677f255c1SYunsheng Lin kinfo = &vport[k].nic.kinfo; 127777f255c1SYunsheng Lin kinfo->prio_tc[i] = prio_tc[i]; 127877f255c1SYunsheng Lin } 127977f255c1SYunsheng Lin } 128077f255c1SYunsheng Lin return 0; 128177f255c1SYunsheng Lin } 128277f255c1SYunsheng Lin 128377f255c1SYunsheng Lin void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc) 128477f255c1SYunsheng Lin { 128577f255c1SYunsheng Lin u8 i, bit_map = 0; 128677f255c1SYunsheng Lin 128777f255c1SYunsheng Lin hdev->tm_info.num_tc = num_tc; 128877f255c1SYunsheng Lin 128977f255c1SYunsheng Lin for (i = 0; i < hdev->tm_info.num_tc; i++) 129077f255c1SYunsheng Lin bit_map |= BIT(i); 129177f255c1SYunsheng Lin 129277f255c1SYunsheng Lin if (!bit_map) { 129377f255c1SYunsheng Lin bit_map = 1; 129477f255c1SYunsheng Lin hdev->tm_info.num_tc = 1; 129577f255c1SYunsheng Lin } 129677f255c1SYunsheng Lin 129777f255c1SYunsheng Lin hdev->hw_tc_map = bit_map; 129877f255c1SYunsheng Lin 129977f255c1SYunsheng Lin hclge_tm_schd_info_init(hdev); 130084844054SSalil } 130184844054SSalil 130284844054SSalil int hclge_tm_init_hw(struct hclge_dev *hdev) 130384844054SSalil { 130484844054SSalil int ret; 130584844054SSalil 130684844054SSalil if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) && 130784844054SSalil (hdev->tx_sch_mode != HCLGE_FLAG_VNET_BASE_SCH_MODE)) 130884844054SSalil return -ENOTSUPP; 130984844054SSalil 131084844054SSalil ret = hclge_tm_schd_setup_hw(hdev); 131184844054SSalil if (ret) 131284844054SSalil return ret; 131384844054SSalil 131484844054SSalil ret = hclge_pause_setup_hw(hdev); 131584844054SSalil if (ret) 131684844054SSalil return ret; 131784844054SSalil 131884844054SSalil return 0; 131984844054SSalil } 132084844054SSalil 132184844054SSalil int hclge_tm_schd_init(struct hclge_dev *hdev) 132284844054SSalil { 13237979a223SYunsheng Lin int ret; 132484844054SSalil 13257979a223SYunsheng Lin /* fc_mode is HCLGE_FC_FULL on reset */ 13267979a223SYunsheng Lin hdev->tm_info.fc_mode = HCLGE_FC_FULL; 13277979a223SYunsheng Lin hdev->fc_mode_last_time = hdev->tm_info.fc_mode; 13287979a223SYunsheng Lin 13297979a223SYunsheng Lin ret = hclge_tm_schd_info_init(hdev); 133084844054SSalil if (ret) 133184844054SSalil return ret; 133284844054SSalil 133384844054SSalil return hclge_tm_init_hw(hdev); 133484844054SSalil } 1335