xref: /freebsd/sys/dev/ixgbe/ixgbe_dcb_82598.c (revision 56e53cb8ef000c3ef72337a4095987a932cdedef)
1 /******************************************************************************
2   SPDX-License-Identifier: BSD-3-Clause
3 
4   Copyright (c) 2001-2017, Intel Corporation
5   All rights reserved.
6 
7   Redistribution and use in source and binary forms, with or without
8   modification, are permitted provided that the following conditions are met:
9 
10    1. Redistributions of source code must retain the above copyright notice,
11       this list of conditions and the following disclaimer.
12 
13    2. Redistributions in binary form must reproduce the above copyright
14       notice, this list of conditions and the following disclaimer in the
15       documentation and/or other materials provided with the distribution.
16 
17    3. Neither the name of the Intel Corporation nor the names of its
18       contributors may be used to endorse or promote products derived from
19       this software without specific prior written permission.
20 
21   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31   POSSIBILITY OF SUCH DAMAGE.
32 
33 ******************************************************************************/
34 /*$FreeBSD$*/
35 
36 
37 #include "ixgbe_type.h"
38 #include "ixgbe_dcb.h"
39 #include "ixgbe_dcb_82598.h"
40 
41 /**
42  * ixgbe_dcb_get_tc_stats_82598 - Return status data for each traffic class
43  * @hw: pointer to hardware structure
44  * @stats: pointer to statistics structure
45  * @tc_count:  Number of elements in bwg_array.
46  *
47  * This function returns the status data for each of the Traffic Classes in use.
48  */
49 s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *hw,
50 				 struct ixgbe_hw_stats *stats,
51 				 u8 tc_count)
52 {
53 	int tc;
54 
55 	DEBUGFUNC("dcb_get_tc_stats");
56 
57 	if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
58 		return IXGBE_ERR_PARAM;
59 
60 	/* Statistics pertaining to each traffic class */
61 	for (tc = 0; tc < tc_count; tc++) {
62 		/* Transmitted Packets */
63 		stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
64 		/* Transmitted Bytes */
65 		stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
66 		/* Received Packets */
67 		stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
68 		/* Received Bytes */
69 		stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
70 
71 #if 0
72 		/* Can we get rid of these??  Consequently, getting rid
73 		 * of the tc_stats structure.
74 		 */
75 		tc_stats_array[up]->in_overflow_discards = 0;
76 		tc_stats_array[up]->out_overflow_discards = 0;
77 #endif
78 	}
79 
80 	return IXGBE_SUCCESS;
81 }
82 
83 /**
84  * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data
85  * @hw: pointer to hardware structure
86  * @stats: pointer to statistics structure
87  * @tc_count:  Number of elements in bwg_array.
88  *
89  * This function returns the CBFC status data for each of the Traffic Classes.
90  */
91 s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw,
92 				  struct ixgbe_hw_stats *stats,
93 				  u8 tc_count)
94 {
95 	int tc;
96 
97 	DEBUGFUNC("dcb_get_pfc_stats");
98 
99 	if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
100 		return IXGBE_ERR_PARAM;
101 
102 	for (tc = 0; tc < tc_count; tc++) {
103 		/* Priority XOFF Transmitted */
104 		stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
105 		/* Priority XOFF Received */
106 		stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc));
107 	}
108 
109 	return IXGBE_SUCCESS;
110 }
111 
112 /**
113  * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter
114  * @hw: pointer to hardware structure
115  * @dcb_config: pointer to ixgbe_dcb_config structure
116  *
117  * Configure Rx Data Arbiter and credits for each traffic class.
118  */
119 s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, u16 *refill,
120 				      u16 *max, u8 *tsa)
121 {
122 	u32 reg = 0;
123 	u32 credit_refill = 0;
124 	u32 credit_max = 0;
125 	u8 i = 0;
126 
127 	reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
128 	IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
129 
130 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
131 	/* Enable Arbiter */
132 	reg &= ~IXGBE_RMCS_ARBDIS;
133 	/* Enable Receive Recycle within the BWG */
134 	reg |= IXGBE_RMCS_RRM;
135 	/* Enable Deficit Fixed Priority arbitration*/
136 	reg |= IXGBE_RMCS_DFP;
137 
138 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
139 
140 	/* Configure traffic class credits and priority */
141 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
142 		credit_refill = refill[i];
143 		credit_max = max[i];
144 
145 		reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
146 
147 		if (tsa[i] == ixgbe_dcb_tsa_strict)
148 			reg |= IXGBE_RT2CR_LSP;
149 
150 		IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
151 	}
152 
153 	reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
154 	reg |= IXGBE_RDRXCTL_RDMTS_1_2;
155 	reg |= IXGBE_RDRXCTL_MPBEN;
156 	reg |= IXGBE_RDRXCTL_MCEN;
157 	IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
158 
159 	reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
160 	/* Make sure there is enough descriptors before arbitration */
161 	reg &= ~IXGBE_RXCTRL_DMBYPS;
162 	IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
163 
164 	return IXGBE_SUCCESS;
165 }
166 
167 /**
168  * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
169  * @hw: pointer to hardware structure
170  * @dcb_config: pointer to ixgbe_dcb_config structure
171  *
172  * Configure Tx Descriptor Arbiter and credits for each traffic class.
173  */
174 s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
175 					   u16 *refill, u16 *max, u8 *bwg_id,
176 					   u8 *tsa)
177 {
178 	u32 reg, max_credits;
179 	u8 i;
180 
181 	reg = IXGBE_READ_REG(hw, IXGBE_DPMCS);
182 
183 	/* Enable arbiter */
184 	reg &= ~IXGBE_DPMCS_ARBDIS;
185 	reg |= IXGBE_DPMCS_TSOEF;
186 
187 	/* Configure Max TSO packet size 34KB including payload and headers */
188 	reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
189 
190 	IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg);
191 
192 	/* Configure traffic class credits and priority */
193 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
194 		max_credits = max[i];
195 		reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
196 		reg |= refill[i];
197 		reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
198 
199 		if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
200 			reg |= IXGBE_TDTQ2TCCR_GSP;
201 
202 		if (tsa[i] == ixgbe_dcb_tsa_strict)
203 			reg |= IXGBE_TDTQ2TCCR_LSP;
204 
205 		IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
206 	}
207 
208 	return IXGBE_SUCCESS;
209 }
210 
211 /**
212  * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter
213  * @hw: pointer to hardware structure
214  * @dcb_config: pointer to ixgbe_dcb_config structure
215  *
216  * Configure Tx Data Arbiter and credits for each traffic class.
217  */
218 s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
219 					   u16 *refill, u16 *max, u8 *bwg_id,
220 					   u8 *tsa)
221 {
222 	u32 reg;
223 	u8 i;
224 
225 	reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
226 	/* Enable Data Plane Arbiter */
227 	reg &= ~IXGBE_PDPMCS_ARBDIS;
228 	/* Enable DFP and Transmit Recycle Mode */
229 	reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM);
230 
231 	IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg);
232 
233 	/* Configure traffic class credits and priority */
234 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
235 		reg = refill[i];
236 		reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT;
237 		reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT;
238 
239 		if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
240 			reg |= IXGBE_TDPT2TCCR_GSP;
241 
242 		if (tsa[i] == ixgbe_dcb_tsa_strict)
243 			reg |= IXGBE_TDPT2TCCR_LSP;
244 
245 		IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
246 	}
247 
248 	/* Enable Tx packet buffer division */
249 	reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
250 	reg |= IXGBE_DTXCTL_ENDBUBD;
251 	IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg);
252 
253 	return IXGBE_SUCCESS;
254 }
255 
256 /**
257  * ixgbe_dcb_config_pfc_82598 - Config priority flow control
258  * @hw: pointer to hardware structure
259  * @dcb_config: pointer to ixgbe_dcb_config structure
260  *
261  * Configure Priority Flow Control for each traffic class.
262  */
263 s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
264 {
265 	u32 fcrtl, reg;
266 	u8 i;
267 
268 	/* Enable Transmit Priority Flow Control */
269 	reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
270 	reg &= ~IXGBE_RMCS_TFCE_802_3X;
271 	reg |= IXGBE_RMCS_TFCE_PRIORITY;
272 	IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
273 
274 	/* Enable Receive Priority Flow Control */
275 	reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
276 	reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE);
277 
278 	if (pfc_en)
279 		reg |= IXGBE_FCTRL_RPFCE;
280 
281 	IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
282 
283 	/* Configure PFC Tx thresholds per TC */
284 	for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
285 		if (!(pfc_en & (1 << i))) {
286 			IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
287 			IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
288 			continue;
289 		}
290 
291 		fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
292 		reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
293 		IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
294 		IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
295 	}
296 
297 	/* Configure pause time */
298 	reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
299 	for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
300 		IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
301 
302 	/* Configure flow control refresh threshold value */
303 	IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
304 
305 	return IXGBE_SUCCESS;
306 }
307 
308 /**
309  * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics
310  * @hw: pointer to hardware structure
311  *
312  * Configure queue statistics registers, all queues belonging to same traffic
313  * class uses a single set of queue statistics counters.
314  */
315 s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
316 {
317 	u32 reg = 0;
318 	u8 i = 0;
319 	u8 j = 0;
320 
321 	/* Receive Queues stats setting -  8 queues per statistics reg */
322 	for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) {
323 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i));
324 		reg |= ((0x1010101) * j);
325 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
326 		reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1));
327 		reg |= ((0x1010101) * j);
328 		IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg);
329 	}
330 	/* Transmit Queues stats setting -  4 queues per statistics reg*/
331 	for (i = 0; i < 8; i++) {
332 		reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i));
333 		reg |= ((0x1010101) * i);
334 		IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg);
335 	}
336 
337 	return IXGBE_SUCCESS;
338 }
339 
340 /**
341  * ixgbe_dcb_hw_config_82598 - Config and enable DCB
342  * @hw: pointer to hardware structure
343  * @dcb_config: pointer to ixgbe_dcb_config structure
344  *
345  * Configure dcb settings and enable dcb mode.
346  */
347 s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, int link_speed,
348 			      u16 *refill, u16 *max, u8 *bwg_id,
349 			      u8 *tsa)
350 {
351 	UNREFERENCED_1PARAMETER(link_speed);
352 
353 	ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
354 	ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
355 					       tsa);
356 	ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
357 					       tsa);
358 	ixgbe_dcb_config_tc_stats_82598(hw);
359 
360 
361 	return IXGBE_SUCCESS;
362 }
363