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