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 
2684844054SSalil #define HCLGE_SHAPER_BS_U_DEF	1
2784844054SSalil #define HCLGE_SHAPER_BS_S_DEF	4
2884844054SSalil 
2984844054SSalil #define HCLGE_ETHER_MAX_RATE	100000
3084844054SSalil 
3184844054SSalil /* hclge_shaper_para_calc: calculate ir parameter for the shaper
3284844054SSalil  * @ir: Rate to be config, its unit is Mbps
3384844054SSalil  * @shaper_level: the shaper level. eg: port, pg, priority, queueset
3484844054SSalil  * @ir_b: IR_B parameter of IR shaper
3584844054SSalil  * @ir_u: IR_U parameter of IR shaper
3684844054SSalil  * @ir_s: IR_S parameter of IR shaper
3784844054SSalil  *
3884844054SSalil  * the formula:
3984844054SSalil  *
4084844054SSalil  *		IR_b * (2 ^ IR_u) * 8
4184844054SSalil  * IR(Mbps) = -------------------------  *  CLOCK(1000Mbps)
4284844054SSalil  *		Tick * (2 ^ IR_s)
4384844054SSalil  *
4484844054SSalil  * @return: 0: calculate sucessful, negative: fail
4584844054SSalil  */
4684844054SSalil static int hclge_shaper_para_calc(u32 ir, u8 shaper_level,
4784844054SSalil 				  u8 *ir_b, u8 *ir_u, u8 *ir_s)
4884844054SSalil {
4984844054SSalil 	const u16 tick_array[HCLGE_SHAPER_LVL_CNT] = {
5084844054SSalil 		6 * 256,        /* Prioriy level */
5184844054SSalil 		6 * 32,         /* Prioriy group level */
5284844054SSalil 		6 * 8,          /* Port level */
5384844054SSalil 		6 * 256         /* Qset level */
5484844054SSalil 	};
5584844054SSalil 	u8 ir_u_calc = 0, ir_s_calc = 0;
5684844054SSalil 	u32 ir_calc;
5784844054SSalil 	u32 tick;
5884844054SSalil 
5984844054SSalil 	/* Calc tick */
6084844054SSalil 	if (shaper_level >= HCLGE_SHAPER_LVL_CNT)
6184844054SSalil 		return -EINVAL;
6284844054SSalil 
6384844054SSalil 	tick = tick_array[shaper_level];
6484844054SSalil 
6584844054SSalil 	/**
6684844054SSalil 	 * Calc the speed if ir_b = 126, ir_u = 0 and ir_s = 0
6784844054SSalil 	 * the formula is changed to:
6884844054SSalil 	 *		126 * 1 * 8
6984844054SSalil 	 * ir_calc = ---------------- * 1000
7084844054SSalil 	 *		tick * 1
7184844054SSalil 	 */
7284844054SSalil 	ir_calc = (1008000 + (tick >> 1) - 1) / tick;
7384844054SSalil 
7484844054SSalil 	if (ir_calc == ir) {
7584844054SSalil 		*ir_b = 126;
7684844054SSalil 		*ir_u = 0;
7784844054SSalil 		*ir_s = 0;
7884844054SSalil 
7984844054SSalil 		return 0;
8084844054SSalil 	} else if (ir_calc > ir) {
8184844054SSalil 		/* Increasing the denominator to select ir_s value */
8284844054SSalil 		while (ir_calc > ir) {
8384844054SSalil 			ir_s_calc++;
8484844054SSalil 			ir_calc = 1008000 / (tick * (1 << ir_s_calc));
8584844054SSalil 		}
8684844054SSalil 
8784844054SSalil 		if (ir_calc == ir)
8884844054SSalil 			*ir_b = 126;
8984844054SSalil 		else
9084844054SSalil 			*ir_b = (ir * tick * (1 << ir_s_calc) + 4000) / 8000;
9184844054SSalil 	} else {
9284844054SSalil 		/* Increasing the numerator to select ir_u value */
9384844054SSalil 		u32 numerator;
9484844054SSalil 
9584844054SSalil 		while (ir_calc < ir) {
9684844054SSalil 			ir_u_calc++;
9784844054SSalil 			numerator = 1008000 * (1 << ir_u_calc);
9884844054SSalil 			ir_calc = (numerator + (tick >> 1)) / tick;
9984844054SSalil 		}
10084844054SSalil 
10184844054SSalil 		if (ir_calc == ir) {
10284844054SSalil 			*ir_b = 126;
10384844054SSalil 		} else {
10484844054SSalil 			u32 denominator = (8000 * (1 << --ir_u_calc));
10584844054SSalil 			*ir_b = (ir * tick + (denominator >> 1)) / denominator;
10684844054SSalil 		}
10784844054SSalil 	}
10884844054SSalil 
10984844054SSalil 	*ir_u = ir_u_calc;
11084844054SSalil 	*ir_s = ir_s_calc;
11184844054SSalil 
11284844054SSalil 	return 0;
11384844054SSalil }
11484844054SSalil 
11584844054SSalil static int hclge_mac_pause_en_cfg(struct hclge_dev *hdev, bool tx, bool rx)
11684844054SSalil {
11784844054SSalil 	struct hclge_desc desc;
11884844054SSalil 
11984844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_CFG_MAC_PAUSE_EN, false);
12084844054SSalil 
12184844054SSalil 	desc.data[0] = cpu_to_le32((tx ? HCLGE_TX_MAC_PAUSE_EN_MSK : 0) |
12284844054SSalil 		(rx ? HCLGE_RX_MAC_PAUSE_EN_MSK : 0));
12384844054SSalil 
12484844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
12584844054SSalil }
12684844054SSalil 
12784844054SSalil static int hclge_fill_pri_array(struct hclge_dev *hdev, u8 *pri, u8 pri_id)
12884844054SSalil {
12984844054SSalil 	u8 tc;
13084844054SSalil 
13184844054SSalil 	for (tc = 0; tc < hdev->tm_info.num_tc; tc++)
13284844054SSalil 		if (hdev->tm_info.tc_info[tc].up == pri_id)
13384844054SSalil 			break;
13484844054SSalil 
13584844054SSalil 	if (tc >= hdev->tm_info.num_tc)
13684844054SSalil 		return -EINVAL;
13784844054SSalil 
13884844054SSalil 	/**
13984844054SSalil 	 * the register for priority has four bytes, the first bytes includes
14084844054SSalil 	 *  priority0 and priority1, the higher 4bit stands for priority1
14184844054SSalil 	 *  while the lower 4bit stands for priority0, as below:
14284844054SSalil 	 * first byte:	| pri_1 | pri_0 |
14384844054SSalil 	 * second byte:	| pri_3 | pri_2 |
14484844054SSalil 	 * third byte:	| pri_5 | pri_4 |
14584844054SSalil 	 * fourth byte:	| pri_7 | pri_6 |
14684844054SSalil 	 */
14784844054SSalil 	pri[pri_id >> 1] |= tc << ((pri_id & 1) * 4);
14884844054SSalil 
14984844054SSalil 	return 0;
15084844054SSalil }
15184844054SSalil 
15284844054SSalil static int hclge_up_to_tc_map(struct hclge_dev *hdev)
15384844054SSalil {
15484844054SSalil 	struct hclge_desc desc;
15584844054SSalil 	u8 *pri = (u8 *)desc.data;
15684844054SSalil 	u8 pri_id;
15784844054SSalil 	int ret;
15884844054SSalil 
15984844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_PRI_TO_TC_MAPPING, false);
16084844054SSalil 
16184844054SSalil 	for (pri_id = 0; pri_id < hdev->tm_info.num_tc; pri_id++) {
16284844054SSalil 		ret = hclge_fill_pri_array(hdev, pri, pri_id);
16384844054SSalil 		if (ret)
16484844054SSalil 			return ret;
16584844054SSalil 	}
16684844054SSalil 
16784844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
16884844054SSalil }
16984844054SSalil 
17084844054SSalil static int hclge_tm_pg_to_pri_map_cfg(struct hclge_dev *hdev,
17184844054SSalil 				      u8 pg_id, u8 pri_bit_map)
17284844054SSalil {
17384844054SSalil 	struct hclge_pg_to_pri_link_cmd *map;
17484844054SSalil 	struct hclge_desc desc;
17584844054SSalil 
17684844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_TO_PRI_LINK, false);
17784844054SSalil 
17884844054SSalil 	map = (struct hclge_pg_to_pri_link_cmd *)desc.data;
17984844054SSalil 
18084844054SSalil 	map->pg_id = pg_id;
18184844054SSalil 	map->pri_bit_map = pri_bit_map;
18284844054SSalil 
18384844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
18484844054SSalil }
18584844054SSalil 
18684844054SSalil static int hclge_tm_qs_to_pri_map_cfg(struct hclge_dev *hdev,
18784844054SSalil 				      u16 qs_id, u8 pri)
18884844054SSalil {
18984844054SSalil 	struct hclge_qs_to_pri_link_cmd *map;
19084844054SSalil 	struct hclge_desc desc;
19184844054SSalil 
19284844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_TO_PRI_LINK, false);
19384844054SSalil 
19484844054SSalil 	map = (struct hclge_qs_to_pri_link_cmd *)desc.data;
19584844054SSalil 
19684844054SSalil 	map->qs_id = cpu_to_le16(qs_id);
19784844054SSalil 	map->priority = pri;
19884844054SSalil 	map->link_vld = HCLGE_TM_QS_PRI_LINK_VLD_MSK;
19984844054SSalil 
20084844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
20184844054SSalil }
20284844054SSalil 
20384844054SSalil static int hclge_tm_q_to_qs_map_cfg(struct hclge_dev *hdev,
20484844054SSalil 				    u8 q_id, u16 qs_id)
20584844054SSalil {
20684844054SSalil 	struct hclge_nq_to_qs_link_cmd *map;
20784844054SSalil 	struct hclge_desc desc;
20884844054SSalil 
20984844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_NQ_TO_QS_LINK, false);
21084844054SSalil 
21184844054SSalil 	map = (struct hclge_nq_to_qs_link_cmd *)desc.data;
21284844054SSalil 
21384844054SSalil 	map->nq_id = cpu_to_le16(q_id);
21484844054SSalil 	map->qset_id = cpu_to_le16(qs_id | HCLGE_TM_Q_QS_LINK_VLD_MSK);
21584844054SSalil 
21684844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
21784844054SSalil }
21884844054SSalil 
21984844054SSalil static int hclge_tm_pg_weight_cfg(struct hclge_dev *hdev, u8 pg_id,
22084844054SSalil 				  u8 dwrr)
22184844054SSalil {
22284844054SSalil 	struct hclge_pg_weight_cmd *weight;
22384844054SSalil 	struct hclge_desc desc;
22484844054SSalil 
22584844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_WEIGHT, false);
22684844054SSalil 
22784844054SSalil 	weight = (struct hclge_pg_weight_cmd *)desc.data;
22884844054SSalil 
22984844054SSalil 	weight->pg_id = pg_id;
23084844054SSalil 	weight->dwrr = dwrr;
23184844054SSalil 
23284844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
23384844054SSalil }
23484844054SSalil 
23584844054SSalil static int hclge_tm_pri_weight_cfg(struct hclge_dev *hdev, u8 pri_id,
23684844054SSalil 				   u8 dwrr)
23784844054SSalil {
23884844054SSalil 	struct hclge_priority_weight_cmd *weight;
23984844054SSalil 	struct hclge_desc desc;
24084844054SSalil 
24184844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_WEIGHT, false);
24284844054SSalil 
24384844054SSalil 	weight = (struct hclge_priority_weight_cmd *)desc.data;
24484844054SSalil 
24584844054SSalil 	weight->pri_id = pri_id;
24684844054SSalil 	weight->dwrr = dwrr;
24784844054SSalil 
24884844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
24984844054SSalil }
25084844054SSalil 
25184844054SSalil static int hclge_tm_qs_weight_cfg(struct hclge_dev *hdev, u16 qs_id,
25284844054SSalil 				  u8 dwrr)
25384844054SSalil {
25484844054SSalil 	struct hclge_qs_weight_cmd *weight;
25584844054SSalil 	struct hclge_desc desc;
25684844054SSalil 
25784844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_WEIGHT, false);
25884844054SSalil 
25984844054SSalil 	weight = (struct hclge_qs_weight_cmd *)desc.data;
26084844054SSalil 
26184844054SSalil 	weight->qs_id = cpu_to_le16(qs_id);
26284844054SSalil 	weight->dwrr = dwrr;
26384844054SSalil 
26484844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
26584844054SSalil }
26684844054SSalil 
26784844054SSalil static int hclge_tm_pg_shapping_cfg(struct hclge_dev *hdev,
26884844054SSalil 				    enum hclge_shap_bucket bucket, u8 pg_id,
26984844054SSalil 				    u8 ir_b, u8 ir_u, u8 ir_s, u8 bs_b, u8 bs_s)
27084844054SSalil {
27184844054SSalil 	struct hclge_pg_shapping_cmd *shap_cfg_cmd;
27284844054SSalil 	enum hclge_opcode_type opcode;
27384844054SSalil 	struct hclge_desc desc;
27484844054SSalil 
27584844054SSalil 	opcode = bucket ? HCLGE_OPC_TM_PG_P_SHAPPING :
27684844054SSalil 		HCLGE_OPC_TM_PG_C_SHAPPING;
27784844054SSalil 	hclge_cmd_setup_basic_desc(&desc, opcode, false);
27884844054SSalil 
27984844054SSalil 	shap_cfg_cmd = (struct hclge_pg_shapping_cmd *)desc.data;
28084844054SSalil 
28184844054SSalil 	shap_cfg_cmd->pg_id = pg_id;
28284844054SSalil 
283c4726338SYunsheng Lin 	hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, IR_B, ir_b);
284c4726338SYunsheng Lin 	hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, IR_U, ir_u);
285c4726338SYunsheng Lin 	hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, IR_S, ir_s);
286c4726338SYunsheng Lin 	hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, BS_B, bs_b);
287c4726338SYunsheng Lin 	hclge_tm_set_field(shap_cfg_cmd->pg_shapping_para, BS_S, bs_s);
28884844054SSalil 
28984844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
29084844054SSalil }
29184844054SSalil 
29284844054SSalil static int hclge_tm_pri_shapping_cfg(struct hclge_dev *hdev,
29384844054SSalil 				     enum hclge_shap_bucket bucket, u8 pri_id,
29484844054SSalil 				     u8 ir_b, u8 ir_u, u8 ir_s,
29584844054SSalil 				     u8 bs_b, u8 bs_s)
29684844054SSalil {
29784844054SSalil 	struct hclge_pri_shapping_cmd *shap_cfg_cmd;
29884844054SSalil 	enum hclge_opcode_type opcode;
29984844054SSalil 	struct hclge_desc desc;
30084844054SSalil 
30184844054SSalil 	opcode = bucket ? HCLGE_OPC_TM_PRI_P_SHAPPING :
30284844054SSalil 		HCLGE_OPC_TM_PRI_C_SHAPPING;
30384844054SSalil 
30484844054SSalil 	hclge_cmd_setup_basic_desc(&desc, opcode, false);
30584844054SSalil 
30684844054SSalil 	shap_cfg_cmd = (struct hclge_pri_shapping_cmd *)desc.data;
30784844054SSalil 
30884844054SSalil 	shap_cfg_cmd->pri_id = pri_id;
30984844054SSalil 
310c4726338SYunsheng Lin 	hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, IR_B, ir_b);
311c4726338SYunsheng Lin 	hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, IR_U, ir_u);
312c4726338SYunsheng Lin 	hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, IR_S, ir_s);
313c4726338SYunsheng Lin 	hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, BS_B, bs_b);
314c4726338SYunsheng Lin 	hclge_tm_set_field(shap_cfg_cmd->pri_shapping_para, BS_S, bs_s);
31584844054SSalil 
31684844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
31784844054SSalil }
31884844054SSalil 
31984844054SSalil static int hclge_tm_pg_schd_mode_cfg(struct hclge_dev *hdev, u8 pg_id)
32084844054SSalil {
32184844054SSalil 	struct hclge_desc desc;
32284844054SSalil 
32384844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PG_SCH_MODE_CFG, false);
32484844054SSalil 
32584844054SSalil 	if (hdev->tm_info.pg_info[pg_id].pg_sch_mode == HCLGE_SCH_MODE_DWRR)
32684844054SSalil 		desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
32784844054SSalil 	else
32884844054SSalil 		desc.data[1] = 0;
32984844054SSalil 
33084844054SSalil 	desc.data[0] = cpu_to_le32(pg_id);
33184844054SSalil 
33284844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
33384844054SSalil }
33484844054SSalil 
33584844054SSalil static int hclge_tm_pri_schd_mode_cfg(struct hclge_dev *hdev, u8 pri_id)
33684844054SSalil {
33784844054SSalil 	struct hclge_desc desc;
33884844054SSalil 
33984844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_PRI_SCH_MODE_CFG, false);
34084844054SSalil 
34184844054SSalil 	if (hdev->tm_info.tc_info[pri_id].tc_sch_mode == HCLGE_SCH_MODE_DWRR)
34284844054SSalil 		desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
34384844054SSalil 	else
34484844054SSalil 		desc.data[1] = 0;
34584844054SSalil 
34684844054SSalil 	desc.data[0] = cpu_to_le32(pri_id);
34784844054SSalil 
34884844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
34984844054SSalil }
35084844054SSalil 
35184844054SSalil static int hclge_tm_qs_schd_mode_cfg(struct hclge_dev *hdev, u16 qs_id)
35284844054SSalil {
35384844054SSalil 	struct hclge_desc desc;
35484844054SSalil 
35584844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_QS_SCH_MODE_CFG, false);
35684844054SSalil 
35784844054SSalil 	if (hdev->tm_info.tc_info[qs_id].tc_sch_mode == HCLGE_SCH_MODE_DWRR)
35884844054SSalil 		desc.data[1] = cpu_to_le32(HCLGE_TM_TX_SCHD_DWRR_MSK);
35984844054SSalil 	else
36084844054SSalil 		desc.data[1] = 0;
36184844054SSalil 
36284844054SSalil 	desc.data[0] = cpu_to_le32(qs_id);
36384844054SSalil 
36484844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
36584844054SSalil }
36684844054SSalil 
36784844054SSalil static int hclge_tm_qs_bp_cfg(struct hclge_dev *hdev, u8 tc)
36884844054SSalil {
36984844054SSalil 	struct hclge_bp_to_qs_map_cmd *bp_to_qs_map_cmd;
37084844054SSalil 	struct hclge_desc desc;
37184844054SSalil 
37284844054SSalil 	hclge_cmd_setup_basic_desc(&desc, HCLGE_OPC_TM_BP_TO_QSET_MAPPING,
37384844054SSalil 				   false);
37484844054SSalil 
37584844054SSalil 	bp_to_qs_map_cmd = (struct hclge_bp_to_qs_map_cmd *)desc.data;
37684844054SSalil 
37784844054SSalil 	bp_to_qs_map_cmd->tc_id = tc;
37884844054SSalil 
37984844054SSalil 	/* Qset and tc is one by one mapping */
38084844054SSalil 	bp_to_qs_map_cmd->qs_bit_map = cpu_to_le32(1 << tc);
38184844054SSalil 
38284844054SSalil 	return hclge_cmd_send(&hdev->hw, &desc, 1);
38384844054SSalil }
38484844054SSalil 
38584844054SSalil static void hclge_tm_vport_tc_info_update(struct hclge_vport *vport)
38684844054SSalil {
38784844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
38884844054SSalil 	struct hclge_dev *hdev = vport->back;
38984844054SSalil 	u8 i;
39084844054SSalil 
39184844054SSalil 	kinfo = &vport->nic.kinfo;
39284844054SSalil 	vport->bw_limit = hdev->tm_info.pg_info[0].bw_limit;
39384844054SSalil 	kinfo->num_tc =
39484844054SSalil 		min_t(u16, kinfo->num_tqps, hdev->tm_info.num_tc);
39584844054SSalil 	kinfo->rss_size
39684844054SSalil 		= min_t(u16, hdev->rss_size_max,
39784844054SSalil 			kinfo->num_tqps / kinfo->num_tc);
39884844054SSalil 	vport->qs_offset = hdev->tm_info.num_tc * vport->vport_id;
39984844054SSalil 	vport->dwrr = 100;  /* 100 percent as init */
40068ece54eSYunsheng Lin 	vport->alloc_rss_size = kinfo->rss_size;
40184844054SSalil 
40284844054SSalil 	for (i = 0; i < kinfo->num_tc; i++) {
40384844054SSalil 		if (hdev->hw_tc_map & BIT(i)) {
40484844054SSalil 			kinfo->tc_info[i].enable = true;
40584844054SSalil 			kinfo->tc_info[i].tqp_offset = i * kinfo->rss_size;
40684844054SSalil 			kinfo->tc_info[i].tqp_count = kinfo->rss_size;
40784844054SSalil 			kinfo->tc_info[i].tc = i;
40884844054SSalil 			kinfo->tc_info[i].up = hdev->tm_info.tc_info[i].up;
40984844054SSalil 		} else {
41084844054SSalil 			/* Set to default queue if TC is disable */
41184844054SSalil 			kinfo->tc_info[i].enable = false;
41284844054SSalil 			kinfo->tc_info[i].tqp_offset = 0;
41384844054SSalil 			kinfo->tc_info[i].tqp_count = 1;
41484844054SSalil 			kinfo->tc_info[i].tc = 0;
41584844054SSalil 			kinfo->tc_info[i].up = 0;
41684844054SSalil 		}
41784844054SSalil 	}
41884844054SSalil }
41984844054SSalil 
42084844054SSalil static void hclge_tm_vport_info_update(struct hclge_dev *hdev)
42184844054SSalil {
42284844054SSalil 	struct hclge_vport *vport = hdev->vport;
42384844054SSalil 	u32 i;
42484844054SSalil 
42584844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
42684844054SSalil 		hclge_tm_vport_tc_info_update(vport);
42784844054SSalil 
42884844054SSalil 		vport++;
42984844054SSalil 	}
43084844054SSalil }
43184844054SSalil 
43284844054SSalil static void hclge_tm_tc_info_init(struct hclge_dev *hdev)
43384844054SSalil {
43484844054SSalil 	u8 i;
43584844054SSalil 
43684844054SSalil 	for (i = 0; i < hdev->tm_info.num_tc; i++) {
43784844054SSalil 		hdev->tm_info.tc_info[i].tc_id = i;
43884844054SSalil 		hdev->tm_info.tc_info[i].tc_sch_mode = HCLGE_SCH_MODE_DWRR;
43984844054SSalil 		hdev->tm_info.tc_info[i].up = i;
44084844054SSalil 		hdev->tm_info.tc_info[i].pgid = 0;
44184844054SSalil 		hdev->tm_info.tc_info[i].bw_limit =
44284844054SSalil 			hdev->tm_info.pg_info[0].bw_limit;
44384844054SSalil 	}
44484844054SSalil 
44584844054SSalil 	hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE;
44684844054SSalil }
44784844054SSalil 
44884844054SSalil static void hclge_tm_pg_info_init(struct hclge_dev *hdev)
44984844054SSalil {
45084844054SSalil 	u8 i;
45184844054SSalil 
45284844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
45384844054SSalil 		int k;
45484844054SSalil 
45584844054SSalil 		hdev->tm_info.pg_dwrr[i] = i ? 0 : 100;
45684844054SSalil 
45784844054SSalil 		hdev->tm_info.pg_info[i].pg_id = i;
45884844054SSalil 		hdev->tm_info.pg_info[i].pg_sch_mode = HCLGE_SCH_MODE_DWRR;
45984844054SSalil 
46084844054SSalil 		hdev->tm_info.pg_info[i].bw_limit = HCLGE_ETHER_MAX_RATE;
46184844054SSalil 
46284844054SSalil 		if (i != 0)
46384844054SSalil 			continue;
46484844054SSalil 
46584844054SSalil 		hdev->tm_info.pg_info[i].tc_bit_map = hdev->hw_tc_map;
46684844054SSalil 		for (k = 0; k < hdev->tm_info.num_tc; k++)
46784844054SSalil 			hdev->tm_info.pg_info[i].tc_dwrr[k] = 100;
46884844054SSalil 	}
46984844054SSalil }
47084844054SSalil 
47184844054SSalil static int hclge_tm_schd_info_init(struct hclge_dev *hdev)
47284844054SSalil {
47384844054SSalil 	if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) &&
47484844054SSalil 	    (hdev->tm_info.num_pg != 1))
47584844054SSalil 		return -EINVAL;
47684844054SSalil 
47784844054SSalil 	hclge_tm_pg_info_init(hdev);
47884844054SSalil 
47984844054SSalil 	hclge_tm_tc_info_init(hdev);
48084844054SSalil 
48184844054SSalil 	hclge_tm_vport_info_update(hdev);
48284844054SSalil 
48384844054SSalil 	hdev->tm_info.fc_mode = HCLGE_FC_NONE;
48484844054SSalil 	hdev->fc_mode_last_time = hdev->tm_info.fc_mode;
48584844054SSalil 
48684844054SSalil 	return 0;
48784844054SSalil }
48884844054SSalil 
48984844054SSalil static int hclge_tm_pg_to_pri_map(struct hclge_dev *hdev)
49084844054SSalil {
49184844054SSalil 	int ret;
49284844054SSalil 	u32 i;
49384844054SSalil 
49484844054SSalil 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE)
49584844054SSalil 		return 0;
49684844054SSalil 
49784844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
49884844054SSalil 		/* Cfg mapping */
49984844054SSalil 		ret = hclge_tm_pg_to_pri_map_cfg(
50084844054SSalil 			hdev, i, hdev->tm_info.pg_info[i].tc_bit_map);
50184844054SSalil 		if (ret)
50284844054SSalil 			return ret;
50384844054SSalil 	}
50484844054SSalil 
50584844054SSalil 	return 0;
50684844054SSalil }
50784844054SSalil 
50884844054SSalil static int hclge_tm_pg_shaper_cfg(struct hclge_dev *hdev)
50984844054SSalil {
51084844054SSalil 	u8 ir_u, ir_b, ir_s;
51184844054SSalil 	int ret;
51284844054SSalil 	u32 i;
51384844054SSalil 
51484844054SSalil 	/* Cfg pg schd */
51584844054SSalil 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE)
51684844054SSalil 		return 0;
51784844054SSalil 
51884844054SSalil 	/* Pg to pri */
51984844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
52084844054SSalil 		/* Calc shaper para */
52184844054SSalil 		ret = hclge_shaper_para_calc(
52284844054SSalil 					hdev->tm_info.pg_info[i].bw_limit,
52384844054SSalil 					HCLGE_SHAPER_LVL_PG,
52484844054SSalil 					&ir_b, &ir_u, &ir_s);
52584844054SSalil 		if (ret)
52684844054SSalil 			return ret;
52784844054SSalil 
52884844054SSalil 		ret = hclge_tm_pg_shapping_cfg(hdev,
52984844054SSalil 					       HCLGE_TM_SHAP_C_BUCKET, i,
53084844054SSalil 					       0, 0, 0, HCLGE_SHAPER_BS_U_DEF,
53184844054SSalil 					       HCLGE_SHAPER_BS_S_DEF);
53284844054SSalil 		if (ret)
53384844054SSalil 			return ret;
53484844054SSalil 
53584844054SSalil 		ret = hclge_tm_pg_shapping_cfg(hdev,
53684844054SSalil 					       HCLGE_TM_SHAP_P_BUCKET, i,
53784844054SSalil 					       ir_b, ir_u, ir_s,
53884844054SSalil 					       HCLGE_SHAPER_BS_U_DEF,
53984844054SSalil 					       HCLGE_SHAPER_BS_S_DEF);
54084844054SSalil 		if (ret)
54184844054SSalil 			return ret;
54284844054SSalil 	}
54384844054SSalil 
54484844054SSalil 	return 0;
54584844054SSalil }
54684844054SSalil 
54784844054SSalil static int hclge_tm_pg_dwrr_cfg(struct hclge_dev *hdev)
54884844054SSalil {
54984844054SSalil 	int ret;
55084844054SSalil 	u32 i;
55184844054SSalil 
55284844054SSalil 	/* cfg pg schd */
55384844054SSalil 	if (hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE)
55484844054SSalil 		return 0;
55584844054SSalil 
55684844054SSalil 	/* pg to prio */
55784844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
55884844054SSalil 		/* Cfg dwrr */
55984844054SSalil 		ret = hclge_tm_pg_weight_cfg(hdev, i,
56084844054SSalil 					     hdev->tm_info.pg_dwrr[i]);
56184844054SSalil 		if (ret)
56284844054SSalil 			return ret;
56384844054SSalil 	}
56484844054SSalil 
56584844054SSalil 	return 0;
56684844054SSalil }
56784844054SSalil 
56884844054SSalil static int hclge_vport_q_to_qs_map(struct hclge_dev *hdev,
56984844054SSalil 				   struct hclge_vport *vport)
57084844054SSalil {
57184844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
57284844054SSalil 	struct hnae3_queue **tqp = kinfo->tqp;
57384844054SSalil 	struct hnae3_tc_info *v_tc_info;
57484844054SSalil 	u32 i, j;
57584844054SSalil 	int ret;
57684844054SSalil 
57784844054SSalil 	for (i = 0; i < kinfo->num_tc; i++) {
57884844054SSalil 		v_tc_info = &kinfo->tc_info[i];
57984844054SSalil 		for (j = 0; j < v_tc_info->tqp_count; j++) {
58084844054SSalil 			struct hnae3_queue *q = tqp[v_tc_info->tqp_offset + j];
58184844054SSalil 
58284844054SSalil 			ret = hclge_tm_q_to_qs_map_cfg(hdev,
58384844054SSalil 						       hclge_get_queue_id(q),
58484844054SSalil 						       vport->qs_offset + i);
58584844054SSalil 			if (ret)
58684844054SSalil 				return ret;
58784844054SSalil 		}
58884844054SSalil 	}
58984844054SSalil 
59084844054SSalil 	return 0;
59184844054SSalil }
59284844054SSalil 
59384844054SSalil static int hclge_tm_pri_q_qs_cfg(struct hclge_dev *hdev)
59484844054SSalil {
59584844054SSalil 	struct hclge_vport *vport = hdev->vport;
59684844054SSalil 	int ret;
59784844054SSalil 	u32 i;
59884844054SSalil 
59984844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
60084844054SSalil 		/* Cfg qs -> pri mapping, one by one mapping */
60184844054SSalil 		for (i = 0; i < hdev->tm_info.num_tc; i++) {
60284844054SSalil 			ret = hclge_tm_qs_to_pri_map_cfg(hdev, i, i);
60384844054SSalil 			if (ret)
60484844054SSalil 				return ret;
60584844054SSalil 		}
60684844054SSalil 	} else if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE) {
60784844054SSalil 		int k;
60884844054SSalil 		/* Cfg qs -> pri mapping,  qs = tc, pri = vf, 8 qs -> 1 pri */
60984844054SSalil 		for (k = 0; k < hdev->num_alloc_vport; k++)
61084844054SSalil 			for (i = 0; i < HNAE3_MAX_TC; i++) {
61184844054SSalil 				ret = hclge_tm_qs_to_pri_map_cfg(
61284844054SSalil 					hdev, vport[k].qs_offset + i, k);
61384844054SSalil 				if (ret)
61484844054SSalil 					return ret;
61584844054SSalil 			}
61684844054SSalil 	} else {
61784844054SSalil 		return -EINVAL;
61884844054SSalil 	}
61984844054SSalil 
62084844054SSalil 	/* Cfg q -> qs mapping */
62184844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
62284844054SSalil 		ret = hclge_vport_q_to_qs_map(hdev, vport);
62384844054SSalil 		if (ret)
62484844054SSalil 			return ret;
62584844054SSalil 
62684844054SSalil 		vport++;
62784844054SSalil 	}
62884844054SSalil 
62984844054SSalil 	return 0;
63084844054SSalil }
63184844054SSalil 
63284844054SSalil static int hclge_tm_pri_tc_base_shaper_cfg(struct hclge_dev *hdev)
63384844054SSalil {
63484844054SSalil 	u8 ir_u, ir_b, ir_s;
63584844054SSalil 	int ret;
63684844054SSalil 	u32 i;
63784844054SSalil 
63884844054SSalil 	for (i = 0; i < hdev->tm_info.num_tc; i++) {
63984844054SSalil 		ret = hclge_shaper_para_calc(
64084844054SSalil 					hdev->tm_info.tc_info[i].bw_limit,
64184844054SSalil 					HCLGE_SHAPER_LVL_PRI,
64284844054SSalil 					&ir_b, &ir_u, &ir_s);
64384844054SSalil 		if (ret)
64484844054SSalil 			return ret;
64584844054SSalil 
64684844054SSalil 		ret = hclge_tm_pri_shapping_cfg(
64784844054SSalil 			hdev, HCLGE_TM_SHAP_C_BUCKET, i,
64884844054SSalil 			0, 0, 0, HCLGE_SHAPER_BS_U_DEF,
64984844054SSalil 			HCLGE_SHAPER_BS_S_DEF);
65084844054SSalil 		if (ret)
65184844054SSalil 			return ret;
65284844054SSalil 
65384844054SSalil 		ret = hclge_tm_pri_shapping_cfg(
65484844054SSalil 			hdev, HCLGE_TM_SHAP_P_BUCKET, i,
65584844054SSalil 			ir_b, ir_u, ir_s, HCLGE_SHAPER_BS_U_DEF,
65684844054SSalil 			HCLGE_SHAPER_BS_S_DEF);
65784844054SSalil 		if (ret)
65884844054SSalil 			return ret;
65984844054SSalil 	}
66084844054SSalil 
66184844054SSalil 	return 0;
66284844054SSalil }
66384844054SSalil 
66484844054SSalil static int hclge_tm_pri_vnet_base_shaper_pri_cfg(struct hclge_vport *vport)
66584844054SSalil {
66684844054SSalil 	struct hclge_dev *hdev = vport->back;
66784844054SSalil 	u8 ir_u, ir_b, ir_s;
66884844054SSalil 	int ret;
66984844054SSalil 
67084844054SSalil 	ret = hclge_shaper_para_calc(vport->bw_limit, HCLGE_SHAPER_LVL_VF,
67184844054SSalil 				     &ir_b, &ir_u, &ir_s);
67284844054SSalil 	if (ret)
67384844054SSalil 		return ret;
67484844054SSalil 
67584844054SSalil 	ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_C_BUCKET,
67684844054SSalil 					vport->vport_id,
67784844054SSalil 					0, 0, 0, HCLGE_SHAPER_BS_U_DEF,
67884844054SSalil 					HCLGE_SHAPER_BS_S_DEF);
67984844054SSalil 	if (ret)
68084844054SSalil 		return ret;
68184844054SSalil 
68284844054SSalil 	ret = hclge_tm_pri_shapping_cfg(hdev, HCLGE_TM_SHAP_P_BUCKET,
68384844054SSalil 					vport->vport_id,
68484844054SSalil 					ir_b, ir_u, ir_s,
68584844054SSalil 					HCLGE_SHAPER_BS_U_DEF,
68684844054SSalil 					HCLGE_SHAPER_BS_S_DEF);
68784844054SSalil 	if (ret)
68884844054SSalil 		return ret;
68984844054SSalil 
69084844054SSalil 	return 0;
69184844054SSalil }
69284844054SSalil 
69384844054SSalil static int hclge_tm_pri_vnet_base_shaper_qs_cfg(struct hclge_vport *vport)
69484844054SSalil {
69584844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
69684844054SSalil 	struct hclge_dev *hdev = vport->back;
69784844054SSalil 	struct hnae3_tc_info *v_tc_info;
69884844054SSalil 	u8 ir_u, ir_b, ir_s;
69984844054SSalil 	u32 i;
70084844054SSalil 	int ret;
70184844054SSalil 
70284844054SSalil 	for (i = 0; i < kinfo->num_tc; i++) {
70384844054SSalil 		v_tc_info = &kinfo->tc_info[i];
70484844054SSalil 		ret = hclge_shaper_para_calc(
70584844054SSalil 					hdev->tm_info.tc_info[i].bw_limit,
70684844054SSalil 					HCLGE_SHAPER_LVL_QSET,
70784844054SSalil 					&ir_b, &ir_u, &ir_s);
70884844054SSalil 		if (ret)
70984844054SSalil 			return ret;
71084844054SSalil 	}
71184844054SSalil 
71284844054SSalil 	return 0;
71384844054SSalil }
71484844054SSalil 
71584844054SSalil static int hclge_tm_pri_vnet_base_shaper_cfg(struct hclge_dev *hdev)
71684844054SSalil {
71784844054SSalil 	struct hclge_vport *vport = hdev->vport;
71884844054SSalil 	int ret;
71984844054SSalil 	u32 i;
72084844054SSalil 
72184844054SSalil 	/* Need config vport shaper */
72284844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
72384844054SSalil 		ret = hclge_tm_pri_vnet_base_shaper_pri_cfg(vport);
72484844054SSalil 		if (ret)
72584844054SSalil 			return ret;
72684844054SSalil 
72784844054SSalil 		ret = hclge_tm_pri_vnet_base_shaper_qs_cfg(vport);
72884844054SSalil 		if (ret)
72984844054SSalil 			return ret;
73084844054SSalil 
73184844054SSalil 		vport++;
73284844054SSalil 	}
73384844054SSalil 
73484844054SSalil 	return 0;
73584844054SSalil }
73684844054SSalil 
73784844054SSalil static int hclge_tm_pri_shaper_cfg(struct hclge_dev *hdev)
73884844054SSalil {
73984844054SSalil 	int ret;
74084844054SSalil 
74184844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
74284844054SSalil 		ret = hclge_tm_pri_tc_base_shaper_cfg(hdev);
74384844054SSalil 		if (ret)
74484844054SSalil 			return ret;
74584844054SSalil 	} else {
74684844054SSalil 		ret = hclge_tm_pri_vnet_base_shaper_cfg(hdev);
74784844054SSalil 		if (ret)
74884844054SSalil 			return ret;
74984844054SSalil 	}
75084844054SSalil 
75184844054SSalil 	return 0;
75284844054SSalil }
75384844054SSalil 
75484844054SSalil static int hclge_tm_pri_tc_base_dwrr_cfg(struct hclge_dev *hdev)
75584844054SSalil {
75684844054SSalil 	struct hclge_pg_info *pg_info;
75784844054SSalil 	u8 dwrr;
75884844054SSalil 	int ret;
75984844054SSalil 	u32 i;
76084844054SSalil 
76184844054SSalil 	for (i = 0; i < hdev->tm_info.num_tc; i++) {
76284844054SSalil 		pg_info =
76384844054SSalil 			&hdev->tm_info.pg_info[hdev->tm_info.tc_info[i].pgid];
76484844054SSalil 		dwrr = pg_info->tc_dwrr[i];
76584844054SSalil 
76684844054SSalil 		ret = hclge_tm_pri_weight_cfg(hdev, i, dwrr);
76784844054SSalil 		if (ret)
76884844054SSalil 			return ret;
76984844054SSalil 
77084844054SSalil 		ret = hclge_tm_qs_weight_cfg(hdev, i, dwrr);
77184844054SSalil 		if (ret)
77284844054SSalil 			return ret;
77384844054SSalil 	}
77484844054SSalil 
77584844054SSalil 	return 0;
77684844054SSalil }
77784844054SSalil 
77884844054SSalil static int hclge_tm_pri_vnet_base_dwrr_pri_cfg(struct hclge_vport *vport)
77984844054SSalil {
78084844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
78184844054SSalil 	struct hclge_dev *hdev = vport->back;
78284844054SSalil 	int ret;
78384844054SSalil 	u8 i;
78484844054SSalil 
78584844054SSalil 	/* Vf dwrr */
78684844054SSalil 	ret = hclge_tm_pri_weight_cfg(hdev, vport->vport_id, vport->dwrr);
78784844054SSalil 	if (ret)
78884844054SSalil 		return ret;
78984844054SSalil 
79084844054SSalil 	/* Qset dwrr */
79184844054SSalil 	for (i = 0; i < kinfo->num_tc; i++) {
79284844054SSalil 		ret = hclge_tm_qs_weight_cfg(
79384844054SSalil 			hdev, vport->qs_offset + i,
79484844054SSalil 			hdev->tm_info.pg_info[0].tc_dwrr[i]);
79584844054SSalil 		if (ret)
79684844054SSalil 			return ret;
79784844054SSalil 	}
79884844054SSalil 
79984844054SSalil 	return 0;
80084844054SSalil }
80184844054SSalil 
80284844054SSalil static int hclge_tm_pri_vnet_base_dwrr_cfg(struct hclge_dev *hdev)
80384844054SSalil {
80484844054SSalil 	struct hclge_vport *vport = hdev->vport;
80584844054SSalil 	int ret;
80684844054SSalil 	u32 i;
80784844054SSalil 
80884844054SSalil 	for (i = 0; i < hdev->num_alloc_vport; i++) {
80984844054SSalil 		ret = hclge_tm_pri_vnet_base_dwrr_pri_cfg(vport);
81084844054SSalil 		if (ret)
81184844054SSalil 			return ret;
81284844054SSalil 
81384844054SSalil 		vport++;
81484844054SSalil 	}
81584844054SSalil 
81684844054SSalil 	return 0;
81784844054SSalil }
81884844054SSalil 
81984844054SSalil static int hclge_tm_pri_dwrr_cfg(struct hclge_dev *hdev)
82084844054SSalil {
82184844054SSalil 	int ret;
82284844054SSalil 
82384844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
82484844054SSalil 		ret = hclge_tm_pri_tc_base_dwrr_cfg(hdev);
82584844054SSalil 		if (ret)
82684844054SSalil 			return ret;
82784844054SSalil 	} else {
82884844054SSalil 		ret = hclge_tm_pri_vnet_base_dwrr_cfg(hdev);
82984844054SSalil 		if (ret)
83084844054SSalil 			return ret;
83184844054SSalil 	}
83284844054SSalil 
83384844054SSalil 	return 0;
83484844054SSalil }
83584844054SSalil 
83684844054SSalil static int hclge_tm_map_cfg(struct hclge_dev *hdev)
83784844054SSalil {
83884844054SSalil 	int ret;
83984844054SSalil 
84084844054SSalil 	ret = hclge_tm_pg_to_pri_map(hdev);
84184844054SSalil 	if (ret)
84284844054SSalil 		return ret;
84384844054SSalil 
84484844054SSalil 	return hclge_tm_pri_q_qs_cfg(hdev);
84584844054SSalil }
84684844054SSalil 
84784844054SSalil static int hclge_tm_shaper_cfg(struct hclge_dev *hdev)
84884844054SSalil {
84984844054SSalil 	int ret;
85084844054SSalil 
85184844054SSalil 	ret = hclge_tm_pg_shaper_cfg(hdev);
85284844054SSalil 	if (ret)
85384844054SSalil 		return ret;
85484844054SSalil 
85584844054SSalil 	return hclge_tm_pri_shaper_cfg(hdev);
85684844054SSalil }
85784844054SSalil 
85884844054SSalil int hclge_tm_dwrr_cfg(struct hclge_dev *hdev)
85984844054SSalil {
86084844054SSalil 	int ret;
86184844054SSalil 
86284844054SSalil 	ret = hclge_tm_pg_dwrr_cfg(hdev);
86384844054SSalil 	if (ret)
86484844054SSalil 		return ret;
86584844054SSalil 
86684844054SSalil 	return hclge_tm_pri_dwrr_cfg(hdev);
86784844054SSalil }
86884844054SSalil 
86984844054SSalil static int hclge_tm_lvl2_schd_mode_cfg(struct hclge_dev *hdev)
87084844054SSalil {
87184844054SSalil 	int ret;
87284844054SSalil 	u8 i;
87384844054SSalil 
87484844054SSalil 	/* Only being config on TC-Based scheduler mode */
87584844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_VNET_BASE_SCH_MODE)
87684844054SSalil 		return 0;
87784844054SSalil 
87884844054SSalil 	for (i = 0; i < hdev->tm_info.num_pg; i++) {
87984844054SSalil 		ret = hclge_tm_pg_schd_mode_cfg(hdev, i);
88084844054SSalil 		if (ret)
88184844054SSalil 			return ret;
88284844054SSalil 	}
88384844054SSalil 
88484844054SSalil 	return 0;
88584844054SSalil }
88684844054SSalil 
88784844054SSalil static int hclge_tm_schd_mode_vnet_base_cfg(struct hclge_vport *vport)
88884844054SSalil {
88984844054SSalil 	struct hnae3_knic_private_info *kinfo = &vport->nic.kinfo;
89084844054SSalil 	struct hclge_dev *hdev = vport->back;
89184844054SSalil 	int ret;
89284844054SSalil 	u8 i;
89384844054SSalil 
89484844054SSalil 	ret = hclge_tm_pri_schd_mode_cfg(hdev, vport->vport_id);
89584844054SSalil 	if (ret)
89684844054SSalil 		return ret;
89784844054SSalil 
89884844054SSalil 	for (i = 0; i < kinfo->num_tc; i++) {
89984844054SSalil 		ret = hclge_tm_qs_schd_mode_cfg(hdev, vport->qs_offset + i);
90084844054SSalil 		if (ret)
90184844054SSalil 			return ret;
90284844054SSalil 	}
90384844054SSalil 
90484844054SSalil 	return 0;
90584844054SSalil }
90684844054SSalil 
90784844054SSalil static int hclge_tm_lvl34_schd_mode_cfg(struct hclge_dev *hdev)
90884844054SSalil {
90984844054SSalil 	struct hclge_vport *vport = hdev->vport;
91084844054SSalil 	int ret;
91184844054SSalil 	u8 i;
91284844054SSalil 
91384844054SSalil 	if (hdev->tx_sch_mode == HCLGE_FLAG_TC_BASE_SCH_MODE) {
91484844054SSalil 		for (i = 0; i < hdev->tm_info.num_tc; i++) {
91584844054SSalil 			ret = hclge_tm_pri_schd_mode_cfg(hdev, i);
91684844054SSalil 			if (ret)
91784844054SSalil 				return ret;
91884844054SSalil 
91984844054SSalil 			ret = hclge_tm_qs_schd_mode_cfg(hdev, i);
92084844054SSalil 			if (ret)
92184844054SSalil 				return ret;
92284844054SSalil 		}
92384844054SSalil 	} else {
92484844054SSalil 		for (i = 0; i < hdev->num_alloc_vport; i++) {
92584844054SSalil 			ret = hclge_tm_schd_mode_vnet_base_cfg(vport);
92684844054SSalil 			if (ret)
92784844054SSalil 				return ret;
92884844054SSalil 
92984844054SSalil 			vport++;
93084844054SSalil 		}
93184844054SSalil 	}
93284844054SSalil 
93384844054SSalil 	return 0;
93484844054SSalil }
93584844054SSalil 
93684844054SSalil static int hclge_tm_schd_mode_hw(struct hclge_dev *hdev)
93784844054SSalil {
93884844054SSalil 	int ret;
93984844054SSalil 
94084844054SSalil 	ret = hclge_tm_lvl2_schd_mode_cfg(hdev);
94184844054SSalil 	if (ret)
94284844054SSalil 		return ret;
94384844054SSalil 
94484844054SSalil 	return hclge_tm_lvl34_schd_mode_cfg(hdev);
94584844054SSalil }
94684844054SSalil 
94784844054SSalil static int hclge_tm_schd_setup_hw(struct hclge_dev *hdev)
94884844054SSalil {
94984844054SSalil 	int ret;
95084844054SSalil 
95184844054SSalil 	/* Cfg tm mapping  */
95284844054SSalil 	ret = hclge_tm_map_cfg(hdev);
95384844054SSalil 	if (ret)
95484844054SSalil 		return ret;
95584844054SSalil 
95684844054SSalil 	/* Cfg tm shaper */
95784844054SSalil 	ret = hclge_tm_shaper_cfg(hdev);
95884844054SSalil 	if (ret)
95984844054SSalil 		return ret;
96084844054SSalil 
96184844054SSalil 	/* Cfg dwrr */
96284844054SSalil 	ret = hclge_tm_dwrr_cfg(hdev);
96384844054SSalil 	if (ret)
96484844054SSalil 		return ret;
96584844054SSalil 
96684844054SSalil 	/* Cfg schd mode for each level schd */
96784844054SSalil 	return hclge_tm_schd_mode_hw(hdev);
96884844054SSalil }
96984844054SSalil 
97084844054SSalil int hclge_pause_setup_hw(struct hclge_dev *hdev)
97184844054SSalil {
97284844054SSalil 	bool en = hdev->tm_info.fc_mode != HCLGE_FC_PFC;
97384844054SSalil 	int ret;
97484844054SSalil 	u8 i;
97584844054SSalil 
97684844054SSalil 	ret = hclge_mac_pause_en_cfg(hdev, en, en);
97784844054SSalil 	if (ret)
97884844054SSalil 		return ret;
97984844054SSalil 
9802daf4a65SYunsheng Lin 	/* Only DCB-supported dev supports qset back pressure setting */
9812daf4a65SYunsheng Lin 	if (!hnae3_dev_dcb_supported(hdev))
9822daf4a65SYunsheng Lin 		return 0;
9832daf4a65SYunsheng Lin 
98484844054SSalil 	for (i = 0; i < hdev->tm_info.num_tc; i++) {
98584844054SSalil 		ret = hclge_tm_qs_bp_cfg(hdev, i);
98684844054SSalil 		if (ret)
98784844054SSalil 			return ret;
98884844054SSalil 	}
98984844054SSalil 
99084844054SSalil 	return hclge_up_to_tc_map(hdev);
99184844054SSalil }
99284844054SSalil 
99384844054SSalil int hclge_tm_init_hw(struct hclge_dev *hdev)
99484844054SSalil {
99584844054SSalil 	int ret;
99684844054SSalil 
99784844054SSalil 	if ((hdev->tx_sch_mode != HCLGE_FLAG_TC_BASE_SCH_MODE) &&
99884844054SSalil 	    (hdev->tx_sch_mode != HCLGE_FLAG_VNET_BASE_SCH_MODE))
99984844054SSalil 		return -ENOTSUPP;
100084844054SSalil 
100184844054SSalil 	ret = hclge_tm_schd_setup_hw(hdev);
100284844054SSalil 	if (ret)
100384844054SSalil 		return ret;
100484844054SSalil 
100584844054SSalil 	ret = hclge_pause_setup_hw(hdev);
100684844054SSalil 	if (ret)
100784844054SSalil 		return ret;
100884844054SSalil 
100984844054SSalil 	return 0;
101084844054SSalil }
101184844054SSalil 
101284844054SSalil int hclge_tm_schd_init(struct hclge_dev *hdev)
101384844054SSalil {
101484844054SSalil 	int ret = hclge_tm_schd_info_init(hdev);
101584844054SSalil 
101684844054SSalil 	if (ret)
101784844054SSalil 		return ret;
101884844054SSalil 
101984844054SSalil 	return hclge_tm_init_hw(hdev);
102084844054SSalil }
1021