aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ixgbe/ixgbe_dcb_82598.c
diff options
context:
space:
mode:
authorAlexander Duyck <alexander.h.duyck@intel.com>2008-11-20 23:52:10 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-20 23:52:10 -0500
commit2f90b8657ec942d1880f720e0177ee71df7c8e3c (patch)
tree844114b22c548fedbab67e53b09b2efcf170563a /drivers/net/ixgbe/ixgbe_dcb_82598.c
parent9db66bdcc83749affe61c61eb8ff3cf08f42afec (diff)
ixgbe: this patch adds support for DCB to the kernel and ixgbe driver
This adds support for Data Center Bridging (DCB) features in the ixgbe driver and adds an rtnetlink interface for configuring DCB to the kernel. The DCB feature support included are Priority Grouping (PG) - which allows bandwidth guarantees to be allocated to groups to traffic based on the 802.1q priority, and Priority Based Flow Control (PFC) - which introduces a new MAC control PAUSE frame which works at granularity of the 802.1p priority instead of the link (IEEE 802.3x). Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_dcb_82598.c')
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_82598.c398
1 files changed, 398 insertions, 0 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c
new file mode 100644
index 00000000000..fce6867a451
--- /dev/null
+++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c
@@ -0,0 +1,398 @@
1/*******************************************************************************
2
3 Intel 10 Gigabit PCI Express Linux driver
4 Copyright(c) 1999 - 2007 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 Linux NICS <linux.nics@intel.com>
24 e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
25 Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
26
27*******************************************************************************/
28
29#include "ixgbe.h"
30#include "ixgbe_type.h"
31#include "ixgbe_dcb.h"
32#include "ixgbe_dcb_82598.h"
33
34/**
35 * ixgbe_dcb_get_tc_stats_82598 - Return status data for each traffic class
36 * @hw: pointer to hardware structure
37 * @stats: pointer to statistics structure
38 * @tc_count: Number of elements in bwg_array.
39 *
40 * This function returns the status data for each of the Traffic Classes in use.
41 */
42s32 ixgbe_dcb_get_tc_stats_82598(struct ixgbe_hw *hw,
43 struct ixgbe_hw_stats *stats,
44 u8 tc_count)
45{
46 int tc;
47
48 if (tc_count > MAX_TRAFFIC_CLASS)
49 return DCB_ERR_PARAM;
50
51 /* Statistics pertaining to each traffic class */
52 for (tc = 0; tc < tc_count; tc++) {
53 /* Transmitted Packets */
54 stats->qptc[tc] += IXGBE_READ_REG(hw, IXGBE_QPTC(tc));
55 /* Transmitted Bytes */
56 stats->qbtc[tc] += IXGBE_READ_REG(hw, IXGBE_QBTC(tc));
57 /* Received Packets */
58 stats->qprc[tc] += IXGBE_READ_REG(hw, IXGBE_QPRC(tc));
59 /* Received Bytes */
60 stats->qbrc[tc] += IXGBE_READ_REG(hw, IXGBE_QBRC(tc));
61 }
62
63 return 0;
64}
65
66/**
67 * ixgbe_dcb_get_pfc_stats_82598 - Returns CBFC status data
68 * @hw: pointer to hardware structure
69 * @stats: pointer to statistics structure
70 * @tc_count: Number of elements in bwg_array.
71 *
72 * This function returns the CBFC status data for each of the Traffic Classes.
73 */
74s32 ixgbe_dcb_get_pfc_stats_82598(struct ixgbe_hw *hw,
75 struct ixgbe_hw_stats *stats,
76 u8 tc_count)
77{
78 int tc;
79
80 if (tc_count > MAX_TRAFFIC_CLASS)
81 return DCB_ERR_PARAM;
82
83 for (tc = 0; tc < tc_count; tc++) {
84 /* Priority XOFF Transmitted */
85 stats->pxofftxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFTXC(tc));
86 /* Priority XOFF Received */
87 stats->pxoffrxc[tc] += IXGBE_READ_REG(hw, IXGBE_PXOFFRXC(tc));
88 }
89
90 return 0;
91}
92
93/**
94 * ixgbe_dcb_config_packet_buffers_82598 - Configure packet buffers
95 * @hw: pointer to hardware structure
96 * @dcb_config: pointer to ixgbe_dcb_config structure
97 *
98 * Configure packet buffers for DCB mode.
99 */
100s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw,
101 struct ixgbe_dcb_config *dcb_config)
102{
103 s32 ret_val = 0;
104 u32 value = IXGBE_RXPBSIZE_64KB;
105 u8 i = 0;
106
107 /* Setup Rx packet buffer sizes */
108 switch (dcb_config->rx_pba_cfg) {
109 case pba_80_48:
110 /* Setup the first four at 80KB */
111 value = IXGBE_RXPBSIZE_80KB;
112 for (; i < 4; i++)
113 IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
114 /* Setup the last four at 48KB...don't re-init i */
115 value = IXGBE_RXPBSIZE_48KB;
116 /* Fall Through */
117 case pba_equal:
118 default:
119 for (; i < IXGBE_MAX_PACKET_BUFFERS; i++)
120 IXGBE_WRITE_REG(hw, IXGBE_RXPBSIZE(i), value);
121
122 /* Setup Tx packet buffer sizes */
123 for (i = 0; i < IXGBE_MAX_PACKET_BUFFERS; i++) {
124 IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i),
125 IXGBE_TXPBSIZE_40KB);
126 }
127 break;
128 }
129
130 return ret_val;
131}
132
133/**
134 * ixgbe_dcb_config_rx_arbiter_82598 - Config Rx data arbiter
135 * @hw: pointer to hardware structure
136 * @dcb_config: pointer to ixgbe_dcb_config structure
137 *
138 * Configure Rx Data Arbiter and credits for each traffic class.
139 */
140s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw,
141 struct ixgbe_dcb_config *dcb_config)
142{
143 struct tc_bw_alloc *p;
144 u32 reg = 0;
145 u32 credit_refill = 0;
146 u32 credit_max = 0;
147 u8 i = 0;
148
149 reg = IXGBE_READ_REG(hw, IXGBE_RUPPBMR) | IXGBE_RUPPBMR_MQA;
150 IXGBE_WRITE_REG(hw, IXGBE_RUPPBMR, reg);
151
152 reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
153 /* Enable Arbiter */
154 reg &= ~IXGBE_RMCS_ARBDIS;
155 /* Enable Receive Recycle within the BWG */
156 reg |= IXGBE_RMCS_RRM;
157 /* Enable Deficit Fixed Priority arbitration*/
158 reg |= IXGBE_RMCS_DFP;
159
160 IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
161
162 /* Configure traffic class credits and priority */
163 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
164 p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG];
165 credit_refill = p->data_credits_refill;
166 credit_max = p->data_credits_max;
167
168 reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT);
169
170 if (p->prio_type == prio_link)
171 reg |= IXGBE_RT2CR_LSP;
172
173 IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg);
174 }
175
176 reg = IXGBE_READ_REG(hw, IXGBE_RDRXCTL);
177 reg |= IXGBE_RDRXCTL_RDMTS_1_2;
178 reg |= IXGBE_RDRXCTL_MPBEN;
179 reg |= IXGBE_RDRXCTL_MCEN;
180 IXGBE_WRITE_REG(hw, IXGBE_RDRXCTL, reg);
181
182 reg = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
183 /* Make sure there is enough descriptors before arbitration */
184 reg &= ~IXGBE_RXCTRL_DMBYPS;
185 IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg);
186
187 return 0;
188}
189
190/**
191 * ixgbe_dcb_config_tx_desc_arbiter_82598 - Config Tx Desc. arbiter
192 * @hw: pointer to hardware structure
193 * @dcb_config: pointer to ixgbe_dcb_config structure
194 *
195 * Configure Tx Descriptor Arbiter and credits for each traffic class.
196 */
197s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw,
198 struct ixgbe_dcb_config *dcb_config)
199{
200 struct tc_bw_alloc *p;
201 u32 reg, max_credits;
202 u8 i;
203
204 reg = IXGBE_READ_REG(hw, IXGBE_DPMCS);
205
206 /* Enable arbiter */
207 reg &= ~IXGBE_DPMCS_ARBDIS;
208 if (!(dcb_config->round_robin_enable)) {
209 /* Enable DFP and Recycle mode */
210 reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM);
211 }
212 reg |= IXGBE_DPMCS_TSOEF;
213 /* Configure Max TSO packet size 34KB including payload and headers */
214 reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT);
215
216 IXGBE_WRITE_REG(hw, IXGBE_DPMCS, reg);
217
218 /* Configure traffic class credits and priority */
219 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
220 p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
221 max_credits = dcb_config->tc_config[i].desc_credits_max;
222 reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT;
223 reg |= p->data_credits_refill;
224 reg |= (u32)(p->bwg_id) << IXGBE_TDTQ2TCCR_BWG_SHIFT;
225
226 if (p->prio_type == prio_group)
227 reg |= IXGBE_TDTQ2TCCR_GSP;
228
229 if (p->prio_type == prio_link)
230 reg |= IXGBE_TDTQ2TCCR_LSP;
231
232 IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg);
233 }
234
235 return 0;
236}
237
238/**
239 * ixgbe_dcb_config_tx_data_arbiter_82598 - Config Tx data arbiter
240 * @hw: pointer to hardware structure
241 * @dcb_config: pointer to ixgbe_dcb_config structure
242 *
243 * Configure Tx Data Arbiter and credits for each traffic class.
244 */
245s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw,
246 struct ixgbe_dcb_config *dcb_config)
247{
248 struct tc_bw_alloc *p;
249 u32 reg;
250 u8 i;
251
252 reg = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
253 /* Enable Data Plane Arbiter */
254 reg &= ~IXGBE_PDPMCS_ARBDIS;
255 /* Enable DFP and Transmit Recycle Mode */
256 reg |= (IXGBE_PDPMCS_TPPAC | IXGBE_PDPMCS_TRM);
257
258 IXGBE_WRITE_REG(hw, IXGBE_PDPMCS, reg);
259
260 /* Configure traffic class credits and priority */
261 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
262 p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG];
263 reg = p->data_credits_refill;
264 reg |= (u32)(p->data_credits_max) << IXGBE_TDPT2TCCR_MCL_SHIFT;
265 reg |= (u32)(p->bwg_id) << IXGBE_TDPT2TCCR_BWG_SHIFT;
266
267 if (p->prio_type == prio_group)
268 reg |= IXGBE_TDPT2TCCR_GSP;
269
270 if (p->prio_type == prio_link)
271 reg |= IXGBE_TDPT2TCCR_LSP;
272
273 IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg);
274 }
275
276 /* Enable Tx packet buffer division */
277 reg = IXGBE_READ_REG(hw, IXGBE_DTXCTL);
278 reg |= IXGBE_DTXCTL_ENDBUBD;
279 IXGBE_WRITE_REG(hw, IXGBE_DTXCTL, reg);
280
281 return 0;
282}
283
284/**
285 * ixgbe_dcb_config_pfc_82598 - Config priority flow control
286 * @hw: pointer to hardware structure
287 * @dcb_config: pointer to ixgbe_dcb_config structure
288 *
289 * Configure Priority Flow Control for each traffic class.
290 */
291s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw,
292 struct ixgbe_dcb_config *dcb_config)
293{
294 u32 reg, rx_pba_size;
295 u8 i;
296
297 /* Enable Transmit Priority Flow Control */
298 reg = IXGBE_READ_REG(hw, IXGBE_RMCS);
299 reg &= ~IXGBE_RMCS_TFCE_802_3X;
300 /* correct the reporting of our flow control status */
301 hw->fc.type = ixgbe_fc_none;
302 reg |= IXGBE_RMCS_TFCE_PRIORITY;
303 IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg);
304
305 /* Enable Receive Priority Flow Control */
306 reg = IXGBE_READ_REG(hw, IXGBE_FCTRL);
307 reg &= ~IXGBE_FCTRL_RFCE;
308 reg |= IXGBE_FCTRL_RPFCE;
309 IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
310
311 /*
312 * Configure flow control thresholds and enable priority flow control
313 * for each traffic class.
314 */
315 for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
316 if (dcb_config->rx_pba_cfg == pba_equal) {
317 rx_pba_size = IXGBE_RXPBSIZE_64KB;
318 } else {
319 rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB
320 : IXGBE_RXPBSIZE_48KB;
321 }
322
323 reg = ((rx_pba_size >> 5) & 0xFFF0);
324 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
325 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
326 reg |= IXGBE_FCRTL_XONE;
327
328 IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg);
329
330 reg = ((rx_pba_size >> 2) & 0xFFF0);
331 if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx ||
332 dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full)
333 reg |= IXGBE_FCRTH_FCEN;
334
335 IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
336 }
337
338 /* Configure pause time */
339 for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++)
340 IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800);
341
342 /* Configure flow control refresh threshold value */
343 IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400);
344
345 return 0;
346}
347
348/**
349 * ixgbe_dcb_config_tc_stats_82598 - Configure traffic class statistics
350 * @hw: pointer to hardware structure
351 *
352 * Configure queue statistics registers, all queues belonging to same traffic
353 * class uses a single set of queue statistics counters.
354 */
355s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw)
356{
357 u32 reg = 0;
358 u8 i = 0;
359 u8 j = 0;
360
361 /* Receive Queues stats setting - 8 queues per statistics reg */
362 for (i = 0, j = 0; i < 15 && j < 8; i = i + 2, j++) {
363 reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i));
364 reg |= ((0x1010101) * j);
365 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i), reg);
366 reg = IXGBE_READ_REG(hw, IXGBE_RQSMR(i + 1));
367 reg |= ((0x1010101) * j);
368 IXGBE_WRITE_REG(hw, IXGBE_RQSMR(i + 1), reg);
369 }
370 /* Transmit Queues stats setting - 4 queues per statistics reg */
371 for (i = 0; i < 8; i++) {
372 reg = IXGBE_READ_REG(hw, IXGBE_TQSMR(i));
373 reg |= ((0x1010101) * i);
374 IXGBE_WRITE_REG(hw, IXGBE_TQSMR(i), reg);
375 }
376
377 return 0;
378}
379
380/**
381 * ixgbe_dcb_hw_config_82598 - Config and enable DCB
382 * @hw: pointer to hardware structure
383 * @dcb_config: pointer to ixgbe_dcb_config structure
384 *
385 * Configure dcb settings and enable dcb mode.
386 */
387s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw,
388 struct ixgbe_dcb_config *dcb_config)
389{
390 ixgbe_dcb_config_packet_buffers_82598(hw, dcb_config);
391 ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config);
392 ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config);
393 ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config);
394 ixgbe_dcb_config_pfc_82598(hw, dcb_config);
395 ixgbe_dcb_config_tc_stats_82598(hw);
396
397 return 0;
398}