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