1d71d8381SJian Shen // SPDX-License-Identifier: GPL-2.0+
2d71d8381SJian Shen // Copyright (c) 2016-2017 Hisilicon Limited.
384844054SSalil 
484844054SSalil #include <linux/etherdevice.h>
584844054SSalil 
684844054SSalil #include "hclge_cmd.h"
784844054SSalil #include "hclge_main.h"
884844054SSalil #include "hclge_tm.h"
984844054SSalil 
1084844054SSalil enum hclge_shaper_level {
1184844054SSalil 	HCLGE_SHAPER_LVL_PRI	= 0,
1284844054SSalil 	HCLGE_SHAPER_LVL_PG	= 1,
1384844054SSalil 	HCLGE_SHAPER_LVL_PORT	= 2,
1484844054SSalil 	HCLGE_SHAPER_LVL_QSET	= 3,
1584844054SSalil 	HCLGE_SHAPER_LVL_CNT	= 4,
1684844054SSalil 	HCLGE_SHAPER_LVL_VF	= 0,
1784844054SSalil 	HCLGE_SHAPER_LVL_PF	= 1,
1884844054SSalil };
1984844054SSalil 
2064fd2300SPeng Li #define HCLGE_TM_PFC_PKT_GET_CMD_NUM	3
2164fd2300SPeng Li #define HCLGE_TM_PFC_NUM_GET_PER_CMD	3
2264fd2300SPeng Li 
233a7d5958SPeng Li #define HCLGE_SHAPER_BS_U_DEF	5
243a7d5958SPeng Li #define HCLGE_SHAPER_BS_S_DEF	20
2584844054SSalil 
2684844054SSalil /* hclge_shaper_para_calc: calculate ir parameter for the shaper
2784844054SSalil  * @ir: Rate to be config, its unit is Mbps
2884844054SSalil  * @shaper_level: the shaper level. eg: port, pg, priority, queueset
29ff7e4d0dSHuazhong Tan  * @ir_para: parameters of IR shaper
30d9c7d20dSGuangbin Huang  * @max_tm_rate: max tm rate is available to config
3184844054SSalil  *
3284844054SSalil  * the formula:
3384844054SSalil  *
3484844054SSalil  *		IR_b * (2 ^ IR_u) * 8
3584844054SSalil  * IR(Mbps) = -------------------------  *  CLOCK(1000Mbps)
3684844054SSalil  *		Tick * (2 ^ IR_s)
3784844054SSalil  *
3884844054SSalil  * @return: 0: calculate sucessful, negative: fail
3984844054SSalil  */
hclge_shaper_para_calc(u32 ir,u8 shaper_level,struct hclge_shaper_ir_para * ir_para,u32 max_tm_rate)4084844054SSalil static int hclge_shaper_para_calc(u32 ir, u8 shaper_level,
41ff7e4d0dSHuazhong Tan 				  struct hclge_shaper_ir_para *ir_para,
42d9c7d20dSGuangbin Huang 				  u32 max_tm_rate)
4384844054SSalil {
449d2a1ceaSPeng Li #define DEFAULT_SHAPER_IR_B	126
45b37ce587SYufeng Mo #define DIVISOR_CLK		(1000 * 8)
469d2a1ceaSPeng Li #define DEFAULT_DIVISOR_IR_B	(DEFAULT_SHAPER_IR_B * DIVISOR_CLK)
47b37ce587SYufeng Mo 
483ea7af9eSColin Ian King 	static const u16 tick_array[HCLGE_SHAPER_LVL_CNT] = {
4984844054SSalil 		6 * 256,        /* Prioriy level */
5084844054SSalil 		6 * 32,         /* Prioriy group level */
5184844054SSalil 		6 * 8,          /* Port level */
5284844054SSalil 		6 * 256         /* Qset level */
5384844054SSalil 	};
549b2f3477SWeihang Li 	u8 ir_u_calc = 0;
559b2f3477SWeihang Li 	u8 ir_s_calc = 0;
5684844054SSalil 	u32 ir_calc;
5784844054SSalil 	u32 tick;
5884844054SSalil 
5984844054SSalil 	/* Calc tick */
6004f25edbSYunsheng Lin 	if (shaper_level >= HCLGE_SHAPER_LVL_CNT ||
61d9c7d20dSGuangbin Huang 	    ir > max_tm_rate)
6284844054SSalil 		return -EINVAL;
6384844054SSalil 
6484844054SSalil 	tick = tick_array[shaper_level];
6584844054SSalil 
6684844054SSalil 	/**
6784844054SSalil 	 * Calc the speed if ir_b = 126, ir_u = 0 and ir_s = 0
6884844054SSalil 	 * the formula is changed to:
6984844054SSalil 	 *		126 * 1 * 8
7084844054SSalil 	 * ir_calc = ---------------- * 1000
7184844054SSalil 	 *		tick * 1
7284844054SSalil 	 */
739d2a1ceaSPeng Li 	ir_calc = (DEFAULT_DIVISOR_IR_B + (tick >> 1) - 1) / tick;
7484844054SSalil 
7584844054SSalil 	if (ir_calc == ir) {
769d2a1ceaSPeng Li 		ir_para->ir_b = DEFAULT_SHAPER_IR_B;
77ff7e4d0dSHuazhong Tan 		ir_para->ir_u = 0;
78ff7e4d0dSHuazhong Tan 		ir_para->ir_s = 0;
7984844054SSalil 
8084844054SSalil 		return 0;
8184844054SSalil 	} else if (ir_calc > ir) {
8284844054SSalil 		/* Increasing the denominator to select ir_s value */
831a92497dSYonglong Liu 		while (ir_calc >= ir && ir) {
8484844054SSalil 			ir_s_calc++;
859d2a1ceaSPeng Li 			ir_calc = DEFAULT_DIVISOR_IR_B /
869d2a1ceaSPeng Li 				  (tick * (1 << ir_s_calc));
8784844054SSalil 		}
8884844054SSalil 
89ff7e4d0dSHuazhong Tan 		ir_para->ir_b = (ir * tick * (1 << ir_s_calc) +
90ff7e4d0dSHuazhong Tan 				(DIVISOR_CLK >> 1)) / DIVISOR_CLK;
9184844054SSalil 	} else {
9284844054SSalil 		/* Increasing the numerator to select ir_u value */
9384844054SSalil 		u32 numerator;
9484844054SSalil 
9584844054SSalil 		while (ir_calc < ir) {
9684844054SSalil 			ir_u_calc++;
979d2a1ceaSPeng Li 			numerator = DEFAULT_DIVISOR_IR_B * (1 << ir_u_calc);
9884844054SSalil 			ir_calc = (numerator + (tick >> 1)) / tick;
9984844054SSalil 		}
10084844054SSalil 
10184844054SSalil 		if (ir_calc == ir) {
1029d2a1ceaSPeng Li 			ir_para->ir_b = DEFAULT_SHAPER_IR_B;
10384844054SSalil 		} else {
1041a92497dSYonglong Liu 			u32 denominator = DIVISOR_CLK * (1 << --ir_u_calc);
105ff7e4d0dSHuazhong Tan 			ir_para->ir_b = (ir * tick + (denominator >> 1)) /
106ff7e4d0dSHuazhong Tan 					denominator;
10784844054SSalil 		}
10884844054SSalil 	}
10984844054SSalil 
110ff7e4d0dSHuazhong Tan 	ir_para->ir_u = ir_u_calc;
111ff7e4d0dSHuazhong Tan 	ir_para->ir_s = ir_s_calc;
11284844054SSalil 
11384844054SSalil 	return 0;
11484844054SSalil }
11584844054SSalil 
1160b653a81SJie Wang static const u16 hclge_pfc_tx_stats_offset[] = {
1170b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri0_pkt_num),
1180b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri1_pkt_num),
1190b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri2_pkt_num),
1200b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri3_pkt_num),
1210b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri4_pkt_num),
1220b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri5_pkt_num),
1230b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri6_pkt_num),
1240b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_tx_pfc_pri7_pkt_num)
1250b653a81SJie Wang };
1260b653a81SJie Wang 
1270b653a81SJie Wang static const u16 hclge_pfc_rx_stats_offset[] = {
1280b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri0_pkt_num),
1290b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri1_pkt_num),
1300b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri2_pkt_num),
1310b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri3_pkt_num),
1320b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri4_pkt_num),
1330b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri5_pkt_num),
1340b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri6_pkt_num),
1350b653a81SJie Wang 	HCLGE_MAC_STATS_FIELD_OFF(mac_rx_pfc_pri7_pkt_num)
1360b653a81SJie Wang };
1370b653a81SJie Wang 
hclge_pfc_stats_get(struct hclge_dev * hdev,bool tx,u64 * stats)1380b653a81SJie Wang static void hclge_pfc_stats_get(struct hclge_dev *hdev, bool tx, u64 *stats)
13964fd2300SPeng Li {
1400b653a81SJie Wang 	const u16 *offset;
1410b653a81SJie Wang 	int i;
14264fd2300SPeng Li 
1430b653a81SJie Wang 	if (tx)
1440b653a81SJie Wang 		offset = hclge_pfc_tx_stats_offset;
1450b653a81SJie Wang 	else
1460b653a81SJie Wang 		offset = hclge_pfc_rx_stats_offset;
14764fd2300SPeng Li 
1480b653a81SJie Wang 	for (i = 0; i < HCLGE_MAX_TC_NUM; i++)
1490b653a81SJie Wang 		stats[i] = HCLGE_STATS_READ(&hdev->mac_stats, offset[i]);
15064fd2300SPeng Li }
15164fd2300SPeng Li 
hclge_pfc_rx_stats_get(struct hclge_dev * hdev,u64 * stats)1520b653a81SJie Wang void hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats)
15364fd2300SPeng Li {
1540b653a81SJie Wang 	hclge_pfc_stats_get(hdev, false, stats);
15564fd2300SPeng Li }
15664fd2300SPeng Li 
hclge_pfc_tx_stats_get(struct hclge_dev * hdev,u64 * stats)1570b653a81SJie Wang void hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats)
15864fd2300SPeng Li {
1590b653a81SJie Wang 	hclge_pfc_stats_get(hdev, true, stats);
16064fd2300SPeng Li }
16164fd2300SPeng Li 
hclge_mac_pause_en_cfg(struct hclge_dev * hdev,bool tx,bool rx)16261387774SPeng Li int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)
16384844054SSalil {
16484844054SSalil 	struct hclge_desc desc;
16584844054SSalil 
16684844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PAUSE_EN, false);
16784844054SSalil 
16884844054SSalil 	desc.data[0] = cpu_to_le32((tx ? HCLGE_TX_MAC_PAUSE_EN_MSK : 0) |
16984844054SSalil 		(rx ? HCLGE_RX_MAC_PAUSE_EN_MSK : 0));
17084844054SSalil 
17184844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
17284844054SSalil }
17384844054SSalil 
hclge_pfc_pause_en_cfg(struct hclge_dev * hdev,u8 tx_rx_bitmap,u8 pfc_bitmap)174f14db070SJijie Shao int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
1759dc2145dSYunsheng Lin 			   u8 pfc_bitmap)
1769dc2145dSYunsheng Lin {
1779dc2145dSYunsheng Lin 	struct hclge_desc desc;
178d0d72bacSJian Shen 	struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)desc.data;
1799dc2145dSYunsheng Lin 
1809dc2145dSYunsheng Lin 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PFC_PAUSE_EN, false);
1819dc2145dSYunsheng Lin 
1829dc2145dSYunsheng Lin 	pfc->tx_rx_en_bitmap = tx_rx_bitmap;
1839dc2145dSYunsheng Lin 	pfc->pri_en_bitmap = pfc_bitmap;
1849dc2145dSYunsheng Lin 
1859dc2145dSYunsheng Lin 	return hclge_cmd_send(&hdev->hw, &desc, 1);
1869dc2145dSYunsheng Lin }
1879dc2145dSYunsheng Lin 
hclge_pause_param_cfg(struct hclge_dev * hdev,const u8 * addr,u8 pause_trans_gap,u16 pause_trans_time)188e98d7183SFuyun Liang static int hclge_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr,
18918838d0cSFuyun Liang 				 u8 pause_trans_gap, u16 pause_trans_time)
19018838d0cSFuyun Liang {
19118838d0cSFuyun Liang 	struct hclge_cfg_pause_param_cmd *pause_param;
19218838d0cSFuyun Liang 	struct hclge_desc desc;
19318838d0cSFuyun Liang 
194d0d72bacSJian Shen 	pause_param = (struct hclge_cfg_pause_param_cmd *)desc.data;
19518838d0cSFuyun Liang 
19618838d0cSFuyun Liang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, false);
19718838d0cSFuyun Liang 
19818838d0cSFuyun Liang 	ether_addr_copy(pause_param->mac_addr, addr);
199cd2086bfSFuyun Liang 	ether_addr_copy(pause_param->mac_addr_extra, addr);
20018838d0cSFuyun Liang 	pause_param->pause_trans_gap = pause_trans_gap;
20118838d0cSFuyun Liang 	pause_param->pause_trans_time = cpu_to_le16(pause_trans_time);
20218838d0cSFuyun Liang 
20318838d0cSFuyun Liang 	return hclge_cmd_send(&hdev->hw, &desc, 1);
20418838d0cSFuyun Liang }
20518838d0cSFuyun Liang 
hclge_pause_addr_cfg(struct hclge_dev * hdev,const u8 * mac_addr)206e98d7183SFuyun Liang int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr)
20718838d0cSFuyun Liang {
20818838d0cSFuyun Liang 	struct hclge_cfg_pause_param_cmd *pause_param;
20918838d0cSFuyun Liang 	struct hclge_desc desc;
21018838d0cSFuyun Liang 	u16 trans_time;
21118838d0cSFuyun Liang 	u8 trans_gap;
21218838d0cSFuyun Liang 	int ret;
21318838d0cSFuyun Liang 
214d0d72bacSJian Shen 	pause_param = (struct hclge_cfg_pause_param_cmd *)desc.data;
21518838d0cSFuyun Liang 
21618838d0cSFuyun Liang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, true);
21718838d0cSFuyun Liang 
21818838d0cSFuyun Liang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
21918838d0cSFuyun Liang 	if (ret)
22018838d0cSFuyun Liang 		return ret;
22118838d0cSFuyun Liang 
22218838d0cSFuyun Liang 	trans_gap = pause_param->pause_trans_gap;
22318838d0cSFuyun Liang 	trans_time = le16_to_cpu(pause_param->pause_trans_time);
22418838d0cSFuyun Liang 
2259b2f3477SWeihang Li 	return hclge_pause_param_cfg(hdev, mac_addr, trans_gap, trans_time);
22618838d0cSFuyun Liang }
22718838d0cSFuyun Liang 
hclge_fill_pri_array(struct hclge_dev * hdev,u8 * pri,u8 pri_id)22884844054SSalil static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id)
22984844054SSalil {
23084844054SSalil 	u8 tc;
23184844054SSalil 
232c5795c53SYunsheng Lin 	tc = hdev->tm_info.prio_tc[pri_id];
23384844054SSalil 
23484844054SSalil 	if (tc >= hdev->tm_info.num_tc)
23584844054SSalil 		return -EINVAL;
23684844054SSalil 
23784844054SSalil 	/**
23884844054SSalil 	 * the register for priority has four bytes, the first bytes includes
23984844054SSalil 	 *  priority0 and priority1, the higher 4bit stands for priority1
24084844054SSalil 	 *  while the lower 4bit stands for priority0, as below:
24184844054SSalil 	 * first byte:	| pri_1 | pri_0 |
24284844054SSalil 	 * second byte:	| pri_3 | pri_2 |
24384844054SSalil 	 * third byte:	| pri_5 | pri_4 |
24484844054SSalil 	 * fourth byte:	| pri_7 | pri_6 |
24584844054SSalil 	 */
24684844054SSalil 	pri[pri_id >> 1] |= tc << ((pri_id & 1) * 4);
24784844054SSalil 
24884844054SSalil 	return 0;
24984844054SSalil }
25084844054SSalil 
hclge_up_to_tc_map(struct hclge_dev * hdev)2510ba22bcbSGuangbin Huang int hclge_up_to_tc_map(struct hclge_dev *hdev)
25284844054SSalil {
25384844054SSalil 	struct hclge_desc desc;
25484844054SSalil 	u8 *pri = (u8 *)desc.data;
25584844054SSalil 	u8 pri_id;
25684844054SSalil 	int ret;
25784844054SSalil 
25884844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PRI_TO_TC_MAPPING, false);
25984844054SSalil 
260c5795c53SYunsheng Lin 	for (pri_id = 0; pri_id < HNAE3_MAX_USER_PRIO; pri_id++) {
26184844054SSalil 		ret = hclge_fill_pri_array(hdev, pri, pri_id);
26284844054SSalil 		if (ret)
26384844054SSalil 			return ret;
26484844054SSalil 	}
26584844054SSalil 
26684844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
26784844054SSalil }
26884844054SSalil 
hclge_dscp_to_prio_map_init(struct hclge_dev * hdev)2690ba22bcbSGuangbin Huang static void hclge_dscp_to_prio_map_init(struct hclge_dev *hdev)
2700ba22bcbSGuangbin Huang {
2710ba22bcbSGuangbin Huang 	u8 i;
2720ba22bcbSGuangbin Huang 
2730ba22bcbSGuangbin Huang 	hdev->vport[0].nic.kinfo.tc_map_mode = HNAE3_TC_MAP_MODE_PRIO;
274dfea275eSGuangbin Huang 	hdev->vport[0].nic.kinfo.dscp_app_cnt = 0;
275dfea275eSGuangbin Huang 	for (i = 0; i < HNAE3_MAX_DSCP; i++)
276dfea275eSGuangbin Huang 		hdev->vport[0].nic.kinfo.dscp_prio[i] = HNAE3_PRIO_ID_INVALID;
2770ba22bcbSGuangbin Huang }
2780ba22bcbSGuangbin Huang 
hclge_dscp_to_tc_map(struct hclge_dev * hdev)2790ba22bcbSGuangbin Huang int hclge_dscp_to_tc_map(struct hclge_dev *hdev)
2800ba22bcbSGuangbin Huang {
2810ba22bcbSGuangbin Huang 	struct hclge_desc desc[HCLGE_DSCP_MAP_TC_BD_NUM];
2820ba22bcbSGuangbin Huang 	u8 *req0 = (u8 *)desc[0].data;
2830ba22bcbSGuangbin Huang 	u8 *req1 = (u8 *)desc[1].data;
2840ba22bcbSGuangbin Huang 	u8 pri_id, tc_id, i, j;
2850ba22bcbSGuangbin Huang 
2860ba22bcbSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc[0], HCLGE_OPC_QOS_MAP, false);
2870ba22bcbSGuangbin Huang 	desc[0].flag |= cpu_to_le16(HCLGE_COMM_CMD_FLAG_NEXT);
2880ba22bcbSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc[1], HCLGE_OPC_QOS_MAP, false);
2890ba22bcbSGuangbin Huang 
2900ba22bcbSGuangbin Huang 	/* The low 32 dscp setting use bd0, high 32 dscp setting use bd1 */
291dfea275eSGuangbin Huang 	for (i = 0; i < HNAE3_MAX_DSCP / HCLGE_DSCP_MAP_TC_BD_NUM; i++) {
292dfea275eSGuangbin Huang 		pri_id = hdev->vport[0].nic.kinfo.dscp_prio[i];
293dfea275eSGuangbin Huang 		pri_id = pri_id == HNAE3_PRIO_ID_INVALID ? 0 : pri_id;
2940ba22bcbSGuangbin Huang 		tc_id = hdev->tm_info.prio_tc[pri_id];
2950ba22bcbSGuangbin Huang 		/* Each dscp setting has 4 bits, so each byte saves two dscp
2960ba22bcbSGuangbin Huang 		 * setting
2970ba22bcbSGuangbin Huang 		 */
2980ba22bcbSGuangbin Huang 		req0[i >> 1] |= tc_id << HCLGE_DSCP_TC_SHIFT(i);
2990ba22bcbSGuangbin Huang 
300dfea275eSGuangbin Huang 		j = i + HNAE3_MAX_DSCP / HCLGE_DSCP_MAP_TC_BD_NUM;
301dfea275eSGuangbin Huang 		pri_id = hdev->vport[0].nic.kinfo.dscp_prio[j];
302dfea275eSGuangbin Huang 		pri_id = pri_id == HNAE3_PRIO_ID_INVALID ? 0 : pri_id;
3030ba22bcbSGuangbin Huang 		tc_id = hdev->tm_info.prio_tc[pri_id];
3040ba22bcbSGuangbin Huang 		req1[i >> 1] |= tc_id << HCLGE_DSCP_TC_SHIFT(i);
3050ba22bcbSGuangbin Huang 	}
3060ba22bcbSGuangbin Huang 
3070ba22bcbSGuangbin Huang 	return hclge_cmd_send(&hdev->hw, desc, HCLGE_DSCP_MAP_TC_BD_NUM);
3080ba22bcbSGuangbin Huang }
3090ba22bcbSGuangbin Huang 
hclge_tm_pg_to_pri_map_cfg(struct hclge_dev * hdev,u8 pg_id,u8 pri_bit_map)31084844054SSalil static int hclge_tm_pg_to_pri_map_cfg(struct hclge_dev *hdev,
31184844054SSalil 				      u8 pg_id, u8 pri_bit_map)
31284844054SSalil {
31384844054SSalil 	struct hclge_pg_to_pri_link_cmd *map;
31484844054SSalil 	struct hclge_desc desc;
31584844054SSalil 
31684844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_TO_PRI_LINK, false);
31784844054SSalil 
31884844054SSalil 	map = (struct hclge_pg_to_pri_link_cmd *)desc.data;
31984844054SSalil 
32084844054SSalil 	map->pg_id = pg_id;
32184844054SSalil 	map->pri_bit_map = pri_bit_map;
32284844054SSalil 
32384844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
32484844054SSalil }
32584844054SSalil 
hclge_tm_qs_to_pri_map_cfg(struct hclge_dev * hdev,u16 qs_id,u8 pri,bool link_vld)326e93530aeSGuangbin Huang static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev, u16 qs_id, u8 pri,
327e93530aeSGuangbin Huang 				      bool link_vld)
32884844054SSalil {
32984844054SSalil 	struct hclge_qs_to_pri_link_cmd *map;
33084844054SSalil 	struct hclge_desc desc;
33184844054SSalil 
33284844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_TO_PRI_LINK, false);
33384844054SSalil 
33484844054SSalil 	map = (struct hclge_qs_to_pri_link_cmd *)desc.data;
33584844054SSalil 
33684844054SSalil 	map->qs_id = cpu_to_le16(qs_id);
33784844054SSalil 	map->priority = pri;
338e93530aeSGuangbin Huang 	map->link_vld = link_vld ? HCLGE_TM_QS_PRI_LINK_VLD_MSK : 0;
33984844054SSalil 
34084844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
34184844054SSalil }
34284844054SSalil 
hclge_tm_q_to_qs_map_cfg(struct hclge_dev * hdev,u16 q_id,u16 qs_id)34384844054SSalil static int hclge_tm_q_to_qs_map_cfg(struct hclge_dev *hdev,
34432c7fbc8SJian Shen 				    u16 q_id, u16 qs_id)
34584844054SSalil {
34684844054SSalil 	struct hclge_nq_to_qs_link_cmd *map;
34784844054SSalil 	struct hclge_desc desc;
3489a5ef4aaSYonglong Liu 	u16 qs_id_l;
3499a5ef4aaSYonglong Liu 	u16 qs_id_h;
35084844054SSalil 
35184844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NQ_TO_QS_LINK, false);
35284844054SSalil 
35384844054SSalil 	map = (struct hclge_nq_to_qs_link_cmd *)desc.data;
35484844054SSalil 
35584844054SSalil 	map->nq_id = cpu_to_le16(q_id);
3569a5ef4aaSYonglong Liu 
3579a5ef4aaSYonglong Liu 	/* convert qs_id to the following format to support qset_id >= 1024
3589a5ef4aaSYonglong Liu 	 * qs_id: | 15 | 14 ~ 10 |  9 ~ 0   |
3599a5ef4aaSYonglong Liu 	 *            /         / \         \
3609a5ef4aaSYonglong Liu 	 *           /         /   \         \
3619a5ef4aaSYonglong Liu 	 * qset_id: | 15 ~ 11 |  10 |  9 ~ 0  |
3629a5ef4aaSYonglong Liu 	 *          | qs_id_h | vld | qs_id_l |
3639a5ef4aaSYonglong Liu 	 */
3649a5ef4aaSYonglong Liu 	qs_id_l = hnae3_get_field(qs_id, HCLGE_TM_QS_ID_L_MSK,
3659a5ef4aaSYonglong Liu 				  HCLGE_TM_QS_ID_L_S);
3669a5ef4aaSYonglong Liu 	qs_id_h = hnae3_get_field(qs_id, HCLGE_TM_QS_ID_H_MSK,
3679a5ef4aaSYonglong Liu 				  HCLGE_TM_QS_ID_H_S);
3689a5ef4aaSYonglong Liu 	hnae3_set_field(qs_id, HCLGE_TM_QS_ID_L_MSK, HCLGE_TM_QS_ID_L_S,
3699a5ef4aaSYonglong Liu 			qs_id_l);
3709a5ef4aaSYonglong Liu 	hnae3_set_field(qs_id, HCLGE_TM_QS_ID_H_EXT_MSK, HCLGE_TM_QS_ID_H_EXT_S,
3719a5ef4aaSYonglong Liu 			qs_id_h);
37284844054SSalil 	map->qset_id = cpu_to_le16(qs_id | HCLGE_TM_Q_QS_LINK_VLD_MSK);
37384844054SSalil 
37484844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
37584844054SSalil }
37684844054SSalil 
hclge_tm_pg_weight_cfg(struct hclge_dev * hdev,u8 pg_id,u8 dwrr)37784844054SSalil static int hclge_tm_pg_weight_cfg(struct hclge_dev *hdev, u8 pg_id,
37884844054SSalil 				  u8 dwrr)
37984844054SSalil {
38084844054SSalil 	struct hclge_pg_weight_cmd *weight;
38184844054SSalil 	struct hclge_desc desc;
38284844054SSalil 
38384844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_WEIGHT, false);
38484844054SSalil 
38584844054SSalil 	weight = (struct hclge_pg_weight_cmd *)desc.data;
38684844054SSalil 
38784844054SSalil 	weight->pg_id = pg_id;
38884844054SSalil 	weight->dwrr = dwrr;
38984844054SSalil 
39084844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
39184844054SSalil }
39284844054SSalil 
hclge_tm_pri_weight_cfg(struct hclge_dev * hdev,u8 pri_id,u8 dwrr)39384844054SSalil static int hclge_tm_pri_weight_cfg(struct hclge_dev *hdev, u8 pri_id,
39484844054SSalil 				   u8 dwrr)
39584844054SSalil {
39684844054SSalil 	struct hclge_priority_weight_cmd *weight;
39784844054SSalil 	struct hclge_desc desc;
39884844054SSalil 
39984844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_WEIGHT, false);
40084844054SSalil 
40184844054SSalil 	weight = (struct hclge_priority_weight_cmd *)desc.data;
40284844054SSalil 
40384844054SSalil 	weight->pri_id = pri_id;
40484844054SSalil 	weight->dwrr = dwrr;
40584844054SSalil 
40684844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
40784844054SSalil }
40884844054SSalil 
hclge_tm_qs_weight_cfg(struct hclge_dev * hdev,u16 qs_id,u8 dwrr)40984844054SSalil static int hclge_tm_qs_weight_cfg(struct hclge_dev *hdev, u16 qs_id,
41084844054SSalil 				  u8 dwrr)
41184844054SSalil {
41284844054SSalil 	struct hclge_qs_weight_cmd *weight;
41384844054SSalil 	struct hclge_desc desc;
41484844054SSalil 
41584844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_WEIGHT, false);
41684844054SSalil 
41784844054SSalil 	weight = (struct hclge_qs_weight_cmd *)desc.data;
41884844054SSalil 
41984844054SSalil 	weight->qs_id = cpu_to_le16(qs_id);
42084844054SSalil 	weight->dwrr = dwrr;
42184844054SSalil 
42284844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
42384844054SSalil }
42484844054SSalil 
hclge_tm_get_shapping_para(u8 ir_b,u8 ir_u,u8 ir_s,u8 bs_b,u8 bs_s)42563cbf7a9SYufeng Mo static u32 hclge_tm_get_shapping_para(u8 ir_b, u8 ir_u, u8 ir_s,
42663cbf7a9SYufeng Mo 				      u8 bs_b, u8 bs_s)
42763cbf7a9SYufeng Mo {
42863cbf7a9SYufeng Mo 	u32 shapping_para = 0;
42963cbf7a9SYufeng Mo 
43063cbf7a9SYufeng Mo 	hclge_tm_set_field(shapping_para, IR_B, ir_b);
43163cbf7a9SYufeng Mo 	hclge_tm_set_field(shapping_para, IR_U, ir_u);
43263cbf7a9SYufeng Mo 	hclge_tm_set_field(shapping_para, IR_S, ir_s);
43363cbf7a9SYufeng Mo 	hclge_tm_set_field(shapping_para, BS_B, bs_b);
43463cbf7a9SYufeng Mo 	hclge_tm_set_field(shapping_para, BS_S, bs_s);
43563cbf7a9SYufeng Mo 
43663cbf7a9SYufeng Mo 	return shapping_para;
43763cbf7a9SYufeng Mo }
43863cbf7a9SYufeng Mo 
hclge_tm_pg_shapping_cfg(struct hclge_dev * hdev,enum hclge_shap_bucket bucket,u8 pg_id,u32 shapping_para,u32 rate)43984844054SSalil static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev,
44084844054SSalil 				    enum hclge_shap_bucket bucket, u8 pg_id,
441e364ad30SYonglong Liu 				    u32 shapping_para, u32 rate)
44284844054SSalil {
44384844054SSalil 	struct hclge_pg_shapping_cmd *shap_cfg_cmd;
44484844054SSalil 	enum hclge_opcode_type opcode;
44584844054SSalil 	struct hclge_desc desc;
44684844054SSalil 
44784844054SSalil 	opcode = bucket ? HCLGE_OPC_TM_PG_P_SHAPPING :
44884844054SSalil 		 HCLGE_OPC_TM_PG_C_SHAPPING;
44984844054SSalil 	hclge_cmd_setup_basic_desc(&desc, opcode, false);
45084844054SSalil 
45184844054SSalil 	shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data;
45284844054SSalil 
45384844054SSalil 	shap_cfg_cmd->pg_id = pg_id;
45484844054SSalil 
455a90bb9a5SYunsheng Lin 	shap_cfg_cmd->pg_shapping_para = cpu_to_le32(shapping_para);
45684844054SSalil 
457e364ad30SYonglong Liu 	hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
458e364ad30SYonglong Liu 
459e364ad30SYonglong Liu 	shap_cfg_cmd->pg_rate = cpu_to_le32(rate);
460e364ad30SYonglong Liu 
46184844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
46284844054SSalil }
46384844054SSalil 
hclge_tm_port_shaper_cfg(struct hclge_dev * hdev)46412a36708SGuangbin Huang int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev)
4650a5677d3SYunsheng Lin {
4660a5677d3SYunsheng Lin 	struct hclge_port_shapping_cmd *shap_cfg_cmd;
467ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
4680a5677d3SYunsheng Lin 	struct hclge_desc desc;
469cdd332acSGuojia Liao 	u32 shapping_para;
4700a5677d3SYunsheng Lin 	int ret;
4710a5677d3SYunsheng Lin 
472ff7e4d0dSHuazhong Tan 	ret = hclge_shaper_para_calc(hdev->hw.mac.speed, HCLGE_SHAPER_LVL_PORT,
473ff7e4d0dSHuazhong Tan 				     &ir_para,
474d9c7d20dSGuangbin Huang 				     hdev->ae_dev->dev_specs.max_tm_rate);
4750a5677d3SYunsheng Lin 	if (ret)
4760a5677d3SYunsheng Lin 		return ret;
4770a5677d3SYunsheng Lin 
4780a5677d3SYunsheng Lin 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PORT_SHAPPING, false);
4790a5677d3SYunsheng Lin 	shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data;
4800a5677d3SYunsheng Lin 
481ff7e4d0dSHuazhong Tan 	shapping_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u,
482ff7e4d0dSHuazhong Tan 						   ir_para.ir_s,
48363cbf7a9SYufeng Mo 						   HCLGE_SHAPER_BS_U_DEF,
48463cbf7a9SYufeng Mo 						   HCLGE_SHAPER_BS_S_DEF);
4850a5677d3SYunsheng Lin 
4860a5677d3SYunsheng Lin 	shap_cfg_cmd->port_shapping_para = cpu_to_le32(shapping_para);
4870a5677d3SYunsheng Lin 
488e364ad30SYonglong Liu 	hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
489e364ad30SYonglong Liu 
490e364ad30SYonglong Liu 	shap_cfg_cmd->port_rate = cpu_to_le32(hdev->hw.mac.speed);
491e364ad30SYonglong Liu 
4920a5677d3SYunsheng Lin 	return hclge_cmd_send(&hdev->hw, &desc, 1);
4930a5677d3SYunsheng Lin }
4940a5677d3SYunsheng Lin 
hclge_tm_pri_shapping_cfg(struct hclge_dev * hdev,enum hclge_shap_bucket bucket,u8 pri_id,u32 shapping_para,u32 rate)49584844054SSalil static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev,
49684844054SSalil 				     enum hclge_shap_bucket bucket, u8 pri_id,
497e364ad30SYonglong Liu 				     u32 shapping_para, u32 rate)
49884844054SSalil {
49984844054SSalil 	struct hclge_pri_shapping_cmd *shap_cfg_cmd;
50084844054SSalil 	enum hclge_opcode_type opcode;
50184844054SSalil 	struct hclge_desc desc;
50284844054SSalil 
50384844054SSalil 	opcode = bucket ? HCLGE_OPC_TM_PRI_P_SHAPPING :
50484844054SSalil 		 HCLGE_OPC_TM_PRI_C_SHAPPING;
50584844054SSalil 
50684844054SSalil 	hclge_cmd_setup_basic_desc(&desc, opcode, false);
50784844054SSalil 
50884844054SSalil 	shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data;
50984844054SSalil 
51084844054SSalil 	shap_cfg_cmd->pri_id = pri_id;
51184844054SSalil 
512a90bb9a5SYunsheng Lin 	shap_cfg_cmd->pri_shapping_para = cpu_to_le32(shapping_para);
51384844054SSalil 
514e364ad30SYonglong Liu 	hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
515e364ad30SYonglong Liu 
516e364ad30SYonglong Liu 	shap_cfg_cmd->pri_rate = cpu_to_le32(rate);
517e364ad30SYonglong Liu 
51884844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
51984844054SSalil }
52084844054SSalil 
hclge_tm_pg_schd_mode_cfg(struct hclge_dev * hdev,u8 pg_id)52184844054SSalil static int hclge_tm_pg_schd_mode_cfg(struct hclge_dev *hdev, u8 pg_id)
52284844054SSalil {
52384844054SSalil 	struct hclge_desc desc;
52484844054SSalil 
52584844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_SCH_MODE_CFG, false);
52684844054SSalil 
52784844054SSalil 	if (hdev->tm_info.pg_info[pg_id].pg_sch_mode == HCLGE_SCH_MODE_DWRR)
52884844054SSalil 		desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
52984844054SSalil 	else
53084844054SSalil 		desc.data[1] = 0;
53184844054SSalil 
53284844054SSalil 	desc.data[0] = cpu_to_le32(pg_id);
53384844054SSalil 
53484844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
53584844054SSalil }
53684844054SSalil 
hclge_tm_pri_schd_mode_cfg(struct hclge_dev * hdev,u8 pri_id)53784844054SSalil static int hclge_tm_pri_schd_mode_cfg(struct hclge_dev *hdev, u8 pri_id)
53884844054SSalil {
53984844054SSalil 	struct hclge_desc desc;
54084844054SSalil 
54184844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_SCH_MODE_CFG, false);
54284844054SSalil 
54384844054SSalil 	if (hdev->tm_info.tc_info[pri_id].tc_sch_mode == HCLGE_SCH_MODE_DWRR)
54484844054SSalil 		desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
54584844054SSalil 	else
54684844054SSalil 		desc.data[1] = 0;
54784844054SSalil 
54884844054SSalil 	desc.data[0] = cpu_to_le32(pri_id);
54984844054SSalil 
55084844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
55184844054SSalil }
55284844054SSalil 
hclge_tm_qs_schd_mode_cfg(struct hclge_dev * hdev,u16 qs_id,u8 mode)553cc9bb43aSYunsheng Lin static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id, u8 mode)
55484844054SSalil {
55584844054SSalil 	struct hclge_desc desc;
55684844054SSalil 
55784844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_SCH_MODE_CFG, false);
55884844054SSalil 
559cc9bb43aSYunsheng Lin 	if (mode == HCLGE_SCH_MODE_DWRR)
56084844054SSalil 		desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
56184844054SSalil 	else
56284844054SSalil 		desc.data[1] = 0;
56384844054SSalil 
56484844054SSalil 	desc.data[0] = cpu_to_le32(qs_id);
56584844054SSalil 
56684844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
56784844054SSalil }
56884844054SSalil 
hclge_tm_qs_bp_cfg(struct hclge_dev * hdev,u8 tc,u8 grp_id,u32 bit_map)56967bf2541SYunsheng Lin static int hclge_tm_qs_bp_cfg(struct hclge_dev *hdev, u8 tc, u8 grp_id,
57067bf2541SYunsheng Lin 			      u32 bit_map)
57184844054SSalil {
57284844054SSalil 	struct hclge_bp_to_qs_map_cmd *bp_to_qs_map_cmd;
57384844054SSalil 	struct hclge_desc desc;
57484844054SSalil 
57584844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_BP_TO_QSET_MAPPING,
57684844054SSalil 				   false);
57784844054SSalil 
57884844054SSalil 	bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data;
57984844054SSalil 
58084844054SSalil 	bp_to_qs_map_cmd->tc_id = tc;
58167bf2541SYunsheng Lin 	bp_to_qs_map_cmd->qs_group_id = grp_id;
58267bf2541SYunsheng Lin 	bp_to_qs_map_cmd->qs_bit_map = cpu_to_le32(bit_map);
58384844054SSalil 
58484844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
58584844054SSalil }
58684844054SSalil 
hclge_tm_qs_shaper_cfg(struct hclge_vport * vport,int max_tx_rate)587ee9e4424SYonglong Liu int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate)
588ee9e4424SYonglong Liu {
589ee9e4424SYonglong Liu 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
590ee9e4424SYonglong Liu 	struct hclge_qs_shapping_cmd *shap_cfg_cmd;
591ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
592ee9e4424SYonglong Liu 	struct hclge_dev *hdev = vport->back;
593ee9e4424SYonglong Liu 	struct hclge_desc desc;
594ee9e4424SYonglong Liu 	u32 shaper_para;
595ee9e4424SYonglong Liu 	int ret, i;
596ee9e4424SYonglong Liu 
597ee9e4424SYonglong Liu 	if (!max_tx_rate)
598d9c7d20dSGuangbin Huang 		max_tx_rate = hdev->ae_dev->dev_specs.max_tm_rate;
599ee9e4424SYonglong Liu 
600ee9e4424SYonglong Liu 	ret = hclge_shaper_para_calc(max_tx_rate, HCLGE_SHAPER_LVL_QSET,
601ff7e4d0dSHuazhong Tan 				     &ir_para,
602d9c7d20dSGuangbin Huang 				     hdev->ae_dev->dev_specs.max_tm_rate);
603ee9e4424SYonglong Liu 	if (ret)
604ee9e4424SYonglong Liu 		return ret;
605ee9e4424SYonglong Liu 
606ff7e4d0dSHuazhong Tan 	shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u,
607ff7e4d0dSHuazhong Tan 						 ir_para.ir_s,
608ee9e4424SYonglong Liu 						 HCLGE_SHAPER_BS_U_DEF,
609ee9e4424SYonglong Liu 						 HCLGE_SHAPER_BS_S_DEF);
610ee9e4424SYonglong Liu 
61135244430SJian Shen 	for (i = 0; i < kinfo->tc_info.num_tc; i++) {
612ee9e4424SYonglong Liu 		hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QCN_SHAPPING_CFG,
613ee9e4424SYonglong Liu 					   false);
614ee9e4424SYonglong Liu 
615ee9e4424SYonglong Liu 		shap_cfg_cmd = (struct hclge_qs_shapping_cmd *)desc.data;
616ee9e4424SYonglong Liu 		shap_cfg_cmd->qs_id = cpu_to_le16(vport->qs_offset + i);
617ee9e4424SYonglong Liu 		shap_cfg_cmd->qs_shapping_para = cpu_to_le32(shaper_para);
618ee9e4424SYonglong Liu 
619e364ad30SYonglong Liu 		hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
620e364ad30SYonglong Liu 		shap_cfg_cmd->qs_rate = cpu_to_le32(max_tx_rate);
621e364ad30SYonglong Liu 
622ee9e4424SYonglong Liu 		ret = hclge_cmd_send(&hdev->hw, &desc, 1);
623ee9e4424SYonglong Liu 		if (ret) {
624ee9e4424SYonglong Liu 			dev_err(&hdev->pdev->dev,
625311c0aaaSJiaran Zhang 				"vport%u, qs%u failed to set tx_rate:%d, ret=%d\n",
626ee9e4424SYonglong Liu 				vport->vport_id, shap_cfg_cmd->qs_id,
627ee9e4424SYonglong Liu 				max_tx_rate, ret);
628ee9e4424SYonglong Liu 			return ret;
629ee9e4424SYonglong Liu 		}
630ee9e4424SYonglong Liu 	}
631ee9e4424SYonglong Liu 
632ee9e4424SYonglong Liu 	return 0;
633ee9e4424SYonglong Liu }
634ee9e4424SYonglong Liu 
hclge_vport_get_max_rss_size(struct hclge_vport * vport)6355a5c9091SJian Shen static u16 hclge_vport_get_max_rss_size(struct hclge_vport *vport)
6365a5c9091SJian Shen {
6375a5c9091SJian Shen 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
6385a5c9091SJian Shen 	struct hnae3_tc_info *tc_info = &kinfo->tc_info;
6395a5c9091SJian Shen 	struct hclge_dev *hdev = vport->back;
6405a5c9091SJian Shen 	u16 max_rss_size = 0;
6415a5c9091SJian Shen 	int i;
6425a5c9091SJian Shen 
6435a5c9091SJian Shen 	if (!tc_info->mqprio_active)
6445a5c9091SJian Shen 		return vport->alloc_tqps / tc_info->num_tc;
6455a5c9091SJian Shen 
6465a5c9091SJian Shen 	for (i = 0; i < HNAE3_MAX_TC; i++) {
6475a5c9091SJian Shen 		if (!(hdev->hw_tc_map & BIT(i)) || i >= tc_info->num_tc)
6485a5c9091SJian Shen 			continue;
6495a5c9091SJian Shen 		if (max_rss_size < tc_info->tqp_count[i])
6505a5c9091SJian Shen 			max_rss_size = tc_info->tqp_count[i];
6515a5c9091SJian Shen 	}
6525a5c9091SJian Shen 
6535a5c9091SJian Shen 	return max_rss_size;
6545a5c9091SJian Shen }
6555a5c9091SJian Shen 
hclge_vport_get_tqp_num(struct hclge_vport * vport)6565a5c9091SJian Shen static u16 hclge_vport_get_tqp_num(struct hclge_vport *vport)
6575a5c9091SJian Shen {
6585a5c9091SJian Shen 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
6595a5c9091SJian Shen 	struct hnae3_tc_info *tc_info = &kinfo->tc_info;
6605a5c9091SJian Shen 	struct hclge_dev *hdev = vport->back;
6615a5c9091SJian Shen 	int sum = 0;
6625a5c9091SJian Shen 	int i;
6635a5c9091SJian Shen 
6645a5c9091SJian Shen 	if (!tc_info->mqprio_active)
6655a5c9091SJian Shen 		return kinfo->rss_size * tc_info->num_tc;
6665a5c9091SJian Shen 
6675a5c9091SJian Shen 	for (i = 0; i < HNAE3_MAX_TC; i++) {
6685a5c9091SJian Shen 		if (hdev->hw_tc_map & BIT(i) && i < tc_info->num_tc)
6695a5c9091SJian Shen 			sum += tc_info->tqp_count[i];
6705a5c9091SJian Shen 	}
6715a5c9091SJian Shen 
6725a5c9091SJian Shen 	return sum;
6735a5c9091SJian Shen }
6745a5c9091SJian Shen 
hclge_tm_update_kinfo_rss_size(struct hclge_vport * vport)675b1261897SGuojia Liao static void hclge_tm_update_kinfo_rss_size(struct hclge_vport *vport)
67684844054SSalil {
67784844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
67884844054SSalil 	struct hclge_dev *hdev = vport->back;
679f1c2e66dSGuojia Liao 	u16 vport_max_rss_size;
680672ad0edSHuazhong Tan 	u16 max_rss_size;
68184844054SSalil 
682de67a690SYunsheng Lin 	/* TC configuration is shared by PF/VF in one port, only allow
683de67a690SYunsheng Lin 	 * one tc for VF for simplicity. VF's vport_id is non zero.
684de67a690SYunsheng Lin 	 */
685693e4415SGuoJia Liao 	if (vport->vport_id) {
686e93530aeSGuangbin Huang 		kinfo->tc_info.max_tc = 1;
687693e4415SGuoJia Liao 		kinfo->tc_info.num_tc = 1;
688693e4415SGuoJia Liao 		vport->qs_offset = HNAE3_MAX_TC +
689693e4415SGuoJia Liao 				   vport->vport_id - HCLGE_VF_VPORT_START_NUM;
690693e4415SGuoJia Liao 		vport_max_rss_size = hdev->vf_rss_size_max;
691693e4415SGuoJia Liao 	} else {
692e93530aeSGuangbin Huang 		kinfo->tc_info.max_tc = hdev->tc_max;
693693e4415SGuoJia Liao 		kinfo->tc_info.num_tc =
694de67a690SYunsheng Lin 			min_t(u16, vport->alloc_tqps, hdev->tm_info.num_tc);
695693e4415SGuoJia Liao 		vport->qs_offset = 0;
696693e4415SGuoJia Liao 		vport_max_rss_size = hdev->pf_rss_size_max;
697693e4415SGuoJia Liao 	}
698de67a690SYunsheng Lin 
699f1c2e66dSGuojia Liao 	max_rss_size = min_t(u16, vport_max_rss_size,
7005a5c9091SJian Shen 			     hclge_vport_get_max_rss_size(vport));
701672ad0edSHuazhong Tan 
7029b2f3477SWeihang Li 	/* Set to user value, no larger than max_rss_size. */
703672ad0edSHuazhong Tan 	if (kinfo->req_rss_size != kinfo->rss_size && kinfo->req_rss_size &&
704672ad0edSHuazhong Tan 	    kinfo->req_rss_size <= max_rss_size) {
705adcf738bSGuojia Liao 		dev_info(&hdev->pdev->dev, "rss changes from %u to %u\n",
706672ad0edSHuazhong Tan 			 kinfo->rss_size, kinfo->req_rss_size);
707672ad0edSHuazhong Tan 		kinfo->rss_size = kinfo->req_rss_size;
708672ad0edSHuazhong Tan 	} else if (kinfo->rss_size > max_rss_size ||
709672ad0edSHuazhong Tan 		   (!kinfo->req_rss_size && kinfo->rss_size < max_rss_size)) {
7109b2f3477SWeihang Li 		/* Set to the maximum specification value (max_rss_size). */
711672ad0edSHuazhong Tan 		kinfo->rss_size = max_rss_size;
712672ad0edSHuazhong Tan 	}
713b1261897SGuojia Liao }
714672ad0edSHuazhong Tan 
hclge_tm_vport_tc_info_update(struct hclge_vport * vport)715b1261897SGuojia Liao static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport)
716b1261897SGuojia Liao {
717b1261897SGuojia Liao 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
718b1261897SGuojia Liao 	struct hclge_dev *hdev = vport->back;
719b1261897SGuojia Liao 	u8 i;
720b1261897SGuojia Liao 
721b1261897SGuojia Liao 	hclge_tm_update_kinfo_rss_size(vport);
7225a5c9091SJian Shen 	kinfo->num_tqps = hclge_vport_get_tqp_num(vport);
72384844054SSalil 	vport->dwrr = 100;  /* 100 percent as init */
724de67a690SYunsheng Lin 	vport->bw_limit = hdev->tm_info.pg_info[0].bw_limit;
72571b215f3SJie Wang 
72671b215f3SJie Wang 	if (vport->vport_id == PF_VPORT_ID)
7277347255eSJie Wang 		hdev->rss_cfg.rss_size = kinfo->rss_size;
72884844054SSalil 
7295a5c9091SJian Shen 	/* when enable mqprio, the tc_info has been updated. */
7305a5c9091SJian Shen 	if (kinfo->tc_info.mqprio_active)
7315a5c9091SJian Shen 		return;
7325a5c9091SJian Shen 
733af958827SHuazhong Tan 	for (i = 0; i < HNAE3_MAX_TC; i++) {
73435244430SJian Shen 		if (hdev->hw_tc_map & BIT(i) && i < kinfo->tc_info.num_tc) {
73535244430SJian Shen 			kinfo->tc_info.tqp_offset[i] = i * kinfo->rss_size;
73635244430SJian Shen 			kinfo->tc_info.tqp_count[i] = kinfo->rss_size;
73784844054SSalil 		} else {
73884844054SSalil 			/* Set to default queue if TC is disable */
73935244430SJian Shen 			kinfo->tc_info.tqp_offset[i] = 0;
74035244430SJian Shen 			kinfo->tc_info.tqp_count[i] = 1;
74184844054SSalil 		}
74284844054SSalil 	}
743c5795c53SYunsheng Lin 
74435244430SJian Shen 	memcpy(kinfo->tc_info.prio_tc, hdev->tm_info.prio_tc,
74535244430SJian Shen 	       sizeof_field(struct hnae3_tc_info, prio_tc));
74684844054SSalil }
74784844054SSalil 
hclge_tm_vport_info_update(struct hclge_dev * hdev)74884844054SSalil static void hclge_tm_vport_info_update(struct hclge_dev *hdev)
74984844054SSalil {
75084844054SSalil 	struct hclge_vport *vport = hdev->vport;
75184844054SSalil 	u32 i;
75284844054SSalil 
75384844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
75484844054SSalil 		hclge_tm_vport_tc_info_update(vport);
75584844054SSalil 
75684844054SSalil 		vport++;
75784844054SSalil 	}
75884844054SSalil }
75984844054SSalil 
hclge_tm_tc_info_init(struct hclge_dev * hdev)76084844054SSalil static void hclge_tm_tc_info_init(struct hclge_dev *hdev)
76184844054SSalil {
762e93530aeSGuangbin Huang 	u8 i, tc_sch_mode;
763e93530aeSGuangbin Huang 	u32 bw_limit;
76484844054SSalil 
765e93530aeSGuangbin Huang 	for (i = 0; i < hdev->tc_max; i++) {
766e93530aeSGuangbin Huang 		if (i < hdev->tm_info.num_tc) {
767e93530aeSGuangbin Huang 			tc_sch_mode = HCLGE_SCH_MODE_DWRR;
768e93530aeSGuangbin Huang 			bw_limit = hdev->tm_info.pg_info[0].bw_limit;
769e93530aeSGuangbin Huang 		} else {
770e93530aeSGuangbin Huang 			tc_sch_mode = HCLGE_SCH_MODE_SP;
771e93530aeSGuangbin Huang 			bw_limit = 0;
772e93530aeSGuangbin Huang 		}
773e93530aeSGuangbin Huang 
77484844054SSalil 		hdev->tm_info.tc_info[i].tc_id = i;
775e93530aeSGuangbin Huang 		hdev->tm_info.tc_info[i].tc_sch_mode = tc_sch_mode;
77684844054SSalil 		hdev->tm_info.tc_info[i].pgid = 0;
777e93530aeSGuangbin Huang 		hdev->tm_info.tc_info[i].bw_limit = bw_limit;
77884844054SSalil 	}
77984844054SSalil 
780c5795c53SYunsheng Lin 	for (i = 0; i < HNAE3_MAX_USER_PRIO; i++)
781c5795c53SYunsheng Lin 		hdev->tm_info.prio_tc[i] =
782c5795c53SYunsheng Lin 			(i >= hdev->tm_info.num_tc) ? 0 : i;
78384844054SSalil }
78484844054SSalil 
hclge_tm_pg_info_init(struct hclge_dev * hdev)78584844054SSalil static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
78684844054SSalil {
787b37ce587SYufeng Mo #define BW_PERCENT	100
788882481b1SJijie Shao #define DEFAULT_BW_WEIGHT	1
789b37ce587SYufeng Mo 
79084844054SSalil 	u8 i;
79184844054SSalil 
79284844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
79384844054SSalil 		int k;
79484844054SSalil 
795b37ce587SYufeng Mo 		hdev->tm_info.pg_dwrr[i] = i ? 0 : BW_PERCENT;
79684844054SSalil 
79784844054SSalil 		hdev->tm_info.pg_info[i].pg_id = i;
79884844054SSalil 		hdev->tm_info.pg_info[i].pg_sch_mode = HCLGE_SCH_MODE_DWRR;
79984844054SSalil 
800d9c7d20dSGuangbin Huang 		hdev->tm_info.pg_info[i].bw_limit =
801d9c7d20dSGuangbin Huang 					hdev->ae_dev->dev_specs.max_tm_rate;
80284844054SSalil 
80384844054SSalil 		if (i != 0)
80484844054SSalil 			continue;
80584844054SSalil 
80684844054SSalil 		hdev->tm_info.pg_info[i].tc_bit_map = hdev->hw_tc_map;
80784844054SSalil 		for (k = 0; k < hdev->tm_info.num_tc; k++)
808b37ce587SYufeng Mo 			hdev->tm_info.pg_info[i].tc_dwrr[k] = BW_PERCENT;
809b63fcaabSGuangbin Huang 		for (; k < HNAE3_MAX_TC; k++)
810882481b1SJijie Shao 			hdev->tm_info.pg_info[i].tc_dwrr[k] = DEFAULT_BW_WEIGHT;
81184844054SSalil 	}
81284844054SSalil }
81384844054SSalil 
hclge_update_fc_mode_by_dcb_flag(struct hclge_dev * hdev)814d78e5b6aSYonglong Liu static void hclge_update_fc_mode_by_dcb_flag(struct hclge_dev *hdev)
8157979a223SYunsheng Lin {
8160472e95fSJian Shen 	if (hdev->tm_info.num_tc == 1 && !hdev->tm_info.pfc_en) {
8177979a223SYunsheng Lin 		if (hdev->fc_mode_last_time == HCLGE_FC_PFC)
8187979a223SYunsheng Lin 			dev_warn(&hdev->pdev->dev,
8190472e95fSJian Shen 				 "Only 1 tc used, but last mode is FC_PFC\n");
8207979a223SYunsheng Lin 
8217979a223SYunsheng Lin 		hdev->tm_info.fc_mode = hdev->fc_mode_last_time;
8227979a223SYunsheng Lin 	} else if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) {
8237979a223SYunsheng Lin 		/* fc_mode_last_time record the last fc_mode when
8247979a223SYunsheng Lin 		 * DCB is enabled, so that fc_mode can be set to
8257979a223SYunsheng Lin 		 * the correct value when DCB is disabled.
8267979a223SYunsheng Lin 		 */
8277979a223SYunsheng Lin 		hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
8287979a223SYunsheng Lin 		hdev->tm_info.fc_mode = HCLGE_FC_PFC;
8297979a223SYunsheng Lin 	}
8307979a223SYunsheng Lin }
8317979a223SYunsheng Lin 
hclge_update_fc_mode(struct hclge_dev * hdev)832d78e5b6aSYonglong Liu static void hclge_update_fc_mode(struct hclge_dev *hdev)
833d78e5b6aSYonglong Liu {
834d78e5b6aSYonglong Liu 	if (!hdev->tm_info.pfc_en) {
835d78e5b6aSYonglong Liu 		hdev->tm_info.fc_mode = hdev->fc_mode_last_time;
836d78e5b6aSYonglong Liu 		return;
837d78e5b6aSYonglong Liu 	}
838d78e5b6aSYonglong Liu 
839d78e5b6aSYonglong Liu 	if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) {
840d78e5b6aSYonglong Liu 		hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
841d78e5b6aSYonglong Liu 		hdev->tm_info.fc_mode = HCLGE_FC_PFC;
842d78e5b6aSYonglong Liu 	}
843d78e5b6aSYonglong Liu }
844d78e5b6aSYonglong Liu 
hclge_tm_pfc_info_update(struct hclge_dev * hdev)8450472e95fSJian Shen void hclge_tm_pfc_info_update(struct hclge_dev *hdev)
846d78e5b6aSYonglong Liu {
847d78e5b6aSYonglong Liu 	if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
848d78e5b6aSYonglong Liu 		hclge_update_fc_mode(hdev);
849d78e5b6aSYonglong Liu 	else
850d78e5b6aSYonglong Liu 		hclge_update_fc_mode_by_dcb_flag(hdev);
851d78e5b6aSYonglong Liu }
852d78e5b6aSYonglong Liu 
hclge_tm_schd_info_init(struct hclge_dev * hdev)853b6872fd3SYunsheng Lin static void hclge_tm_schd_info_init(struct hclge_dev *hdev)
85484844054SSalil {
85584844054SSalil 	hclge_tm_pg_info_init(hdev);
85684844054SSalil 
85784844054SSalil 	hclge_tm_tc_info_init(hdev);
85884844054SSalil 
85984844054SSalil 	hclge_tm_vport_info_update(hdev);
86084844054SSalil 
8610472e95fSJian Shen 	hclge_tm_pfc_info_update(hdev);
86284844054SSalil }
86384844054SSalil 
hclge_tm_pg_to_pri_map(struct hclge_dev * hdev)86484844054SSalil static int hclge_tm_pg_to_pri_map(struct hclge_dev *hdev)
86584844054SSalil {
86684844054SSalil 	int ret;
86784844054SSalil 	u32 i;
86884844054SSalil 
86984844054SSalil 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE)
87084844054SSalil 		return 0;
87184844054SSalil 
87284844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
87384844054SSalil 		/* Cfg mapping */
87484844054SSalil 		ret = hclge_tm_pg_to_pri_map_cfg(
87584844054SSalil 			hdev, i, hdev->tm_info.pg_info[i].tc_bit_map);
87684844054SSalil 		if (ret)
87784844054SSalil 			return ret;
87884844054SSalil 	}
87984844054SSalil 
88084844054SSalil 	return 0;
88184844054SSalil }
88284844054SSalil 
hclge_tm_pg_shaper_cfg(struct hclge_dev * hdev)88384844054SSalil static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev)
88484844054SSalil {
885d9c7d20dSGuangbin Huang 	u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate;
886ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
88763cbf7a9SYufeng Mo 	u32 shaper_para;
88884844054SSalil 	int ret;
88984844054SSalil 	u32 i;
89084844054SSalil 
89184844054SSalil 	/* Cfg pg schd */
89284844054SSalil 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE)
89384844054SSalil 		return 0;
89484844054SSalil 
89584844054SSalil 	/* Pg to pri */
89684844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
897e364ad30SYonglong Liu 		u32 rate = hdev->tm_info.pg_info[i].bw_limit;
898e364ad30SYonglong Liu 
89984844054SSalil 		/* Calc shaper para */
900e364ad30SYonglong Liu 		ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PG,
901ff7e4d0dSHuazhong Tan 					     &ir_para, max_tm_rate);
90284844054SSalil 		if (ret)
90384844054SSalil 			return ret;
90484844054SSalil 
90563cbf7a9SYufeng Mo 		shaper_para = hclge_tm_get_shapping_para(0, 0, 0,
90663cbf7a9SYufeng Mo 							 HCLGE_SHAPER_BS_U_DEF,
90763cbf7a9SYufeng Mo 							 HCLGE_SHAPER_BS_S_DEF);
90884844054SSalil 		ret = hclge_tm_pg_shapping_cfg(hdev,
90984844054SSalil 					       HCLGE_TM_SHAP_C_BUCKET, i,
910e364ad30SYonglong Liu 					       shaper_para, rate);
91184844054SSalil 		if (ret)
91284844054SSalil 			return ret;
91384844054SSalil 
914ff7e4d0dSHuazhong Tan 		shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b,
915ff7e4d0dSHuazhong Tan 							 ir_para.ir_u,
916ff7e4d0dSHuazhong Tan 							 ir_para.ir_s,
91784844054SSalil 							 HCLGE_SHAPER_BS_U_DEF,
91884844054SSalil 							 HCLGE_SHAPER_BS_S_DEF);
91963cbf7a9SYufeng Mo 		ret = hclge_tm_pg_shapping_cfg(hdev,
92063cbf7a9SYufeng Mo 					       HCLGE_TM_SHAP_P_BUCKET, i,
921e364ad30SYonglong Liu 					       shaper_para, rate);
92284844054SSalil 		if (ret)
92384844054SSalil 			return ret;
92484844054SSalil 	}
92584844054SSalil 
92684844054SSalil 	return 0;
92784844054SSalil }
92884844054SSalil 
hclge_tm_pg_dwrr_cfg(struct hclge_dev * hdev)92984844054SSalil static int hclge_tm_pg_dwrr_cfg(struct hclge_dev *hdev)
93084844054SSalil {
93184844054SSalil 	int ret;
93284844054SSalil 	u32 i;
93384844054SSalil 
93484844054SSalil 	/* cfg pg schd */
93584844054SSalil 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE)
93684844054SSalil 		return 0;
93784844054SSalil 
93884844054SSalil 	/* pg to prio */
93984844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
94084844054SSalil 		/* Cfg dwrr */
9419b2f3477SWeihang Li 		ret = hclge_tm_pg_weight_cfg(hdev, i, hdev->tm_info.pg_dwrr[i]);
94284844054SSalil 		if (ret)
94384844054SSalil 			return ret;
94484844054SSalil 	}
94584844054SSalil 
94684844054SSalil 	return 0;
94784844054SSalil }
94884844054SSalil 
hclge_vport_q_to_qs_map(struct hclge_dev * hdev,struct hclge_vport * vport)94984844054SSalil static int hclge_vport_q_to_qs_map(struct hclge_dev *hdev,
95084844054SSalil 				   struct hclge_vport *vport)
95184844054SSalil {
95284844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
95335244430SJian Shen 	struct hnae3_tc_info *tc_info = &kinfo->tc_info;
95484844054SSalil 	struct hnae3_queue **tqp = kinfo->tqp;
95584844054SSalil 	u32 i, j;
95684844054SSalil 	int ret;
95784844054SSalil 
95835244430SJian Shen 	for (i = 0; i < tc_info->num_tc; i++) {
95935244430SJian Shen 		for (j = 0; j < tc_info->tqp_count[i]; j++) {
96035244430SJian Shen 			struct hnae3_queue *q = tqp[tc_info->tqp_offset[i] + j];
96184844054SSalil 
96284844054SSalil 			ret = hclge_tm_q_to_qs_map_cfg(hdev,
96384844054SSalil 						       hclge_get_queue_id(q),
96484844054SSalil 						       vport->qs_offset + i);
96584844054SSalil 			if (ret)
96684844054SSalil 				return ret;
96784844054SSalil 		}
96884844054SSalil 	}
96984844054SSalil 
97084844054SSalil 	return 0;
97184844054SSalil }
97284844054SSalil 
hclge_tm_pri_q_qs_cfg_tc_base(struct hclge_dev * hdev)973e06dac52SGuangbin Huang static int hclge_tm_pri_q_qs_cfg_tc_base(struct hclge_dev *hdev)
974e06dac52SGuangbin Huang {
975e06dac52SGuangbin Huang 	struct hclge_vport *vport = hdev->vport;
976e06dac52SGuangbin Huang 	u16 i, k;
977e06dac52SGuangbin Huang 	int ret;
978e06dac52SGuangbin Huang 
979e06dac52SGuangbin Huang 	/* Cfg qs -> pri mapping, one by one mapping */
980e06dac52SGuangbin Huang 	for (k = 0; k < hdev->num_alloc_vport; k++) {
981e06dac52SGuangbin Huang 		struct hnae3_knic_private_info *kinfo = &vport[k].nic.kinfo;
982e06dac52SGuangbin Huang 
983e93530aeSGuangbin Huang 		for (i = 0; i < kinfo->tc_info.max_tc; i++) {
984e93530aeSGuangbin Huang 			u8 pri = i < kinfo->tc_info.num_tc ? i : 0;
985e93530aeSGuangbin Huang 			bool link_vld = i < kinfo->tc_info.num_tc;
986e93530aeSGuangbin Huang 
987e06dac52SGuangbin Huang 			ret = hclge_tm_qs_to_pri_map_cfg(hdev,
988e06dac52SGuangbin Huang 							 vport[k].qs_offset + i,
989e93530aeSGuangbin Huang 							 pri, link_vld);
990e06dac52SGuangbin Huang 			if (ret)
991e06dac52SGuangbin Huang 				return ret;
992e06dac52SGuangbin Huang 		}
993e06dac52SGuangbin Huang 	}
994e06dac52SGuangbin Huang 
995e06dac52SGuangbin Huang 	return 0;
996e06dac52SGuangbin Huang }
997e06dac52SGuangbin Huang 
hclge_tm_pri_q_qs_cfg_vnet_base(struct hclge_dev * hdev)998e06dac52SGuangbin Huang static int hclge_tm_pri_q_qs_cfg_vnet_base(struct hclge_dev *hdev)
999e06dac52SGuangbin Huang {
1000e06dac52SGuangbin Huang 	struct hclge_vport *vport = hdev->vport;
1001e06dac52SGuangbin Huang 	u16 i, k;
1002e06dac52SGuangbin Huang 	int ret;
1003e06dac52SGuangbin Huang 
1004e06dac52SGuangbin Huang 	/* Cfg qs -> pri mapping,  qs = tc, pri = vf, 8 qs -> 1 pri */
1005e06dac52SGuangbin Huang 	for (k = 0; k < hdev->num_alloc_vport; k++)
1006e06dac52SGuangbin Huang 		for (i = 0; i < HNAE3_MAX_TC; i++) {
1007e06dac52SGuangbin Huang 			ret = hclge_tm_qs_to_pri_map_cfg(hdev,
1008e06dac52SGuangbin Huang 							 vport[k].qs_offset + i,
1009e93530aeSGuangbin Huang 							 k, true);
1010e06dac52SGuangbin Huang 			if (ret)
1011e06dac52SGuangbin Huang 				return ret;
1012e06dac52SGuangbin Huang 		}
1013e06dac52SGuangbin Huang 
1014e06dac52SGuangbin Huang 	return 0;
1015e06dac52SGuangbin Huang }
1016e06dac52SGuangbin Huang 
hclge_tm_pri_q_qs_cfg(struct hclge_dev * hdev)101784844054SSalil static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev)
101884844054SSalil {
101984844054SSalil 	struct hclge_vport *vport = hdev->vport;
102084844054SSalil 	int ret;
1021e06dac52SGuangbin Huang 	u32 i;
102284844054SSalil 
1023e06dac52SGuangbin Huang 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE)
1024e06dac52SGuangbin Huang 		ret = hclge_tm_pri_q_qs_cfg_tc_base(hdev);
1025e06dac52SGuangbin Huang 	else if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE)
1026e06dac52SGuangbin Huang 		ret = hclge_tm_pri_q_qs_cfg_vnet_base(hdev);
1027e06dac52SGuangbin Huang 	else
102884844054SSalil 		return -EINVAL;
1029e06dac52SGuangbin Huang 
1030e06dac52SGuangbin Huang 	if (ret)
1031e06dac52SGuangbin Huang 		return ret;
103284844054SSalil 
103384844054SSalil 	/* Cfg q -> qs mapping */
103484844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
103584844054SSalil 		ret = hclge_vport_q_to_qs_map(hdev, vport);
103684844054SSalil 		if (ret)
103784844054SSalil 			return ret;
103884844054SSalil 
103984844054SSalil 		vport++;
104084844054SSalil 	}
104184844054SSalil 
104284844054SSalil 	return 0;
104384844054SSalil }
104484844054SSalil 
hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev * hdev)104584844054SSalil static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev)
104684844054SSalil {
1047d9c7d20dSGuangbin Huang 	u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate;
1048ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
1049e93530aeSGuangbin Huang 	u32 shaper_para_c, shaper_para_p;
105084844054SSalil 	int ret;
105184844054SSalil 	u32 i;
105284844054SSalil 
1053e93530aeSGuangbin Huang 	for (i = 0; i < hdev->tc_max; i++) {
1054e364ad30SYonglong Liu 		u32 rate = hdev->tm_info.tc_info[i].bw_limit;
1055e364ad30SYonglong Liu 
1056e93530aeSGuangbin Huang 		if (rate) {
1057e364ad30SYonglong Liu 			ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PRI,
1058ff7e4d0dSHuazhong Tan 						     &ir_para, max_tm_rate);
105984844054SSalil 			if (ret)
106084844054SSalil 				return ret;
106184844054SSalil 
1062e93530aeSGuangbin Huang 			shaper_para_c = hclge_tm_get_shapping_para(0, 0, 0,
106363cbf7a9SYufeng Mo 								   HCLGE_SHAPER_BS_U_DEF,
106484844054SSalil 								   HCLGE_SHAPER_BS_S_DEF);
1065e93530aeSGuangbin Huang 			shaper_para_p = hclge_tm_get_shapping_para(ir_para.ir_b,
1066ff7e4d0dSHuazhong Tan 								   ir_para.ir_u,
1067ff7e4d0dSHuazhong Tan 								   ir_para.ir_s,
106863cbf7a9SYufeng Mo 								   HCLGE_SHAPER_BS_U_DEF,
106984844054SSalil 								   HCLGE_SHAPER_BS_S_DEF);
1070e93530aeSGuangbin Huang 		} else {
1071e93530aeSGuangbin Huang 			shaper_para_c = 0;
1072e93530aeSGuangbin Huang 			shaper_para_p = 0;
1073e93530aeSGuangbin Huang 		}
1074e93530aeSGuangbin Huang 
1075e93530aeSGuangbin Huang 		ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, i,
1076e93530aeSGuangbin Huang 						shaper_para_c, rate);
1077e93530aeSGuangbin Huang 		if (ret)
1078e93530aeSGuangbin Huang 			return ret;
1079e93530aeSGuangbin Huang 
108063cbf7a9SYufeng Mo 		ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, i,
1081e93530aeSGuangbin Huang 						shaper_para_p, rate);
108284844054SSalil 		if (ret)
108384844054SSalil 			return ret;
108484844054SSalil 	}
108584844054SSalil 
108684844054SSalil 	return 0;
108784844054SSalil }
108884844054SSalil 
hclge_tm_pri_vnet_base_shaper_pri_cfg(struct hclge_vport * vport)108984844054SSalil static int hclge_tm_pri_vnet_base_shaper_pri_cfg(struct hclge_vport *vport)
109084844054SSalil {
109184844054SSalil 	struct hclge_dev *hdev = vport->back;
1092ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
109363cbf7a9SYufeng Mo 	u32 shaper_para;
109484844054SSalil 	int ret;
109584844054SSalil 
109684844054SSalil 	ret = hclge_shaper_para_calc(vport->bw_limit, HCLGE_SHAPER_LVL_VF,
1097ff7e4d0dSHuazhong Tan 				     &ir_para,
1098d9c7d20dSGuangbin Huang 				     hdev->ae_dev->dev_specs.max_tm_rate);
109984844054SSalil 	if (ret)
110084844054SSalil 		return ret;
110184844054SSalil 
110263cbf7a9SYufeng Mo 	shaper_para = hclge_tm_get_shapping_para(0, 0, 0,
110363cbf7a9SYufeng Mo 						 HCLGE_SHAPER_BS_U_DEF,
110484844054SSalil 						 HCLGE_SHAPER_BS_S_DEF);
110563cbf7a9SYufeng Mo 	ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET,
1106e364ad30SYonglong Liu 					vport->vport_id, shaper_para,
1107e364ad30SYonglong Liu 					vport->bw_limit);
110884844054SSalil 	if (ret)
110984844054SSalil 		return ret;
111084844054SSalil 
1111ff7e4d0dSHuazhong Tan 	shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u,
1112ff7e4d0dSHuazhong Tan 						 ir_para.ir_s,
111384844054SSalil 						 HCLGE_SHAPER_BS_U_DEF,
111484844054SSalil 						 HCLGE_SHAPER_BS_S_DEF);
111563cbf7a9SYufeng Mo 	ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET,
1116e364ad30SYonglong Liu 					vport->vport_id, shaper_para,
1117e364ad30SYonglong Liu 					vport->bw_limit);
111884844054SSalil 	if (ret)
111984844054SSalil 		return ret;
112084844054SSalil 
112184844054SSalil 	return 0;
112284844054SSalil }
112384844054SSalil 
hclge_tm_pri_vnet_base_shaper_qs_cfg(struct hclge_vport * vport)112484844054SSalil static int hclge_tm_pri_vnet_base_shaper_qs_cfg(struct hclge_vport *vport)
112584844054SSalil {
112684844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
112784844054SSalil 	struct hclge_dev *hdev = vport->back;
1128d9c7d20dSGuangbin Huang 	u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate;
1129ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
113084844054SSalil 	u32 i;
113184844054SSalil 	int ret;
113284844054SSalil 
113335244430SJian Shen 	for (i = 0; i < kinfo->tc_info.num_tc; i++) {
1134ff7e4d0dSHuazhong Tan 		ret = hclge_shaper_para_calc(hdev->tm_info.tc_info[i].bw_limit,
113584844054SSalil 					     HCLGE_SHAPER_LVL_QSET,
1136ff7e4d0dSHuazhong Tan 					     &ir_para, max_tm_rate);
113784844054SSalil 		if (ret)
113884844054SSalil 			return ret;
113984844054SSalil 	}
114084844054SSalil 
114184844054SSalil 	return 0;
114284844054SSalil }
114384844054SSalil 
hclge_tm_pri_vnet_base_shaper_cfg(struct hclge_dev * hdev)114484844054SSalil static int hclge_tm_pri_vnet_base_shaper_cfg(struct hclge_dev *hdev)
114584844054SSalil {
114684844054SSalil 	struct hclge_vport *vport = hdev->vport;
114784844054SSalil 	int ret;
114884844054SSalil 	u32 i;
114984844054SSalil 
115084844054SSalil 	/* Need config vport shaper */
115184844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
115284844054SSalil 		ret = hclge_tm_pri_vnet_base_shaper_pri_cfg(vport);
115384844054SSalil 		if (ret)
115484844054SSalil 			return ret;
115584844054SSalil 
115684844054SSalil 		ret = hclge_tm_pri_vnet_base_shaper_qs_cfg(vport);
115784844054SSalil 		if (ret)
115884844054SSalil 			return ret;
115984844054SSalil 
116084844054SSalil 		vport++;
116184844054SSalil 	}
116284844054SSalil 
116384844054SSalil 	return 0;
116484844054SSalil }
116584844054SSalil 
hclge_tm_pri_shaper_cfg(struct hclge_dev * hdev)116684844054SSalil static int hclge_tm_pri_shaper_cfg(struct hclge_dev *hdev)
116784844054SSalil {
116884844054SSalil 	int ret;
116984844054SSalil 
117084844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
117184844054SSalil 		ret = hclge_tm_pri_tc_base_shaper_cfg(hdev);
117284844054SSalil 		if (ret)
117384844054SSalil 			return ret;
117484844054SSalil 	} else {
117584844054SSalil 		ret = hclge_tm_pri_vnet_base_shaper_cfg(hdev);
117684844054SSalil 		if (ret)
117784844054SSalil 			return ret;
117884844054SSalil 	}
117984844054SSalil 
118084844054SSalil 	return 0;
118184844054SSalil }
118284844054SSalil 
hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev * hdev)118384844054SSalil static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev)
118484844054SSalil {
1185cc9bb43aSYunsheng Lin 	struct hclge_vport *vport = hdev->vport;
118684844054SSalil 	struct hclge_pg_info *pg_info;
118784844054SSalil 	u8 dwrr;
118884844054SSalil 	int ret;
1189cc9bb43aSYunsheng Lin 	u32 i, k;
119084844054SSalil 
1191e93530aeSGuangbin Huang 	for (i = 0; i < hdev->tc_max; i++) {
119284844054SSalil 		pg_info =
119384844054SSalil 			&hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid];
119484844054SSalil 		dwrr = pg_info->tc_dwrr[i];
119584844054SSalil 
119684844054SSalil 		ret = hclge_tm_pri_weight_cfg(hdev, i, dwrr);
119784844054SSalil 		if (ret)
119884844054SSalil 			return ret;
119984844054SSalil 
1200cc9bb43aSYunsheng Lin 		for (k = 0; k < hdev->num_alloc_vport; k++) {
1201e93530aeSGuangbin Huang 			struct hnae3_knic_private_info *kinfo = &vport[k].nic.kinfo;
1202e93530aeSGuangbin Huang 
1203e93530aeSGuangbin Huang 			if (i >= kinfo->tc_info.max_tc)
1204e93530aeSGuangbin Huang 				continue;
1205e93530aeSGuangbin Huang 
1206e93530aeSGuangbin Huang 			dwrr = i < kinfo->tc_info.num_tc ? vport[k].dwrr : 0;
1207cc9bb43aSYunsheng Lin 			ret = hclge_tm_qs_weight_cfg(
1208cc9bb43aSYunsheng Lin 				hdev, vport[k].qs_offset + i,
1209e93530aeSGuangbin Huang 				dwrr);
121084844054SSalil 			if (ret)
121184844054SSalil 				return ret;
121284844054SSalil 		}
1213cc9bb43aSYunsheng Lin 	}
121484844054SSalil 
121584844054SSalil 	return 0;
121684844054SSalil }
121784844054SSalil 
hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev * hdev)1218330baff5SYunsheng Lin static int hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev *hdev)
1219330baff5SYunsheng Lin {
1220330baff5SYunsheng Lin #define DEFAULT_TC_OFFSET	14
1221330baff5SYunsheng Lin 
1222330baff5SYunsheng Lin 	struct hclge_ets_tc_weight_cmd *ets_weight;
1223330baff5SYunsheng Lin 	struct hclge_desc desc;
1224ebaf1908SWeihang Li 	unsigned int i;
1225330baff5SYunsheng Lin 
1226330baff5SYunsheng Lin 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_ETS_TC_WEIGHT, false);
1227330baff5SYunsheng Lin 	ets_weight = (struct hclge_ets_tc_weight_cmd *)desc.data;
1228330baff5SYunsheng Lin 
1229330baff5SYunsheng Lin 	for (i = 0; i < HNAE3_MAX_TC; i++) {
1230330baff5SYunsheng Lin 		struct hclge_pg_info *pg_info;
1231330baff5SYunsheng Lin 
1232688db0c7SGuangbin Huang 		pg_info = &hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid];
1233330baff5SYunsheng Lin 		ets_weight->tc_weight[i] = pg_info->tc_dwrr[i];
1234330baff5SYunsheng Lin 	}
1235330baff5SYunsheng Lin 
1236330baff5SYunsheng Lin 	ets_weight->weight_offset = DEFAULT_TC_OFFSET;
1237330baff5SYunsheng Lin 
1238330baff5SYunsheng Lin 	return hclge_cmd_send(&hdev->hw, &desc, 1);
1239330baff5SYunsheng Lin }
1240330baff5SYunsheng Lin 
hclge_tm_pri_vnet_base_dwrr_pri_cfg(struct hclge_vport * vport)124184844054SSalil static int hclge_tm_pri_vnet_base_dwrr_pri_cfg(struct hclge_vport *vport)
124284844054SSalil {
124384844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
124484844054SSalil 	struct hclge_dev *hdev = vport->back;
124584844054SSalil 	int ret;
124684844054SSalil 	u8 i;
124784844054SSalil 
124884844054SSalil 	/* Vf dwrr */
124984844054SSalil 	ret = hclge_tm_pri_weight_cfg(hdev, vport->vport_id, vport->dwrr);
125084844054SSalil 	if (ret)
125184844054SSalil 		return ret;
125284844054SSalil 
125384844054SSalil 	/* Qset dwrr */
125435244430SJian Shen 	for (i = 0; i < kinfo->tc_info.num_tc; i++) {
125584844054SSalil 		ret = hclge_tm_qs_weight_cfg(
125684844054SSalil 			hdev, vport->qs_offset + i,
125784844054SSalil 			hdev->tm_info.pg_info[0].tc_dwrr[i]);
125884844054SSalil 		if (ret)
125984844054SSalil 			return ret;
126084844054SSalil 	}
126184844054SSalil 
126284844054SSalil 	return 0;
126384844054SSalil }
126484844054SSalil 
hclge_tm_pri_vnet_base_dwrr_cfg(struct hclge_dev * hdev)126584844054SSalil static int hclge_tm_pri_vnet_base_dwrr_cfg(struct hclge_dev *hdev)
126684844054SSalil {
126784844054SSalil 	struct hclge_vport *vport = hdev->vport;
126884844054SSalil 	int ret;
126984844054SSalil 	u32 i;
127084844054SSalil 
127184844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
127284844054SSalil 		ret = hclge_tm_pri_vnet_base_dwrr_pri_cfg(vport);
127384844054SSalil 		if (ret)
127484844054SSalil 			return ret;
127584844054SSalil 
127684844054SSalil 		vport++;
127784844054SSalil 	}
127884844054SSalil 
127984844054SSalil 	return 0;
128084844054SSalil }
128184844054SSalil 
hclge_tm_pri_dwrr_cfg(struct hclge_dev * hdev)128284844054SSalil static int hclge_tm_pri_dwrr_cfg(struct hclge_dev *hdev)
128384844054SSalil {
128484844054SSalil 	int ret;
128584844054SSalil 
128684844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
128784844054SSalil 		ret = hclge_tm_pri_tc_base_dwrr_cfg(hdev);
128884844054SSalil 		if (ret)
128984844054SSalil 			return ret;
1290330baff5SYunsheng Lin 
1291330baff5SYunsheng Lin 		if (!hnae3_dev_dcb_supported(hdev))
1292330baff5SYunsheng Lin 			return 0;
1293330baff5SYunsheng Lin 
1294330baff5SYunsheng Lin 		ret = hclge_tm_ets_tc_dwrr_cfg(hdev);
1295330baff5SYunsheng Lin 		if (ret == -EOPNOTSUPP) {
1296330baff5SYunsheng Lin 			dev_warn(&hdev->pdev->dev,
1297f4034430SColin Ian King 				 "fw %08x doesn't support ets tc weight cmd\n",
1298330baff5SYunsheng Lin 				 hdev->fw_version);
1299330baff5SYunsheng Lin 			ret = 0;
1300330baff5SYunsheng Lin 		}
1301330baff5SYunsheng Lin 
1302330baff5SYunsheng Lin 		return ret;
130384844054SSalil 	} else {
130484844054SSalil 		ret = hclge_tm_pri_vnet_base_dwrr_cfg(hdev);
130584844054SSalil 		if (ret)
130684844054SSalil 			return ret;
130784844054SSalil 	}
130884844054SSalil 
130984844054SSalil 	return 0;
131084844054SSalil }
131184844054SSalil 
hclge_tm_map_cfg(struct hclge_dev * hdev)13129e5157baSYunsheng Lin static int hclge_tm_map_cfg(struct hclge_dev *hdev)
131384844054SSalil {
131484844054SSalil 	int ret;
131584844054SSalil 
131677f255c1SYunsheng Lin 	ret = hclge_up_to_tc_map(hdev);
131777f255c1SYunsheng Lin 	if (ret)
131877f255c1SYunsheng Lin 		return ret;
131977f255c1SYunsheng Lin 
13200ba22bcbSGuangbin Huang 	if (hdev->vport[0].nic.kinfo.tc_map_mode == HNAE3_TC_MAP_MODE_DSCP) {
13210ba22bcbSGuangbin Huang 		ret = hclge_dscp_to_tc_map(hdev);
13220ba22bcbSGuangbin Huang 		if (ret)
13230ba22bcbSGuangbin Huang 			return ret;
13240ba22bcbSGuangbin Huang 	}
13250ba22bcbSGuangbin Huang 
132684844054SSalil 	ret = hclge_tm_pg_to_pri_map(hdev);
132784844054SSalil 	if (ret)
132884844054SSalil 		return ret;
132984844054SSalil 
133084844054SSalil 	return hclge_tm_pri_q_qs_cfg(hdev);
133184844054SSalil }
133284844054SSalil 
hclge_tm_shaper_cfg(struct hclge_dev * hdev)133384844054SSalil static int hclge_tm_shaper_cfg(struct hclge_dev *hdev)
133484844054SSalil {
133584844054SSalil 	int ret;
133684844054SSalil 
13370a5677d3SYunsheng Lin 	ret = hclge_tm_port_shaper_cfg(hdev);
13380a5677d3SYunsheng Lin 	if (ret)
13390a5677d3SYunsheng Lin 		return ret;
13400a5677d3SYunsheng Lin 
134184844054SSalil 	ret = hclge_tm_pg_shaper_cfg(hdev);
134284844054SSalil 	if (ret)
134384844054SSalil 		return ret;
134484844054SSalil 
134584844054SSalil 	return hclge_tm_pri_shaper_cfg(hdev);
134684844054SSalil }
134784844054SSalil 
hclge_tm_dwrr_cfg(struct hclge_dev * hdev)134884844054SSalil int hclge_tm_dwrr_cfg(struct hclge_dev *hdev)
134984844054SSalil {
135084844054SSalil 	int ret;
135184844054SSalil 
135284844054SSalil 	ret = hclge_tm_pg_dwrr_cfg(hdev);
135384844054SSalil 	if (ret)
135484844054SSalil 		return ret;
135584844054SSalil 
135684844054SSalil 	return hclge_tm_pri_dwrr_cfg(hdev);
135784844054SSalil }
135884844054SSalil 
hclge_tm_lvl2_schd_mode_cfg(struct hclge_dev * hdev)135984844054SSalil static int hclge_tm_lvl2_schd_mode_cfg(struct hclge_dev *hdev)
136084844054SSalil {
136184844054SSalil 	int ret;
136284844054SSalil 	u8 i;
136384844054SSalil 
136484844054SSalil 	/* Only being config on TC-Based scheduler mode */
136584844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE)
136684844054SSalil 		return 0;
136784844054SSalil 
136884844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
136984844054SSalil 		ret = hclge_tm_pg_schd_mode_cfg(hdev, i);
137084844054SSalil 		if (ret)
137184844054SSalil 			return ret;
137284844054SSalil 	}
137384844054SSalil 
137484844054SSalil 	return 0;
137584844054SSalil }
137684844054SSalil 
hclge_tm_schd_mode_tc_base_cfg(struct hclge_dev * hdev,u8 pri_id)13777ca561beSGuangbin Huang static int hclge_tm_schd_mode_tc_base_cfg(struct hclge_dev *hdev, u8 pri_id)
13787ca561beSGuangbin Huang {
13797ca561beSGuangbin Huang 	struct hclge_vport *vport = hdev->vport;
13807ca561beSGuangbin Huang 	int ret;
1381e93530aeSGuangbin Huang 	u8 mode;
13827ca561beSGuangbin Huang 	u16 i;
13837ca561beSGuangbin Huang 
13847ca561beSGuangbin Huang 	ret = hclge_tm_pri_schd_mode_cfg(hdev, pri_id);
13857ca561beSGuangbin Huang 	if (ret)
13867ca561beSGuangbin Huang 		return ret;
13877ca561beSGuangbin Huang 
13887ca561beSGuangbin Huang 	for (i = 0; i < hdev->num_alloc_vport; i++) {
1389e93530aeSGuangbin Huang 		struct hnae3_knic_private_info *kinfo = &vport[i].nic.kinfo;
1390e93530aeSGuangbin Huang 
1391e93530aeSGuangbin Huang 		if (pri_id >= kinfo->tc_info.max_tc)
1392e93530aeSGuangbin Huang 			continue;
1393e93530aeSGuangbin Huang 
1394e93530aeSGuangbin Huang 		mode = pri_id < kinfo->tc_info.num_tc ? HCLGE_SCH_MODE_DWRR :
1395e93530aeSGuangbin Huang 		       HCLGE_SCH_MODE_SP;
13967ca561beSGuangbin Huang 		ret = hclge_tm_qs_schd_mode_cfg(hdev,
13977ca561beSGuangbin Huang 						vport[i].qs_offset + pri_id,
1398e93530aeSGuangbin Huang 						mode);
13997ca561beSGuangbin Huang 		if (ret)
14007ca561beSGuangbin Huang 			return ret;
14017ca561beSGuangbin Huang 	}
14027ca561beSGuangbin Huang 
14037ca561beSGuangbin Huang 	return 0;
14047ca561beSGuangbin Huang }
14057ca561beSGuangbin Huang 
hclge_tm_schd_mode_vnet_base_cfg(struct hclge_vport * vport)140684844054SSalil static int hclge_tm_schd_mode_vnet_base_cfg(struct hclge_vport *vport)
140784844054SSalil {
140884844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
140984844054SSalil 	struct hclge_dev *hdev = vport->back;
141084844054SSalil 	int ret;
141184844054SSalil 	u8 i;
141284844054SSalil 
141304f25edbSYunsheng Lin 	if (vport->vport_id >= HNAE3_MAX_TC)
141404f25edbSYunsheng Lin 		return -EINVAL;
141504f25edbSYunsheng Lin 
141684844054SSalil 	ret = hclge_tm_pri_schd_mode_cfg(hdev, vport->vport_id);
141784844054SSalil 	if (ret)
141884844054SSalil 		return ret;
141984844054SSalil 
142035244430SJian Shen 	for (i = 0; i < kinfo->tc_info.num_tc; i++) {
1421cc9bb43aSYunsheng Lin 		u8 sch_mode = hdev->tm_info.tc_info[i].tc_sch_mode;
1422cc9bb43aSYunsheng Lin 
1423cc9bb43aSYunsheng Lin 		ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i,
1424cc9bb43aSYunsheng Lin 						sch_mode);
142584844054SSalil 		if (ret)
142684844054SSalil 			return ret;
142784844054SSalil 	}
142884844054SSalil 
142984844054SSalil 	return 0;
143084844054SSalil }
143184844054SSalil 
hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev * hdev)143284844054SSalil static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev *hdev)
143384844054SSalil {
143484844054SSalil 	struct hclge_vport *vport = hdev->vport;
143584844054SSalil 	int ret;
14367ca561beSGuangbin Huang 	u8 i;
143784844054SSalil 
143884844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
1439e93530aeSGuangbin Huang 		for (i = 0; i < hdev->tc_max; i++) {
14407ca561beSGuangbin Huang 			ret = hclge_tm_schd_mode_tc_base_cfg(hdev, i);
144184844054SSalil 			if (ret)
144284844054SSalil 				return ret;
1443cc9bb43aSYunsheng Lin 		}
144484844054SSalil 	} else {
144584844054SSalil 		for (i = 0; i < hdev->num_alloc_vport; i++) {
144684844054SSalil 			ret = hclge_tm_schd_mode_vnet_base_cfg(vport);
144784844054SSalil 			if (ret)
144884844054SSalil 				return ret;
144984844054SSalil 
145084844054SSalil 			vport++;
145184844054SSalil 		}
145284844054SSalil 	}
145384844054SSalil 
145484844054SSalil 	return 0;
145584844054SSalil }
145684844054SSalil 
hclge_tm_schd_mode_hw(struct hclge_dev * hdev)14579e5157baSYunsheng Lin static int hclge_tm_schd_mode_hw(struct hclge_dev *hdev)
145884844054SSalil {
145984844054SSalil 	int ret;
146084844054SSalil 
146184844054SSalil 	ret = hclge_tm_lvl2_schd_mode_cfg(hdev);
146284844054SSalil 	if (ret)
146384844054SSalil 		return ret;
146484844054SSalil 
146584844054SSalil 	return hclge_tm_lvl34_schd_mode_cfg(hdev);
146684844054SSalil }
146784844054SSalil 
hclge_tm_schd_setup_hw(struct hclge_dev * hdev)14689e5157baSYunsheng Lin int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
146984844054SSalil {
147084844054SSalil 	int ret;
147184844054SSalil 
147284844054SSalil 	/* Cfg tm mapping  */
147384844054SSalil 	ret = hclge_tm_map_cfg(hdev);
147484844054SSalil 	if (ret)
147584844054SSalil 		return ret;
147684844054SSalil 
147784844054SSalil 	/* Cfg tm shaper */
147884844054SSalil 	ret = hclge_tm_shaper_cfg(hdev);
147984844054SSalil 	if (ret)
148084844054SSalil 		return ret;
148184844054SSalil 
148284844054SSalil 	/* Cfg dwrr */
148384844054SSalil 	ret = hclge_tm_dwrr_cfg(hdev);
148484844054SSalil 	if (ret)
148584844054SSalil 		return ret;
148684844054SSalil 
148784844054SSalil 	/* Cfg schd mode for each level schd */
14886d233612SHao Lan 	ret = hclge_tm_schd_mode_hw(hdev);
14896d233612SHao Lan 	if (ret)
14906d233612SHao Lan 		return ret;
14916d233612SHao Lan 
14926d233612SHao Lan 	return hclge_tm_flush_cfg(hdev, false);
149384844054SSalil }
149484844054SSalil 
hclge_pause_param_setup_hw(struct hclge_dev * hdev)1495e98d7183SFuyun Liang static int hclge_pause_param_setup_hw(struct hclge_dev *hdev)
149618838d0cSFuyun Liang {
149718838d0cSFuyun Liang 	struct hclge_mac *mac = &hdev->hw.mac;
149818838d0cSFuyun Liang 
1499e98d7183SFuyun Liang 	return hclge_pause_param_cfg(hdev, mac->mac_addr,
150018838d0cSFuyun Liang 				     HCLGE_DEFAULT_PAUSE_TRANS_GAP,
150118838d0cSFuyun Liang 				     HCLGE_DEFAULT_PAUSE_TRANS_TIME);
150218838d0cSFuyun Liang }
150318838d0cSFuyun Liang 
hclge_pfc_setup_hw(struct hclge_dev * hdev)15049dc2145dSYunsheng Lin static int hclge_pfc_setup_hw(struct hclge_dev *hdev)
15059dc2145dSYunsheng Lin {
15069dc2145dSYunsheng Lin 	u8 enable_bitmap = 0;
15079dc2145dSYunsheng Lin 
15089dc2145dSYunsheng Lin 	if (hdev->tm_info.fc_mode == HCLGE_FC_PFC)
15099dc2145dSYunsheng Lin 		enable_bitmap = HCLGE_TX_MAC_PAUSE_EN_MSK |
15109dc2145dSYunsheng Lin 				HCLGE_RX_MAC_PAUSE_EN_MSK;
15119dc2145dSYunsheng Lin 
15129dc2145dSYunsheng Lin 	return hclge_pfc_pause_en_cfg(hdev, enable_bitmap,
1513d3ad430aSYunsheng Lin 				      hdev->tm_info.pfc_en);
15149dc2145dSYunsheng Lin }
15159dc2145dSYunsheng Lin 
15169a5ef4aaSYonglong Liu /* for the queues that use for backpress, divides to several groups,
15179a5ef4aaSYonglong Liu  * each group contains 32 queue sets, which can be represented by u32 bitmap.
151867bf2541SYunsheng Lin  */
hclge_bp_setup_hw(struct hclge_dev * hdev,u8 tc)151967bf2541SYunsheng Lin static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc)
152067bf2541SYunsheng Lin {
15219a5ef4aaSYonglong Liu 	u16 grp_id_shift = HCLGE_BP_GRP_ID_S;
15229a5ef4aaSYonglong Liu 	u16 grp_id_mask = HCLGE_BP_GRP_ID_M;
15239a5ef4aaSYonglong Liu 	u8 grp_num = HCLGE_BP_GRP_NUM;
1524e8ccbb7dSYunsheng Lin 	int i;
152567bf2541SYunsheng Lin 
15269a5ef4aaSYonglong Liu 	if (hdev->num_tqps > HCLGE_TQP_MAX_SIZE_DEV_V2) {
15279a5ef4aaSYonglong Liu 		grp_num = HCLGE_BP_EXT_GRP_NUM;
15289a5ef4aaSYonglong Liu 		grp_id_mask = HCLGE_BP_EXT_GRP_ID_M;
15299a5ef4aaSYonglong Liu 		grp_id_shift = HCLGE_BP_EXT_GRP_ID_S;
15309a5ef4aaSYonglong Liu 	}
15319a5ef4aaSYonglong Liu 
15329a5ef4aaSYonglong Liu 	for (i = 0; i < grp_num; i++) {
1533e8ccbb7dSYunsheng Lin 		u32 qs_bitmap = 0;
1534e8ccbb7dSYunsheng Lin 		int k, ret;
153567bf2541SYunsheng Lin 
153667bf2541SYunsheng Lin 		for (k = 0; k < hdev->num_alloc_vport; k++) {
1537e8ccbb7dSYunsheng Lin 			struct hclge_vport *vport = &hdev->vport[k];
153867bf2541SYunsheng Lin 			u16 qs_id = vport->qs_offset + tc;
153967bf2541SYunsheng Lin 			u8 grp, sub_grp;
154067bf2541SYunsheng Lin 
15419a5ef4aaSYonglong Liu 			grp = hnae3_get_field(qs_id, grp_id_mask, grp_id_shift);
1542e4e87715SPeng Li 			sub_grp = hnae3_get_field(qs_id, HCLGE_BP_SUB_GRP_ID_M,
154367bf2541SYunsheng Lin 						  HCLGE_BP_SUB_GRP_ID_S);
154467bf2541SYunsheng Lin 			if (i == grp)
154567bf2541SYunsheng Lin 				qs_bitmap |= (1 << sub_grp);
154667bf2541SYunsheng Lin 		}
154767bf2541SYunsheng Lin 
154867bf2541SYunsheng Lin 		ret = hclge_tm_qs_bp_cfg(hdev, tc, i, qs_bitmap);
154967bf2541SYunsheng Lin 		if (ret)
155067bf2541SYunsheng Lin 			return ret;
155167bf2541SYunsheng Lin 	}
155267bf2541SYunsheng Lin 
155367bf2541SYunsheng Lin 	return 0;
155467bf2541SYunsheng Lin }
155567bf2541SYunsheng Lin 
hclge_mac_pause_setup_hw(struct hclge_dev * hdev)1556*15159ec0SJian Shen int hclge_mac_pause_setup_hw(struct hclge_dev *hdev)
15579dc2145dSYunsheng Lin {
15589dc2145dSYunsheng Lin 	bool tx_en, rx_en;
15599dc2145dSYunsheng Lin 
15609dc2145dSYunsheng Lin 	switch (hdev->tm_info.fc_mode) {
15619dc2145dSYunsheng Lin 	case HCLGE_FC_NONE:
15629dc2145dSYunsheng Lin 		tx_en = false;
15639dc2145dSYunsheng Lin 		rx_en = false;
15649dc2145dSYunsheng Lin 		break;
15659dc2145dSYunsheng Lin 	case HCLGE_FC_RX_PAUSE:
15669dc2145dSYunsheng Lin 		tx_en = false;
15679dc2145dSYunsheng Lin 		rx_en = true;
15689dc2145dSYunsheng Lin 		break;
15699dc2145dSYunsheng Lin 	case HCLGE_FC_TX_PAUSE:
15709dc2145dSYunsheng Lin 		tx_en = true;
15719dc2145dSYunsheng Lin 		rx_en = false;
15729dc2145dSYunsheng Lin 		break;
15739dc2145dSYunsheng Lin 	case HCLGE_FC_FULL:
15749dc2145dSYunsheng Lin 		tx_en = true;
15759dc2145dSYunsheng Lin 		rx_en = true;
15769dc2145dSYunsheng Lin 		break;
15776d0ec65cSYunsheng Lin 	case HCLGE_FC_PFC:
15786d0ec65cSYunsheng Lin 		tx_en = false;
15796d0ec65cSYunsheng Lin 		rx_en = false;
15806d0ec65cSYunsheng Lin 		break;
15819dc2145dSYunsheng Lin 	default:
15829dc2145dSYunsheng Lin 		tx_en = true;
15839dc2145dSYunsheng Lin 		rx_en = true;
15849dc2145dSYunsheng Lin 	}
15859dc2145dSYunsheng Lin 
15869dc2145dSYunsheng Lin 	return hclge_mac_pause_en_cfg(hdev, tx_en, rx_en);
15879dc2145dSYunsheng Lin }
15889dc2145dSYunsheng Lin 
hclge_tm_bp_setup(struct hclge_dev * hdev)158973fc9c48SHuazhong Tan static int hclge_tm_bp_setup(struct hclge_dev *hdev)
159073fc9c48SHuazhong Tan {
15919d8d5a36SYufeng Mo 	int ret;
159273fc9c48SHuazhong Tan 	int i;
159373fc9c48SHuazhong Tan 
159473fc9c48SHuazhong Tan 	for (i = 0; i < hdev->tm_info.num_tc; i++) {
159573fc9c48SHuazhong Tan 		ret = hclge_bp_setup_hw(hdev, i);
159673fc9c48SHuazhong Tan 		if (ret)
159773fc9c48SHuazhong Tan 			return ret;
159873fc9c48SHuazhong Tan 	}
159973fc9c48SHuazhong Tan 
1600ee7a3764SDan Carpenter 	return 0;
160173fc9c48SHuazhong Tan }
160273fc9c48SHuazhong Tan 
hclge_pause_setup_hw(struct hclge_dev * hdev,bool init)160344e59e37SYunsheng Lin int hclge_pause_setup_hw(struct hclge_dev *hdev, bool init)
160484844054SSalil {
160584844054SSalil 	int ret;
160684844054SSalil 
1607e98d7183SFuyun Liang 	ret = hclge_pause_param_setup_hw(hdev);
160818838d0cSFuyun Liang 	if (ret)
160918838d0cSFuyun Liang 		return ret;
161018838d0cSFuyun Liang 
16116d0ec65cSYunsheng Lin 	ret = hclge_mac_pause_setup_hw(hdev);
16126d0ec65cSYunsheng Lin 	if (ret)
16136d0ec65cSYunsheng Lin 		return ret;
161484844054SSalil 
16159dc2145dSYunsheng Lin 	/* Only DCB-supported dev supports qset back pressure and pfc cmd */
16162daf4a65SYunsheng Lin 	if (!hnae3_dev_dcb_supported(hdev))
16172daf4a65SYunsheng Lin 		return 0;
16182daf4a65SYunsheng Lin 
161944e59e37SYunsheng Lin 	/* GE MAC does not support PFC, when driver is initializing and MAC
162044e59e37SYunsheng Lin 	 * is in GE Mode, ignore the error here, otherwise initialization
162144e59e37SYunsheng Lin 	 * will fail.
162244e59e37SYunsheng Lin 	 */
16239dc2145dSYunsheng Lin 	ret = hclge_pfc_setup_hw(hdev);
162444e59e37SYunsheng Lin 	if (init && ret == -EOPNOTSUPP)
162544e59e37SYunsheng Lin 		dev_warn(&hdev->pdev->dev, "GE MAC does not support pfc\n");
1626fba2efdaSHuazhong Tan 	else if (ret) {
1627fba2efdaSHuazhong Tan 		dev_err(&hdev->pdev->dev, "config pfc failed! ret = %d\n",
1628fba2efdaSHuazhong Tan 			ret);
162944e59e37SYunsheng Lin 		return ret;
1630fba2efdaSHuazhong Tan 	}
16319dc2145dSYunsheng Lin 
163273fc9c48SHuazhong Tan 	return hclge_tm_bp_setup(hdev);
163377f255c1SYunsheng Lin }
163477f255c1SYunsheng Lin 
hclge_tm_prio_tc_info_update(struct hclge_dev * hdev,u8 * prio_tc)1635e432abfbSYunsheng Lin void hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc)
163677f255c1SYunsheng Lin {
163777f255c1SYunsheng Lin 	struct hclge_vport *vport = hdev->vport;
163877f255c1SYunsheng Lin 	struct hnae3_knic_private_info *kinfo;
163977f255c1SYunsheng Lin 	u32 i, k;
164077f255c1SYunsheng Lin 
164177f255c1SYunsheng Lin 	for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
164277f255c1SYunsheng Lin 		hdev->tm_info.prio_tc[i] = prio_tc[i];
164377f255c1SYunsheng Lin 
164477f255c1SYunsheng Lin 		for (k = 0;  k < hdev->num_alloc_vport; k++) {
164577f255c1SYunsheng Lin 			kinfo = &vport[k].nic.kinfo;
164635244430SJian Shen 			kinfo->tc_info.prio_tc[i] = prio_tc[i];
164777f255c1SYunsheng Lin 		}
164877f255c1SYunsheng Lin 	}
164977f255c1SYunsheng Lin }
165077f255c1SYunsheng Lin 
hclge_tm_schd_info_update(struct hclge_dev * hdev,u8 num_tc)1651e432abfbSYunsheng Lin void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc)
165277f255c1SYunsheng Lin {
16539b2f3477SWeihang Li 	u8 bit_map = 0;
16549b2f3477SWeihang Li 	u8 i;
165577f255c1SYunsheng Lin 
165677f255c1SYunsheng Lin 	hdev->tm_info.num_tc = num_tc;
165777f255c1SYunsheng Lin 
165877f255c1SYunsheng Lin 	for (i = 0; i < hdev->tm_info.num_tc; i++)
165977f255c1SYunsheng Lin 		bit_map |= BIT(i);
166077f255c1SYunsheng Lin 
166177f255c1SYunsheng Lin 	if (!bit_map) {
166277f255c1SYunsheng Lin 		bit_map = 1;
166377f255c1SYunsheng Lin 		hdev->tm_info.num_tc = 1;
166477f255c1SYunsheng Lin 	}
166577f255c1SYunsheng Lin 
166677f255c1SYunsheng Lin 	hdev->hw_tc_map = bit_map;
166777f255c1SYunsheng Lin 
166877f255c1SYunsheng Lin 	hclge_tm_schd_info_init(hdev);
166984844054SSalil }
167084844054SSalil 
hclge_tm_init_hw(struct hclge_dev * hdev,bool init)167144e59e37SYunsheng Lin int hclge_tm_init_hw(struct hclge_dev *hdev, bool init)
167284844054SSalil {
167384844054SSalil 	int ret;
167484844054SSalil 
167584844054SSalil 	if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) &&
167684844054SSalil 	    (hdev->tx_sch_mode != HCLGE_FLAG_VNET_BASE_SCH_MODE))
167784844054SSalil 		return -ENOTSUPP;
167884844054SSalil 
167984844054SSalil 	ret = hclge_tm_schd_setup_hw(hdev);
168084844054SSalil 	if (ret)
168184844054SSalil 		return ret;
168284844054SSalil 
168344e59e37SYunsheng Lin 	ret = hclge_pause_setup_hw(hdev, init);
168484844054SSalil 	if (ret)
168584844054SSalil 		return ret;
168684844054SSalil 
168784844054SSalil 	return 0;
168884844054SSalil }
168984844054SSalil 
hclge_tm_schd_init(struct hclge_dev * hdev)169084844054SSalil int hclge_tm_schd_init(struct hclge_dev *hdev)
169184844054SSalil {
16927979a223SYunsheng Lin 	/* fc_mode is HCLGE_FC_FULL on reset */
16937979a223SYunsheng Lin 	hdev->tm_info.fc_mode = HCLGE_FC_FULL;
16947979a223SYunsheng Lin 	hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
16957979a223SYunsheng Lin 
1696b6872fd3SYunsheng Lin 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE &&
1697b6872fd3SYunsheng Lin 	    hdev->tm_info.num_pg != 1)
1698b6872fd3SYunsheng Lin 		return -EINVAL;
1699b6872fd3SYunsheng Lin 
1700b6872fd3SYunsheng Lin 	hclge_tm_schd_info_init(hdev);
17010ba22bcbSGuangbin Huang 	hclge_dscp_to_prio_map_init(hdev);
170284844054SSalil 
170344e59e37SYunsheng Lin 	return hclge_tm_init_hw(hdev, true);
170484844054SSalil }
1705672ad0edSHuazhong Tan 
hclge_tm_vport_map_update(struct hclge_dev * hdev)1706672ad0edSHuazhong Tan int hclge_tm_vport_map_update(struct hclge_dev *hdev)
1707672ad0edSHuazhong Tan {
1708672ad0edSHuazhong Tan 	struct hclge_vport *vport = hdev->vport;
1709672ad0edSHuazhong Tan 	int ret;
1710672ad0edSHuazhong Tan 
1711672ad0edSHuazhong Tan 	hclge_tm_vport_tc_info_update(vport);
1712672ad0edSHuazhong Tan 
1713672ad0edSHuazhong Tan 	ret = hclge_vport_q_to_qs_map(hdev, vport);
1714672ad0edSHuazhong Tan 	if (ret)
1715672ad0edSHuazhong Tan 		return ret;
1716672ad0edSHuazhong Tan 
17170472e95fSJian Shen 	if (hdev->tm_info.num_tc == 1 && !hdev->tm_info.pfc_en)
1718672ad0edSHuazhong Tan 		return 0;
1719672ad0edSHuazhong Tan 
1720672ad0edSHuazhong Tan 	return hclge_tm_bp_setup(hdev);
1721672ad0edSHuazhong Tan }
17222bbad0aaSGuangbin Huang 
hclge_tm_get_qset_num(struct hclge_dev * hdev,u16 * qset_num)17232bbad0aaSGuangbin Huang int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num)
17242bbad0aaSGuangbin Huang {
17252bbad0aaSGuangbin Huang 	struct hclge_tm_nodes_cmd *nodes;
17262bbad0aaSGuangbin Huang 	struct hclge_desc desc;
17272bbad0aaSGuangbin Huang 	int ret;
17282bbad0aaSGuangbin Huang 
17292bbad0aaSGuangbin Huang 	if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) {
17302bbad0aaSGuangbin Huang 		/* Each PF has 8 qsets and each VF has 1 qset */
17312bbad0aaSGuangbin Huang 		*qset_num = HCLGE_TM_PF_MAX_QSET_NUM + pci_num_vf(hdev->pdev);
17322bbad0aaSGuangbin Huang 		return 0;
17332bbad0aaSGuangbin Huang 	}
17342bbad0aaSGuangbin Huang 
17352bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NODES, true);
17362bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
17372bbad0aaSGuangbin Huang 	if (ret) {
17382bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
17392bbad0aaSGuangbin Huang 			"failed to get qset num, ret = %d\n", ret);
17402bbad0aaSGuangbin Huang 		return ret;
17412bbad0aaSGuangbin Huang 	}
17422bbad0aaSGuangbin Huang 
17432bbad0aaSGuangbin Huang 	nodes = (struct hclge_tm_nodes_cmd *)desc.data;
17442bbad0aaSGuangbin Huang 	*qset_num = le16_to_cpu(nodes->qset_num);
17452bbad0aaSGuangbin Huang 	return 0;
17462bbad0aaSGuangbin Huang }
17472bbad0aaSGuangbin Huang 
hclge_tm_get_pri_num(struct hclge_dev * hdev,u8 * pri_num)17482bbad0aaSGuangbin Huang int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num)
17492bbad0aaSGuangbin Huang {
17502bbad0aaSGuangbin Huang 	struct hclge_tm_nodes_cmd *nodes;
17512bbad0aaSGuangbin Huang 	struct hclge_desc desc;
17522bbad0aaSGuangbin Huang 	int ret;
17532bbad0aaSGuangbin Huang 
17542bbad0aaSGuangbin Huang 	if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) {
17552bbad0aaSGuangbin Huang 		*pri_num = HCLGE_TM_PF_MAX_PRI_NUM;
17562bbad0aaSGuangbin Huang 		return 0;
17572bbad0aaSGuangbin Huang 	}
17582bbad0aaSGuangbin Huang 
17592bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NODES, true);
17602bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
17612bbad0aaSGuangbin Huang 	if (ret) {
17622bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
17632bbad0aaSGuangbin Huang 			"failed to get pri num, ret = %d\n", ret);
17642bbad0aaSGuangbin Huang 		return ret;
17652bbad0aaSGuangbin Huang 	}
17662bbad0aaSGuangbin Huang 
17672bbad0aaSGuangbin Huang 	nodes = (struct hclge_tm_nodes_cmd *)desc.data;
17682bbad0aaSGuangbin Huang 	*pri_num = nodes->pri_num;
17692bbad0aaSGuangbin Huang 	return 0;
17702bbad0aaSGuangbin Huang }
17712bbad0aaSGuangbin Huang 
hclge_tm_get_qset_map_pri(struct hclge_dev * hdev,u16 qset_id,u8 * priority,u8 * link_vld)17722bbad0aaSGuangbin Huang int hclge_tm_get_qset_map_pri(struct hclge_dev *hdev, u16 qset_id, u8 *priority,
17732bbad0aaSGuangbin Huang 			      u8 *link_vld)
17742bbad0aaSGuangbin Huang {
17752bbad0aaSGuangbin Huang 	struct hclge_qs_to_pri_link_cmd *map;
17762bbad0aaSGuangbin Huang 	struct hclge_desc desc;
17772bbad0aaSGuangbin Huang 	int ret;
17782bbad0aaSGuangbin Huang 
17792bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_TO_PRI_LINK, true);
17802bbad0aaSGuangbin Huang 	map = (struct hclge_qs_to_pri_link_cmd *)desc.data;
17812bbad0aaSGuangbin Huang 	map->qs_id = cpu_to_le16(qset_id);
17822bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
17832bbad0aaSGuangbin Huang 	if (ret) {
17842bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
17852bbad0aaSGuangbin Huang 			"failed to get qset map priority, ret = %d\n", ret);
17862bbad0aaSGuangbin Huang 		return ret;
17872bbad0aaSGuangbin Huang 	}
17882bbad0aaSGuangbin Huang 
17892bbad0aaSGuangbin Huang 	*priority = map->priority;
17902bbad0aaSGuangbin Huang 	*link_vld = map->link_vld;
17912bbad0aaSGuangbin Huang 	return 0;
17922bbad0aaSGuangbin Huang }
17932bbad0aaSGuangbin Huang 
hclge_tm_get_qset_sch_mode(struct hclge_dev * hdev,u16 qset_id,u8 * mode)17942bbad0aaSGuangbin Huang int hclge_tm_get_qset_sch_mode(struct hclge_dev *hdev, u16 qset_id, u8 *mode)
17952bbad0aaSGuangbin Huang {
17962bbad0aaSGuangbin Huang 	struct hclge_qs_sch_mode_cfg_cmd *qs_sch_mode;
17972bbad0aaSGuangbin Huang 	struct hclge_desc desc;
17982bbad0aaSGuangbin Huang 	int ret;
17992bbad0aaSGuangbin Huang 
18002bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_SCH_MODE_CFG, true);
18012bbad0aaSGuangbin Huang 	qs_sch_mode = (struct hclge_qs_sch_mode_cfg_cmd *)desc.data;
18022bbad0aaSGuangbin Huang 	qs_sch_mode->qs_id = cpu_to_le16(qset_id);
18032bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
18042bbad0aaSGuangbin Huang 	if (ret) {
18052bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
18062bbad0aaSGuangbin Huang 			"failed to get qset sch mode, ret = %d\n", ret);
18072bbad0aaSGuangbin Huang 		return ret;
18082bbad0aaSGuangbin Huang 	}
18092bbad0aaSGuangbin Huang 
18102bbad0aaSGuangbin Huang 	*mode = qs_sch_mode->sch_mode;
18112bbad0aaSGuangbin Huang 	return 0;
18122bbad0aaSGuangbin Huang }
18132bbad0aaSGuangbin Huang 
hclge_tm_get_qset_weight(struct hclge_dev * hdev,u16 qset_id,u8 * weight)18142bbad0aaSGuangbin Huang int hclge_tm_get_qset_weight(struct hclge_dev *hdev, u16 qset_id, u8 *weight)
18152bbad0aaSGuangbin Huang {
18162bbad0aaSGuangbin Huang 	struct hclge_qs_weight_cmd *qs_weight;
18172bbad0aaSGuangbin Huang 	struct hclge_desc desc;
18182bbad0aaSGuangbin Huang 	int ret;
18192bbad0aaSGuangbin Huang 
18202bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_WEIGHT, true);
18212bbad0aaSGuangbin Huang 	qs_weight = (struct hclge_qs_weight_cmd *)desc.data;
18222bbad0aaSGuangbin Huang 	qs_weight->qs_id = cpu_to_le16(qset_id);
18232bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
18242bbad0aaSGuangbin Huang 	if (ret) {
18252bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
18262bbad0aaSGuangbin Huang 			"failed to get qset weight, ret = %d\n", ret);
18272bbad0aaSGuangbin Huang 		return ret;
18282bbad0aaSGuangbin Huang 	}
18292bbad0aaSGuangbin Huang 
18302bbad0aaSGuangbin Huang 	*weight = qs_weight->dwrr;
18312bbad0aaSGuangbin Huang 	return 0;
18322bbad0aaSGuangbin Huang }
18332bbad0aaSGuangbin Huang 
hclge_tm_get_qset_shaper(struct hclge_dev * hdev,u16 qset_id,struct hclge_tm_shaper_para * para)1834484e1ed1SGuangbin Huang int hclge_tm_get_qset_shaper(struct hclge_dev *hdev, u16 qset_id,
1835484e1ed1SGuangbin Huang 			     struct hclge_tm_shaper_para *para)
1836484e1ed1SGuangbin Huang {
1837484e1ed1SGuangbin Huang 	struct hclge_qs_shapping_cmd *shap_cfg_cmd;
1838484e1ed1SGuangbin Huang 	struct hclge_desc desc;
1839484e1ed1SGuangbin Huang 	u32 shapping_para;
1840484e1ed1SGuangbin Huang 	int ret;
1841484e1ed1SGuangbin Huang 
1842484e1ed1SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QCN_SHAPPING_CFG, true);
1843484e1ed1SGuangbin Huang 	shap_cfg_cmd = (struct hclge_qs_shapping_cmd *)desc.data;
1844484e1ed1SGuangbin Huang 	shap_cfg_cmd->qs_id = cpu_to_le16(qset_id);
1845484e1ed1SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
1846484e1ed1SGuangbin Huang 	if (ret) {
1847484e1ed1SGuangbin Huang 		dev_err(&hdev->pdev->dev,
1848484e1ed1SGuangbin Huang 			"failed to get qset %u shaper, ret = %d\n", qset_id,
1849484e1ed1SGuangbin Huang 			ret);
1850484e1ed1SGuangbin Huang 		return ret;
1851484e1ed1SGuangbin Huang 	}
1852484e1ed1SGuangbin Huang 
1853484e1ed1SGuangbin Huang 	shapping_para = le32_to_cpu(shap_cfg_cmd->qs_shapping_para);
1854484e1ed1SGuangbin Huang 	para->ir_b = hclge_tm_get_field(shapping_para, IR_B);
1855484e1ed1SGuangbin Huang 	para->ir_u = hclge_tm_get_field(shapping_para, IR_U);
1856484e1ed1SGuangbin Huang 	para->ir_s = hclge_tm_get_field(shapping_para, IR_S);
1857484e1ed1SGuangbin Huang 	para->bs_b = hclge_tm_get_field(shapping_para, BS_B);
1858484e1ed1SGuangbin Huang 	para->bs_s = hclge_tm_get_field(shapping_para, BS_S);
1859484e1ed1SGuangbin Huang 	para->flag = shap_cfg_cmd->flag;
1860484e1ed1SGuangbin Huang 	para->rate = le32_to_cpu(shap_cfg_cmd->qs_rate);
1861484e1ed1SGuangbin Huang 	return 0;
1862484e1ed1SGuangbin Huang }
1863484e1ed1SGuangbin Huang 
hclge_tm_get_pri_sch_mode(struct hclge_dev * hdev,u8 pri_id,u8 * mode)18642bbad0aaSGuangbin Huang int hclge_tm_get_pri_sch_mode(struct hclge_dev *hdev, u8 pri_id, u8 *mode)
18652bbad0aaSGuangbin Huang {
18662bbad0aaSGuangbin Huang 	struct hclge_pri_sch_mode_cfg_cmd *pri_sch_mode;
18672bbad0aaSGuangbin Huang 	struct hclge_desc desc;
18682bbad0aaSGuangbin Huang 	int ret;
18692bbad0aaSGuangbin Huang 
18702bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_SCH_MODE_CFG, true);
18712bbad0aaSGuangbin Huang 	pri_sch_mode = (struct hclge_pri_sch_mode_cfg_cmd *)desc.data;
18722bbad0aaSGuangbin Huang 	pri_sch_mode->pri_id = pri_id;
18732bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
18742bbad0aaSGuangbin Huang 	if (ret) {
18752bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
18762bbad0aaSGuangbin Huang 			"failed to get priority sch mode, ret = %d\n", ret);
18772bbad0aaSGuangbin Huang 		return ret;
18782bbad0aaSGuangbin Huang 	}
18792bbad0aaSGuangbin Huang 
18802bbad0aaSGuangbin Huang 	*mode = pri_sch_mode->sch_mode;
18812bbad0aaSGuangbin Huang 	return 0;
18822bbad0aaSGuangbin Huang }
18832bbad0aaSGuangbin Huang 
hclge_tm_get_pri_weight(struct hclge_dev * hdev,u8 pri_id,u8 * weight)18842bbad0aaSGuangbin Huang int hclge_tm_get_pri_weight(struct hclge_dev *hdev, u8 pri_id, u8 *weight)
18852bbad0aaSGuangbin Huang {
18862bbad0aaSGuangbin Huang 	struct hclge_priority_weight_cmd *priority_weight;
18872bbad0aaSGuangbin Huang 	struct hclge_desc desc;
18882bbad0aaSGuangbin Huang 	int ret;
18892bbad0aaSGuangbin Huang 
18902bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_WEIGHT, true);
18912bbad0aaSGuangbin Huang 	priority_weight = (struct hclge_priority_weight_cmd *)desc.data;
18922bbad0aaSGuangbin Huang 	priority_weight->pri_id = pri_id;
18932bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
18942bbad0aaSGuangbin Huang 	if (ret) {
18952bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
18962bbad0aaSGuangbin Huang 			"failed to get priority weight, ret = %d\n", ret);
18972bbad0aaSGuangbin Huang 		return ret;
18982bbad0aaSGuangbin Huang 	}
18992bbad0aaSGuangbin Huang 
19002bbad0aaSGuangbin Huang 	*weight = priority_weight->dwrr;
19012bbad0aaSGuangbin Huang 	return 0;
19022bbad0aaSGuangbin Huang }
19032bbad0aaSGuangbin Huang 
hclge_tm_get_pri_shaper(struct hclge_dev * hdev,u8 pri_id,enum hclge_opcode_type cmd,struct hclge_tm_shaper_para * para)19042bbad0aaSGuangbin Huang int hclge_tm_get_pri_shaper(struct hclge_dev *hdev, u8 pri_id,
19052bbad0aaSGuangbin Huang 			    enum hclge_opcode_type cmd,
1906cad7c215SGuangbin Huang 			    struct hclge_tm_shaper_para *para)
19072bbad0aaSGuangbin Huang {
19082bbad0aaSGuangbin Huang 	struct hclge_pri_shapping_cmd *shap_cfg_cmd;
19092bbad0aaSGuangbin Huang 	struct hclge_desc desc;
19102bbad0aaSGuangbin Huang 	u32 shapping_para;
19112bbad0aaSGuangbin Huang 	int ret;
19122bbad0aaSGuangbin Huang 
19132bbad0aaSGuangbin Huang 	if (cmd != HCLGE_OPC_TM_PRI_C_SHAPPING &&
19142bbad0aaSGuangbin Huang 	    cmd != HCLGE_OPC_TM_PRI_P_SHAPPING)
19152bbad0aaSGuangbin Huang 		return -EINVAL;
19162bbad0aaSGuangbin Huang 
19172bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, cmd, true);
19182bbad0aaSGuangbin Huang 	shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data;
19192bbad0aaSGuangbin Huang 	shap_cfg_cmd->pri_id = pri_id;
19202bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
19212bbad0aaSGuangbin Huang 	if (ret) {
19222bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
19232bbad0aaSGuangbin Huang 			"failed to get priority shaper(%#x), ret = %d\n",
19242bbad0aaSGuangbin Huang 			cmd, ret);
19252bbad0aaSGuangbin Huang 		return ret;
19262bbad0aaSGuangbin Huang 	}
19272bbad0aaSGuangbin Huang 
19282bbad0aaSGuangbin Huang 	shapping_para = le32_to_cpu(shap_cfg_cmd->pri_shapping_para);
19292bbad0aaSGuangbin Huang 	para->ir_b = hclge_tm_get_field(shapping_para, IR_B);
19302bbad0aaSGuangbin Huang 	para->ir_u = hclge_tm_get_field(shapping_para, IR_U);
19312bbad0aaSGuangbin Huang 	para->ir_s = hclge_tm_get_field(shapping_para, IR_S);
19322bbad0aaSGuangbin Huang 	para->bs_b = hclge_tm_get_field(shapping_para, BS_B);
19332bbad0aaSGuangbin Huang 	para->bs_s = hclge_tm_get_field(shapping_para, BS_S);
19342bbad0aaSGuangbin Huang 	para->flag = shap_cfg_cmd->flag;
19352bbad0aaSGuangbin Huang 	para->rate = le32_to_cpu(shap_cfg_cmd->pri_rate);
19362bbad0aaSGuangbin Huang 	return 0;
19372bbad0aaSGuangbin Huang }
19387679f28eSGuangbin Huang 
hclge_tm_get_q_to_qs_map(struct hclge_dev * hdev,u16 q_id,u16 * qset_id)19397679f28eSGuangbin Huang int hclge_tm_get_q_to_qs_map(struct hclge_dev *hdev, u16 q_id, u16 *qset_id)
19407679f28eSGuangbin Huang {
19417679f28eSGuangbin Huang 	struct hclge_nq_to_qs_link_cmd *map;
19427679f28eSGuangbin Huang 	struct hclge_desc desc;
19437679f28eSGuangbin Huang 	u16 qs_id_l;
19447679f28eSGuangbin Huang 	u16 qs_id_h;
19457679f28eSGuangbin Huang 	int ret;
19467679f28eSGuangbin Huang 
19477679f28eSGuangbin Huang 	map = (struct hclge_nq_to_qs_link_cmd *)desc.data;
19487679f28eSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NQ_TO_QS_LINK, true);
19497679f28eSGuangbin Huang 	map->nq_id = cpu_to_le16(q_id);
19507679f28eSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
19517679f28eSGuangbin Huang 	if (ret) {
19527679f28eSGuangbin Huang 		dev_err(&hdev->pdev->dev,
19537679f28eSGuangbin Huang 			"failed to get queue to qset map, ret = %d\n", ret);
19547679f28eSGuangbin Huang 		return ret;
19557679f28eSGuangbin Huang 	}
19567679f28eSGuangbin Huang 	*qset_id = le16_to_cpu(map->qset_id);
19577679f28eSGuangbin Huang 
19587679f28eSGuangbin Huang 	/* convert qset_id to the following format, drop the vld bit
19597679f28eSGuangbin Huang 	 *            | qs_id_h | vld | qs_id_l |
19607679f28eSGuangbin Huang 	 * qset_id:   | 15 ~ 11 |  10 |  9 ~ 0  |
19617679f28eSGuangbin Huang 	 *             \         \   /         /
19627679f28eSGuangbin Huang 	 *              \         \ /         /
19637679f28eSGuangbin Huang 	 * qset_id: | 15 | 14 ~ 10 |  9 ~ 0  |
19647679f28eSGuangbin Huang 	 */
19657679f28eSGuangbin Huang 	qs_id_l = hnae3_get_field(*qset_id, HCLGE_TM_QS_ID_L_MSK,
19667679f28eSGuangbin Huang 				  HCLGE_TM_QS_ID_L_S);
19677679f28eSGuangbin Huang 	qs_id_h = hnae3_get_field(*qset_id, HCLGE_TM_QS_ID_H_EXT_MSK,
19687679f28eSGuangbin Huang 				  HCLGE_TM_QS_ID_H_EXT_S);
19697679f28eSGuangbin Huang 	*qset_id = 0;
19707679f28eSGuangbin Huang 	hnae3_set_field(*qset_id, HCLGE_TM_QS_ID_L_MSK, HCLGE_TM_QS_ID_L_S,
19717679f28eSGuangbin Huang 			qs_id_l);
19727679f28eSGuangbin Huang 	hnae3_set_field(*qset_id, HCLGE_TM_QS_ID_H_MSK, HCLGE_TM_QS_ID_H_S,
19737679f28eSGuangbin Huang 			qs_id_h);
19747679f28eSGuangbin Huang 	return 0;
19757679f28eSGuangbin Huang }
19767679f28eSGuangbin Huang 
hclge_tm_get_q_to_tc(struct hclge_dev * hdev,u16 q_id,u8 * tc_id)19777679f28eSGuangbin Huang int hclge_tm_get_q_to_tc(struct hclge_dev *hdev, u16 q_id, u8 *tc_id)
19787679f28eSGuangbin Huang {
19797679f28eSGuangbin Huang #define HCLGE_TM_TC_MASK		0x7
19807679f28eSGuangbin Huang 
19817679f28eSGuangbin Huang 	struct hclge_tqp_tx_queue_tc_cmd *tc;
19827679f28eSGuangbin Huang 	struct hclge_desc desc;
19837679f28eSGuangbin Huang 	int ret;
19847679f28eSGuangbin Huang 
19857679f28eSGuangbin Huang 	tc = (struct hclge_tqp_tx_queue_tc_cmd *)desc.data;
19867679f28eSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TQP_TX_QUEUE_TC, true);
19877679f28eSGuangbin Huang 	tc->queue_id = cpu_to_le16(q_id);
19887679f28eSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
19897679f28eSGuangbin Huang 	if (ret) {
19907679f28eSGuangbin Huang 		dev_err(&hdev->pdev->dev,
19917679f28eSGuangbin Huang 			"failed to get queue to tc map, ret = %d\n", ret);
19927679f28eSGuangbin Huang 		return ret;
19937679f28eSGuangbin Huang 	}
19947679f28eSGuangbin Huang 
19957679f28eSGuangbin Huang 	*tc_id = tc->tc_id & HCLGE_TM_TC_MASK;
19967679f28eSGuangbin Huang 	return 0;
19977679f28eSGuangbin Huang }
1998cad7c215SGuangbin Huang 
hclge_tm_get_pg_to_pri_map(struct hclge_dev * hdev,u8 pg_id,u8 * pri_bit_map)1999cad7c215SGuangbin Huang int hclge_tm_get_pg_to_pri_map(struct hclge_dev *hdev, u8 pg_id,
2000cad7c215SGuangbin Huang 			       u8 *pri_bit_map)
2001cad7c215SGuangbin Huang {
2002cad7c215SGuangbin Huang 	struct hclge_pg_to_pri_link_cmd *map;
2003cad7c215SGuangbin Huang 	struct hclge_desc desc;
2004cad7c215SGuangbin Huang 	int ret;
2005cad7c215SGuangbin Huang 
2006cad7c215SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_TO_PRI_LINK, true);
2007cad7c215SGuangbin Huang 	map = (struct hclge_pg_to_pri_link_cmd *)desc.data;
2008cad7c215SGuangbin Huang 	map->pg_id = pg_id;
2009cad7c215SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
2010cad7c215SGuangbin Huang 	if (ret) {
2011cad7c215SGuangbin Huang 		dev_err(&hdev->pdev->dev,
2012cad7c215SGuangbin Huang 			"failed to get pg to pri map, ret = %d\n", ret);
2013cad7c215SGuangbin Huang 		return ret;
2014cad7c215SGuangbin Huang 	}
2015cad7c215SGuangbin Huang 
2016cad7c215SGuangbin Huang 	*pri_bit_map = map->pri_bit_map;
2017cad7c215SGuangbin Huang 	return 0;
2018cad7c215SGuangbin Huang }
2019cad7c215SGuangbin Huang 
hclge_tm_get_pg_weight(struct hclge_dev * hdev,u8 pg_id,u8 * weight)2020cad7c215SGuangbin Huang int hclge_tm_get_pg_weight(struct hclge_dev *hdev, u8 pg_id, u8 *weight)
2021cad7c215SGuangbin Huang {
2022cad7c215SGuangbin Huang 	struct hclge_pg_weight_cmd *pg_weight_cmd;
2023cad7c215SGuangbin Huang 	struct hclge_desc desc;
2024cad7c215SGuangbin Huang 	int ret;
2025cad7c215SGuangbin Huang 
2026cad7c215SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_WEIGHT, true);
2027cad7c215SGuangbin Huang 	pg_weight_cmd = (struct hclge_pg_weight_cmd *)desc.data;
2028cad7c215SGuangbin Huang 	pg_weight_cmd->pg_id = pg_id;
2029cad7c215SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
2030cad7c215SGuangbin Huang 	if (ret) {
2031cad7c215SGuangbin Huang 		dev_err(&hdev->pdev->dev,
2032cad7c215SGuangbin Huang 			"failed to get pg weight, ret = %d\n", ret);
2033cad7c215SGuangbin Huang 		return ret;
2034cad7c215SGuangbin Huang 	}
2035cad7c215SGuangbin Huang 
2036cad7c215SGuangbin Huang 	*weight = pg_weight_cmd->dwrr;
2037cad7c215SGuangbin Huang 	return 0;
2038cad7c215SGuangbin Huang }
2039cad7c215SGuangbin Huang 
hclge_tm_get_pg_sch_mode(struct hclge_dev * hdev,u8 pg_id,u8 * mode)2040cad7c215SGuangbin Huang int hclge_tm_get_pg_sch_mode(struct hclge_dev *hdev, u8 pg_id, u8 *mode)
2041cad7c215SGuangbin Huang {
2042cad7c215SGuangbin Huang 	struct hclge_desc desc;
2043cad7c215SGuangbin Huang 	int ret;
2044cad7c215SGuangbin Huang 
2045cad7c215SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_SCH_MODE_CFG, true);
2046cad7c215SGuangbin Huang 	desc.data[0] = cpu_to_le32(pg_id);
2047cad7c215SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
2048cad7c215SGuangbin Huang 	if (ret) {
2049cad7c215SGuangbin Huang 		dev_err(&hdev->pdev->dev,
2050cad7c215SGuangbin Huang 			"failed to get pg sch mode, ret = %d\n", ret);
2051cad7c215SGuangbin Huang 		return ret;
2052cad7c215SGuangbin Huang 	}
2053cad7c215SGuangbin Huang 
2054cad7c215SGuangbin Huang 	*mode = (u8)le32_to_cpu(desc.data[1]);
2055cad7c215SGuangbin Huang 	return 0;
2056cad7c215SGuangbin Huang }
2057cad7c215SGuangbin Huang 
hclge_tm_get_pg_shaper(struct hclge_dev * hdev,u8 pg_id,enum hclge_opcode_type cmd,struct hclge_tm_shaper_para * para)2058cad7c215SGuangbin Huang int hclge_tm_get_pg_shaper(struct hclge_dev *hdev, u8 pg_id,
2059cad7c215SGuangbin Huang 			   enum hclge_opcode_type cmd,
2060cad7c215SGuangbin Huang 			   struct hclge_tm_shaper_para *para)
2061cad7c215SGuangbin Huang {
2062cad7c215SGuangbin Huang 	struct hclge_pg_shapping_cmd *shap_cfg_cmd;
2063cad7c215SGuangbin Huang 	struct hclge_desc desc;
2064cad7c215SGuangbin Huang 	u32 shapping_para;
2065cad7c215SGuangbin Huang 	int ret;
2066cad7c215SGuangbin Huang 
2067cad7c215SGuangbin Huang 	if (cmd != HCLGE_OPC_TM_PG_C_SHAPPING &&
2068cad7c215SGuangbin Huang 	    cmd != HCLGE_OPC_TM_PG_P_SHAPPING)
2069cad7c215SGuangbin Huang 		return -EINVAL;
2070cad7c215SGuangbin Huang 
2071cad7c215SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, cmd, true);
2072cad7c215SGuangbin Huang 	shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data;
2073cad7c215SGuangbin Huang 	shap_cfg_cmd->pg_id = pg_id;
2074cad7c215SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
2075cad7c215SGuangbin Huang 	if (ret) {
2076cad7c215SGuangbin Huang 		dev_err(&hdev->pdev->dev,
2077cad7c215SGuangbin Huang 			"failed to get pg shaper(%#x), ret = %d\n",
2078cad7c215SGuangbin Huang 			cmd, ret);
2079cad7c215SGuangbin Huang 		return ret;
2080cad7c215SGuangbin Huang 	}
2081cad7c215SGuangbin Huang 
2082cad7c215SGuangbin Huang 	shapping_para = le32_to_cpu(shap_cfg_cmd->pg_shapping_para);
2083cad7c215SGuangbin Huang 	para->ir_b = hclge_tm_get_field(shapping_para, IR_B);
2084cad7c215SGuangbin Huang 	para->ir_u = hclge_tm_get_field(shapping_para, IR_U);
2085cad7c215SGuangbin Huang 	para->ir_s = hclge_tm_get_field(shapping_para, IR_S);
2086cad7c215SGuangbin Huang 	para->bs_b = hclge_tm_get_field(shapping_para, BS_B);
2087cad7c215SGuangbin Huang 	para->bs_s = hclge_tm_get_field(shapping_para, BS_S);
2088cad7c215SGuangbin Huang 	para->flag = shap_cfg_cmd->flag;
2089cad7c215SGuangbin Huang 	para->rate = le32_to_cpu(shap_cfg_cmd->pg_rate);
2090cad7c215SGuangbin Huang 	return 0;
2091cad7c215SGuangbin Huang }
2092cad7c215SGuangbin Huang 
hclge_tm_get_port_shaper(struct hclge_dev * hdev,struct hclge_tm_shaper_para * para)2093cad7c215SGuangbin Huang int hclge_tm_get_port_shaper(struct hclge_dev *hdev,
2094cad7c215SGuangbin Huang 			     struct hclge_tm_shaper_para *para)
2095cad7c215SGuangbin Huang {
2096cad7c215SGuangbin Huang 	struct hclge_port_shapping_cmd *port_shap_cfg_cmd;
2097cad7c215SGuangbin Huang 	struct hclge_desc desc;
2098cad7c215SGuangbin Huang 	u32 shapping_para;
2099cad7c215SGuangbin Huang 	int ret;
2100cad7c215SGuangbin Huang 
2101cad7c215SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PORT_SHAPPING, true);
2102cad7c215SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
2103cad7c215SGuangbin Huang 	if (ret) {
2104cad7c215SGuangbin Huang 		dev_err(&hdev->pdev->dev,
2105cad7c215SGuangbin Huang 			"failed to get port shaper, ret = %d\n", ret);
2106cad7c215SGuangbin Huang 		return ret;
2107cad7c215SGuangbin Huang 	}
2108cad7c215SGuangbin Huang 
2109cad7c215SGuangbin Huang 	port_shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data;
2110cad7c215SGuangbin Huang 	shapping_para = le32_to_cpu(port_shap_cfg_cmd->port_shapping_para);
2111cad7c215SGuangbin Huang 	para->ir_b = hclge_tm_get_field(shapping_para, IR_B);
2112cad7c215SGuangbin Huang 	para->ir_u = hclge_tm_get_field(shapping_para, IR_U);
2113cad7c215SGuangbin Huang 	para->ir_s = hclge_tm_get_field(shapping_para, IR_S);
2114cad7c215SGuangbin Huang 	para->bs_b = hclge_tm_get_field(shapping_para, BS_B);
2115cad7c215SGuangbin Huang 	para->bs_s = hclge_tm_get_field(shapping_para, BS_S);
2116cad7c215SGuangbin Huang 	para->flag = port_shap_cfg_cmd->flag;
2117cad7c215SGuangbin Huang 	para->rate = le32_to_cpu(port_shap_cfg_cmd->port_rate);
2118cad7c215SGuangbin Huang 
2119cad7c215SGuangbin Huang 	return 0;
2120cad7c215SGuangbin Huang }
21216d233612SHao Lan 
hclge_tm_flush_cfg(struct hclge_dev * hdev,bool enable)21226d233612SHao Lan int hclge_tm_flush_cfg(struct hclge_dev *hdev, bool enable)
21236d233612SHao Lan {
21246d233612SHao Lan 	struct hclge_desc desc;
21256d233612SHao Lan 	int ret;
21266d233612SHao Lan 
21276d233612SHao Lan 	if (!hnae3_ae_dev_tm_flush_supported(hdev))
21286d233612SHao Lan 		return 0;
21296d233612SHao Lan 
21306d233612SHao Lan 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_FLUSH, false);
21316d233612SHao Lan 
21326d233612SHao Lan 	desc.data[0] = cpu_to_le32(enable ? HCLGE_TM_FLUSH_EN_MSK : 0);
21336d233612SHao Lan 
21346d233612SHao Lan 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
21356d233612SHao Lan 	if (ret) {
21366d233612SHao Lan 		dev_err(&hdev->pdev->dev,
21376d233612SHao Lan 			"failed to config tm flush, ret = %d\n", ret);
21386d233612SHao Lan 		return ret;
21396d233612SHao Lan 	}
21406d233612SHao Lan 
21416d233612SHao Lan 	if (enable)
21426d233612SHao Lan 		msleep(HCLGE_TM_FLUSH_TIME_MS);
21436d233612SHao Lan 
21446d233612SHao Lan 	return ret;
21456d233612SHao Lan }
2146