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