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