1ae06c70bSJeff Kirsher // SPDX-License-Identifier: GPL-2.0
251dce24bSJeff Kirsher /* Copyright(c) 1999 - 2018 Intel Corporation. */
3dee1ad47SJeff Kirsher 
4dee1ad47SJeff Kirsher #include "ixgbe.h"
5dee1ad47SJeff Kirsher #include "ixgbe_type.h"
6dee1ad47SJeff Kirsher #include "ixgbe_dcb.h"
7dee1ad47SJeff Kirsher #include "ixgbe_dcb_82598.h"
8dee1ad47SJeff Kirsher 
9dee1ad47SJeff Kirsher /**
10dee1ad47SJeff Kirsher  * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter
11dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
125ba643c6STony Nguyen  * @refill: refill credits index by traffic class
135ba643c6STony Nguyen  * @max: max credits index by traffic class
145ba643c6STony Nguyen  * @prio_type: priority type indexed by traffic class
15dee1ad47SJeff Kirsher  *
16dee1ad47SJeff Kirsher  * Configure Rx Data Arbiter and credits for each traffic class.
17dee1ad47SJeff Kirsher  */
ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * prio_type)18dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
19dee1ad47SJeff Kirsher 					u16 *refill,
20dee1ad47SJeff Kirsher 					u16 *max,
21dee1ad47SJeff Kirsher 					u8 *prio_type)
22dee1ad47SJeff Kirsher {
23dee1ad47SJeff Kirsher 	u32    reg           = 0;
24dee1ad47SJeff Kirsher 	u32    credit_refill = 0;
25dee1ad47SJeff Kirsher 	u32    credit_max    = 0;
26dee1ad47SJeff Kirsher 	u8     i             = 0;
27dee1ad47SJeff Kirsher 
28dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
29dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
30dee1ad47SJeff Kirsher 
31dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
32dee1ad47SJeff Kirsher 	/* Enable Arbiter */
33dee1ad47SJeff Kirsher 	reg &= ~IXGBE_RMCS_ARBDIS;
34dee1ad47SJeff Kirsher 	/* Enable Receive Recycle within the BWG */
35dee1ad47SJeff Kirsher 	reg |= IXGBE_RMCS_RRM;
36dee1ad47SJeff Kirsher 	/* Enable Deficit Fixed Priority arbitration*/
37dee1ad47SJeff Kirsher 	reg |= IXGBE_RMCS_DFP;
38dee1ad47SJeff Kirsher 
39dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
40dee1ad47SJeff Kirsher 
41dee1ad47SJeff Kirsher 	/* Configure traffic class credits and priority */
42dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
43dee1ad47SJeff Kirsher 		credit_refill = refill[i];
44dee1ad47SJeff Kirsher 		credit_max    = max[i];
45dee1ad47SJeff Kirsher 
46dee1ad47SJeff Kirsher 		reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
47dee1ad47SJeff Kirsher 
48dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_link)
49dee1ad47SJeff Kirsher 			reg |= IXGBE_RT2CR_LSP;
50dee1ad47SJeff Kirsher 
51dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
52dee1ad47SJeff Kirsher 	}
53dee1ad47SJeff Kirsher 
54dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
55dee1ad47SJeff Kirsher 	reg |= IXGBE_RDRXCTL_RDMTS_1_2;
56dee1ad47SJeff Kirsher 	reg |= IXGBE_RDRXCTL_MPBEN;
57dee1ad47SJeff Kirsher 	reg |= IXGBE_RDRXCTL_MCEN;
58dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
59dee1ad47SJeff Kirsher 
60dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
61dee1ad47SJeff Kirsher 	/* Make sure there is enough descriptors before arbitration */
62dee1ad47SJeff Kirsher 	reg &= ~IXGBE_RXCTRL_DMBYPS;
63dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
64dee1ad47SJeff Kirsher 
65dee1ad47SJeff Kirsher 	return 0;
66dee1ad47SJeff Kirsher }
67dee1ad47SJeff Kirsher 
68dee1ad47SJeff Kirsher /**
69dee1ad47SJeff Kirsher  * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
70dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
715ba643c6STony Nguyen  * @refill: refill credits index by traffic class
725ba643c6STony Nguyen  * @max: max credits index by traffic class
735ba643c6STony Nguyen  * @bwg_id: bandwidth grouping indexed by traffic class
745ba643c6STony Nguyen  * @prio_type: priority type indexed by traffic class
75dee1ad47SJeff Kirsher  *
76dee1ad47SJeff Kirsher  * Configure Tx Descriptor Arbiter and credits for each traffic class.
77dee1ad47SJeff Kirsher  */
ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * prio_type)78dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
79dee1ad47SJeff Kirsher 						u16 *refill,
80dee1ad47SJeff Kirsher 						u16 *max,
81dee1ad47SJeff Kirsher 						u8 *bwg_id,
82dee1ad47SJeff Kirsher 						u8 *prio_type)
83dee1ad47SJeff Kirsher {
84dee1ad47SJeff Kirsher 	u32    reg, max_credits;
85dee1ad47SJeff Kirsher 	u8     i;
86dee1ad47SJeff Kirsher 
87dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_DPMCS);
88dee1ad47SJeff Kirsher 
89dee1ad47SJeff Kirsher 	/* Enable arbiter */
90dee1ad47SJeff Kirsher 	reg &= ~IXGBE_DPMCS_ARBDIS;
91dee1ad47SJeff Kirsher 	reg |= IXGBE_DPMCS_TSOEF;
921eb9ac14SJacob Keller 
93dee1ad47SJeff Kirsher 	/* Configure Max TSO packet size 34KB including payload and headers */
94dee1ad47SJeff Kirsher 	reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
95dee1ad47SJeff Kirsher 
96dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg);
97dee1ad47SJeff Kirsher 
98dee1ad47SJeff Kirsher 	/* Configure traffic class credits and priority */
99dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
100dee1ad47SJeff Kirsher 		max_credits = max[i];
101dee1ad47SJeff Kirsher 		reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
102dee1ad47SJeff Kirsher 		reg |= refill[i];
103dee1ad47SJeff Kirsher 		reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
104dee1ad47SJeff Kirsher 
105dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_group)
106dee1ad47SJeff Kirsher 			reg |= IXGBE_TDTQ2TCCR_GSP;
107dee1ad47SJeff Kirsher 
108dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_link)
109dee1ad47SJeff Kirsher 			reg |= IXGBE_TDTQ2TCCR_LSP;
110dee1ad47SJeff Kirsher 
111dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
112dee1ad47SJeff Kirsher 	}
113dee1ad47SJeff Kirsher 
114dee1ad47SJeff Kirsher 	return 0;
115dee1ad47SJeff Kirsher }
116dee1ad47SJeff Kirsher 
117dee1ad47SJeff Kirsher /**
118dee1ad47SJeff Kirsher  * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter
119dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
1205ba643c6STony Nguyen  * @refill: refill credits index by traffic class
1215ba643c6STony Nguyen  * @max: max credits index by traffic class
1225ba643c6STony Nguyen  * @bwg_id: bandwidth grouping indexed by traffic class
1235ba643c6STony Nguyen  * @prio_type: priority type indexed by traffic class
124dee1ad47SJeff Kirsher  *
125dee1ad47SJeff Kirsher  * Configure Tx Data Arbiter and credits for each traffic class.
126dee1ad47SJeff Kirsher  */
ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * prio_type)127dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
128dee1ad47SJeff Kirsher 						u16 *refill,
129dee1ad47SJeff Kirsher 						u16 *max,
130dee1ad47SJeff Kirsher 						u8 *bwg_id,
131dee1ad47SJeff Kirsher 						u8 *prio_type)
132dee1ad47SJeff Kirsher {
133dee1ad47SJeff Kirsher 	u32 reg;
134dee1ad47SJeff Kirsher 	u8 i;
135dee1ad47SJeff Kirsher 
136dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
137dee1ad47SJeff Kirsher 	/* Enable Data Plane Arbiter */
138dee1ad47SJeff Kirsher 	reg &= ~IXGBE_PDPMCS_ARBDIS;
139dee1ad47SJeff Kirsher 	/* Enable DFP and Transmit Recycle Mode */
140dee1ad47SJeff Kirsher 	reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM);
141dee1ad47SJeff Kirsher 
142dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg);
143dee1ad47SJeff Kirsher 
144dee1ad47SJeff Kirsher 	/* Configure traffic class credits and priority */
145dee1ad47SJeff Kirsher 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
146dee1ad47SJeff Kirsher 		reg = refill[i];
147dee1ad47SJeff Kirsher 		reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT;
148dee1ad47SJeff Kirsher 		reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT;
149dee1ad47SJeff Kirsher 
150dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_group)
151dee1ad47SJeff Kirsher 			reg |= IXGBE_TDPT2TCCR_GSP;
152dee1ad47SJeff Kirsher 
153dee1ad47SJeff Kirsher 		if (prio_type[i] == prio_link)
154dee1ad47SJeff Kirsher 			reg |= IXGBE_TDPT2TCCR_LSP;
155dee1ad47SJeff Kirsher 
156dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
157dee1ad47SJeff Kirsher 	}
158dee1ad47SJeff Kirsher 
159dee1ad47SJeff Kirsher 	/* Enable Tx packet buffer division */
160dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
161dee1ad47SJeff Kirsher 	reg |= IXGBE_DTXCTL_ENDBUBD;
162dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg);
163dee1ad47SJeff Kirsher 
164dee1ad47SJeff Kirsher 	return 0;
165dee1ad47SJeff Kirsher }
166dee1ad47SJeff Kirsher 
167dee1ad47SJeff Kirsher /**
168dee1ad47SJeff Kirsher  * ixgbe_dcb_config_pfc_82598 - Config priority flow control
169dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
1705ba643c6STony Nguyen  * @pfc_en: enabled pfc bitmask
171dee1ad47SJeff Kirsher  *
172dee1ad47SJeff Kirsher  * Configure Priority Flow Control for each traffic class.
173dee1ad47SJeff Kirsher  */
ixgbe_dcb_config_pfc_82598(struct ixgbe_hw * hw,u8 pfc_en)174dee1ad47SJeff Kirsher s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
175dee1ad47SJeff Kirsher {
176943561d3SAlexander Duyck 	u32 fcrtl, reg;
177dee1ad47SJeff Kirsher 	u8  i;
178dee1ad47SJeff Kirsher 
179dee1ad47SJeff Kirsher 	/* Enable Transmit Priority Flow Control */
180dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
181dee1ad47SJeff Kirsher 	reg &= ~IXGBE_RMCS_TFCE_802_3X;
182dee1ad47SJeff Kirsher 	reg |= IXGBE_RMCS_TFCE_PRIORITY;
183dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
184dee1ad47SJeff Kirsher 
185dee1ad47SJeff Kirsher 	/* Enable Receive Priority Flow Control */
186dee1ad47SJeff Kirsher 	reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
187943561d3SAlexander Duyck 	reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE);
188943561d3SAlexander Duyck 
189943561d3SAlexander Duyck 	if (pfc_en)
190dee1ad47SJeff Kirsher 		reg |= IXGBE_FCTRL_RPFCE;
191943561d3SAlexander Duyck 
192dee1ad47SJeff Kirsher 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
193dee1ad47SJeff Kirsher 
194943561d3SAlexander Duyck 	/* Configure PFC Tx thresholds per TC */
195943561d3SAlexander Duyck 	for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
196b4f47a48SJacob Keller 		if (!(pfc_en & BIT(i))) {
197943561d3SAlexander Duyck 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
198943561d3SAlexander Duyck 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
199943561d3SAlexander Duyck 			continue;
200dee1ad47SJeff Kirsher 		}
201dee1ad47SJeff Kirsher 
202e5776620SJacob Keller 		fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
203943561d3SAlexander Duyck 		reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
204943561d3SAlexander Duyck 		IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
205dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
206dee1ad47SJeff Kirsher 	}
207dee1ad47SJeff Kirsher 
208943561d3SAlexander Duyck 	/* Configure pause time */
209943561d3SAlexander Duyck 	reg = hw->fc.pause_time * 0x00010001;
210943561d3SAlexander Duyck 	for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
211943561d3SAlexander Duyck 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
212943561d3SAlexander Duyck 
213943561d3SAlexander Duyck 	/* Configure flow control refresh threshold value */
214943561d3SAlexander Duyck 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
215943561d3SAlexander Duyck 
216943561d3SAlexander Duyck 
217dee1ad47SJeff Kirsher 	return 0;
218dee1ad47SJeff Kirsher }
219dee1ad47SJeff Kirsher 
220dee1ad47SJeff Kirsher /**
221dee1ad47SJeff Kirsher  * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics
222dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
223dee1ad47SJeff Kirsher  *
224dee1ad47SJeff Kirsher  * Configure queue statistics registers, all queues belonging to same traffic
225dee1ad47SJeff Kirsher  * class uses a single set of queue statistics counters.
226dee1ad47SJeff Kirsher  */
ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw * hw)227dee1ad47SJeff Kirsher static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
228dee1ad47SJeff Kirsher {
229dee1ad47SJeff Kirsher 	u32 reg = 0;
230dee1ad47SJeff Kirsher 	u8  i   = 0;
231dee1ad47SJeff Kirsher 	u8  j   = 0;
232dee1ad47SJeff Kirsher 
233dee1ad47SJeff Kirsher 	/* Receive Queues stats setting -  8 queues per statistics reg */
234dee1ad47SJeff Kirsher 	for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) {
235dee1ad47SJeff Kirsher 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i));
236dee1ad47SJeff Kirsher 		reg |= ((0x1010101) * j);
237dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
238dee1ad47SJeff Kirsher 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1));
239dee1ad47SJeff Kirsher 		reg |= ((0x1010101) * j);
240dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg);
241dee1ad47SJeff Kirsher 	}
242dee1ad47SJeff Kirsher 	/* Transmit Queues stats setting -  4 queues per statistics reg */
243dee1ad47SJeff Kirsher 	for (i = 0; i < 8; i++) {
244dee1ad47SJeff Kirsher 		reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i));
245dee1ad47SJeff Kirsher 		reg |= ((0x1010101) * i);
246dee1ad47SJeff Kirsher 		IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg);
247dee1ad47SJeff Kirsher 	}
248dee1ad47SJeff Kirsher 
249dee1ad47SJeff Kirsher 	return 0;
250dee1ad47SJeff Kirsher }
251dee1ad47SJeff Kirsher 
252dee1ad47SJeff Kirsher /**
253dee1ad47SJeff Kirsher  * ixgbe_dcb_hw_config_82598 - Config and enable DCB
254dee1ad47SJeff Kirsher  * @hw: pointer to hardware structure
2555ba643c6STony Nguyen  * @pfc_en: enabled pfc bitmask
2565ba643c6STony Nguyen  * @refill: refill credits index by traffic class
2575ba643c6STony Nguyen  * @max: max credits index by traffic class
2585ba643c6STony Nguyen  * @bwg_id: bandwidth grouping indexed by traffic class
2595ba643c6STony Nguyen  * @prio_type: priority type indexed by traffic class
260dee1ad47SJeff Kirsher  *
261dee1ad47SJeff Kirsher  * Configure dcb settings and enable dcb mode.
262dee1ad47SJeff Kirsher  */
ixgbe_dcb_hw_config_82598(struct ixgbe_hw * hw,u8 pfc_en,u16 * refill,u16 * max,u8 * bwg_id,u8 * prio_type)263dee1ad47SJeff Kirsher s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, u8 pfc_en, u16 *refill,
264dee1ad47SJeff Kirsher 			      u16 *max, u8 *bwg_id, u8 *prio_type)
265dee1ad47SJeff Kirsher {
266dee1ad47SJeff Kirsher 	ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type);
267dee1ad47SJeff Kirsher 	ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max,
268dee1ad47SJeff Kirsher 					       bwg_id, prio_type);
269dee1ad47SJeff Kirsher 	ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max,
270dee1ad47SJeff Kirsher 					       bwg_id, prio_type);
271dee1ad47SJeff Kirsher 	ixgbe_dcb_config_pfc_82598(hw, pfc_en);
272dee1ad47SJeff Kirsher 	ixgbe_dcb_config_tc_stats_82598(hw);
273dee1ad47SJeff Kirsher 
274dee1ad47SJeff Kirsher 	return 0;
275dee1ad47SJeff Kirsher }
276