aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_dcb_82599.c
diff options
context:
space:
mode:
authorPJ Waskiewicz <peter.p.waskiewicz.jr@intel.com>2009-02-27 10:44:48 -0500
committerDavid S. Miller <davem@davemloft.net>2009-03-01 03:24:35 -0500
commit235ea828a1640ed493562a5fe08aa666ff84fbc4 (patch)
tree11a5420b59fc14caca14d5100262adb34331cba9 /drivers/net/ixgbe/ixgbe_dcb_82599.c
parent11afc1b1fd802c11dc0fa986c210602c177f1e21 (diff)
ixgbe: Add DCB for 82599, remove BCN support
This patch adds the DCB (Data Center Bridging) support for 82599 hardware. This is similar to how the 82598 DCB code works. This patch also removes the BCN (Backwards Congestion Notification) netlink configuration code from the driver. BCN was a pre-standard congestion notification framework, and was not what the IEEE body decided upon for standard congestion management. QCN (802.1Qau), Quantized Congestion Notification is the accepted standard, which is not supported by 82599, hence we remove the support altogether. Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_dcb_82599.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82599.c472
1 files changed, 472 insertions, 0 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ixgbe/ixgbe_dcb_82599.c
new file mode 100644
index 000000000000..1467d56435a0
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_dcb_82599.c
@@ -0,0 +1,472 @@
1/*******************************************************************************
2
3 Intel 10 Gigabit PCI Express Linux driver
4 Copyright(c) 1999 - 2009 Intel Corporation.
5
6 This program is free software; you can redistribute it and/or modify it
7 under the terms and conditions of the GNU General Public License,
8 version 2, as published by the Free Software Foundation.
9
10 This program is distributed in the hope it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
18
19 The full GNU General Public License is included in this distribution in
20 the file called "COPYING".
21
22 Contact Information:
23 e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
24 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
25
26*******************************************************************************/
27
28#include "ixgbe.h"
29#include "ixgbe_type.h"
30#include "ixgbe_dcb.h"
31#include "ixgbe_dcb_82599.h"
32
33/**
34 * ixgbe_dcb_get_tc_stats_82599 - Returns status for each traffic class
35 * @hw: pointer to hardware structure
36 * @stats: pointer to statistics structure
37 * @tc_count: Number of elements in bwg_array.
38 *
39 * This function returns the status data for each of the Traffic Classes in use.
40 */
41s32 ixgbe_dcb_get_tc_stats_82599(struct ixgbe_hw *hw,
42 struct ixgbe_hw_stats *stats,
43 u8 tc_count)
44{
45 int tc;
46
47 if (tc_count > MAX_TRAFFIC_CLASS)
48 return DCB_ERR_PARAM;
49 /* Statistics pertaining to each traffic class */
50 for (tc = 0; tc < tc_count; tc++) {
51 /* Transmitted Packets */
52 stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
53 /* Transmitted Bytes */
54 stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
55 /* Received Packets */
56 stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
57 /* Received Bytes */
58 stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
59 }
60
61 return 0;
62}
63
64/**
65 * ixgbe_dcb_get_pfc_stats_82599 - Return CBFC status data
66 * @hw: pointer to hardware structure
67 * @stats: pointer to statistics structure
68 * @tc_count: Number of elements in bwg_array.
69 *
70 * This function returns the CBFC status data for each of the Traffic Classes.
71 */
72s32 ixgbe_dcb_get_pfc_stats_82599(struct ixgbe_hw *hw,
73 struct ixgbe_hw_stats *stats,
74 u8 tc_count)
75{
76 int tc;
77
78 if (tc_count > MAX_TRAFFIC_CLASS)
79 return DCB_ERR_PARAM;
80 for (tc = 0; tc < tc_count; tc++) {
81 /* Priority XOFF Transmitted */
82 stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
83 /* Priority XOFF Received */
84 stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXCNT(tc));
85 }
86
87 return 0;
88}
89
90/**
91 * ixgbe_dcb_config_packet_buffers_82599 - Configure DCB packet buffers
92 * @hw: pointer to hardware structure
93 * @dcb_config: pointer to ixgbe_dcb_config structure
94 *
95 * Configure packet buffers for DCB mode.
96 */
97s32 ixgbe_dcb_config_packet_buffers_82599(struct ixgbe_hw *hw,
98 struct ixgbe_dcb_config *dcb_config)
99{
100 s32 ret_val = 0;
101 u32 value = IXGBE_RXPBSIZE_64KB;
102 u8 i = 0;
103
104 /* Setup Rx packet buffer sizes */
105 switch (dcb_config->rx_pba_cfg) {
106 case pba_80_48:
107 /* Setup the first four at 80KB */
108 value = IXGBE_RXPBSIZE_80KB;
109 for (; i < 4; i++)
110 IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
111 /* Setup the last four at 48KB...don't re-init i */
112 value = IXGBE_RXPBSIZE_48KB;
113 /* Fall Through */
114 case pba_equal:
115 default:
116 for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
117 IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
118
119 /* Setup Tx packet buffer sizes */
120 for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
121 IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i),
122 IXGBE_TXPBSIZE_20KB);
123 IXGBE_WRITE_REG(hw, IXGBE_TXPBTHRESH(i),
124 IXGBE_TXPBTHRESH_DCB);
125 }
126 break;
127 }
128
129 return ret_val;
130}
131
132/**
133 * ixgbe_dcb_config_rx_arbiter_82599 - Config Rx Data arbiter
134 * @hw: pointer to hardware structure
135 * @dcb_config: pointer to ixgbe_dcb_config structure
136 *
137 * Configure Rx Packet Arbiter and credits for each traffic class.
138 */
139s32 ixgbe_dcb_config_rx_arbiter_82599(struct ixgbe_hw *hw,
140 struct ixgbe_dcb_config *dcb_config)
141{
142 struct tc_bw_alloc *p;
143 u32 reg = 0;
144 u32 credit_refill = 0;
145 u32 credit_max = 0;
146 u8 i = 0;
147
148 /* Disable the arbiter before changing parameters */
149 IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, IXGBE_RTRPCS_ARBDIS);
150
151 /* Map all traffic classes to their UP, 1 to 1 */
152 reg = 0;
153 for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
154 reg |= (i << (i * IXGBE_RTRUP2TC_UP_SHIFT));
155 IXGBE_WRITE_REG(hw, IXGBE_RTRUP2TC, reg);
156
157 /* Configure traffic class credits and priority */
158 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
159 p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG];
160
161 credit_refill = p->data_credits_refill;
162 credit_max = p->data_credits_max;
163 reg = credit_refill | (credit_max << IXGBE_RTRPT4C_MCL_SHIFT);
164
165 reg |= (u32)(p->bwg_id) << IXGBE_RTRPT4C_BWG_SHIFT;
166
167 if (p->prio_type == prio_link)
168 reg |= IXGBE_RTRPT4C_LSP;
169
170 IXGBE_WRITE_REG(hw, IXGBE_RTRPT4C(i), reg);
171 }
172
173 /*
174 * Configure Rx packet plane (recycle mode; WSP) and
175 * enable arbiter
176 */
177 reg = IXGBE_RTRPCS_RRM | IXGBE_RTRPCS_RAC;
178 IXGBE_WRITE_REG(hw, IXGBE_RTRPCS, reg);
179
180 return 0;
181}
182
183/**
184 * ixgbe_dcb_config_tx_desc_arbiter_82599 - Config Tx Desc. arbiter
185 * @hw: pointer to hardware structure
186 * @dcb_config: pointer to ixgbe_dcb_config structure
187 *
188 * Configure Tx Descriptor Arbiter and credits for each traffic class.
189 */
190s32 ixgbe_dcb_config_tx_desc_arbiter_82599(struct ixgbe_hw *hw,
191 struct ixgbe_dcb_config *dcb_config)
192{
193 struct tc_bw_alloc *p;
194 u32 reg, max_credits;
195 u8 i;
196
197 /* Disable the arbiter before changing parameters */
198 IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, IXGBE_RTTDCS_ARBDIS);
199
200 /* Clear the per-Tx queue credits; we use per-TC instead */
201 for (i = 0; i < 128; i++) {
202 IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, i);
203 IXGBE_WRITE_REG(hw, IXGBE_RTTDT1C, 0);
204 }
205
206 /* Configure traffic class credits and priority */
207 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
208 p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
209 max_credits = dcb_config->tc_config[i].desc_credits_max;
210 reg = max_credits << IXGBE_RTTDT2C_MCL_SHIFT;
211 reg |= p->data_credits_refill;
212 reg |= (u32)(p->bwg_id) << IXGBE_RTTDT2C_BWG_SHIFT;
213
214 if (p->prio_type == prio_group)
215 reg |= IXGBE_RTTDT2C_GSP;
216
217 if (p->prio_type == prio_link)
218 reg |= IXGBE_RTTDT2C_LSP;
219
220 IXGBE_WRITE_REG(hw, IXGBE_RTTDT2C(i), reg);
221 }
222
223 /*
224 * Configure Tx descriptor plane (recycle mode; WSP) and
225 * enable arbiter
226 */
227 reg = IXGBE_RTTDCS_TDPAC | IXGBE_RTTDCS_TDRM;
228 IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
229
230 return 0;
231}
232
233/**
234 * ixgbe_dcb_config_tx_data_arbiter_82599 - Config Tx Data arbiter
235 * @hw: pointer to hardware structure
236 * @dcb_config: pointer to ixgbe_dcb_config structure
237 *
238 * Configure Tx Packet Arbiter and credits for each traffic class.
239 */
240s32 ixgbe_dcb_config_tx_data_arbiter_82599(struct ixgbe_hw *hw,
241 struct ixgbe_dcb_config *dcb_config)
242{
243 struct tc_bw_alloc *p;
244 u32 reg;
245 u8 i;
246
247 /* Disable the arbiter before changing parameters */
248 IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, IXGBE_RTTPCS_ARBDIS);
249
250 /* Map all traffic classes to their UP, 1 to 1 */
251 reg = 0;
252 for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
253 reg |= (i << (i * IXGBE_RTTUP2TC_UP_SHIFT));
254 IXGBE_WRITE_REG(hw, IXGBE_RTTUP2TC, reg);
255
256 /* Configure traffic class credits and priority */
257 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
258 p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
259 reg = p->data_credits_refill;
260 reg |= (u32)(p->data_credits_max) << IXGBE_RTTPT2C_MCL_SHIFT;
261 reg |= (u32)(p->bwg_id) << IXGBE_RTTPT2C_BWG_SHIFT;
262
263 if (p->prio_type == prio_group)
264 reg |= IXGBE_RTTPT2C_GSP;
265
266 if (p->prio_type == prio_link)
267 reg |= IXGBE_RTTPT2C_LSP;
268
269 IXGBE_WRITE_REG(hw, IXGBE_RTTPT2C(i), reg);
270 }
271
272 /*
273 * Configure Tx packet plane (recycle mode; SP; arb delay) and
274 * enable arbiter
275 */
276 reg = IXGBE_RTTPCS_TPPAC | IXGBE_RTTPCS_TPRM |
277 (IXGBE_RTTPCS_ARBD_DCB << IXGBE_RTTPCS_ARBD_SHIFT);
278 IXGBE_WRITE_REG(hw, IXGBE_RTTPCS, reg);
279
280 return 0;
281}
282
283/**
284 * ixgbe_dcb_config_pfc_82599 - Configure priority flow control
285 * @hw: pointer to hardware structure
286 * @dcb_config: pointer to ixgbe_dcb_config structure
287 *
288 * Configure Priority Flow Control (PFC) for each traffic class.
289 */
290s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw,
291 struct ixgbe_dcb_config *dcb_config)
292{
293 u32 i, reg;
294
295 /* If PFC is disabled globally then fall back to LFC. */
296 if (!dcb_config->pfc_mode_enable) {
297 for (i = 0; i < MAX_TRAFFIC_CLASS; i++)
298 hw->mac.ops.setup_fc(hw, i);
299 goto out;
300 }
301
302 /* PFC is mutually exclusive with link flow control */
303 hw->fc.current_mode = ixgbe_fc_none;
304
305 /* Configure PFC Tx thresholds per TC */
306 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
307 /* Config and remember Tx */
308 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full ||
309 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx) {
310 reg = hw->fc.high_water | IXGBE_FCRTH_FCEN;
311 IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), reg);
312 reg = hw->fc.low_water | IXGBE_FCRTL_XONE;
313 IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), reg);
314 } else {
315 IXGBE_WRITE_REG(hw, IXGBE_FCRTH_82599(i), 0);
316 IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), 0);
317 }
318 }
319
320 /* Configure pause time (2 TCs per register) */
321 reg = hw->fc.pause_time | (hw->fc.pause_time << 16);
322 for (i = 0; i < (MAX_TRAFFIC_CLASS / 2); i++)
323 IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), reg);
324
325 /* Configure flow control refresh threshold value */
326 IXGBE_WRITE_REG(hw, IXGBE_FCRTV, hw->fc.pause_time / 2);
327
328 /* Enable Transmit PFC */
329 reg = IXGBE_FCCFG_TFCE_PRIORITY;
330 IXGBE_WRITE_REG(hw, IXGBE_FCCFG, reg);
331
332 /*
333 * Enable Receive PFC
334 * We will always honor XOFF frames we receive when
335 * we are in PFC mode.
336 */
337 reg = IXGBE_READ_REG(hw, IXGBE_MFLCN);
338 reg &= ~IXGBE_MFLCN_RFCE;
339 reg |= IXGBE_MFLCN_RPFCE;
340 IXGBE_WRITE_REG(hw, IXGBE_MFLCN, reg);
341out:
342 return 0;
343}
344
345/**
346 * ixgbe_dcb_config_tc_stats_82599 - Config traffic class statistics
347 * @hw: pointer to hardware structure
348 *
349 * Configure queue statistics registers, all queues belonging to same traffic
350 * class uses a single set of queue statistics counters.
351 */
352s32 ixgbe_dcb_config_tc_stats_82599(struct ixgbe_hw *hw)
353{
354 u32 reg = 0;
355 u8 i = 0;
356
357 /*
358 * Receive Queues stats setting
359 * 32 RQSMR registers, each configuring 4 queues.
360 * Set all 16 queues of each TC to the same stat
361 * with TC 'n' going to stat 'n'.
362 */
363 for (i = 0; i < 32; i++) {
364 reg = 0x01010101 * (i / 4);
365 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
366 }
367 /*
368 * Transmit Queues stats setting
369 * 32 TQSM registers, each controlling 4 queues.
370 * Set all queues of each TC to the same stat
371 * with TC 'n' going to stat 'n'.
372 * Tx queues are allocated non-uniformly to TCs:
373 * 32, 32, 16, 16, 8, 8, 8, 8.
374 */
375 for (i = 0; i < 32; i++) {
376 if (i < 8)
377 reg = 0x00000000;
378 else if (i < 16)
379 reg = 0x01010101;
380 else if (i < 20)
381 reg = 0x02020202;
382 else if (i < 24)
383 reg = 0x03030303;
384 else if (i < 26)
385 reg = 0x04040404;
386 else if (i < 28)
387 reg = 0x05050505;
388 else if (i < 30)
389 reg = 0x06060606;
390 else
391 reg = 0x07070707;
392 IXGBE_WRITE_REG(hw, IXGBE_TQSM(i), reg);
393 }
394
395 return 0;
396}
397
398/**
399 * ixgbe_dcb_config_82599 - Configure general DCB parameters
400 * @hw: pointer to hardware structure
401 * @dcb_config: pointer to ixgbe_dcb_config structure
402 *
403 * Configure general DCB parameters.
404 */
405s32 ixgbe_dcb_config_82599(struct ixgbe_hw *hw)
406{
407 u32 reg;
408 u32 q;
409
410 /* Disable the Tx desc arbiter so that MTQC can be changed */
411 reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
412 reg |= IXGBE_RTTDCS_ARBDIS;
413 IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
414
415 /* Enable DCB for Rx with 8 TCs */
416 reg = IXGBE_READ_REG(hw, IXGBE_MRQC);
417 switch (reg & IXGBE_MRQC_MRQE_MASK) {
418 case 0:
419 case IXGBE_MRQC_RT4TCEN:
420 /* RSS disabled cases */
421 reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RT8TCEN;
422 break;
423 case IXGBE_MRQC_RSSEN:
424 case IXGBE_MRQC_RTRSS4TCEN:
425 /* RSS enabled cases */
426 reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RTRSS8TCEN;
427 break;
428 default:
429 /* Unsupported value, assume stale data, overwrite no RSS */
430 reg = (reg & ~IXGBE_MRQC_MRQE_MASK) | IXGBE_MRQC_RT8TCEN;
431 }
432 IXGBE_WRITE_REG(hw, IXGBE_MRQC, reg);
433
434 /* Enable DCB for Tx with 8 TCs */
435 reg = IXGBE_MTQC_RT_ENA | IXGBE_MTQC_8TC_8TQ;
436 IXGBE_WRITE_REG(hw, IXGBE_MTQC, reg);
437
438 /* Disable drop for all queues */
439 for (q = 0; q < 128; q++)
440 IXGBE_WRITE_REG(hw, IXGBE_QDE, q << IXGBE_QDE_IDX_SHIFT);
441
442 /* Enable the Tx desc arbiter */
443 reg = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
444 reg &= ~IXGBE_RTTDCS_ARBDIS;
445 IXGBE_WRITE_REG(hw, IXGBE_RTTDCS, reg);
446
447 return 0;
448}
449
450/**
451 * ixgbe_dcb_hw_config_82599 - Configure and enable DCB
452 * @hw: pointer to hardware structure
453 * @dcb_config: pointer to ixgbe_dcb_config structure
454 *
455 * Configure dcb settings and enable dcb mode.
456 */
457s32 ixgbe_dcb_hw_config_82599(struct ixgbe_hw *hw,
458 struct ixgbe_dcb_config *dcb_config)
459{
460 u32 pap = 0;
461
462 ixgbe_dcb_config_packet_buffers_82599(hw, dcb_config);
463 ixgbe_dcb_config_82599(hw);
464 ixgbe_dcb_config_rx_arbiter_82599(hw, dcb_config);
465 ixgbe_dcb_config_tx_desc_arbiter_82599(hw, dcb_config);
466 ixgbe_dcb_config_tx_data_arbiter_82599(hw, dcb_config);
467 ixgbe_dcb_config_pfc_82599(hw, dcb_config);
468 ixgbe_dcb_config_tc_stats_82599(hw);
469
470 return 0;
471}
472