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