1d71d8381SJian Shen // SPDX-License-Identifier: GPL-2.0+
2d71d8381SJian Shen // Copyright (c) 2016-2017 Hisilicon Limited.
384844054SSalil 
484844054SSalil #include <linux/etherdevice.h>
584844054SSalil 
684844054SSalil #include "hclge_cmd.h"
784844054SSalil #include "hclge_main.h"
884844054SSalil #include "hclge_tm.h"
984844054SSalil 
1084844054SSalil enum hclge_shaper_level {
1184844054SSalil 	HCLGE_SHAPER_LVL_PRI	= 0,
1284844054SSalil 	HCLGE_SHAPER_LVL_PG	= 1,
1384844054SSalil 	HCLGE_SHAPER_LVL_PORT	= 2,
1484844054SSalil 	HCLGE_SHAPER_LVL_QSET	= 3,
1584844054SSalil 	HCLGE_SHAPER_LVL_CNT	= 4,
1684844054SSalil 	HCLGE_SHAPER_LVL_VF	= 0,
1784844054SSalil 	HCLGE_SHAPER_LVL_PF	= 1,
1884844054SSalil };
1984844054SSalil 
2064fd2300SPeng Li #define HCLGE_TM_PFC_PKT_GET_CMD_NUM	3
2164fd2300SPeng Li #define HCLGE_TM_PFC_NUM_GET_PER_CMD	3
2264fd2300SPeng Li 
233a7d5958SPeng Li #define HCLGE_SHAPER_BS_U_DEF	5
243a7d5958SPeng Li #define HCLGE_SHAPER_BS_S_DEF	20
2584844054SSalil 
2684844054SSalil /* hclge_shaper_para_calc: calculate ir parameter for the shaper
2784844054SSalil  * @ir: Rate to be config, its unit is Mbps
2884844054SSalil  * @shaper_level: the shaper level. eg: port, pg, priority, queueset
29ff7e4d0dSHuazhong Tan  * @ir_para: parameters of IR shaper
30d9c7d20dSGuangbin Huang  * @max_tm_rate: max tm rate is available to config
3184844054SSalil  *
3284844054SSalil  * the formula:
3384844054SSalil  *
3484844054SSalil  *		IR_b * (2 ^ IR_u) * 8
3584844054SSalil  * IR(Mbps) = -------------------------  *  CLOCK(1000Mbps)
3684844054SSalil  *		Tick * (2 ^ IR_s)
3784844054SSalil  *
3884844054SSalil  * @return: 0: calculate sucessful, negative: fail
3984844054SSalil  */
4084844054SSalil static int hclge_shaper_para_calc(u32 ir, u8 shaper_level,
41ff7e4d0dSHuazhong Tan 				  struct hclge_shaper_ir_para *ir_para,
42d9c7d20dSGuangbin Huang 				  u32 max_tm_rate)
4384844054SSalil {
449d2a1ceaSPeng Li #define DEFAULT_SHAPER_IR_B	126
45b37ce587SYufeng Mo #define DIVISOR_CLK		(1000 * 8)
469d2a1ceaSPeng Li #define DEFAULT_DIVISOR_IR_B	(DEFAULT_SHAPER_IR_B * DIVISOR_CLK)
47b37ce587SYufeng Mo 
483ea7af9eSColin Ian King 	static const u16 tick_array[HCLGE_SHAPER_LVL_CNT] = {
4984844054SSalil 		6 * 256,        /* Prioriy level */
5084844054SSalil 		6 * 32,         /* Prioriy group level */
5184844054SSalil 		6 * 8,          /* Port level */
5284844054SSalil 		6 * 256         /* Qset level */
5384844054SSalil 	};
549b2f3477SWeihang Li 	u8 ir_u_calc = 0;
559b2f3477SWeihang Li 	u8 ir_s_calc = 0;
5684844054SSalil 	u32 ir_calc;
5784844054SSalil 	u32 tick;
5884844054SSalil 
5984844054SSalil 	/* Calc tick */
6004f25edbSYunsheng Lin 	if (shaper_level >= HCLGE_SHAPER_LVL_CNT ||
61d9c7d20dSGuangbin Huang 	    ir > max_tm_rate)
6284844054SSalil 		return -EINVAL;
6384844054SSalil 
6484844054SSalil 	tick = tick_array[shaper_level];
6584844054SSalil 
6684844054SSalil 	/**
6784844054SSalil 	 * Calc the speed if ir_b = 126, ir_u = 0 and ir_s = 0
6884844054SSalil 	 * the formula is changed to:
6984844054SSalil 	 *		126 * 1 * 8
7084844054SSalil 	 * ir_calc = ---------------- * 1000
7184844054SSalil 	 *		tick * 1
7284844054SSalil 	 */
739d2a1ceaSPeng Li 	ir_calc = (DEFAULT_DIVISOR_IR_B + (tick >> 1) - 1) / tick;
7484844054SSalil 
7584844054SSalil 	if (ir_calc == ir) {
769d2a1ceaSPeng Li 		ir_para->ir_b = DEFAULT_SHAPER_IR_B;
77ff7e4d0dSHuazhong Tan 		ir_para->ir_u = 0;
78ff7e4d0dSHuazhong Tan 		ir_para->ir_s = 0;
7984844054SSalil 
8084844054SSalil 		return 0;
8184844054SSalil 	} else if (ir_calc > ir) {
8284844054SSalil 		/* Increasing the denominator to select ir_s value */
831a92497dSYonglong Liu 		while (ir_calc >= ir && ir) {
8484844054SSalil 			ir_s_calc++;
859d2a1ceaSPeng Li 			ir_calc = DEFAULT_DIVISOR_IR_B /
869d2a1ceaSPeng Li 				  (tick * (1 << ir_s_calc));
8784844054SSalil 		}
8884844054SSalil 
89ff7e4d0dSHuazhong Tan 		ir_para->ir_b = (ir * tick * (1 << ir_s_calc) +
90ff7e4d0dSHuazhong Tan 				(DIVISOR_CLK >> 1)) / DIVISOR_CLK;
9184844054SSalil 	} else {
9284844054SSalil 		/* Increasing the numerator to select ir_u value */
9384844054SSalil 		u32 numerator;
9484844054SSalil 
9584844054SSalil 		while (ir_calc < ir) {
9684844054SSalil 			ir_u_calc++;
979d2a1ceaSPeng Li 			numerator = DEFAULT_DIVISOR_IR_B * (1 << ir_u_calc);
9884844054SSalil 			ir_calc = (numerator + (tick >> 1)) / tick;
9984844054SSalil 		}
10084844054SSalil 
10184844054SSalil 		if (ir_calc == ir) {
1029d2a1ceaSPeng Li 			ir_para->ir_b = DEFAULT_SHAPER_IR_B;
10384844054SSalil 		} else {
1041a92497dSYonglong Liu 			u32 denominator = DIVISOR_CLK * (1 << --ir_u_calc);
105ff7e4d0dSHuazhong Tan 			ir_para->ir_b = (ir * tick + (denominator >> 1)) /
106ff7e4d0dSHuazhong Tan 					denominator;
10784844054SSalil 		}
10884844054SSalil 	}
10984844054SSalil 
110ff7e4d0dSHuazhong Tan 	ir_para->ir_u = ir_u_calc;
111ff7e4d0dSHuazhong Tan 	ir_para->ir_s = ir_s_calc;
11284844054SSalil 
11384844054SSalil 	return 0;
11484844054SSalil }
11584844054SSalil 
11664fd2300SPeng Li static int hclge_pfc_stats_get(struct hclge_dev *hdev,
11764fd2300SPeng Li 			       enum hclge_opcode_type opcode, u64 *stats)
11864fd2300SPeng Li {
11964fd2300SPeng Li 	struct hclge_desc desc[HCLGE_TM_PFC_PKT_GET_CMD_NUM];
12064fd2300SPeng Li 	int ret, i, j;
12164fd2300SPeng Li 
12264fd2300SPeng Li 	if (!(opcode == HCLGE_OPC_QUERY_PFC_RX_PKT_CNT ||
12364fd2300SPeng Li 	      opcode == HCLGE_OPC_QUERY_PFC_TX_PKT_CNT))
12464fd2300SPeng Li 		return -EINVAL;
12564fd2300SPeng Li 
12663cbf7a9SYufeng Mo 	for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM - 1; i++) {
12764fd2300SPeng Li 		hclge_cmd_setup_basic_desc(&desc[i], opcode, true);
12864fd2300SPeng Li 		desc[i].flag |= cpu_to_le16(HCLGE_CMD_FLAG_NEXT);
12964fd2300SPeng Li 	}
13064fd2300SPeng Li 
13163cbf7a9SYufeng Mo 	hclge_cmd_setup_basic_desc(&desc[i], opcode, true);
13263cbf7a9SYufeng Mo 
13364fd2300SPeng Li 	ret = hclge_cmd_send(&hdev->hw, desc, HCLGE_TM_PFC_PKT_GET_CMD_NUM);
13420670328SYunsheng Lin 	if (ret)
13564fd2300SPeng Li 		return ret;
13664fd2300SPeng Li 
13764fd2300SPeng Li 	for (i = 0; i < HCLGE_TM_PFC_PKT_GET_CMD_NUM; i++) {
13864fd2300SPeng Li 		struct hclge_pfc_stats_cmd *pfc_stats =
13964fd2300SPeng Li 				(struct hclge_pfc_stats_cmd *)desc[i].data;
14064fd2300SPeng Li 
14164fd2300SPeng Li 		for (j = 0; j < HCLGE_TM_PFC_NUM_GET_PER_CMD; j++) {
14264fd2300SPeng Li 			u32 index = i * HCLGE_TM_PFC_PKT_GET_CMD_NUM + j;
14364fd2300SPeng Li 
14464fd2300SPeng Li 			if (index < HCLGE_MAX_TC_NUM)
14564fd2300SPeng Li 				stats[index] =
14664fd2300SPeng Li 					le64_to_cpu(pfc_stats->pkt_num[j]);
14764fd2300SPeng Li 		}
14864fd2300SPeng Li 	}
14964fd2300SPeng Li 	return 0;
15064fd2300SPeng Li }
15164fd2300SPeng Li 
15264fd2300SPeng Li int hclge_pfc_rx_stats_get(struct hclge_dev *hdev, u64 *stats)
15364fd2300SPeng Li {
15464fd2300SPeng Li 	return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_RX_PKT_CNT, stats);
15564fd2300SPeng Li }
15664fd2300SPeng Li 
15764fd2300SPeng Li int hclge_pfc_tx_stats_get(struct hclge_dev *hdev, u64 *stats)
15864fd2300SPeng Li {
15964fd2300SPeng Li 	return hclge_pfc_stats_get(hdev, HCLGE_OPC_QUERY_PFC_TX_PKT_CNT, stats);
16064fd2300SPeng Li }
16164fd2300SPeng Li 
16261387774SPeng Li int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)
16384844054SSalil {
16484844054SSalil 	struct hclge_desc desc;
16584844054SSalil 
16684844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PAUSE_EN, false);
16784844054SSalil 
16884844054SSalil 	desc.data[0] = cpu_to_le32((tx ? HCLGE_TX_MAC_PAUSE_EN_MSK : 0) |
16984844054SSalil 		(rx ? HCLGE_RX_MAC_PAUSE_EN_MSK : 0));
17084844054SSalil 
17184844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
17284844054SSalil }
17384844054SSalil 
1749dc2145dSYunsheng Lin static int hclge_pfc_pause_en_cfg(struct hclge_dev *hdev, u8 tx_rx_bitmap,
1759dc2145dSYunsheng Lin 				  u8 pfc_bitmap)
1769dc2145dSYunsheng Lin {
1779dc2145dSYunsheng Lin 	struct hclge_desc desc;
178d0d72bacSJian Shen 	struct hclge_pfc_en_cmd *pfc = (struct hclge_pfc_en_cmd *)desc.data;
1799dc2145dSYunsheng Lin 
1809dc2145dSYunsheng Lin 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_PFC_PAUSE_EN, false);
1819dc2145dSYunsheng Lin 
1829dc2145dSYunsheng Lin 	pfc->tx_rx_en_bitmap = tx_rx_bitmap;
1839dc2145dSYunsheng Lin 	pfc->pri_en_bitmap = pfc_bitmap;
1849dc2145dSYunsheng Lin 
1859dc2145dSYunsheng Lin 	return hclge_cmd_send(&hdev->hw, &desc, 1);
1869dc2145dSYunsheng Lin }
1879dc2145dSYunsheng Lin 
188e98d7183SFuyun Liang static int hclge_pause_param_cfg(struct hclge_dev *hdev, const u8 *addr,
18918838d0cSFuyun Liang 				 u8 pause_trans_gap, u16 pause_trans_time)
19018838d0cSFuyun Liang {
19118838d0cSFuyun Liang 	struct hclge_cfg_pause_param_cmd *pause_param;
19218838d0cSFuyun Liang 	struct hclge_desc desc;
19318838d0cSFuyun Liang 
194d0d72bacSJian Shen 	pause_param = (struct hclge_cfg_pause_param_cmd *)desc.data;
19518838d0cSFuyun Liang 
19618838d0cSFuyun Liang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, false);
19718838d0cSFuyun Liang 
19818838d0cSFuyun Liang 	ether_addr_copy(pause_param->mac_addr, addr);
199cd2086bfSFuyun Liang 	ether_addr_copy(pause_param->mac_addr_extra, addr);
20018838d0cSFuyun Liang 	pause_param->pause_trans_gap = pause_trans_gap;
20118838d0cSFuyun Liang 	pause_param->pause_trans_time = cpu_to_le16(pause_trans_time);
20218838d0cSFuyun Liang 
20318838d0cSFuyun Liang 	return hclge_cmd_send(&hdev->hw, &desc, 1);
20418838d0cSFuyun Liang }
20518838d0cSFuyun Liang 
206e98d7183SFuyun Liang int hclge_pause_addr_cfg(struct hclge_dev *hdev, const u8 *mac_addr)
20718838d0cSFuyun Liang {
20818838d0cSFuyun Liang 	struct hclge_cfg_pause_param_cmd *pause_param;
20918838d0cSFuyun Liang 	struct hclge_desc desc;
21018838d0cSFuyun Liang 	u16 trans_time;
21118838d0cSFuyun Liang 	u8 trans_gap;
21218838d0cSFuyun Liang 	int ret;
21318838d0cSFuyun Liang 
214d0d72bacSJian Shen 	pause_param = (struct hclge_cfg_pause_param_cmd *)desc.data;
21518838d0cSFuyun Liang 
21618838d0cSFuyun Liang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PARA, true);
21718838d0cSFuyun Liang 
21818838d0cSFuyun Liang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
21918838d0cSFuyun Liang 	if (ret)
22018838d0cSFuyun Liang 		return ret;
22118838d0cSFuyun Liang 
22218838d0cSFuyun Liang 	trans_gap = pause_param->pause_trans_gap;
22318838d0cSFuyun Liang 	trans_time = le16_to_cpu(pause_param->pause_trans_time);
22418838d0cSFuyun Liang 
2259b2f3477SWeihang Li 	return hclge_pause_param_cfg(hdev, mac_addr, trans_gap, trans_time);
22618838d0cSFuyun Liang }
22718838d0cSFuyun Liang 
22884844054SSalil static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id)
22984844054SSalil {
23084844054SSalil 	u8 tc;
23184844054SSalil 
232c5795c53SYunsheng Lin 	tc = hdev->tm_info.prio_tc[pri_id];
23384844054SSalil 
23484844054SSalil 	if (tc >= hdev->tm_info.num_tc)
23584844054SSalil 		return -EINVAL;
23684844054SSalil 
23784844054SSalil 	/**
23884844054SSalil 	 * the register for priority has four bytes, the first bytes includes
23984844054SSalil 	 *  priority0 and priority1, the higher 4bit stands for priority1
24084844054SSalil 	 *  while the lower 4bit stands for priority0, as below:
24184844054SSalil 	 * first byte:	| pri_1 | pri_0 |
24284844054SSalil 	 * second byte:	| pri_3 | pri_2 |
24384844054SSalil 	 * third byte:	| pri_5 | pri_4 |
24484844054SSalil 	 * fourth byte:	| pri_7 | pri_6 |
24584844054SSalil 	 */
24684844054SSalil 	pri[pri_id >> 1] |= tc << ((pri_id & 1) * 4);
24784844054SSalil 
24884844054SSalil 	return 0;
24984844054SSalil }
25084844054SSalil 
25184844054SSalil static int hclge_up_to_tc_map(struct hclge_dev *hdev)
25284844054SSalil {
25384844054SSalil 	struct hclge_desc desc;
25484844054SSalil 	u8 *pri = (u8 *)desc.data;
25584844054SSalil 	u8 pri_id;
25684844054SSalil 	int ret;
25784844054SSalil 
25884844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PRI_TO_TC_MAPPING, false);
25984844054SSalil 
260c5795c53SYunsheng Lin 	for (pri_id = 0; pri_id < HNAE3_MAX_USER_PRIO; pri_id++) {
26184844054SSalil 		ret = hclge_fill_pri_array(hdev, pri, pri_id);
26284844054SSalil 		if (ret)
26384844054SSalil 			return ret;
26484844054SSalil 	}
26584844054SSalil 
26684844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
26784844054SSalil }
26884844054SSalil 
26984844054SSalil static int hclge_tm_pg_to_pri_map_cfg(struct hclge_dev *hdev,
27084844054SSalil 				      u8 pg_id, u8 pri_bit_map)
27184844054SSalil {
27284844054SSalil 	struct hclge_pg_to_pri_link_cmd *map;
27384844054SSalil 	struct hclge_desc desc;
27484844054SSalil 
27584844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_TO_PRI_LINK, false);
27684844054SSalil 
27784844054SSalil 	map = (struct hclge_pg_to_pri_link_cmd *)desc.data;
27884844054SSalil 
27984844054SSalil 	map->pg_id = pg_id;
28084844054SSalil 	map->pri_bit_map = pri_bit_map;
28184844054SSalil 
28284844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
28384844054SSalil }
28484844054SSalil 
28584844054SSalil static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev,
28684844054SSalil 				      u16 qs_id, u8 pri)
28784844054SSalil {
28884844054SSalil 	struct hclge_qs_to_pri_link_cmd *map;
28984844054SSalil 	struct hclge_desc desc;
29084844054SSalil 
29184844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_TO_PRI_LINK, false);
29284844054SSalil 
29384844054SSalil 	map = (struct hclge_qs_to_pri_link_cmd *)desc.data;
29484844054SSalil 
29584844054SSalil 	map->qs_id = cpu_to_le16(qs_id);
29684844054SSalil 	map->priority = pri;
29784844054SSalil 	map->link_vld = HCLGE_TM_QS_PRI_LINK_VLD_MSK;
29884844054SSalil 
29984844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
30084844054SSalil }
30184844054SSalil 
30284844054SSalil static int hclge_tm_q_to_qs_map_cfg(struct hclge_dev *hdev,
30332c7fbc8SJian Shen 				    u16 q_id, u16 qs_id)
30484844054SSalil {
30584844054SSalil 	struct hclge_nq_to_qs_link_cmd *map;
30684844054SSalil 	struct hclge_desc desc;
3079a5ef4aaSYonglong Liu 	u16 qs_id_l;
3089a5ef4aaSYonglong Liu 	u16 qs_id_h;
30984844054SSalil 
31084844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NQ_TO_QS_LINK, false);
31184844054SSalil 
31284844054SSalil 	map = (struct hclge_nq_to_qs_link_cmd *)desc.data;
31384844054SSalil 
31484844054SSalil 	map->nq_id = cpu_to_le16(q_id);
3159a5ef4aaSYonglong Liu 
3169a5ef4aaSYonglong Liu 	/* convert qs_id to the following format to support qset_id >= 1024
3179a5ef4aaSYonglong Liu 	 * qs_id: | 15 | 14 ~ 10 |  9 ~ 0   |
3189a5ef4aaSYonglong Liu 	 *            /         / \         \
3199a5ef4aaSYonglong Liu 	 *           /         /   \         \
3209a5ef4aaSYonglong Liu 	 * qset_id: | 15 ~ 11 |  10 |  9 ~ 0  |
3219a5ef4aaSYonglong Liu 	 *          | qs_id_h | vld | qs_id_l |
3229a5ef4aaSYonglong Liu 	 */
3239a5ef4aaSYonglong Liu 	qs_id_l = hnae3_get_field(qs_id, HCLGE_TM_QS_ID_L_MSK,
3249a5ef4aaSYonglong Liu 				  HCLGE_TM_QS_ID_L_S);
3259a5ef4aaSYonglong Liu 	qs_id_h = hnae3_get_field(qs_id, HCLGE_TM_QS_ID_H_MSK,
3269a5ef4aaSYonglong Liu 				  HCLGE_TM_QS_ID_H_S);
3279a5ef4aaSYonglong Liu 	hnae3_set_field(qs_id, HCLGE_TM_QS_ID_L_MSK, HCLGE_TM_QS_ID_L_S,
3289a5ef4aaSYonglong Liu 			qs_id_l);
3299a5ef4aaSYonglong Liu 	hnae3_set_field(qs_id, HCLGE_TM_QS_ID_H_EXT_MSK, HCLGE_TM_QS_ID_H_EXT_S,
3309a5ef4aaSYonglong Liu 			qs_id_h);
33184844054SSalil 	map->qset_id = cpu_to_le16(qs_id | HCLGE_TM_Q_QS_LINK_VLD_MSK);
33284844054SSalil 
33384844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
33484844054SSalil }
33584844054SSalil 
33684844054SSalil static int hclge_tm_pg_weight_cfg(struct hclge_dev *hdev, u8 pg_id,
33784844054SSalil 				  u8 dwrr)
33884844054SSalil {
33984844054SSalil 	struct hclge_pg_weight_cmd *weight;
34084844054SSalil 	struct hclge_desc desc;
34184844054SSalil 
34284844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_WEIGHT, false);
34384844054SSalil 
34484844054SSalil 	weight = (struct hclge_pg_weight_cmd *)desc.data;
34584844054SSalil 
34684844054SSalil 	weight->pg_id = pg_id;
34784844054SSalil 	weight->dwrr = dwrr;
34884844054SSalil 
34984844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
35084844054SSalil }
35184844054SSalil 
35284844054SSalil static int hclge_tm_pri_weight_cfg(struct hclge_dev *hdev, u8 pri_id,
35384844054SSalil 				   u8 dwrr)
35484844054SSalil {
35584844054SSalil 	struct hclge_priority_weight_cmd *weight;
35684844054SSalil 	struct hclge_desc desc;
35784844054SSalil 
35884844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_WEIGHT, false);
35984844054SSalil 
36084844054SSalil 	weight = (struct hclge_priority_weight_cmd *)desc.data;
36184844054SSalil 
36284844054SSalil 	weight->pri_id = pri_id;
36384844054SSalil 	weight->dwrr = dwrr;
36484844054SSalil 
36584844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
36684844054SSalil }
36784844054SSalil 
36884844054SSalil static int hclge_tm_qs_weight_cfg(struct hclge_dev *hdev, u16 qs_id,
36984844054SSalil 				  u8 dwrr)
37084844054SSalil {
37184844054SSalil 	struct hclge_qs_weight_cmd *weight;
37284844054SSalil 	struct hclge_desc desc;
37384844054SSalil 
37484844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_WEIGHT, false);
37584844054SSalil 
37684844054SSalil 	weight = (struct hclge_qs_weight_cmd *)desc.data;
37784844054SSalil 
37884844054SSalil 	weight->qs_id = cpu_to_le16(qs_id);
37984844054SSalil 	weight->dwrr = dwrr;
38084844054SSalil 
38184844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
38284844054SSalil }
38384844054SSalil 
38463cbf7a9SYufeng Mo static u32 hclge_tm_get_shapping_para(u8 ir_b, u8 ir_u, u8 ir_s,
38563cbf7a9SYufeng Mo 				      u8 bs_b, u8 bs_s)
38663cbf7a9SYufeng Mo {
38763cbf7a9SYufeng Mo 	u32 shapping_para = 0;
38863cbf7a9SYufeng Mo 
38963cbf7a9SYufeng Mo 	hclge_tm_set_field(shapping_para, IR_B, ir_b);
39063cbf7a9SYufeng Mo 	hclge_tm_set_field(shapping_para, IR_U, ir_u);
39163cbf7a9SYufeng Mo 	hclge_tm_set_field(shapping_para, IR_S, ir_s);
39263cbf7a9SYufeng Mo 	hclge_tm_set_field(shapping_para, BS_B, bs_b);
39363cbf7a9SYufeng Mo 	hclge_tm_set_field(shapping_para, BS_S, bs_s);
39463cbf7a9SYufeng Mo 
39563cbf7a9SYufeng Mo 	return shapping_para;
39663cbf7a9SYufeng Mo }
39763cbf7a9SYufeng Mo 
39884844054SSalil static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev,
39984844054SSalil 				    enum hclge_shap_bucket bucket, u8 pg_id,
400e364ad30SYonglong Liu 				    u32 shapping_para, u32 rate)
40184844054SSalil {
40284844054SSalil 	struct hclge_pg_shapping_cmd *shap_cfg_cmd;
40384844054SSalil 	enum hclge_opcode_type opcode;
40484844054SSalil 	struct hclge_desc desc;
40584844054SSalil 
40684844054SSalil 	opcode = bucket ? HCLGE_OPC_TM_PG_P_SHAPPING :
40784844054SSalil 		 HCLGE_OPC_TM_PG_C_SHAPPING;
40884844054SSalil 	hclge_cmd_setup_basic_desc(&desc, opcode, false);
40984844054SSalil 
41084844054SSalil 	shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data;
41184844054SSalil 
41284844054SSalil 	shap_cfg_cmd->pg_id = pg_id;
41384844054SSalil 
414a90bb9a5SYunsheng Lin 	shap_cfg_cmd->pg_shapping_para = cpu_to_le32(shapping_para);
41584844054SSalil 
416e364ad30SYonglong Liu 	hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
417e364ad30SYonglong Liu 
418e364ad30SYonglong Liu 	shap_cfg_cmd->pg_rate = cpu_to_le32(rate);
419e364ad30SYonglong Liu 
42084844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
42184844054SSalil }
42284844054SSalil 
4230a5677d3SYunsheng Lin static int hclge_tm_port_shaper_cfg(struct hclge_dev *hdev)
4240a5677d3SYunsheng Lin {
4250a5677d3SYunsheng Lin 	struct hclge_port_shapping_cmd *shap_cfg_cmd;
426ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
4270a5677d3SYunsheng Lin 	struct hclge_desc desc;
428cdd332acSGuojia Liao 	u32 shapping_para;
4290a5677d3SYunsheng Lin 	int ret;
4300a5677d3SYunsheng Lin 
431ff7e4d0dSHuazhong Tan 	ret = hclge_shaper_para_calc(hdev->hw.mac.speed, HCLGE_SHAPER_LVL_PORT,
432ff7e4d0dSHuazhong Tan 				     &ir_para,
433d9c7d20dSGuangbin Huang 				     hdev->ae_dev->dev_specs.max_tm_rate);
4340a5677d3SYunsheng Lin 	if (ret)
4350a5677d3SYunsheng Lin 		return ret;
4360a5677d3SYunsheng Lin 
4370a5677d3SYunsheng Lin 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PORT_SHAPPING, false);
4380a5677d3SYunsheng Lin 	shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data;
4390a5677d3SYunsheng Lin 
440ff7e4d0dSHuazhong Tan 	shapping_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u,
441ff7e4d0dSHuazhong Tan 						   ir_para.ir_s,
44263cbf7a9SYufeng Mo 						   HCLGE_SHAPER_BS_U_DEF,
44363cbf7a9SYufeng Mo 						   HCLGE_SHAPER_BS_S_DEF);
4440a5677d3SYunsheng Lin 
4450a5677d3SYunsheng Lin 	shap_cfg_cmd->port_shapping_para = cpu_to_le32(shapping_para);
4460a5677d3SYunsheng Lin 
447e364ad30SYonglong Liu 	hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
448e364ad30SYonglong Liu 
449e364ad30SYonglong Liu 	shap_cfg_cmd->port_rate = cpu_to_le32(hdev->hw.mac.speed);
450e364ad30SYonglong Liu 
4510a5677d3SYunsheng Lin 	return hclge_cmd_send(&hdev->hw, &desc, 1);
4520a5677d3SYunsheng Lin }
4530a5677d3SYunsheng Lin 
45484844054SSalil static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev,
45584844054SSalil 				     enum hclge_shap_bucket bucket, u8 pri_id,
456e364ad30SYonglong Liu 				     u32 shapping_para, u32 rate)
45784844054SSalil {
45884844054SSalil 	struct hclge_pri_shapping_cmd *shap_cfg_cmd;
45984844054SSalil 	enum hclge_opcode_type opcode;
46084844054SSalil 	struct hclge_desc desc;
46184844054SSalil 
46284844054SSalil 	opcode = bucket ? HCLGE_OPC_TM_PRI_P_SHAPPING :
46384844054SSalil 		 HCLGE_OPC_TM_PRI_C_SHAPPING;
46484844054SSalil 
46584844054SSalil 	hclge_cmd_setup_basic_desc(&desc, opcode, false);
46684844054SSalil 
46784844054SSalil 	shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data;
46884844054SSalil 
46984844054SSalil 	shap_cfg_cmd->pri_id = pri_id;
47084844054SSalil 
471a90bb9a5SYunsheng Lin 	shap_cfg_cmd->pri_shapping_para = cpu_to_le32(shapping_para);
47284844054SSalil 
473e364ad30SYonglong Liu 	hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
474e364ad30SYonglong Liu 
475e364ad30SYonglong Liu 	shap_cfg_cmd->pri_rate = cpu_to_le32(rate);
476e364ad30SYonglong Liu 
47784844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
47884844054SSalil }
47984844054SSalil 
48084844054SSalil static int hclge_tm_pg_schd_mode_cfg(struct hclge_dev *hdev, u8 pg_id)
48184844054SSalil {
48284844054SSalil 	struct hclge_desc desc;
48384844054SSalil 
48484844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_SCH_MODE_CFG, false);
48584844054SSalil 
48684844054SSalil 	if (hdev->tm_info.pg_info[pg_id].pg_sch_mode == HCLGE_SCH_MODE_DWRR)
48784844054SSalil 		desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
48884844054SSalil 	else
48984844054SSalil 		desc.data[1] = 0;
49084844054SSalil 
49184844054SSalil 	desc.data[0] = cpu_to_le32(pg_id);
49284844054SSalil 
49384844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
49484844054SSalil }
49584844054SSalil 
49684844054SSalil static int hclge_tm_pri_schd_mode_cfg(struct hclge_dev *hdev, u8 pri_id)
49784844054SSalil {
49884844054SSalil 	struct hclge_desc desc;
49984844054SSalil 
50084844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_SCH_MODE_CFG, false);
50184844054SSalil 
50284844054SSalil 	if (hdev->tm_info.tc_info[pri_id].tc_sch_mode == HCLGE_SCH_MODE_DWRR)
50384844054SSalil 		desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
50484844054SSalil 	else
50584844054SSalil 		desc.data[1] = 0;
50684844054SSalil 
50784844054SSalil 	desc.data[0] = cpu_to_le32(pri_id);
50884844054SSalil 
50984844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
51084844054SSalil }
51184844054SSalil 
512cc9bb43aSYunsheng Lin static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id, u8 mode)
51384844054SSalil {
51484844054SSalil 	struct hclge_desc desc;
51584844054SSalil 
51684844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_SCH_MODE_CFG, false);
51784844054SSalil 
518cc9bb43aSYunsheng Lin 	if (mode == HCLGE_SCH_MODE_DWRR)
51984844054SSalil 		desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
52084844054SSalil 	else
52184844054SSalil 		desc.data[1] = 0;
52284844054SSalil 
52384844054SSalil 	desc.data[0] = cpu_to_le32(qs_id);
52484844054SSalil 
52584844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
52684844054SSalil }
52784844054SSalil 
52867bf2541SYunsheng Lin static int hclge_tm_qs_bp_cfg(struct hclge_dev *hdev, u8 tc, u8 grp_id,
52967bf2541SYunsheng Lin 			      u32 bit_map)
53084844054SSalil {
53184844054SSalil 	struct hclge_bp_to_qs_map_cmd *bp_to_qs_map_cmd;
53284844054SSalil 	struct hclge_desc desc;
53384844054SSalil 
53484844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_BP_TO_QSET_MAPPING,
53584844054SSalil 				   false);
53684844054SSalil 
53784844054SSalil 	bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data;
53884844054SSalil 
53984844054SSalil 	bp_to_qs_map_cmd->tc_id = tc;
54067bf2541SYunsheng Lin 	bp_to_qs_map_cmd->qs_group_id = grp_id;
54167bf2541SYunsheng Lin 	bp_to_qs_map_cmd->qs_bit_map = cpu_to_le32(bit_map);
54284844054SSalil 
54384844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
54484844054SSalil }
54584844054SSalil 
546ee9e4424SYonglong Liu int hclge_tm_qs_shaper_cfg(struct hclge_vport *vport, int max_tx_rate)
547ee9e4424SYonglong Liu {
548ee9e4424SYonglong Liu 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
549ee9e4424SYonglong Liu 	struct hclge_qs_shapping_cmd *shap_cfg_cmd;
550ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
551ee9e4424SYonglong Liu 	struct hclge_dev *hdev = vport->back;
552ee9e4424SYonglong Liu 	struct hclge_desc desc;
553ee9e4424SYonglong Liu 	u32 shaper_para;
554ee9e4424SYonglong Liu 	int ret, i;
555ee9e4424SYonglong Liu 
556ee9e4424SYonglong Liu 	if (!max_tx_rate)
557d9c7d20dSGuangbin Huang 		max_tx_rate = hdev->ae_dev->dev_specs.max_tm_rate;
558ee9e4424SYonglong Liu 
559ee9e4424SYonglong Liu 	ret = hclge_shaper_para_calc(max_tx_rate, HCLGE_SHAPER_LVL_QSET,
560ff7e4d0dSHuazhong Tan 				     &ir_para,
561d9c7d20dSGuangbin Huang 				     hdev->ae_dev->dev_specs.max_tm_rate);
562ee9e4424SYonglong Liu 	if (ret)
563ee9e4424SYonglong Liu 		return ret;
564ee9e4424SYonglong Liu 
565ff7e4d0dSHuazhong Tan 	shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u,
566ff7e4d0dSHuazhong Tan 						 ir_para.ir_s,
567ee9e4424SYonglong Liu 						 HCLGE_SHAPER_BS_U_DEF,
568ee9e4424SYonglong Liu 						 HCLGE_SHAPER_BS_S_DEF);
569ee9e4424SYonglong Liu 
57035244430SJian Shen 	for (i = 0; i < kinfo->tc_info.num_tc; i++) {
571ee9e4424SYonglong Liu 		hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_QCN_SHAPPING_CFG,
572ee9e4424SYonglong Liu 					   false);
573ee9e4424SYonglong Liu 
574ee9e4424SYonglong Liu 		shap_cfg_cmd = (struct hclge_qs_shapping_cmd *)desc.data;
575ee9e4424SYonglong Liu 		shap_cfg_cmd->qs_id = cpu_to_le16(vport->qs_offset + i);
576ee9e4424SYonglong Liu 		shap_cfg_cmd->qs_shapping_para = cpu_to_le32(shaper_para);
577ee9e4424SYonglong Liu 
578e364ad30SYonglong Liu 		hnae3_set_bit(shap_cfg_cmd->flag, HCLGE_TM_RATE_VLD, 1);
579e364ad30SYonglong Liu 		shap_cfg_cmd->qs_rate = cpu_to_le32(max_tx_rate);
580e364ad30SYonglong Liu 
581ee9e4424SYonglong Liu 		ret = hclge_cmd_send(&hdev->hw, &desc, 1);
582ee9e4424SYonglong Liu 		if (ret) {
583ee9e4424SYonglong Liu 			dev_err(&hdev->pdev->dev,
584adcf738bSGuojia Liao 				"vf%u, qs%u failed to set tx_rate:%d, ret=%d\n",
585ee9e4424SYonglong Liu 				vport->vport_id, shap_cfg_cmd->qs_id,
586ee9e4424SYonglong Liu 				max_tx_rate, ret);
587ee9e4424SYonglong Liu 			return ret;
588ee9e4424SYonglong Liu 		}
589ee9e4424SYonglong Liu 	}
590ee9e4424SYonglong Liu 
591ee9e4424SYonglong Liu 	return 0;
592ee9e4424SYonglong Liu }
593ee9e4424SYonglong Liu 
5945a5c9091SJian Shen static u16 hclge_vport_get_max_rss_size(struct hclge_vport *vport)
5955a5c9091SJian Shen {
5965a5c9091SJian Shen 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
5975a5c9091SJian Shen 	struct hnae3_tc_info *tc_info = &kinfo->tc_info;
5985a5c9091SJian Shen 	struct hclge_dev *hdev = vport->back;
5995a5c9091SJian Shen 	u16 max_rss_size = 0;
6005a5c9091SJian Shen 	int i;
6015a5c9091SJian Shen 
6025a5c9091SJian Shen 	if (!tc_info->mqprio_active)
6035a5c9091SJian Shen 		return vport->alloc_tqps / tc_info->num_tc;
6045a5c9091SJian Shen 
6055a5c9091SJian Shen 	for (i = 0; i < HNAE3_MAX_TC; i++) {
6065a5c9091SJian Shen 		if (!(hdev->hw_tc_map & BIT(i)) || i >= tc_info->num_tc)
6075a5c9091SJian Shen 			continue;
6085a5c9091SJian Shen 		if (max_rss_size < tc_info->tqp_count[i])
6095a5c9091SJian Shen 			max_rss_size = tc_info->tqp_count[i];
6105a5c9091SJian Shen 	}
6115a5c9091SJian Shen 
6125a5c9091SJian Shen 	return max_rss_size;
6135a5c9091SJian Shen }
6145a5c9091SJian Shen 
6155a5c9091SJian Shen static u16 hclge_vport_get_tqp_num(struct hclge_vport *vport)
6165a5c9091SJian Shen {
6175a5c9091SJian Shen 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
6185a5c9091SJian Shen 	struct hnae3_tc_info *tc_info = &kinfo->tc_info;
6195a5c9091SJian Shen 	struct hclge_dev *hdev = vport->back;
6205a5c9091SJian Shen 	int sum = 0;
6215a5c9091SJian Shen 	int i;
6225a5c9091SJian Shen 
6235a5c9091SJian Shen 	if (!tc_info->mqprio_active)
6245a5c9091SJian Shen 		return kinfo->rss_size * tc_info->num_tc;
6255a5c9091SJian Shen 
6265a5c9091SJian Shen 	for (i = 0; i < HNAE3_MAX_TC; i++) {
6275a5c9091SJian Shen 		if (hdev->hw_tc_map & BIT(i) && i < tc_info->num_tc)
6285a5c9091SJian Shen 			sum += tc_info->tqp_count[i];
6295a5c9091SJian Shen 	}
6305a5c9091SJian Shen 
6315a5c9091SJian Shen 	return sum;
6325a5c9091SJian Shen }
6335a5c9091SJian Shen 
634b1261897SGuojia Liao static void hclge_tm_update_kinfo_rss_size(struct hclge_vport *vport)
63584844054SSalil {
63684844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
63784844054SSalil 	struct hclge_dev *hdev = vport->back;
638f1c2e66dSGuojia Liao 	u16 vport_max_rss_size;
639672ad0edSHuazhong Tan 	u16 max_rss_size;
64084844054SSalil 
641de67a690SYunsheng Lin 	/* TC configuration is shared by PF/VF in one port, only allow
642de67a690SYunsheng Lin 	 * one tc for VF for simplicity. VF's vport_id is non zero.
643de67a690SYunsheng Lin 	 */
644693e4415SGuoJia Liao 	if (vport->vport_id) {
645693e4415SGuoJia Liao 		kinfo->tc_info.num_tc = 1;
646693e4415SGuoJia Liao 		vport->qs_offset = HNAE3_MAX_TC +
647693e4415SGuoJia Liao 				   vport->vport_id - HCLGE_VF_VPORT_START_NUM;
648693e4415SGuoJia Liao 		vport_max_rss_size = hdev->vf_rss_size_max;
649693e4415SGuoJia Liao 	} else {
650693e4415SGuoJia Liao 		kinfo->tc_info.num_tc =
651de67a690SYunsheng Lin 			min_t(u16, vport->alloc_tqps, hdev->tm_info.num_tc);
652693e4415SGuoJia Liao 		vport->qs_offset = 0;
653693e4415SGuoJia Liao 		vport_max_rss_size = hdev->pf_rss_size_max;
654693e4415SGuoJia Liao 	}
655de67a690SYunsheng Lin 
656f1c2e66dSGuojia Liao 	max_rss_size = min_t(u16, vport_max_rss_size,
6575a5c9091SJian Shen 			     hclge_vport_get_max_rss_size(vport));
658672ad0edSHuazhong Tan 
6599b2f3477SWeihang Li 	/* Set to user value, no larger than max_rss_size. */
660672ad0edSHuazhong Tan 	if (kinfo->req_rss_size != kinfo->rss_size && kinfo->req_rss_size &&
661672ad0edSHuazhong Tan 	    kinfo->req_rss_size <= max_rss_size) {
662adcf738bSGuojia Liao 		dev_info(&hdev->pdev->dev, "rss changes from %u to %u\n",
663672ad0edSHuazhong Tan 			 kinfo->rss_size, kinfo->req_rss_size);
664672ad0edSHuazhong Tan 		kinfo->rss_size = kinfo->req_rss_size;
665672ad0edSHuazhong Tan 	} else if (kinfo->rss_size > max_rss_size ||
666672ad0edSHuazhong Tan 		   (!kinfo->req_rss_size && kinfo->rss_size < max_rss_size)) {
6679b2f3477SWeihang Li 		/* Set to the maximum specification value (max_rss_size). */
668672ad0edSHuazhong Tan 		kinfo->rss_size = max_rss_size;
669672ad0edSHuazhong Tan 	}
670b1261897SGuojia Liao }
671672ad0edSHuazhong Tan 
672b1261897SGuojia Liao static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport)
673b1261897SGuojia Liao {
674b1261897SGuojia Liao 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
675b1261897SGuojia Liao 	struct hclge_dev *hdev = vport->back;
676b1261897SGuojia Liao 	u8 i;
677b1261897SGuojia Liao 
678b1261897SGuojia Liao 	hclge_tm_update_kinfo_rss_size(vport);
6795a5c9091SJian Shen 	kinfo->num_tqps = hclge_vport_get_tqp_num(vport);
68084844054SSalil 	vport->dwrr = 100;  /* 100 percent as init */
68168ece54eSYunsheng Lin 	vport->alloc_rss_size = kinfo->rss_size;
682de67a690SYunsheng Lin 	vport->bw_limit = hdev->tm_info.pg_info[0].bw_limit;
68384844054SSalil 
6845a5c9091SJian Shen 	/* when enable mqprio, the tc_info has been updated. */
6855a5c9091SJian Shen 	if (kinfo->tc_info.mqprio_active)
6865a5c9091SJian Shen 		return;
6875a5c9091SJian Shen 
688af958827SHuazhong Tan 	for (i = 0; i < HNAE3_MAX_TC; i++) {
68935244430SJian Shen 		if (hdev->hw_tc_map & BIT(i) && i < kinfo->tc_info.num_tc) {
69035244430SJian Shen 			set_bit(i, &kinfo->tc_info.tc_en);
69135244430SJian Shen 			kinfo->tc_info.tqp_offset[i] = i * kinfo->rss_size;
69235244430SJian Shen 			kinfo->tc_info.tqp_count[i] = kinfo->rss_size;
69384844054SSalil 		} else {
69484844054SSalil 			/* Set to default queue if TC is disable */
69535244430SJian Shen 			clear_bit(i, &kinfo->tc_info.tc_en);
69635244430SJian Shen 			kinfo->tc_info.tqp_offset[i] = 0;
69735244430SJian Shen 			kinfo->tc_info.tqp_count[i] = 1;
69884844054SSalil 		}
69984844054SSalil 	}
700c5795c53SYunsheng Lin 
70135244430SJian Shen 	memcpy(kinfo->tc_info.prio_tc, hdev->tm_info.prio_tc,
70235244430SJian Shen 	       sizeof_field(struct hnae3_tc_info, prio_tc));
70384844054SSalil }
70484844054SSalil 
70584844054SSalil static void hclge_tm_vport_info_update(struct hclge_dev *hdev)
70684844054SSalil {
70784844054SSalil 	struct hclge_vport *vport = hdev->vport;
70884844054SSalil 	u32 i;
70984844054SSalil 
71084844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
71184844054SSalil 		hclge_tm_vport_tc_info_update(vport);
71284844054SSalil 
71384844054SSalil 		vport++;
71484844054SSalil 	}
71584844054SSalil }
71684844054SSalil 
71784844054SSalil static void hclge_tm_tc_info_init(struct hclge_dev *hdev)
71884844054SSalil {
71984844054SSalil 	u8 i;
72084844054SSalil 
72184844054SSalil 	for (i = 0; i < hdev->tm_info.num_tc; i++) {
72284844054SSalil 		hdev->tm_info.tc_info[i].tc_id = i;
72384844054SSalil 		hdev->tm_info.tc_info[i].tc_sch_mode = HCLGE_SCH_MODE_DWRR;
72484844054SSalil 		hdev->tm_info.tc_info[i].pgid = 0;
72584844054SSalil 		hdev->tm_info.tc_info[i].bw_limit =
72684844054SSalil 			hdev->tm_info.pg_info[0].bw_limit;
72784844054SSalil 	}
72884844054SSalil 
729c5795c53SYunsheng Lin 	for (i = 0; i < HNAE3_MAX_USER_PRIO; i++)
730c5795c53SYunsheng Lin 		hdev->tm_info.prio_tc[i] =
731c5795c53SYunsheng Lin 			(i >= hdev->tm_info.num_tc) ? 0 : i;
732c5795c53SYunsheng Lin 
733ae179b2fSYunsheng Lin 	/* DCB is enabled if we have more than 1 TC or pfc_en is
734ae179b2fSYunsheng Lin 	 * non-zero.
735ae179b2fSYunsheng Lin 	 */
736ae179b2fSYunsheng Lin 	if (hdev->tm_info.num_tc > 1 || hdev->tm_info.pfc_en)
7377979a223SYunsheng Lin 		hdev->flag |= HCLGE_FLAG_DCB_ENABLE;
7387979a223SYunsheng Lin 	else
73984844054SSalil 		hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
74084844054SSalil }
74184844054SSalil 
74284844054SSalil static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
74384844054SSalil {
744b37ce587SYufeng Mo #define BW_PERCENT	100
745b37ce587SYufeng Mo 
74684844054SSalil 	u8 i;
74784844054SSalil 
74884844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
74984844054SSalil 		int k;
75084844054SSalil 
751b37ce587SYufeng Mo 		hdev->tm_info.pg_dwrr[i] = i ? 0 : BW_PERCENT;
75284844054SSalil 
75384844054SSalil 		hdev->tm_info.pg_info[i].pg_id = i;
75484844054SSalil 		hdev->tm_info.pg_info[i].pg_sch_mode = HCLGE_SCH_MODE_DWRR;
75584844054SSalil 
756d9c7d20dSGuangbin Huang 		hdev->tm_info.pg_info[i].bw_limit =
757d9c7d20dSGuangbin Huang 					hdev->ae_dev->dev_specs.max_tm_rate;
75884844054SSalil 
75984844054SSalil 		if (i != 0)
76084844054SSalil 			continue;
76184844054SSalil 
76284844054SSalil 		hdev->tm_info.pg_info[i].tc_bit_map = hdev->hw_tc_map;
76384844054SSalil 		for (k = 0; k < hdev->tm_info.num_tc; k++)
764b37ce587SYufeng Mo 			hdev->tm_info.pg_info[i].tc_dwrr[k] = BW_PERCENT;
76584844054SSalil 	}
76684844054SSalil }
76784844054SSalil 
768d78e5b6aSYonglong Liu static void hclge_update_fc_mode_by_dcb_flag(struct hclge_dev *hdev)
7697979a223SYunsheng Lin {
7707979a223SYunsheng Lin 	if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE)) {
7717979a223SYunsheng Lin 		if (hdev->fc_mode_last_time == HCLGE_FC_PFC)
7727979a223SYunsheng Lin 			dev_warn(&hdev->pdev->dev,
7737979a223SYunsheng Lin 				 "DCB is disable, but last mode is FC_PFC\n");
7747979a223SYunsheng Lin 
7757979a223SYunsheng Lin 		hdev->tm_info.fc_mode = hdev->fc_mode_last_time;
7767979a223SYunsheng Lin 	} else if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) {
7777979a223SYunsheng Lin 		/* fc_mode_last_time record the last fc_mode when
7787979a223SYunsheng Lin 		 * DCB is enabled, so that fc_mode can be set to
7797979a223SYunsheng Lin 		 * the correct value when DCB is disabled.
7807979a223SYunsheng Lin 		 */
7817979a223SYunsheng Lin 		hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
7827979a223SYunsheng Lin 		hdev->tm_info.fc_mode = HCLGE_FC_PFC;
7837979a223SYunsheng Lin 	}
7847979a223SYunsheng Lin }
7857979a223SYunsheng Lin 
786d78e5b6aSYonglong Liu static void hclge_update_fc_mode(struct hclge_dev *hdev)
787d78e5b6aSYonglong Liu {
788d78e5b6aSYonglong Liu 	if (!hdev->tm_info.pfc_en) {
789d78e5b6aSYonglong Liu 		hdev->tm_info.fc_mode = hdev->fc_mode_last_time;
790d78e5b6aSYonglong Liu 		return;
791d78e5b6aSYonglong Liu 	}
792d78e5b6aSYonglong Liu 
793d78e5b6aSYonglong Liu 	if (hdev->tm_info.fc_mode != HCLGE_FC_PFC) {
794d78e5b6aSYonglong Liu 		hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
795d78e5b6aSYonglong Liu 		hdev->tm_info.fc_mode = HCLGE_FC_PFC;
796d78e5b6aSYonglong Liu 	}
797d78e5b6aSYonglong Liu }
798d78e5b6aSYonglong Liu 
799d78e5b6aSYonglong Liu static void hclge_pfc_info_init(struct hclge_dev *hdev)
800d78e5b6aSYonglong Liu {
801d78e5b6aSYonglong Liu 	if (hdev->ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
802d78e5b6aSYonglong Liu 		hclge_update_fc_mode(hdev);
803d78e5b6aSYonglong Liu 	else
804d78e5b6aSYonglong Liu 		hclge_update_fc_mode_by_dcb_flag(hdev);
805d78e5b6aSYonglong Liu }
806d78e5b6aSYonglong Liu 
807b6872fd3SYunsheng Lin static void hclge_tm_schd_info_init(struct hclge_dev *hdev)
80884844054SSalil {
80984844054SSalil 	hclge_tm_pg_info_init(hdev);
81084844054SSalil 
81184844054SSalil 	hclge_tm_tc_info_init(hdev);
81284844054SSalil 
81384844054SSalil 	hclge_tm_vport_info_update(hdev);
81484844054SSalil 
8157979a223SYunsheng Lin 	hclge_pfc_info_init(hdev);
81684844054SSalil }
81784844054SSalil 
81884844054SSalil static int hclge_tm_pg_to_pri_map(struct hclge_dev *hdev)
81984844054SSalil {
82084844054SSalil 	int ret;
82184844054SSalil 	u32 i;
82284844054SSalil 
82384844054SSalil 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE)
82484844054SSalil 		return 0;
82584844054SSalil 
82684844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
82784844054SSalil 		/* Cfg mapping */
82884844054SSalil 		ret = hclge_tm_pg_to_pri_map_cfg(
82984844054SSalil 			hdev, i, hdev->tm_info.pg_info[i].tc_bit_map);
83084844054SSalil 		if (ret)
83184844054SSalil 			return ret;
83284844054SSalil 	}
83384844054SSalil 
83484844054SSalil 	return 0;
83584844054SSalil }
83684844054SSalil 
83784844054SSalil static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev)
83884844054SSalil {
839d9c7d20dSGuangbin Huang 	u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate;
840ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
84163cbf7a9SYufeng Mo 	u32 shaper_para;
84284844054SSalil 	int ret;
84384844054SSalil 	u32 i;
84484844054SSalil 
84584844054SSalil 	/* Cfg pg schd */
84684844054SSalil 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE)
84784844054SSalil 		return 0;
84884844054SSalil 
84984844054SSalil 	/* Pg to pri */
85084844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
851e364ad30SYonglong Liu 		u32 rate = hdev->tm_info.pg_info[i].bw_limit;
852e364ad30SYonglong Liu 
85384844054SSalil 		/* Calc shaper para */
854e364ad30SYonglong Liu 		ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PG,
855ff7e4d0dSHuazhong Tan 					     &ir_para, max_tm_rate);
85684844054SSalil 		if (ret)
85784844054SSalil 			return ret;
85884844054SSalil 
85963cbf7a9SYufeng Mo 		shaper_para = hclge_tm_get_shapping_para(0, 0, 0,
86063cbf7a9SYufeng Mo 							 HCLGE_SHAPER_BS_U_DEF,
86163cbf7a9SYufeng Mo 							 HCLGE_SHAPER_BS_S_DEF);
86284844054SSalil 		ret = hclge_tm_pg_shapping_cfg(hdev,
86384844054SSalil 					       HCLGE_TM_SHAP_C_BUCKET, i,
864e364ad30SYonglong Liu 					       shaper_para, rate);
86584844054SSalil 		if (ret)
86684844054SSalil 			return ret;
86784844054SSalil 
868ff7e4d0dSHuazhong Tan 		shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b,
869ff7e4d0dSHuazhong Tan 							 ir_para.ir_u,
870ff7e4d0dSHuazhong Tan 							 ir_para.ir_s,
87184844054SSalil 							 HCLGE_SHAPER_BS_U_DEF,
87284844054SSalil 							 HCLGE_SHAPER_BS_S_DEF);
87363cbf7a9SYufeng Mo 		ret = hclge_tm_pg_shapping_cfg(hdev,
87463cbf7a9SYufeng Mo 					       HCLGE_TM_SHAP_P_BUCKET, i,
875e364ad30SYonglong Liu 					       shaper_para, rate);
87684844054SSalil 		if (ret)
87784844054SSalil 			return ret;
87884844054SSalil 	}
87984844054SSalil 
88084844054SSalil 	return 0;
88184844054SSalil }
88284844054SSalil 
88384844054SSalil static int hclge_tm_pg_dwrr_cfg(struct hclge_dev *hdev)
88484844054SSalil {
88584844054SSalil 	int ret;
88684844054SSalil 	u32 i;
88784844054SSalil 
88884844054SSalil 	/* cfg pg schd */
88984844054SSalil 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE)
89084844054SSalil 		return 0;
89184844054SSalil 
89284844054SSalil 	/* pg to prio */
89384844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
89484844054SSalil 		/* Cfg dwrr */
8959b2f3477SWeihang Li 		ret = hclge_tm_pg_weight_cfg(hdev, i, hdev->tm_info.pg_dwrr[i]);
89684844054SSalil 		if (ret)
89784844054SSalil 			return ret;
89884844054SSalil 	}
89984844054SSalil 
90084844054SSalil 	return 0;
90184844054SSalil }
90284844054SSalil 
90384844054SSalil static int hclge_vport_q_to_qs_map(struct hclge_dev *hdev,
90484844054SSalil 				   struct hclge_vport *vport)
90584844054SSalil {
90684844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
90735244430SJian Shen 	struct hnae3_tc_info *tc_info = &kinfo->tc_info;
90884844054SSalil 	struct hnae3_queue **tqp = kinfo->tqp;
90984844054SSalil 	u32 i, j;
91084844054SSalil 	int ret;
91184844054SSalil 
91235244430SJian Shen 	for (i = 0; i < tc_info->num_tc; i++) {
91335244430SJian Shen 		for (j = 0; j < tc_info->tqp_count[i]; j++) {
91435244430SJian Shen 			struct hnae3_queue *q = tqp[tc_info->tqp_offset[i] + j];
91584844054SSalil 
91684844054SSalil 			ret = hclge_tm_q_to_qs_map_cfg(hdev,
91784844054SSalil 						       hclge_get_queue_id(q),
91884844054SSalil 						       vport->qs_offset + i);
91984844054SSalil 			if (ret)
92084844054SSalil 				return ret;
92184844054SSalil 		}
92284844054SSalil 	}
92384844054SSalil 
92484844054SSalil 	return 0;
92584844054SSalil }
92684844054SSalil 
92784844054SSalil static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev)
92884844054SSalil {
92984844054SSalil 	struct hclge_vport *vport = hdev->vport;
93084844054SSalil 	int ret;
931cc9bb43aSYunsheng Lin 	u32 i, k;
93284844054SSalil 
93384844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
93484844054SSalil 		/* Cfg qs -> pri mapping, one by one mapping */
935de67a690SYunsheng Lin 		for (k = 0; k < hdev->num_alloc_vport; k++) {
936de67a690SYunsheng Lin 			struct hnae3_knic_private_info *kinfo =
937de67a690SYunsheng Lin 				&vport[k].nic.kinfo;
938de67a690SYunsheng Lin 
93935244430SJian Shen 			for (i = 0; i < kinfo->tc_info.num_tc; i++) {
940cc9bb43aSYunsheng Lin 				ret = hclge_tm_qs_to_pri_map_cfg(
941cc9bb43aSYunsheng Lin 					hdev, vport[k].qs_offset + i, i);
94284844054SSalil 				if (ret)
94384844054SSalil 					return ret;
94484844054SSalil 			}
945de67a690SYunsheng Lin 		}
94684844054SSalil 	} else if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) {
94784844054SSalil 		/* Cfg qs -> pri mapping,  qs = tc, pri = vf, 8 qs -> 1 pri */
94884844054SSalil 		for (k = 0; k < hdev->num_alloc_vport; k++)
94984844054SSalil 			for (i = 0; i < HNAE3_MAX_TC; i++) {
95084844054SSalil 				ret = hclge_tm_qs_to_pri_map_cfg(
95184844054SSalil 					hdev, vport[k].qs_offset + i, k);
95284844054SSalil 				if (ret)
95384844054SSalil 					return ret;
95484844054SSalil 			}
95584844054SSalil 	} else {
95684844054SSalil 		return -EINVAL;
95784844054SSalil 	}
95884844054SSalil 
95984844054SSalil 	/* Cfg q -> qs mapping */
96084844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
96184844054SSalil 		ret = hclge_vport_q_to_qs_map(hdev, vport);
96284844054SSalil 		if (ret)
96384844054SSalil 			return ret;
96484844054SSalil 
96584844054SSalil 		vport++;
96684844054SSalil 	}
96784844054SSalil 
96884844054SSalil 	return 0;
96984844054SSalil }
97084844054SSalil 
97184844054SSalil static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev)
97284844054SSalil {
973d9c7d20dSGuangbin Huang 	u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate;
974ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
97563cbf7a9SYufeng Mo 	u32 shaper_para;
97684844054SSalil 	int ret;
97784844054SSalil 	u32 i;
97884844054SSalil 
97984844054SSalil 	for (i = 0; i < hdev->tm_info.num_tc; i++) {
980e364ad30SYonglong Liu 		u32 rate = hdev->tm_info.tc_info[i].bw_limit;
981e364ad30SYonglong Liu 
982e364ad30SYonglong Liu 		ret = hclge_shaper_para_calc(rate, HCLGE_SHAPER_LVL_PRI,
983ff7e4d0dSHuazhong Tan 					     &ir_para, max_tm_rate);
98484844054SSalil 		if (ret)
98584844054SSalil 			return ret;
98684844054SSalil 
98763cbf7a9SYufeng Mo 		shaper_para = hclge_tm_get_shapping_para(0, 0, 0,
98863cbf7a9SYufeng Mo 							 HCLGE_SHAPER_BS_U_DEF,
98984844054SSalil 							 HCLGE_SHAPER_BS_S_DEF);
99063cbf7a9SYufeng Mo 		ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET, i,
991e364ad30SYonglong Liu 						shaper_para, rate);
99284844054SSalil 		if (ret)
99384844054SSalil 			return ret;
99484844054SSalil 
995ff7e4d0dSHuazhong Tan 		shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b,
996ff7e4d0dSHuazhong Tan 							 ir_para.ir_u,
997ff7e4d0dSHuazhong Tan 							 ir_para.ir_s,
99863cbf7a9SYufeng Mo 							 HCLGE_SHAPER_BS_U_DEF,
99984844054SSalil 							 HCLGE_SHAPER_BS_S_DEF);
100063cbf7a9SYufeng Mo 		ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET, i,
1001e364ad30SYonglong Liu 						shaper_para, rate);
100284844054SSalil 		if (ret)
100384844054SSalil 			return ret;
100484844054SSalil 	}
100584844054SSalil 
100684844054SSalil 	return 0;
100784844054SSalil }
100884844054SSalil 
100984844054SSalil static int hclge_tm_pri_vnet_base_shaper_pri_cfg(struct hclge_vport *vport)
101084844054SSalil {
101184844054SSalil 	struct hclge_dev *hdev = vport->back;
1012ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
101363cbf7a9SYufeng Mo 	u32 shaper_para;
101484844054SSalil 	int ret;
101584844054SSalil 
101684844054SSalil 	ret = hclge_shaper_para_calc(vport->bw_limit, HCLGE_SHAPER_LVL_VF,
1017ff7e4d0dSHuazhong Tan 				     &ir_para,
1018d9c7d20dSGuangbin Huang 				     hdev->ae_dev->dev_specs.max_tm_rate);
101984844054SSalil 	if (ret)
102084844054SSalil 		return ret;
102184844054SSalil 
102263cbf7a9SYufeng Mo 	shaper_para = hclge_tm_get_shapping_para(0, 0, 0,
102363cbf7a9SYufeng Mo 						 HCLGE_SHAPER_BS_U_DEF,
102484844054SSalil 						 HCLGE_SHAPER_BS_S_DEF);
102563cbf7a9SYufeng Mo 	ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET,
1026e364ad30SYonglong Liu 					vport->vport_id, shaper_para,
1027e364ad30SYonglong Liu 					vport->bw_limit);
102884844054SSalil 	if (ret)
102984844054SSalil 		return ret;
103084844054SSalil 
1031ff7e4d0dSHuazhong Tan 	shaper_para = hclge_tm_get_shapping_para(ir_para.ir_b, ir_para.ir_u,
1032ff7e4d0dSHuazhong Tan 						 ir_para.ir_s,
103384844054SSalil 						 HCLGE_SHAPER_BS_U_DEF,
103484844054SSalil 						 HCLGE_SHAPER_BS_S_DEF);
103563cbf7a9SYufeng Mo 	ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET,
1036e364ad30SYonglong Liu 					vport->vport_id, shaper_para,
1037e364ad30SYonglong Liu 					vport->bw_limit);
103884844054SSalil 	if (ret)
103984844054SSalil 		return ret;
104084844054SSalil 
104184844054SSalil 	return 0;
104284844054SSalil }
104384844054SSalil 
104484844054SSalil static int hclge_tm_pri_vnet_base_shaper_qs_cfg(struct hclge_vport *vport)
104584844054SSalil {
104684844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
104784844054SSalil 	struct hclge_dev *hdev = vport->back;
1048d9c7d20dSGuangbin Huang 	u32 max_tm_rate = hdev->ae_dev->dev_specs.max_tm_rate;
1049ff7e4d0dSHuazhong Tan 	struct hclge_shaper_ir_para ir_para;
105084844054SSalil 	u32 i;
105184844054SSalil 	int ret;
105284844054SSalil 
105335244430SJian Shen 	for (i = 0; i < kinfo->tc_info.num_tc; i++) {
1054ff7e4d0dSHuazhong Tan 		ret = hclge_shaper_para_calc(hdev->tm_info.tc_info[i].bw_limit,
105584844054SSalil 					     HCLGE_SHAPER_LVL_QSET,
1056ff7e4d0dSHuazhong Tan 					     &ir_para, max_tm_rate);
105784844054SSalil 		if (ret)
105884844054SSalil 			return ret;
105984844054SSalil 	}
106084844054SSalil 
106184844054SSalil 	return 0;
106284844054SSalil }
106384844054SSalil 
106484844054SSalil static int hclge_tm_pri_vnet_base_shaper_cfg(struct hclge_dev *hdev)
106584844054SSalil {
106684844054SSalil 	struct hclge_vport *vport = hdev->vport;
106784844054SSalil 	int ret;
106884844054SSalil 	u32 i;
106984844054SSalil 
107084844054SSalil 	/* Need config vport shaper */
107184844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
107284844054SSalil 		ret = hclge_tm_pri_vnet_base_shaper_pri_cfg(vport);
107384844054SSalil 		if (ret)
107484844054SSalil 			return ret;
107584844054SSalil 
107684844054SSalil 		ret = hclge_tm_pri_vnet_base_shaper_qs_cfg(vport);
107784844054SSalil 		if (ret)
107884844054SSalil 			return ret;
107984844054SSalil 
108084844054SSalil 		vport++;
108184844054SSalil 	}
108284844054SSalil 
108384844054SSalil 	return 0;
108484844054SSalil }
108584844054SSalil 
108684844054SSalil static int hclge_tm_pri_shaper_cfg(struct hclge_dev *hdev)
108784844054SSalil {
108884844054SSalil 	int ret;
108984844054SSalil 
109084844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
109184844054SSalil 		ret = hclge_tm_pri_tc_base_shaper_cfg(hdev);
109284844054SSalil 		if (ret)
109384844054SSalil 			return ret;
109484844054SSalil 	} else {
109584844054SSalil 		ret = hclge_tm_pri_vnet_base_shaper_cfg(hdev);
109684844054SSalil 		if (ret)
109784844054SSalil 			return ret;
109884844054SSalil 	}
109984844054SSalil 
110084844054SSalil 	return 0;
110184844054SSalil }
110284844054SSalil 
110384844054SSalil static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev)
110484844054SSalil {
1105cc9bb43aSYunsheng Lin 	struct hclge_vport *vport = hdev->vport;
110684844054SSalil 	struct hclge_pg_info *pg_info;
110784844054SSalil 	u8 dwrr;
110884844054SSalil 	int ret;
1109cc9bb43aSYunsheng Lin 	u32 i, k;
111084844054SSalil 
111184844054SSalil 	for (i = 0; i < hdev->tm_info.num_tc; i++) {
111284844054SSalil 		pg_info =
111384844054SSalil 			&hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid];
111484844054SSalil 		dwrr = pg_info->tc_dwrr[i];
111584844054SSalil 
111684844054SSalil 		ret = hclge_tm_pri_weight_cfg(hdev, i, dwrr);
111784844054SSalil 		if (ret)
111884844054SSalil 			return ret;
111984844054SSalil 
1120cc9bb43aSYunsheng Lin 		for (k = 0; k < hdev->num_alloc_vport; k++) {
1121cc9bb43aSYunsheng Lin 			ret = hclge_tm_qs_weight_cfg(
1122cc9bb43aSYunsheng Lin 				hdev, vport[k].qs_offset + i,
1123cc9bb43aSYunsheng Lin 				vport[k].dwrr);
112484844054SSalil 			if (ret)
112584844054SSalil 				return ret;
112684844054SSalil 		}
1127cc9bb43aSYunsheng Lin 	}
112884844054SSalil 
112984844054SSalil 	return 0;
113084844054SSalil }
113184844054SSalil 
1132330baff5SYunsheng Lin static int hclge_tm_ets_tc_dwrr_cfg(struct hclge_dev *hdev)
1133330baff5SYunsheng Lin {
1134330baff5SYunsheng Lin #define DEFAULT_TC_WEIGHT	1
1135330baff5SYunsheng Lin #define DEFAULT_TC_OFFSET	14
1136330baff5SYunsheng Lin 
1137330baff5SYunsheng Lin 	struct hclge_ets_tc_weight_cmd *ets_weight;
1138330baff5SYunsheng Lin 	struct hclge_desc desc;
1139ebaf1908SWeihang Li 	unsigned int i;
1140330baff5SYunsheng Lin 
1141330baff5SYunsheng Lin 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_ETS_TC_WEIGHT, false);
1142330baff5SYunsheng Lin 	ets_weight = (struct hclge_ets_tc_weight_cmd *)desc.data;
1143330baff5SYunsheng Lin 
1144330baff5SYunsheng Lin 	for (i = 0; i < HNAE3_MAX_TC; i++) {
1145330baff5SYunsheng Lin 		struct hclge_pg_info *pg_info;
1146330baff5SYunsheng Lin 
1147330baff5SYunsheng Lin 		ets_weight->tc_weight[i] = DEFAULT_TC_WEIGHT;
1148330baff5SYunsheng Lin 
1149330baff5SYunsheng Lin 		if (!(hdev->hw_tc_map & BIT(i)))
1150330baff5SYunsheng Lin 			continue;
1151330baff5SYunsheng Lin 
1152330baff5SYunsheng Lin 		pg_info =
1153330baff5SYunsheng Lin 			&hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid];
1154330baff5SYunsheng Lin 		ets_weight->tc_weight[i] = pg_info->tc_dwrr[i];
1155330baff5SYunsheng Lin 	}
1156330baff5SYunsheng Lin 
1157330baff5SYunsheng Lin 	ets_weight->weight_offset = DEFAULT_TC_OFFSET;
1158330baff5SYunsheng Lin 
1159330baff5SYunsheng Lin 	return hclge_cmd_send(&hdev->hw, &desc, 1);
1160330baff5SYunsheng Lin }
1161330baff5SYunsheng Lin 
116284844054SSalil static int hclge_tm_pri_vnet_base_dwrr_pri_cfg(struct hclge_vport *vport)
116384844054SSalil {
116484844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
116584844054SSalil 	struct hclge_dev *hdev = vport->back;
116684844054SSalil 	int ret;
116784844054SSalil 	u8 i;
116884844054SSalil 
116984844054SSalil 	/* Vf dwrr */
117084844054SSalil 	ret = hclge_tm_pri_weight_cfg(hdev, vport->vport_id, vport->dwrr);
117184844054SSalil 	if (ret)
117284844054SSalil 		return ret;
117384844054SSalil 
117484844054SSalil 	/* Qset dwrr */
117535244430SJian Shen 	for (i = 0; i < kinfo->tc_info.num_tc; i++) {
117684844054SSalil 		ret = hclge_tm_qs_weight_cfg(
117784844054SSalil 			hdev, vport->qs_offset + i,
117884844054SSalil 			hdev->tm_info.pg_info[0].tc_dwrr[i]);
117984844054SSalil 		if (ret)
118084844054SSalil 			return ret;
118184844054SSalil 	}
118284844054SSalil 
118384844054SSalil 	return 0;
118484844054SSalil }
118584844054SSalil 
118684844054SSalil static int hclge_tm_pri_vnet_base_dwrr_cfg(struct hclge_dev *hdev)
118784844054SSalil {
118884844054SSalil 	struct hclge_vport *vport = hdev->vport;
118984844054SSalil 	int ret;
119084844054SSalil 	u32 i;
119184844054SSalil 
119284844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
119384844054SSalil 		ret = hclge_tm_pri_vnet_base_dwrr_pri_cfg(vport);
119484844054SSalil 		if (ret)
119584844054SSalil 			return ret;
119684844054SSalil 
119784844054SSalil 		vport++;
119884844054SSalil 	}
119984844054SSalil 
120084844054SSalil 	return 0;
120184844054SSalil }
120284844054SSalil 
120384844054SSalil static int hclge_tm_pri_dwrr_cfg(struct hclge_dev *hdev)
120484844054SSalil {
120584844054SSalil 	int ret;
120684844054SSalil 
120784844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
120884844054SSalil 		ret = hclge_tm_pri_tc_base_dwrr_cfg(hdev);
120984844054SSalil 		if (ret)
121084844054SSalil 			return ret;
1211330baff5SYunsheng Lin 
1212330baff5SYunsheng Lin 		if (!hnae3_dev_dcb_supported(hdev))
1213330baff5SYunsheng Lin 			return 0;
1214330baff5SYunsheng Lin 
1215330baff5SYunsheng Lin 		ret = hclge_tm_ets_tc_dwrr_cfg(hdev);
1216330baff5SYunsheng Lin 		if (ret == -EOPNOTSUPP) {
1217330baff5SYunsheng Lin 			dev_warn(&hdev->pdev->dev,
1218330baff5SYunsheng Lin 				 "fw %08x does't support ets tc weight cmd\n",
1219330baff5SYunsheng Lin 				 hdev->fw_version);
1220330baff5SYunsheng Lin 			ret = 0;
1221330baff5SYunsheng Lin 		}
1222330baff5SYunsheng Lin 
1223330baff5SYunsheng Lin 		return ret;
122484844054SSalil 	} else {
122584844054SSalil 		ret = hclge_tm_pri_vnet_base_dwrr_cfg(hdev);
122684844054SSalil 		if (ret)
122784844054SSalil 			return ret;
122884844054SSalil 	}
122984844054SSalil 
123084844054SSalil 	return 0;
123184844054SSalil }
123284844054SSalil 
12339e5157baSYunsheng Lin static int hclge_tm_map_cfg(struct hclge_dev *hdev)
123484844054SSalil {
123584844054SSalil 	int ret;
123684844054SSalil 
123777f255c1SYunsheng Lin 	ret = hclge_up_to_tc_map(hdev);
123877f255c1SYunsheng Lin 	if (ret)
123977f255c1SYunsheng Lin 		return ret;
124077f255c1SYunsheng Lin 
124184844054SSalil 	ret = hclge_tm_pg_to_pri_map(hdev);
124284844054SSalil 	if (ret)
124384844054SSalil 		return ret;
124484844054SSalil 
124584844054SSalil 	return hclge_tm_pri_q_qs_cfg(hdev);
124684844054SSalil }
124784844054SSalil 
124884844054SSalil static int hclge_tm_shaper_cfg(struct hclge_dev *hdev)
124984844054SSalil {
125084844054SSalil 	int ret;
125184844054SSalil 
12520a5677d3SYunsheng Lin 	ret = hclge_tm_port_shaper_cfg(hdev);
12530a5677d3SYunsheng Lin 	if (ret)
12540a5677d3SYunsheng Lin 		return ret;
12550a5677d3SYunsheng Lin 
125684844054SSalil 	ret = hclge_tm_pg_shaper_cfg(hdev);
125784844054SSalil 	if (ret)
125884844054SSalil 		return ret;
125984844054SSalil 
126084844054SSalil 	return hclge_tm_pri_shaper_cfg(hdev);
126184844054SSalil }
126284844054SSalil 
126384844054SSalil int hclge_tm_dwrr_cfg(struct hclge_dev *hdev)
126484844054SSalil {
126584844054SSalil 	int ret;
126684844054SSalil 
126784844054SSalil 	ret = hclge_tm_pg_dwrr_cfg(hdev);
126884844054SSalil 	if (ret)
126984844054SSalil 		return ret;
127084844054SSalil 
127184844054SSalil 	return hclge_tm_pri_dwrr_cfg(hdev);
127284844054SSalil }
127384844054SSalil 
127484844054SSalil static int hclge_tm_lvl2_schd_mode_cfg(struct hclge_dev *hdev)
127584844054SSalil {
127684844054SSalil 	int ret;
127784844054SSalil 	u8 i;
127884844054SSalil 
127984844054SSalil 	/* Only being config on TC-Based scheduler mode */
128084844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE)
128184844054SSalil 		return 0;
128284844054SSalil 
128384844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
128484844054SSalil 		ret = hclge_tm_pg_schd_mode_cfg(hdev, i);
128584844054SSalil 		if (ret)
128684844054SSalil 			return ret;
128784844054SSalil 	}
128884844054SSalil 
128984844054SSalil 	return 0;
129084844054SSalil }
129184844054SSalil 
129284844054SSalil static int hclge_tm_schd_mode_vnet_base_cfg(struct hclge_vport *vport)
129384844054SSalil {
129484844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
129584844054SSalil 	struct hclge_dev *hdev = vport->back;
129684844054SSalil 	int ret;
129784844054SSalil 	u8 i;
129884844054SSalil 
129904f25edbSYunsheng Lin 	if (vport->vport_id >= HNAE3_MAX_TC)
130004f25edbSYunsheng Lin 		return -EINVAL;
130104f25edbSYunsheng Lin 
130284844054SSalil 	ret = hclge_tm_pri_schd_mode_cfg(hdev, vport->vport_id);
130384844054SSalil 	if (ret)
130484844054SSalil 		return ret;
130584844054SSalil 
130635244430SJian Shen 	for (i = 0; i < kinfo->tc_info.num_tc; i++) {
1307cc9bb43aSYunsheng Lin 		u8 sch_mode = hdev->tm_info.tc_info[i].tc_sch_mode;
1308cc9bb43aSYunsheng Lin 
1309cc9bb43aSYunsheng Lin 		ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i,
1310cc9bb43aSYunsheng Lin 						sch_mode);
131184844054SSalil 		if (ret)
131284844054SSalil 			return ret;
131384844054SSalil 	}
131484844054SSalil 
131584844054SSalil 	return 0;
131684844054SSalil }
131784844054SSalil 
131884844054SSalil static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev *hdev)
131984844054SSalil {
132084844054SSalil 	struct hclge_vport *vport = hdev->vport;
132184844054SSalil 	int ret;
1322cc9bb43aSYunsheng Lin 	u8 i, k;
132384844054SSalil 
132484844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
132584844054SSalil 		for (i = 0; i < hdev->tm_info.num_tc; i++) {
132684844054SSalil 			ret = hclge_tm_pri_schd_mode_cfg(hdev, i);
132784844054SSalil 			if (ret)
132884844054SSalil 				return ret;
132984844054SSalil 
1330cc9bb43aSYunsheng Lin 			for (k = 0; k < hdev->num_alloc_vport; k++) {
1331cc9bb43aSYunsheng Lin 				ret = hclge_tm_qs_schd_mode_cfg(
1332cc9bb43aSYunsheng Lin 					hdev, vport[k].qs_offset + i,
1333cc9bb43aSYunsheng Lin 					HCLGE_SCH_MODE_DWRR);
133484844054SSalil 				if (ret)
133584844054SSalil 					return ret;
133684844054SSalil 			}
1337cc9bb43aSYunsheng Lin 		}
133884844054SSalil 	} else {
133984844054SSalil 		for (i = 0; i < hdev->num_alloc_vport; i++) {
134084844054SSalil 			ret = hclge_tm_schd_mode_vnet_base_cfg(vport);
134184844054SSalil 			if (ret)
134284844054SSalil 				return ret;
134384844054SSalil 
134484844054SSalil 			vport++;
134584844054SSalil 		}
134684844054SSalil 	}
134784844054SSalil 
134884844054SSalil 	return 0;
134984844054SSalil }
135084844054SSalil 
13519e5157baSYunsheng Lin static int hclge_tm_schd_mode_hw(struct hclge_dev *hdev)
135284844054SSalil {
135384844054SSalil 	int ret;
135484844054SSalil 
135584844054SSalil 	ret = hclge_tm_lvl2_schd_mode_cfg(hdev);
135684844054SSalil 	if (ret)
135784844054SSalil 		return ret;
135884844054SSalil 
135984844054SSalil 	return hclge_tm_lvl34_schd_mode_cfg(hdev);
136084844054SSalil }
136184844054SSalil 
13629e5157baSYunsheng Lin int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
136384844054SSalil {
136484844054SSalil 	int ret;
136584844054SSalil 
136684844054SSalil 	/* Cfg tm mapping  */
136784844054SSalil 	ret = hclge_tm_map_cfg(hdev);
136884844054SSalil 	if (ret)
136984844054SSalil 		return ret;
137084844054SSalil 
137184844054SSalil 	/* Cfg tm shaper */
137284844054SSalil 	ret = hclge_tm_shaper_cfg(hdev);
137384844054SSalil 	if (ret)
137484844054SSalil 		return ret;
137584844054SSalil 
137684844054SSalil 	/* Cfg dwrr */
137784844054SSalil 	ret = hclge_tm_dwrr_cfg(hdev);
137884844054SSalil 	if (ret)
137984844054SSalil 		return ret;
138084844054SSalil 
138184844054SSalil 	/* Cfg schd mode for each level schd */
138284844054SSalil 	return hclge_tm_schd_mode_hw(hdev);
138384844054SSalil }
138484844054SSalil 
1385e98d7183SFuyun Liang static int hclge_pause_param_setup_hw(struct hclge_dev *hdev)
138618838d0cSFuyun Liang {
138718838d0cSFuyun Liang 	struct hclge_mac *mac = &hdev->hw.mac;
138818838d0cSFuyun Liang 
1389e98d7183SFuyun Liang 	return hclge_pause_param_cfg(hdev, mac->mac_addr,
139018838d0cSFuyun Liang 				     HCLGE_DEFAULT_PAUSE_TRANS_GAP,
139118838d0cSFuyun Liang 				     HCLGE_DEFAULT_PAUSE_TRANS_TIME);
139218838d0cSFuyun Liang }
139318838d0cSFuyun Liang 
13949dc2145dSYunsheng Lin static int hclge_pfc_setup_hw(struct hclge_dev *hdev)
13959dc2145dSYunsheng Lin {
13969dc2145dSYunsheng Lin 	u8 enable_bitmap = 0;
13979dc2145dSYunsheng Lin 
13989dc2145dSYunsheng Lin 	if (hdev->tm_info.fc_mode == HCLGE_FC_PFC)
13999dc2145dSYunsheng Lin 		enable_bitmap = HCLGE_TX_MAC_PAUSE_EN_MSK |
14009dc2145dSYunsheng Lin 				HCLGE_RX_MAC_PAUSE_EN_MSK;
14019dc2145dSYunsheng Lin 
14029dc2145dSYunsheng Lin 	return hclge_pfc_pause_en_cfg(hdev, enable_bitmap,
1403d3ad430aSYunsheng Lin 				      hdev->tm_info.pfc_en);
14049dc2145dSYunsheng Lin }
14059dc2145dSYunsheng Lin 
14069a5ef4aaSYonglong Liu /* for the queues that use for backpress, divides to several groups,
14079a5ef4aaSYonglong Liu  * each group contains 32 queue sets, which can be represented by u32 bitmap.
140867bf2541SYunsheng Lin  */
140967bf2541SYunsheng Lin static int hclge_bp_setup_hw(struct hclge_dev *hdev, u8 tc)
141067bf2541SYunsheng Lin {
14119a5ef4aaSYonglong Liu 	u16 grp_id_shift = HCLGE_BP_GRP_ID_S;
14129a5ef4aaSYonglong Liu 	u16 grp_id_mask = HCLGE_BP_GRP_ID_M;
14139a5ef4aaSYonglong Liu 	u8 grp_num = HCLGE_BP_GRP_NUM;
1414e8ccbb7dSYunsheng Lin 	int i;
141567bf2541SYunsheng Lin 
14169a5ef4aaSYonglong Liu 	if (hdev->num_tqps > HCLGE_TQP_MAX_SIZE_DEV_V2) {
14179a5ef4aaSYonglong Liu 		grp_num = HCLGE_BP_EXT_GRP_NUM;
14189a5ef4aaSYonglong Liu 		grp_id_mask = HCLGE_BP_EXT_GRP_ID_M;
14199a5ef4aaSYonglong Liu 		grp_id_shift = HCLGE_BP_EXT_GRP_ID_S;
14209a5ef4aaSYonglong Liu 	}
14219a5ef4aaSYonglong Liu 
14229a5ef4aaSYonglong Liu 	for (i = 0; i < grp_num; i++) {
1423e8ccbb7dSYunsheng Lin 		u32 qs_bitmap = 0;
1424e8ccbb7dSYunsheng Lin 		int k, ret;
142567bf2541SYunsheng Lin 
142667bf2541SYunsheng Lin 		for (k = 0; k < hdev->num_alloc_vport; k++) {
1427e8ccbb7dSYunsheng Lin 			struct hclge_vport *vport = &hdev->vport[k];
142867bf2541SYunsheng Lin 			u16 qs_id = vport->qs_offset + tc;
142967bf2541SYunsheng Lin 			u8 grp, sub_grp;
143067bf2541SYunsheng Lin 
14319a5ef4aaSYonglong Liu 			grp = hnae3_get_field(qs_id, grp_id_mask, grp_id_shift);
1432e4e87715SPeng Li 			sub_grp = hnae3_get_field(qs_id, HCLGE_BP_SUB_GRP_ID_M,
143367bf2541SYunsheng Lin 						  HCLGE_BP_SUB_GRP_ID_S);
143467bf2541SYunsheng Lin 			if (i == grp)
143567bf2541SYunsheng Lin 				qs_bitmap |= (1 << sub_grp);
143667bf2541SYunsheng Lin 		}
143767bf2541SYunsheng Lin 
143867bf2541SYunsheng Lin 		ret = hclge_tm_qs_bp_cfg(hdev, tc, i, qs_bitmap);
143967bf2541SYunsheng Lin 		if (ret)
144067bf2541SYunsheng Lin 			return ret;
144167bf2541SYunsheng Lin 	}
144267bf2541SYunsheng Lin 
144367bf2541SYunsheng Lin 	return 0;
144467bf2541SYunsheng Lin }
144567bf2541SYunsheng Lin 
14469dc2145dSYunsheng Lin static int hclge_mac_pause_setup_hw(struct hclge_dev *hdev)
14479dc2145dSYunsheng Lin {
14489dc2145dSYunsheng Lin 	bool tx_en, rx_en;
14499dc2145dSYunsheng Lin 
14509dc2145dSYunsheng Lin 	switch (hdev->tm_info.fc_mode) {
14519dc2145dSYunsheng Lin 	case HCLGE_FC_NONE:
14529dc2145dSYunsheng Lin 		tx_en = false;
14539dc2145dSYunsheng Lin 		rx_en = false;
14549dc2145dSYunsheng Lin 		break;
14559dc2145dSYunsheng Lin 	case HCLGE_FC_RX_PAUSE:
14569dc2145dSYunsheng Lin 		tx_en = false;
14579dc2145dSYunsheng Lin 		rx_en = true;
14589dc2145dSYunsheng Lin 		break;
14599dc2145dSYunsheng Lin 	case HCLGE_FC_TX_PAUSE:
14609dc2145dSYunsheng Lin 		tx_en = true;
14619dc2145dSYunsheng Lin 		rx_en = false;
14629dc2145dSYunsheng Lin 		break;
14639dc2145dSYunsheng Lin 	case HCLGE_FC_FULL:
14649dc2145dSYunsheng Lin 		tx_en = true;
14659dc2145dSYunsheng Lin 		rx_en = true;
14669dc2145dSYunsheng Lin 		break;
14676d0ec65cSYunsheng Lin 	case HCLGE_FC_PFC:
14686d0ec65cSYunsheng Lin 		tx_en = false;
14696d0ec65cSYunsheng Lin 		rx_en = false;
14706d0ec65cSYunsheng Lin 		break;
14719dc2145dSYunsheng Lin 	default:
14729dc2145dSYunsheng Lin 		tx_en = true;
14739dc2145dSYunsheng Lin 		rx_en = true;
14749dc2145dSYunsheng Lin 	}
14759dc2145dSYunsheng Lin 
14769dc2145dSYunsheng Lin 	return hclge_mac_pause_en_cfg(hdev, tx_en, rx_en);
14779dc2145dSYunsheng Lin }
14789dc2145dSYunsheng Lin 
147973fc9c48SHuazhong Tan static int hclge_tm_bp_setup(struct hclge_dev *hdev)
148073fc9c48SHuazhong Tan {
14819d8d5a36SYufeng Mo 	int ret;
148273fc9c48SHuazhong Tan 	int i;
148373fc9c48SHuazhong Tan 
148473fc9c48SHuazhong Tan 	for (i = 0; i < hdev->tm_info.num_tc; i++) {
148573fc9c48SHuazhong Tan 		ret = hclge_bp_setup_hw(hdev, i);
148673fc9c48SHuazhong Tan 		if (ret)
148773fc9c48SHuazhong Tan 			return ret;
148873fc9c48SHuazhong Tan 	}
148973fc9c48SHuazhong Tan 
1490ee7a3764SDan Carpenter 	return 0;
149173fc9c48SHuazhong Tan }
149273fc9c48SHuazhong Tan 
149344e59e37SYunsheng Lin int hclge_pause_setup_hw(struct hclge_dev *hdev, bool init)
149484844054SSalil {
149584844054SSalil 	int ret;
149684844054SSalil 
1497e98d7183SFuyun Liang 	ret = hclge_pause_param_setup_hw(hdev);
149818838d0cSFuyun Liang 	if (ret)
149918838d0cSFuyun Liang 		return ret;
150018838d0cSFuyun Liang 
15016d0ec65cSYunsheng Lin 	ret = hclge_mac_pause_setup_hw(hdev);
15026d0ec65cSYunsheng Lin 	if (ret)
15036d0ec65cSYunsheng Lin 		return ret;
150484844054SSalil 
15059dc2145dSYunsheng Lin 	/* Only DCB-supported dev supports qset back pressure and pfc cmd */
15062daf4a65SYunsheng Lin 	if (!hnae3_dev_dcb_supported(hdev))
15072daf4a65SYunsheng Lin 		return 0;
15082daf4a65SYunsheng Lin 
150944e59e37SYunsheng Lin 	/* GE MAC does not support PFC, when driver is initializing and MAC
151044e59e37SYunsheng Lin 	 * is in GE Mode, ignore the error here, otherwise initialization
151144e59e37SYunsheng Lin 	 * will fail.
151244e59e37SYunsheng Lin 	 */
15139dc2145dSYunsheng Lin 	ret = hclge_pfc_setup_hw(hdev);
151444e59e37SYunsheng Lin 	if (init && ret == -EOPNOTSUPP)
151544e59e37SYunsheng Lin 		dev_warn(&hdev->pdev->dev, "GE MAC does not support pfc\n");
1516fba2efdaSHuazhong Tan 	else if (ret) {
1517fba2efdaSHuazhong Tan 		dev_err(&hdev->pdev->dev, "config pfc failed! ret = %d\n",
1518fba2efdaSHuazhong Tan 			ret);
151944e59e37SYunsheng Lin 		return ret;
1520fba2efdaSHuazhong Tan 	}
15219dc2145dSYunsheng Lin 
152273fc9c48SHuazhong Tan 	return hclge_tm_bp_setup(hdev);
152377f255c1SYunsheng Lin }
152477f255c1SYunsheng Lin 
1525e432abfbSYunsheng Lin void hclge_tm_prio_tc_info_update(struct hclge_dev *hdev, u8 *prio_tc)
152677f255c1SYunsheng Lin {
152777f255c1SYunsheng Lin 	struct hclge_vport *vport = hdev->vport;
152877f255c1SYunsheng Lin 	struct hnae3_knic_private_info *kinfo;
152977f255c1SYunsheng Lin 	u32 i, k;
153077f255c1SYunsheng Lin 
153177f255c1SYunsheng Lin 	for (i = 0; i < HNAE3_MAX_USER_PRIO; i++) {
153277f255c1SYunsheng Lin 		hdev->tm_info.prio_tc[i] = prio_tc[i];
153377f255c1SYunsheng Lin 
153477f255c1SYunsheng Lin 		for (k = 0;  k < hdev->num_alloc_vport; k++) {
153577f255c1SYunsheng Lin 			kinfo = &vport[k].nic.kinfo;
153635244430SJian Shen 			kinfo->tc_info.prio_tc[i] = prio_tc[i];
153777f255c1SYunsheng Lin 		}
153877f255c1SYunsheng Lin 	}
153977f255c1SYunsheng Lin }
154077f255c1SYunsheng Lin 
1541e432abfbSYunsheng Lin void hclge_tm_schd_info_update(struct hclge_dev *hdev, u8 num_tc)
154277f255c1SYunsheng Lin {
15439b2f3477SWeihang Li 	u8 bit_map = 0;
15449b2f3477SWeihang Li 	u8 i;
154577f255c1SYunsheng Lin 
154677f255c1SYunsheng Lin 	hdev->tm_info.num_tc = num_tc;
154777f255c1SYunsheng Lin 
154877f255c1SYunsheng Lin 	for (i = 0; i < hdev->tm_info.num_tc; i++)
154977f255c1SYunsheng Lin 		bit_map |= BIT(i);
155077f255c1SYunsheng Lin 
155177f255c1SYunsheng Lin 	if (!bit_map) {
155277f255c1SYunsheng Lin 		bit_map = 1;
155377f255c1SYunsheng Lin 		hdev->tm_info.num_tc = 1;
155477f255c1SYunsheng Lin 	}
155577f255c1SYunsheng Lin 
155677f255c1SYunsheng Lin 	hdev->hw_tc_map = bit_map;
155777f255c1SYunsheng Lin 
155877f255c1SYunsheng Lin 	hclge_tm_schd_info_init(hdev);
155984844054SSalil }
156084844054SSalil 
1561ae179b2fSYunsheng Lin void hclge_tm_pfc_info_update(struct hclge_dev *hdev)
1562ae179b2fSYunsheng Lin {
1563ae179b2fSYunsheng Lin 	/* DCB is enabled if we have more than 1 TC or pfc_en is
1564ae179b2fSYunsheng Lin 	 * non-zero.
1565ae179b2fSYunsheng Lin 	 */
1566ae179b2fSYunsheng Lin 	if (hdev->tm_info.num_tc > 1 || hdev->tm_info.pfc_en)
1567ae179b2fSYunsheng Lin 		hdev->flag |= HCLGE_FLAG_DCB_ENABLE;
1568ae179b2fSYunsheng Lin 	else
1569ae179b2fSYunsheng Lin 		hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
1570ae179b2fSYunsheng Lin 
1571ae179b2fSYunsheng Lin 	hclge_pfc_info_init(hdev);
1572ae179b2fSYunsheng Lin }
1573ae179b2fSYunsheng Lin 
157444e59e37SYunsheng Lin int hclge_tm_init_hw(struct hclge_dev *hdev, bool init)
157584844054SSalil {
157684844054SSalil 	int ret;
157784844054SSalil 
157884844054SSalil 	if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) &&
157984844054SSalil 	    (hdev->tx_sch_mode != HCLGE_FLAG_VNET_BASE_SCH_MODE))
158084844054SSalil 		return -ENOTSUPP;
158184844054SSalil 
158284844054SSalil 	ret = hclge_tm_schd_setup_hw(hdev);
158384844054SSalil 	if (ret)
158484844054SSalil 		return ret;
158584844054SSalil 
158644e59e37SYunsheng Lin 	ret = hclge_pause_setup_hw(hdev, init);
158784844054SSalil 	if (ret)
158884844054SSalil 		return ret;
158984844054SSalil 
159084844054SSalil 	return 0;
159184844054SSalil }
159284844054SSalil 
159384844054SSalil int hclge_tm_schd_init(struct hclge_dev *hdev)
159484844054SSalil {
15957979a223SYunsheng Lin 	/* fc_mode is HCLGE_FC_FULL on reset */
15967979a223SYunsheng Lin 	hdev->tm_info.fc_mode = HCLGE_FC_FULL;
15977979a223SYunsheng Lin 	hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
15987979a223SYunsheng Lin 
1599b6872fd3SYunsheng Lin 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE &&
1600b6872fd3SYunsheng Lin 	    hdev->tm_info.num_pg != 1)
1601b6872fd3SYunsheng Lin 		return -EINVAL;
1602b6872fd3SYunsheng Lin 
1603b6872fd3SYunsheng Lin 	hclge_tm_schd_info_init(hdev);
160484844054SSalil 
160544e59e37SYunsheng Lin 	return hclge_tm_init_hw(hdev, true);
160684844054SSalil }
1607672ad0edSHuazhong Tan 
1608672ad0edSHuazhong Tan int hclge_tm_vport_map_update(struct hclge_dev *hdev)
1609672ad0edSHuazhong Tan {
1610672ad0edSHuazhong Tan 	struct hclge_vport *vport = hdev->vport;
1611672ad0edSHuazhong Tan 	int ret;
1612672ad0edSHuazhong Tan 
1613672ad0edSHuazhong Tan 	hclge_tm_vport_tc_info_update(vport);
1614672ad0edSHuazhong Tan 
1615672ad0edSHuazhong Tan 	ret = hclge_vport_q_to_qs_map(hdev, vport);
1616672ad0edSHuazhong Tan 	if (ret)
1617672ad0edSHuazhong Tan 		return ret;
1618672ad0edSHuazhong Tan 
1619672ad0edSHuazhong Tan 	if (!(hdev->flag & HCLGE_FLAG_DCB_ENABLE))
1620672ad0edSHuazhong Tan 		return 0;
1621672ad0edSHuazhong Tan 
1622672ad0edSHuazhong Tan 	return hclge_tm_bp_setup(hdev);
1623672ad0edSHuazhong Tan }
16242bbad0aaSGuangbin Huang 
16252bbad0aaSGuangbin Huang int hclge_tm_get_qset_num(struct hclge_dev *hdev, u16 *qset_num)
16262bbad0aaSGuangbin Huang {
16272bbad0aaSGuangbin Huang 	struct hclge_tm_nodes_cmd *nodes;
16282bbad0aaSGuangbin Huang 	struct hclge_desc desc;
16292bbad0aaSGuangbin Huang 	int ret;
16302bbad0aaSGuangbin Huang 
16312bbad0aaSGuangbin Huang 	if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) {
16322bbad0aaSGuangbin Huang 		/* Each PF has 8 qsets and each VF has 1 qset */
16332bbad0aaSGuangbin Huang 		*qset_num = HCLGE_TM_PF_MAX_QSET_NUM + pci_num_vf(hdev->pdev);
16342bbad0aaSGuangbin Huang 		return 0;
16352bbad0aaSGuangbin Huang 	}
16362bbad0aaSGuangbin Huang 
16372bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NODES, true);
16382bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
16392bbad0aaSGuangbin Huang 	if (ret) {
16402bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
16412bbad0aaSGuangbin Huang 			"failed to get qset num, ret = %d\n", ret);
16422bbad0aaSGuangbin Huang 		return ret;
16432bbad0aaSGuangbin Huang 	}
16442bbad0aaSGuangbin Huang 
16452bbad0aaSGuangbin Huang 	nodes = (struct hclge_tm_nodes_cmd *)desc.data;
16462bbad0aaSGuangbin Huang 	*qset_num = le16_to_cpu(nodes->qset_num);
16472bbad0aaSGuangbin Huang 	return 0;
16482bbad0aaSGuangbin Huang }
16492bbad0aaSGuangbin Huang 
16502bbad0aaSGuangbin Huang int hclge_tm_get_pri_num(struct hclge_dev *hdev, u8 *pri_num)
16512bbad0aaSGuangbin Huang {
16522bbad0aaSGuangbin Huang 	struct hclge_tm_nodes_cmd *nodes;
16532bbad0aaSGuangbin Huang 	struct hclge_desc desc;
16542bbad0aaSGuangbin Huang 	int ret;
16552bbad0aaSGuangbin Huang 
16562bbad0aaSGuangbin Huang 	if (hdev->ae_dev->dev_version <= HNAE3_DEVICE_VERSION_V2) {
16572bbad0aaSGuangbin Huang 		*pri_num = HCLGE_TM_PF_MAX_PRI_NUM;
16582bbad0aaSGuangbin Huang 		return 0;
16592bbad0aaSGuangbin Huang 	}
16602bbad0aaSGuangbin Huang 
16612bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NODES, true);
16622bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
16632bbad0aaSGuangbin Huang 	if (ret) {
16642bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
16652bbad0aaSGuangbin Huang 			"failed to get pri num, ret = %d\n", ret);
16662bbad0aaSGuangbin Huang 		return ret;
16672bbad0aaSGuangbin Huang 	}
16682bbad0aaSGuangbin Huang 
16692bbad0aaSGuangbin Huang 	nodes = (struct hclge_tm_nodes_cmd *)desc.data;
16702bbad0aaSGuangbin Huang 	*pri_num = nodes->pri_num;
16712bbad0aaSGuangbin Huang 	return 0;
16722bbad0aaSGuangbin Huang }
16732bbad0aaSGuangbin Huang 
16742bbad0aaSGuangbin Huang int hclge_tm_get_qset_map_pri(struct hclge_dev *hdev, u16 qset_id, u8 *priority,
16752bbad0aaSGuangbin Huang 			      u8 *link_vld)
16762bbad0aaSGuangbin Huang {
16772bbad0aaSGuangbin Huang 	struct hclge_qs_to_pri_link_cmd *map;
16782bbad0aaSGuangbin Huang 	struct hclge_desc desc;
16792bbad0aaSGuangbin Huang 	int ret;
16802bbad0aaSGuangbin Huang 
16812bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_TO_PRI_LINK, true);
16822bbad0aaSGuangbin Huang 	map = (struct hclge_qs_to_pri_link_cmd *)desc.data;
16832bbad0aaSGuangbin Huang 	map->qs_id = cpu_to_le16(qset_id);
16842bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
16852bbad0aaSGuangbin Huang 	if (ret) {
16862bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
16872bbad0aaSGuangbin Huang 			"failed to get qset map priority, ret = %d\n", ret);
16882bbad0aaSGuangbin Huang 		return ret;
16892bbad0aaSGuangbin Huang 	}
16902bbad0aaSGuangbin Huang 
16912bbad0aaSGuangbin Huang 	*priority = map->priority;
16922bbad0aaSGuangbin Huang 	*link_vld = map->link_vld;
16932bbad0aaSGuangbin Huang 	return 0;
16942bbad0aaSGuangbin Huang }
16952bbad0aaSGuangbin Huang 
16962bbad0aaSGuangbin Huang int hclge_tm_get_qset_sch_mode(struct hclge_dev *hdev, u16 qset_id, u8 *mode)
16972bbad0aaSGuangbin Huang {
16982bbad0aaSGuangbin Huang 	struct hclge_qs_sch_mode_cfg_cmd *qs_sch_mode;
16992bbad0aaSGuangbin Huang 	struct hclge_desc desc;
17002bbad0aaSGuangbin Huang 	int ret;
17012bbad0aaSGuangbin Huang 
17022bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_SCH_MODE_CFG, true);
17032bbad0aaSGuangbin Huang 	qs_sch_mode = (struct hclge_qs_sch_mode_cfg_cmd *)desc.data;
17042bbad0aaSGuangbin Huang 	qs_sch_mode->qs_id = cpu_to_le16(qset_id);
17052bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
17062bbad0aaSGuangbin Huang 	if (ret) {
17072bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
17082bbad0aaSGuangbin Huang 			"failed to get qset sch mode, ret = %d\n", ret);
17092bbad0aaSGuangbin Huang 		return ret;
17102bbad0aaSGuangbin Huang 	}
17112bbad0aaSGuangbin Huang 
17122bbad0aaSGuangbin Huang 	*mode = qs_sch_mode->sch_mode;
17132bbad0aaSGuangbin Huang 	return 0;
17142bbad0aaSGuangbin Huang }
17152bbad0aaSGuangbin Huang 
17162bbad0aaSGuangbin Huang int hclge_tm_get_qset_weight(struct hclge_dev *hdev, u16 qset_id, u8 *weight)
17172bbad0aaSGuangbin Huang {
17182bbad0aaSGuangbin Huang 	struct hclge_qs_weight_cmd *qs_weight;
17192bbad0aaSGuangbin Huang 	struct hclge_desc desc;
17202bbad0aaSGuangbin Huang 	int ret;
17212bbad0aaSGuangbin Huang 
17222bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_WEIGHT, true);
17232bbad0aaSGuangbin Huang 	qs_weight = (struct hclge_qs_weight_cmd *)desc.data;
17242bbad0aaSGuangbin Huang 	qs_weight->qs_id = cpu_to_le16(qset_id);
17252bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
17262bbad0aaSGuangbin Huang 	if (ret) {
17272bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
17282bbad0aaSGuangbin Huang 			"failed to get qset weight, ret = %d\n", ret);
17292bbad0aaSGuangbin Huang 		return ret;
17302bbad0aaSGuangbin Huang 	}
17312bbad0aaSGuangbin Huang 
17322bbad0aaSGuangbin Huang 	*weight = qs_weight->dwrr;
17332bbad0aaSGuangbin Huang 	return 0;
17342bbad0aaSGuangbin Huang }
17352bbad0aaSGuangbin Huang 
17362bbad0aaSGuangbin Huang int hclge_tm_get_pri_sch_mode(struct hclge_dev *hdev, u8 pri_id, u8 *mode)
17372bbad0aaSGuangbin Huang {
17382bbad0aaSGuangbin Huang 	struct hclge_pri_sch_mode_cfg_cmd *pri_sch_mode;
17392bbad0aaSGuangbin Huang 	struct hclge_desc desc;
17402bbad0aaSGuangbin Huang 	int ret;
17412bbad0aaSGuangbin Huang 
17422bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_SCH_MODE_CFG, true);
17432bbad0aaSGuangbin Huang 	pri_sch_mode = (struct hclge_pri_sch_mode_cfg_cmd *)desc.data;
17442bbad0aaSGuangbin Huang 	pri_sch_mode->pri_id = pri_id;
17452bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
17462bbad0aaSGuangbin Huang 	if (ret) {
17472bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
17482bbad0aaSGuangbin Huang 			"failed to get priority sch mode, ret = %d\n", ret);
17492bbad0aaSGuangbin Huang 		return ret;
17502bbad0aaSGuangbin Huang 	}
17512bbad0aaSGuangbin Huang 
17522bbad0aaSGuangbin Huang 	*mode = pri_sch_mode->sch_mode;
17532bbad0aaSGuangbin Huang 	return 0;
17542bbad0aaSGuangbin Huang }
17552bbad0aaSGuangbin Huang 
17562bbad0aaSGuangbin Huang int hclge_tm_get_pri_weight(struct hclge_dev *hdev, u8 pri_id, u8 *weight)
17572bbad0aaSGuangbin Huang {
17582bbad0aaSGuangbin Huang 	struct hclge_priority_weight_cmd *priority_weight;
17592bbad0aaSGuangbin Huang 	struct hclge_desc desc;
17602bbad0aaSGuangbin Huang 	int ret;
17612bbad0aaSGuangbin Huang 
17622bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_WEIGHT, true);
17632bbad0aaSGuangbin Huang 	priority_weight = (struct hclge_priority_weight_cmd *)desc.data;
17642bbad0aaSGuangbin Huang 	priority_weight->pri_id = pri_id;
17652bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
17662bbad0aaSGuangbin Huang 	if (ret) {
17672bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
17682bbad0aaSGuangbin Huang 			"failed to get priority weight, ret = %d\n", ret);
17692bbad0aaSGuangbin Huang 		return ret;
17702bbad0aaSGuangbin Huang 	}
17712bbad0aaSGuangbin Huang 
17722bbad0aaSGuangbin Huang 	*weight = priority_weight->dwrr;
17732bbad0aaSGuangbin Huang 	return 0;
17742bbad0aaSGuangbin Huang }
17752bbad0aaSGuangbin Huang 
17762bbad0aaSGuangbin Huang int hclge_tm_get_pri_shaper(struct hclge_dev *hdev, u8 pri_id,
17772bbad0aaSGuangbin Huang 			    enum hclge_opcode_type cmd,
1778*cad7c215SGuangbin Huang 			    struct hclge_tm_shaper_para *para)
17792bbad0aaSGuangbin Huang {
17802bbad0aaSGuangbin Huang 	struct hclge_pri_shapping_cmd *shap_cfg_cmd;
17812bbad0aaSGuangbin Huang 	struct hclge_desc desc;
17822bbad0aaSGuangbin Huang 	u32 shapping_para;
17832bbad0aaSGuangbin Huang 	int ret;
17842bbad0aaSGuangbin Huang 
17852bbad0aaSGuangbin Huang 	if (cmd != HCLGE_OPC_TM_PRI_C_SHAPPING &&
17862bbad0aaSGuangbin Huang 	    cmd != HCLGE_OPC_TM_PRI_P_SHAPPING)
17872bbad0aaSGuangbin Huang 		return -EINVAL;
17882bbad0aaSGuangbin Huang 
17892bbad0aaSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, cmd, true);
17902bbad0aaSGuangbin Huang 	shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data;
17912bbad0aaSGuangbin Huang 	shap_cfg_cmd->pri_id = pri_id;
17922bbad0aaSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
17932bbad0aaSGuangbin Huang 	if (ret) {
17942bbad0aaSGuangbin Huang 		dev_err(&hdev->pdev->dev,
17952bbad0aaSGuangbin Huang 			"failed to get priority shaper(%#x), ret = %d\n",
17962bbad0aaSGuangbin Huang 			cmd, ret);
17972bbad0aaSGuangbin Huang 		return ret;
17982bbad0aaSGuangbin Huang 	}
17992bbad0aaSGuangbin Huang 
18002bbad0aaSGuangbin Huang 	shapping_para = le32_to_cpu(shap_cfg_cmd->pri_shapping_para);
18012bbad0aaSGuangbin Huang 	para->ir_b = hclge_tm_get_field(shapping_para, IR_B);
18022bbad0aaSGuangbin Huang 	para->ir_u = hclge_tm_get_field(shapping_para, IR_U);
18032bbad0aaSGuangbin Huang 	para->ir_s = hclge_tm_get_field(shapping_para, IR_S);
18042bbad0aaSGuangbin Huang 	para->bs_b = hclge_tm_get_field(shapping_para, BS_B);
18052bbad0aaSGuangbin Huang 	para->bs_s = hclge_tm_get_field(shapping_para, BS_S);
18062bbad0aaSGuangbin Huang 	para->flag = shap_cfg_cmd->flag;
18072bbad0aaSGuangbin Huang 	para->rate = le32_to_cpu(shap_cfg_cmd->pri_rate);
18082bbad0aaSGuangbin Huang 	return 0;
18092bbad0aaSGuangbin Huang }
18107679f28eSGuangbin Huang 
18117679f28eSGuangbin Huang int hclge_tm_get_q_to_qs_map(struct hclge_dev *hdev, u16 q_id, u16 *qset_id)
18127679f28eSGuangbin Huang {
18137679f28eSGuangbin Huang 	struct hclge_nq_to_qs_link_cmd *map;
18147679f28eSGuangbin Huang 	struct hclge_desc desc;
18157679f28eSGuangbin Huang 	u16 qs_id_l;
18167679f28eSGuangbin Huang 	u16 qs_id_h;
18177679f28eSGuangbin Huang 	int ret;
18187679f28eSGuangbin Huang 
18197679f28eSGuangbin Huang 	map = (struct hclge_nq_to_qs_link_cmd *)desc.data;
18207679f28eSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NQ_TO_QS_LINK, true);
18217679f28eSGuangbin Huang 	map->nq_id = cpu_to_le16(q_id);
18227679f28eSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
18237679f28eSGuangbin Huang 	if (ret) {
18247679f28eSGuangbin Huang 		dev_err(&hdev->pdev->dev,
18257679f28eSGuangbin Huang 			"failed to get queue to qset map, ret = %d\n", ret);
18267679f28eSGuangbin Huang 		return ret;
18277679f28eSGuangbin Huang 	}
18287679f28eSGuangbin Huang 	*qset_id = le16_to_cpu(map->qset_id);
18297679f28eSGuangbin Huang 
18307679f28eSGuangbin Huang 	/* convert qset_id to the following format, drop the vld bit
18317679f28eSGuangbin Huang 	 *            | qs_id_h | vld | qs_id_l |
18327679f28eSGuangbin Huang 	 * qset_id:   | 15 ~ 11 |  10 |  9 ~ 0  |
18337679f28eSGuangbin Huang 	 *             \         \   /         /
18347679f28eSGuangbin Huang 	 *              \         \ /         /
18357679f28eSGuangbin Huang 	 * qset_id: | 15 | 14 ~ 10 |  9 ~ 0  |
18367679f28eSGuangbin Huang 	 */
18377679f28eSGuangbin Huang 	qs_id_l = hnae3_get_field(*qset_id, HCLGE_TM_QS_ID_L_MSK,
18387679f28eSGuangbin Huang 				  HCLGE_TM_QS_ID_L_S);
18397679f28eSGuangbin Huang 	qs_id_h = hnae3_get_field(*qset_id, HCLGE_TM_QS_ID_H_EXT_MSK,
18407679f28eSGuangbin Huang 				  HCLGE_TM_QS_ID_H_EXT_S);
18417679f28eSGuangbin Huang 	*qset_id = 0;
18427679f28eSGuangbin Huang 	hnae3_set_field(*qset_id, HCLGE_TM_QS_ID_L_MSK, HCLGE_TM_QS_ID_L_S,
18437679f28eSGuangbin Huang 			qs_id_l);
18447679f28eSGuangbin Huang 	hnae3_set_field(*qset_id, HCLGE_TM_QS_ID_H_MSK, HCLGE_TM_QS_ID_H_S,
18457679f28eSGuangbin Huang 			qs_id_h);
18467679f28eSGuangbin Huang 	return 0;
18477679f28eSGuangbin Huang }
18487679f28eSGuangbin Huang 
18497679f28eSGuangbin Huang int hclge_tm_get_q_to_tc(struct hclge_dev *hdev, u16 q_id, u8 *tc_id)
18507679f28eSGuangbin Huang {
18517679f28eSGuangbin Huang #define HCLGE_TM_TC_MASK		0x7
18527679f28eSGuangbin Huang 
18537679f28eSGuangbin Huang 	struct hclge_tqp_tx_queue_tc_cmd *tc;
18547679f28eSGuangbin Huang 	struct hclge_desc desc;
18557679f28eSGuangbin Huang 	int ret;
18567679f28eSGuangbin Huang 
18577679f28eSGuangbin Huang 	tc = (struct hclge_tqp_tx_queue_tc_cmd *)desc.data;
18587679f28eSGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TQP_TX_QUEUE_TC, true);
18597679f28eSGuangbin Huang 	tc->queue_id = cpu_to_le16(q_id);
18607679f28eSGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
18617679f28eSGuangbin Huang 	if (ret) {
18627679f28eSGuangbin Huang 		dev_err(&hdev->pdev->dev,
18637679f28eSGuangbin Huang 			"failed to get queue to tc map, ret = %d\n", ret);
18647679f28eSGuangbin Huang 		return ret;
18657679f28eSGuangbin Huang 	}
18667679f28eSGuangbin Huang 
18677679f28eSGuangbin Huang 	*tc_id = tc->tc_id & HCLGE_TM_TC_MASK;
18687679f28eSGuangbin Huang 	return 0;
18697679f28eSGuangbin Huang }
1870*cad7c215SGuangbin Huang 
1871*cad7c215SGuangbin Huang int hclge_tm_get_pg_to_pri_map(struct hclge_dev *hdev, u8 pg_id,
1872*cad7c215SGuangbin Huang 			       u8 *pri_bit_map)
1873*cad7c215SGuangbin Huang {
1874*cad7c215SGuangbin Huang 	struct hclge_pg_to_pri_link_cmd *map;
1875*cad7c215SGuangbin Huang 	struct hclge_desc desc;
1876*cad7c215SGuangbin Huang 	int ret;
1877*cad7c215SGuangbin Huang 
1878*cad7c215SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_TO_PRI_LINK, true);
1879*cad7c215SGuangbin Huang 	map = (struct hclge_pg_to_pri_link_cmd *)desc.data;
1880*cad7c215SGuangbin Huang 	map->pg_id = pg_id;
1881*cad7c215SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
1882*cad7c215SGuangbin Huang 	if (ret) {
1883*cad7c215SGuangbin Huang 		dev_err(&hdev->pdev->dev,
1884*cad7c215SGuangbin Huang 			"failed to get pg to pri map, ret = %d\n", ret);
1885*cad7c215SGuangbin Huang 		return ret;
1886*cad7c215SGuangbin Huang 	}
1887*cad7c215SGuangbin Huang 
1888*cad7c215SGuangbin Huang 	*pri_bit_map = map->pri_bit_map;
1889*cad7c215SGuangbin Huang 	return 0;
1890*cad7c215SGuangbin Huang }
1891*cad7c215SGuangbin Huang 
1892*cad7c215SGuangbin Huang int hclge_tm_get_pg_weight(struct hclge_dev *hdev, u8 pg_id, u8 *weight)
1893*cad7c215SGuangbin Huang {
1894*cad7c215SGuangbin Huang 	struct hclge_pg_weight_cmd *pg_weight_cmd;
1895*cad7c215SGuangbin Huang 	struct hclge_desc desc;
1896*cad7c215SGuangbin Huang 	int ret;
1897*cad7c215SGuangbin Huang 
1898*cad7c215SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_WEIGHT, true);
1899*cad7c215SGuangbin Huang 	pg_weight_cmd = (struct hclge_pg_weight_cmd *)desc.data;
1900*cad7c215SGuangbin Huang 	pg_weight_cmd->pg_id = pg_id;
1901*cad7c215SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
1902*cad7c215SGuangbin Huang 	if (ret) {
1903*cad7c215SGuangbin Huang 		dev_err(&hdev->pdev->dev,
1904*cad7c215SGuangbin Huang 			"failed to get pg weight, ret = %d\n", ret);
1905*cad7c215SGuangbin Huang 		return ret;
1906*cad7c215SGuangbin Huang 	}
1907*cad7c215SGuangbin Huang 
1908*cad7c215SGuangbin Huang 	*weight = pg_weight_cmd->dwrr;
1909*cad7c215SGuangbin Huang 	return 0;
1910*cad7c215SGuangbin Huang }
1911*cad7c215SGuangbin Huang 
1912*cad7c215SGuangbin Huang int hclge_tm_get_pg_sch_mode(struct hclge_dev *hdev, u8 pg_id, u8 *mode)
1913*cad7c215SGuangbin Huang {
1914*cad7c215SGuangbin Huang 	struct hclge_desc desc;
1915*cad7c215SGuangbin Huang 	int ret;
1916*cad7c215SGuangbin Huang 
1917*cad7c215SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_SCH_MODE_CFG, true);
1918*cad7c215SGuangbin Huang 	desc.data[0] = cpu_to_le32(pg_id);
1919*cad7c215SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
1920*cad7c215SGuangbin Huang 	if (ret) {
1921*cad7c215SGuangbin Huang 		dev_err(&hdev->pdev->dev,
1922*cad7c215SGuangbin Huang 			"failed to get pg sch mode, ret = %d\n", ret);
1923*cad7c215SGuangbin Huang 		return ret;
1924*cad7c215SGuangbin Huang 	}
1925*cad7c215SGuangbin Huang 
1926*cad7c215SGuangbin Huang 	*mode = (u8)le32_to_cpu(desc.data[1]);
1927*cad7c215SGuangbin Huang 	return 0;
1928*cad7c215SGuangbin Huang }
1929*cad7c215SGuangbin Huang 
1930*cad7c215SGuangbin Huang int hclge_tm_get_pg_shaper(struct hclge_dev *hdev, u8 pg_id,
1931*cad7c215SGuangbin Huang 			   enum hclge_opcode_type cmd,
1932*cad7c215SGuangbin Huang 			   struct hclge_tm_shaper_para *para)
1933*cad7c215SGuangbin Huang {
1934*cad7c215SGuangbin Huang 	struct hclge_pg_shapping_cmd *shap_cfg_cmd;
1935*cad7c215SGuangbin Huang 	struct hclge_desc desc;
1936*cad7c215SGuangbin Huang 	u32 shapping_para;
1937*cad7c215SGuangbin Huang 	int ret;
1938*cad7c215SGuangbin Huang 
1939*cad7c215SGuangbin Huang 	if (cmd != HCLGE_OPC_TM_PG_C_SHAPPING &&
1940*cad7c215SGuangbin Huang 	    cmd != HCLGE_OPC_TM_PG_P_SHAPPING)
1941*cad7c215SGuangbin Huang 		return -EINVAL;
1942*cad7c215SGuangbin Huang 
1943*cad7c215SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, cmd, true);
1944*cad7c215SGuangbin Huang 	shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data;
1945*cad7c215SGuangbin Huang 	shap_cfg_cmd->pg_id = pg_id;
1946*cad7c215SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
1947*cad7c215SGuangbin Huang 	if (ret) {
1948*cad7c215SGuangbin Huang 		dev_err(&hdev->pdev->dev,
1949*cad7c215SGuangbin Huang 			"failed to get pg shaper(%#x), ret = %d\n",
1950*cad7c215SGuangbin Huang 			cmd, ret);
1951*cad7c215SGuangbin Huang 		return ret;
1952*cad7c215SGuangbin Huang 	}
1953*cad7c215SGuangbin Huang 
1954*cad7c215SGuangbin Huang 	shapping_para = le32_to_cpu(shap_cfg_cmd->pg_shapping_para);
1955*cad7c215SGuangbin Huang 	para->ir_b = hclge_tm_get_field(shapping_para, IR_B);
1956*cad7c215SGuangbin Huang 	para->ir_u = hclge_tm_get_field(shapping_para, IR_U);
1957*cad7c215SGuangbin Huang 	para->ir_s = hclge_tm_get_field(shapping_para, IR_S);
1958*cad7c215SGuangbin Huang 	para->bs_b = hclge_tm_get_field(shapping_para, BS_B);
1959*cad7c215SGuangbin Huang 	para->bs_s = hclge_tm_get_field(shapping_para, BS_S);
1960*cad7c215SGuangbin Huang 	para->flag = shap_cfg_cmd->flag;
1961*cad7c215SGuangbin Huang 	para->rate = le32_to_cpu(shap_cfg_cmd->pg_rate);
1962*cad7c215SGuangbin Huang 	return 0;
1963*cad7c215SGuangbin Huang }
1964*cad7c215SGuangbin Huang 
1965*cad7c215SGuangbin Huang int hclge_tm_get_port_shaper(struct hclge_dev *hdev,
1966*cad7c215SGuangbin Huang 			     struct hclge_tm_shaper_para *para)
1967*cad7c215SGuangbin Huang {
1968*cad7c215SGuangbin Huang 	struct hclge_port_shapping_cmd *port_shap_cfg_cmd;
1969*cad7c215SGuangbin Huang 	struct hclge_desc desc;
1970*cad7c215SGuangbin Huang 	u32 shapping_para;
1971*cad7c215SGuangbin Huang 	int ret;
1972*cad7c215SGuangbin Huang 
1973*cad7c215SGuangbin Huang 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PORT_SHAPPING, true);
1974*cad7c215SGuangbin Huang 	ret = hclge_cmd_send(&hdev->hw, &desc, 1);
1975*cad7c215SGuangbin Huang 	if (ret) {
1976*cad7c215SGuangbin Huang 		dev_err(&hdev->pdev->dev,
1977*cad7c215SGuangbin Huang 			"failed to get port shaper, ret = %d\n", ret);
1978*cad7c215SGuangbin Huang 		return ret;
1979*cad7c215SGuangbin Huang 	}
1980*cad7c215SGuangbin Huang 
1981*cad7c215SGuangbin Huang 	port_shap_cfg_cmd = (struct hclge_port_shapping_cmd *)desc.data;
1982*cad7c215SGuangbin Huang 	shapping_para = le32_to_cpu(port_shap_cfg_cmd->port_shapping_para);
1983*cad7c215SGuangbin Huang 	para->ir_b = hclge_tm_get_field(shapping_para, IR_B);
1984*cad7c215SGuangbin Huang 	para->ir_u = hclge_tm_get_field(shapping_para, IR_U);
1985*cad7c215SGuangbin Huang 	para->ir_s = hclge_tm_get_field(shapping_para, IR_S);
1986*cad7c215SGuangbin Huang 	para->bs_b = hclge_tm_get_field(shapping_para, BS_B);
1987*cad7c215SGuangbin Huang 	para->bs_s = hclge_tm_get_field(shapping_para, BS_S);
1988*cad7c215SGuangbin Huang 	para->flag = port_shap_cfg_cmd->flag;
1989*cad7c215SGuangbin Huang 	para->rate = le32_to_cpu(port_shap_cfg_cmd->port_rate);
1990*cad7c215SGuangbin Huang 
1991*cad7c215SGuangbin Huang 	return 0;
1992*cad7c215SGuangbin Huang }
1993