1 /* $NetBSD: ixgbe_dcb_82598.c,v 1.13 2023/10/06 14:48:08 msaitoh Exp $ */
2 /******************************************************************************
3 SPDX-License-Identifier: BSD-3-Clause
4
5 Copyright (c) 2001-2020, 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.13 2023/10/06 14:48:08 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 */
ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)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
75 return IXGBE_SUCCESS;
76 }
77
78 /**
79 * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data
80 * @hw: pointer to hardware structure
81 * @stats: pointer to statistics structure
82 * @tc_count: Number of elements in bwg_array.
83 *
84 * This function returns the CBFC status data for each of the Traffic Classes.
85 */
ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw * hw,struct ixgbe_hw_stats * stats,u8 tc_count)86 s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw,
87 struct ixgbe_hw_stats *stats,
88 u8 tc_count)
89 {
90 int tc;
91
92 DEBUGFUNC("dcb_get_pfc_stats");
93
94 if (tc_count > IXGBE_DCB_MAX_TRAFFIC_CLASS)
95 return IXGBE_ERR_PARAM;
96
97 for (tc = 0; tc < tc_count; tc++) {
98 /* Priority XOFF Transmitted */
99 stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
100 /* Priority XOFF Received */
101 stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc));
102 }
103
104 return IXGBE_SUCCESS;
105 }
106
107 /**
108 * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter
109 * @hw: pointer to hardware structure
110 * @refill: refill credits index by traffic class
111 * @max: max credits index by traffic class
112 * @tsa: transmission selection algorithm indexed by traffic class
113 *
114 * Configure Rx Data Arbiter and credits for each traffic class.
115 */
ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * tsa)116 s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, u16 *refill,
117 u16 *max, u8 *tsa)
118 {
119 u32 reg = 0;
120 u32 credit_refill = 0;
121 u32 credit_max = 0;
122 u8 i = 0;
123
124 reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
125 IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
126
127 reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
128 /* Enable Arbiter */
129 reg &= ~IXGBE_RMCS_ARBDIS;
130 /* Enable Receive Recycle within the BWG */
131 reg |= IXGBE_RMCS_RRM;
132 /* Enable Deficit Fixed Priority arbitration*/
133 reg |= IXGBE_RMCS_DFP;
134
135 IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
136
137 /* Configure traffic class credits and priority */
138 for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
139 credit_refill = refill[i];
140 credit_max = max[i];
141
142 reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
143
144 if (tsa[i] == ixgbe_dcb_tsa_strict)
145 reg |= IXGBE_RT2CR_LSP;
146
147 IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
148 }
149
150 reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
151 reg |= IXGBE_RDRXCTL_RDMTS_1_2;
152 reg |= IXGBE_RDRXCTL_MPBEN;
153 reg |= IXGBE_RDRXCTL_MCEN;
154 IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
155
156 reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
157 /* Make sure there is enough descriptors before arbitration */
158 reg &= ~IXGBE_RXCTRL_DMBYPS;
159 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
160
161 return IXGBE_SUCCESS;
162 }
163
164 /**
165 * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
166 * @hw: pointer to hardware structure
167 * @refill: refill credits index by traffic class
168 * @max: max credits index by traffic class
169 * @bwg_id: bandwidth grouping indexed by traffic class
170 * @tsa: transmission selection algorithm indexed by traffic class
171 *
172 * Configure Tx Descriptor Arbiter and credits for each traffic class.
173 */
ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)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 |= (u32)(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 * @refill: refill credits index by traffic class
215 * @max: max credits index by traffic class
216 * @bwg_id: bandwidth grouping indexed by traffic class
217 * @tsa: transmission selection algorithm indexed by traffic class
218 *
219 * Configure Tx Data Arbiter and credits for each traffic class.
220 */
ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)221 s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
222 u16 *refill, u16 *max, u8 *bwg_id,
223 u8 *tsa)
224 {
225 u32 reg;
226 u8 i;
227
228 reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
229 /* Enable Data Plane Arbiter */
230 reg &= ~IXGBE_PDPMCS_ARBDIS;
231 /* Enable DFP and Transmit Recycle Mode */
232 reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM);
233
234 IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg);
235
236 /* Configure traffic class credits and priority */
237 for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
238 reg = refill[i];
239 reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT;
240 reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT;
241
242 if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
243 reg |= IXGBE_TDPT2TCCR_GSP;
244
245 if (tsa[i] == ixgbe_dcb_tsa_strict)
246 reg |= IXGBE_TDPT2TCCR_LSP;
247
248 IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
249 }
250
251 /* Enable Tx packet buffer division */
252 reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
253 reg |= IXGBE_DTXCTL_ENDBUBD;
254 IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg);
255
256 return IXGBE_SUCCESS;
257 }
258
259 /**
260 * ixgbe_dcb_config_pfc_82598 - Config priority flow control
261 * @hw: pointer to hardware structure
262 * @pfc_en: enabled pfc bitmask
263 *
264 * Configure Priority Flow Control for each traffic class.
265 */
ixgbe_dcb_config_pfc_82598(struct ixgbe_hw * hw,u8 pfc_en)266 s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
267 {
268 u32 fcrtl, reg;
269 u8 i;
270
271 /* Enable Transmit Priority Flow Control */
272 reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
273 reg &= ~IXGBE_RMCS_TFCE_802_3X;
274 reg |= IXGBE_RMCS_TFCE_PRIORITY;
275 IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
276
277 /* Enable Receive Priority Flow Control */
278 reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
279 reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE);
280
281 if (pfc_en)
282 reg |= IXGBE_FCTRL_RPFCE;
283
284 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
285
286 /* Configure PFC Tx thresholds per TC */
287 for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
288 if (!(pfc_en & (1 << i))) {
289 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
290 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
291 continue;
292 }
293
294 fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
295 reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
296 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
297 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
298 }
299
300 /* Configure pause time */
301 reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
302 for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
303 IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
304
305 /* Configure flow control refresh threshold value */
306 IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
307
308 return IXGBE_SUCCESS;
309 }
310
311 /**
312 * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics
313 * @hw: pointer to hardware structure
314 *
315 * Configure queue statistics registers, all queues belonging to same traffic
316 * class uses a single set of queue statistics counters.
317 */
ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw * hw)318 s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
319 {
320 u32 reg = 0;
321 u8 i = 0;
322 u8 j = 0;
323
324 /* Receive Queues stats setting - 8 queues per statistics reg */
325 for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) {
326 reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i));
327 reg |= ((0x1010101) * j);
328 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
329 reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1));
330 reg |= ((0x1010101) * j);
331 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg);
332 }
333 /* Transmit Queues stats setting - 4 queues per statistics reg*/
334 for (i = 0; i < 8; i++) {
335 reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i));
336 reg |= ((0x1010101) * i);
337 IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg);
338 }
339
340 return IXGBE_SUCCESS;
341 }
342
343 /**
344 * ixgbe_dcb_hw_config_82598 - Config and enable DCB
345 * @hw: pointer to hardware structure
346 * @link_speed: unused
347 * @refill: refill credits index by traffic class
348 * @max: max credits index by traffic class
349 * @bwg_id: bandwidth grouping indexed by traffic class
350 * @tsa: transmission selection algorithm indexed by traffic class
351 *
352 * Configure dcb settings and enable dcb mode.
353 */
ixgbe_dcb_hw_config_82598(struct ixgbe_hw * hw,int link_speed,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)354 s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, int link_speed,
355 u16 *refill, u16 *max, u8 *bwg_id,
356 u8 *tsa)
357 {
358 UNREFERENCED_1PARAMETER(link_speed);
359
360 ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
361 ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
362 tsa);
363 ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
364 tsa);
365 ixgbe_dcb_config_tc_stats_82598(hw);
366
367 return IXGBE_SUCCESS;
368 }
369