1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2001-2020 Intel Corporation
3  */
4 
5 
6 #include "ixgbe_type.h"
7 #include "ixgbe_dcb.h"
8 #include "ixgbe_dcb_82598.h"
9 
10 /**
11  * ixgbe_dcb_get_tc_stats_82598 - Return status data for each traffic class
12  * @hw: pointer to hardware structure
13  * @stats: pointer to statistics structure
14  * @tc_count:  Number of elements in bwg_array.
15  *
16  * This function returns the status data for each of the Traffic Classes in use.
17  */
ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)18 s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *hw,
19 				 struct ixgbe_hw_stats *stats,
20 				 u8 tc_count)
21 {
22 	int tc;
23 
24 	DEBUGFUNC("dcb_get_tc_stats");
25 
26 	if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
27 		return IXGBE_ERR_PARAM;
28 
29 	/* Statistics pertaining to each traffic class */
30 	for (tc = 0; tc < tc_count; tc++) {
31 		/* Transmitted Packets */
32 		stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
33 		/* Transmitted Bytes */
34 		stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
35 		/* Received Packets */
36 		stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
37 		/* Received Bytes */
38 		stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
39 	}
40 
41 	return IXGBE_SUCCESS;
42 }
43 
44 /**
45  * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data
46  * @hw: pointer to hardware structure
47  * @stats: pointer to statistics structure
48  * @tc_count:  Number of elements in bwg_array.
49  *
50  * This function returns the CBFC status data for each of the Traffic Classes.
51  */
ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)52 s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw,
53 				  struct ixgbe_hw_stats *stats,
54 				  u8 tc_count)
55 {
56 	int tc;
57 
58 	DEBUGFUNC("dcb_get_pfc_stats");
59 
60 	if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
61 		return IXGBE_ERR_PARAM;
62 
63 	for (tc = 0; tc < tc_count; tc++) {
64 		/* Priority XOFF Transmitted */
65 		stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
66 		/* Priority XOFF Received */
67 		stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc));
68 	}
69 
70 	return IXGBE_SUCCESS;
71 }
72 
73 /**
74  * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter
75  * @hw: pointer to hardware structure
76  * @refill: refill credits index by traffic class
77  * @max: max credits index by traffic class
78  * @tsa: transmission selection algorithm indexed by traffic class
79  *
80  * Configure Rx Data Arbiter and credits for each traffic class.
81  */
ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * tsa)82 s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, u16 *refill,
83 				      u16 *max, u8 *tsa)
84 {
85 	u32 reg = 0;
86 	u32 credit_refill = 0;
87 	u32 credit_max = 0;
88 	u8 i = 0;
89 
90 	reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
91 	IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
92 
93 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
94 	/* Enable Arbiter */
95 	reg &= ~IXGBE_RMCS_ARBDIS;
96 	/* Enable Receive Recycle within the BWG */
97 	reg |= IXGBE_RMCS_RRM;
98 	/* Enable Deficit Fixed Priority arbitration*/
99 	reg |= IXGBE_RMCS_DFP;
100 
101 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
102 
103 	/* Configure traffic class credits and priority */
104 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
105 		credit_refill = refill[i];
106 		credit_max = max[i];
107 
108 		reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
109 
110 		if (tsa[i] == ixgbe_dcb_tsa_strict)
111 			reg |= IXGBE_RT2CR_LSP;
112 
113 		IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
114 	}
115 
116 	reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
117 	reg |= IXGBE_RDRXCTL_RDMTS_1_2;
118 	reg |= IXGBE_RDRXCTL_MPBEN;
119 	reg |= IXGBE_RDRXCTL_MCEN;
120 	IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
121 
122 	reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
123 	/* Make sure there is enough descriptors before arbitration */
124 	reg &= ~IXGBE_RXCTRL_DMBYPS;
125 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
126 
127 	return IXGBE_SUCCESS;
128 }
129 
130 /**
131  * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
132  * @hw: pointer to hardware structure
133  * @refill: refill credits index by traffic class
134  * @max: max credits index by traffic class
135  * @bwg_id: bandwidth grouping indexed by traffic class
136  * @tsa: transmission selection algorithm indexed by traffic class
137  *
138  * Configure Tx Descriptor Arbiter and credits for each traffic class.
139  */
ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)140 s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
141 					   u16 *refill, u16 *max, u8 *bwg_id,
142 					   u8 *tsa)
143 {
144 	u32 reg, max_credits;
145 	u8 i;
146 
147 	reg = IXGBE_READ_REG(hw, IXGBE_DPMCS);
148 
149 	/* Enable arbiter */
150 	reg &= ~IXGBE_DPMCS_ARBDIS;
151 	reg |= IXGBE_DPMCS_TSOEF;
152 
153 	/* Configure Max TSO packet size 34KB including payload and headers */
154 	reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
155 
156 	IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg);
157 
158 	/* Configure traffic class credits and priority */
159 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
160 		max_credits = max[i];
161 		reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
162 		reg |= (u32)(refill[i]);
163 		reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
164 
165 		if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
166 			reg |= IXGBE_TDTQ2TCCR_GSP;
167 
168 		if (tsa[i] == ixgbe_dcb_tsa_strict)
169 			reg |= IXGBE_TDTQ2TCCR_LSP;
170 
171 		IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
172 	}
173 
174 	return IXGBE_SUCCESS;
175 }
176 
177 /**
178  * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter
179  * @hw: pointer to hardware structure
180  * @refill: refill credits index by traffic class
181  * @max: max credits index by traffic class
182  * @bwg_id: bandwidth grouping indexed by traffic class
183  * @tsa: transmission selection algorithm indexed by traffic class
184  *
185  * Configure Tx Data Arbiter and credits for each traffic class.
186  */
ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)187 s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
188 					   u16 *refill, u16 *max, u8 *bwg_id,
189 					   u8 *tsa)
190 {
191 	u32 reg;
192 	u8 i;
193 
194 	reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
195 	/* Enable Data Plane Arbiter */
196 	reg &= ~IXGBE_PDPMCS_ARBDIS;
197 	/* Enable DFP and Transmit Recycle Mode */
198 	reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM);
199 
200 	IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg);
201 
202 	/* Configure traffic class credits and priority */
203 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
204 		reg = refill[i];
205 		reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT;
206 		reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT;
207 
208 		if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
209 			reg |= IXGBE_TDPT2TCCR_GSP;
210 
211 		if (tsa[i] == ixgbe_dcb_tsa_strict)
212 			reg |= IXGBE_TDPT2TCCR_LSP;
213 
214 		IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
215 	}
216 
217 	/* Enable Tx packet buffer division */
218 	reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
219 	reg |= IXGBE_DTXCTL_ENDBUBD;
220 	IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg);
221 
222 	return IXGBE_SUCCESS;
223 }
224 
225 /**
226  * ixgbe_dcb_config_pfc_82598 - Config priority flow control
227  * @hw: pointer to hardware structure
228  * @pfc_en: enabled pfc bitmask
229  *
230  * Configure Priority Flow Control for each traffic class.
231  */
ixgbe_dcb_config_pfc_82598(struct ixgbe_hw * hw,u8 pfc_en)232 s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
233 {
234 	u32 fcrtl, reg;
235 	u8 i;
236 
237 	/* Enable Transmit Priority Flow Control */
238 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
239 	reg &= ~IXGBE_RMCS_TFCE_802_3X;
240 	reg |= IXGBE_RMCS_TFCE_PRIORITY;
241 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
242 
243 	/* Enable Receive Priority Flow Control */
244 	reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
245 	reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE);
246 
247 	if (pfc_en)
248 		reg |= IXGBE_FCTRL_RPFCE;
249 
250 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
251 
252 	/* Configure PFC Tx thresholds per TC */
253 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
254 		if (!(pfc_en & (1 << i))) {
255 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
256 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
257 			continue;
258 		}
259 
260 		fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
261 		reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
262 		IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
263 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
264 	}
265 
266 	/* Configure pause time */
267 	reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
268 	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
269 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
270 
271 	/* Configure flow control refresh threshold value */
272 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
273 
274 	return IXGBE_SUCCESS;
275 }
276 
277 /**
278  * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics
279  * @hw: pointer to hardware structure
280  *
281  * Configure queue statistics registers, all queues belonging to same traffic
282  * class uses a single set of queue statistics counters.
283  */
ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw * hw)284 s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
285 {
286 	u32 reg = 0;
287 	u8 i = 0;
288 	u8 j = 0;
289 
290 	/* Receive Queues stats setting -  8 queues per statistics reg */
291 	for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) {
292 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i));
293 		reg |= ((0x1010101) * j);
294 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
295 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1));
296 		reg |= ((0x1010101) * j);
297 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg);
298 	}
299 	/* Transmit Queues stats setting -  4 queues per statistics reg*/
300 	for (i = 0; i < 8; i++) {
301 		reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i));
302 		reg |= ((0x1010101) * i);
303 		IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg);
304 	}
305 
306 	return IXGBE_SUCCESS;
307 }
308 
309 /**
310  * ixgbe_dcb_hw_config_82598 - Config and enable DCB
311  * @hw: pointer to hardware structure
312  * @link_speed: unused
313  * @refill: refill credits index by traffic class
314  * @max: max credits index by traffic class
315  * @bwg_id: bandwidth grouping indexed by traffic class
316  * @tsa: transmission selection algorithm indexed by traffic class
317  *
318  * Configure dcb settings and enable dcb mode.
319  */
ixgbe_dcb_hw_config_82598(struct ixgbe_hw * hw,int link_speed,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)320 s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, int link_speed,
321 			      u16 *refill, u16 *max, u8 *bwg_id,
322 			      u8 *tsa)
323 {
324 	UNREFERENCED_1PARAMETER(link_speed);
325 
326 	ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
327 	ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
328 					       tsa);
329 	ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
330 					       tsa);
331 	ixgbe_dcb_config_tc_stats_82598(hw);
332 
333 
334 	return IXGBE_SUCCESS;
335 }
336