1 /******************************************************************************
2
3 Copyright (c) 2001-2015, 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 * @dcb_config: pointer to ixgbe_dcb_config structure
115 *
116 * Configure Rx Data Arbiter and credits for each traffic class.
117 */
ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * tsa)118 s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, u16 *refill,
119 u16 *max, u8 *tsa)
120 {
121 u32 reg = 0;
122 u32 credit_refill = 0;
123 u32 credit_max = 0;
124 u8 i = 0;
125
126 reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
127 IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
128
129 reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
130 /* Enable Arbiter */
131 reg &= ~IXGBE_RMCS_ARBDIS;
132 /* Enable Receive Recycle within the BWG */
133 reg |= IXGBE_RMCS_RRM;
134 /* Enable Deficit Fixed Priority arbitration*/
135 reg |= IXGBE_RMCS_DFP;
136
137 IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
138
139 /* Configure traffic class credits and priority */
140 for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
141 credit_refill = refill[i];
142 credit_max = max[i];
143
144 reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
145
146 if (tsa[i] == ixgbe_dcb_tsa_strict)
147 reg |= IXGBE_RT2CR_LSP;
148
149 IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
150 }
151
152 reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
153 reg |= IXGBE_RDRXCTL_RDMTS_1_2;
154 reg |= IXGBE_RDRXCTL_MPBEN;
155 reg |= IXGBE_RDRXCTL_MCEN;
156 IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
157
158 reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
159 /* Make sure there is enough descriptors before arbitration */
160 reg &= ~IXGBE_RXCTRL_DMBYPS;
161 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
162
163 return IXGBE_SUCCESS;
164 }
165
166 /**
167 * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
168 * @hw: pointer to hardware structure
169 * @dcb_config: pointer to ixgbe_dcb_config structure
170 *
171 * Configure Tx Descriptor Arbiter and credits for each traffic class.
172 */
ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)173 s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
174 u16 *refill, u16 *max, u8 *bwg_id,
175 u8 *tsa)
176 {
177 u32 reg, max_credits;
178 u8 i;
179
180 reg = IXGBE_READ_REG(hw, IXGBE_DPMCS);
181
182 /* Enable arbiter */
183 reg &= ~IXGBE_DPMCS_ARBDIS;
184 reg |= IXGBE_DPMCS_TSOEF;
185
186 /* Configure Max TSO packet size 34KB including payload and headers */
187 reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
188
189 IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg);
190
191 /* Configure traffic class credits and priority */
192 for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
193 max_credits = max[i];
194 reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
195 reg |= refill[i];
196 reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
197
198 if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
199 reg |= IXGBE_TDTQ2TCCR_GSP;
200
201 if (tsa[i] == ixgbe_dcb_tsa_strict)
202 reg |= IXGBE_TDTQ2TCCR_LSP;
203
204 IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
205 }
206
207 return IXGBE_SUCCESS;
208 }
209
210 /**
211 * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter
212 * @hw: pointer to hardware structure
213 * @dcb_config: pointer to ixgbe_dcb_config structure
214 *
215 * Configure Tx Data Arbiter and credits for each traffic class.
216 */
ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw * hw,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)217 s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
218 u16 *refill, u16 *max, u8 *bwg_id,
219 u8 *tsa)
220 {
221 u32 reg;
222 u8 i;
223
224 reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
225 /* Enable Data Plane Arbiter */
226 reg &= ~IXGBE_PDPMCS_ARBDIS;
227 /* Enable DFP and Transmit Recycle Mode */
228 reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM);
229
230 IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg);
231
232 /* Configure traffic class credits and priority */
233 for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
234 reg = refill[i];
235 reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT;
236 reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT;
237
238 if (tsa[i] == ixgbe_dcb_tsa_group_strict_cee)
239 reg |= IXGBE_TDPT2TCCR_GSP;
240
241 if (tsa[i] == ixgbe_dcb_tsa_strict)
242 reg |= IXGBE_TDPT2TCCR_LSP;
243
244 IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
245 }
246
247 /* Enable Tx packet buffer division */
248 reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
249 reg |= IXGBE_DTXCTL_ENDBUBD;
250 IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg);
251
252 return IXGBE_SUCCESS;
253 }
254
255 /**
256 * ixgbe_dcb_config_pfc_82598 - Config priority flow control
257 * @hw: pointer to hardware structure
258 * @dcb_config: pointer to ixgbe_dcb_config structure
259 *
260 * Configure Priority Flow Control for each traffic class.
261 */
ixgbe_dcb_config_pfc_82598(struct ixgbe_hw * hw,u8 pfc_en)262 s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
263 {
264 u32 fcrtl, reg;
265 u8 i;
266
267 /* Enable Transmit Priority Flow Control */
268 reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
269 reg &= ~IXGBE_RMCS_TFCE_802_3X;
270 reg |= IXGBE_RMCS_TFCE_PRIORITY;
271 IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
272
273 /* Enable Receive Priority Flow Control */
274 reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
275 reg &= ~(IXGBE_FCTRL_RPFCE | IXGBE_FCTRL_RFCE);
276
277 if (pfc_en)
278 reg |= IXGBE_FCTRL_RPFCE;
279
280 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
281
282 /* Configure PFC Tx thresholds per TC */
283 for (i = 0; i < IXGBE_DCB_MAX_TRAFFIC_CLASS; i++) {
284 if (!(pfc_en & (1 << i))) {
285 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), 0);
286 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), 0);
287 continue;
288 }
289
290 fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
291 reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
292 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
293 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
294 }
295
296 /* Configure pause time */
297 reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
298 for (i = 0; i < (IXGBE_DCB_MAX_TRAFFIC_CLASS / 2); i++)
299 IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
300
301 /* Configure flow control refresh threshold value */
302 IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
303
304 return IXGBE_SUCCESS;
305 }
306
307 /**
308 * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics
309 * @hw: pointer to hardware structure
310 *
311 * Configure queue statistics registers, all queues belonging to same traffic
312 * class uses a single set of queue statistics counters.
313 */
ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw * hw)314 s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
315 {
316 u32 reg = 0;
317 u8 i = 0;
318 u8 j = 0;
319
320 /* Receive Queues stats setting - 8 queues per statistics reg */
321 for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) {
322 reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i));
323 reg |= ((0x1010101) * j);
324 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
325 reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1));
326 reg |= ((0x1010101) * j);
327 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg);
328 }
329 /* Transmit Queues stats setting - 4 queues per statistics reg*/
330 for (i = 0; i < 8; i++) {
331 reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i));
332 reg |= ((0x1010101) * i);
333 IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg);
334 }
335
336 return IXGBE_SUCCESS;
337 }
338
339 /**
340 * ixgbe_dcb_hw_config_82598 - Config and enable DCB
341 * @hw: pointer to hardware structure
342 * @dcb_config: pointer to ixgbe_dcb_config structure
343 *
344 * Configure dcb settings and enable dcb mode.
345 */
ixgbe_dcb_hw_config_82598(struct ixgbe_hw * hw,int link_speed,u16 * refill,u16 * max,u8 * bwg_id,u8 * tsa)346 s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, int link_speed,
347 u16 *refill, u16 *max, u8 *bwg_id,
348 u8 *tsa)
349 {
350 UNREFERENCED_1PARAMETER(link_speed);
351
352 ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, tsa);
353 ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, bwg_id,
354 tsa);
355 ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, bwg_id,
356 tsa);
357 ixgbe_dcb_config_tc_stats_82598(hw);
358
359
360 return IXGBE_SUCCESS;
361 }
362