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