diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_dcb_82598.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb_82598.c | 203 |
1 files changed, 70 insertions, 133 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ixgbe/ixgbe_dcb_82598.c index f0e9279d4669..771d01a60d06 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_82598.c +++ b/drivers/net/ixgbe/ixgbe_dcb_82598.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | Intel 10 Gigabit PCI Express Linux driver | 3 | Intel 10 Gigabit PCI Express Linux driver |
4 | Copyright(c) 1999 - 2010 Intel Corporation. | 4 | Copyright(c) 1999 - 2011 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 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, | 7 | under the terms and conditions of the GNU General Public License, |
@@ -32,80 +32,20 @@ | |||
32 | #include "ixgbe_dcb_82598.h" | 32 | #include "ixgbe_dcb_82598.h" |
33 | 33 | ||
34 | /** | 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 | */ | ||
42 | s32 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 | */ | ||
74 | s32 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 | 35 | * ixgbe_dcb_config_packet_buffers_82598 - Configure packet buffers |
95 | * @hw: pointer to hardware structure | 36 | * @hw: pointer to hardware structure |
96 | * @dcb_config: pointer to ixgbe_dcb_config structure | 37 | * @dcb_config: pointer to ixgbe_dcb_config structure |
97 | * | 38 | * |
98 | * Configure packet buffers for DCB mode. | 39 | * Configure packet buffers for DCB mode. |
99 | */ | 40 | */ |
100 | static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw, | 41 | static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw, u8 rx_pba) |
101 | struct ixgbe_dcb_config *dcb_config) | ||
102 | { | 42 | { |
103 | s32 ret_val = 0; | 43 | s32 ret_val = 0; |
104 | u32 value = IXGBE_RXPBSIZE_64KB; | 44 | u32 value = IXGBE_RXPBSIZE_64KB; |
105 | u8 i = 0; | 45 | u8 i = 0; |
106 | 46 | ||
107 | /* Setup Rx packet buffer sizes */ | 47 | /* Setup Rx packet buffer sizes */ |
108 | switch (dcb_config->rx_pba_cfg) { | 48 | switch (rx_pba) { |
109 | case pba_80_48: | 49 | case pba_80_48: |
110 | /* Setup the first four at 80KB */ | 50 | /* Setup the first four at 80KB */ |
111 | value = IXGBE_RXPBSIZE_80KB; | 51 | value = IXGBE_RXPBSIZE_80KB; |
@@ -138,9 +78,10 @@ static s32 ixgbe_dcb_config_packet_buffers_82598(struct ixgbe_hw *hw, | |||
138 | * Configure Rx Data Arbiter and credits for each traffic class. | 78 | * Configure Rx Data Arbiter and credits for each traffic class. |
139 | */ | 79 | */ |
140 | s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, | 80 | s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, |
141 | struct ixgbe_dcb_config *dcb_config) | 81 | u16 *refill, |
82 | u16 *max, | ||
83 | u8 *prio_type) | ||
142 | { | 84 | { |
143 | struct tc_bw_alloc *p; | ||
144 | u32 reg = 0; | 85 | u32 reg = 0; |
145 | u32 credit_refill = 0; | 86 | u32 credit_refill = 0; |
146 | u32 credit_max = 0; | 87 | u32 credit_max = 0; |
@@ -161,13 +102,12 @@ s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, | |||
161 | 102 | ||
162 | /* Configure traffic class credits and priority */ | 103 | /* Configure traffic class credits and priority */ |
163 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | 104 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { |
164 | p = &dcb_config->tc_config[i].path[DCB_RX_CONFIG]; | 105 | credit_refill = refill[i]; |
165 | credit_refill = p->data_credits_refill; | 106 | credit_max = max[i]; |
166 | credit_max = p->data_credits_max; | ||
167 | 107 | ||
168 | reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT); | 108 | reg = credit_refill | (credit_max << IXGBE_RT2CR_MCL_SHIFT); |
169 | 109 | ||
170 | if (p->prio_type == prio_link) | 110 | if (prio_type[i] == prio_link) |
171 | reg |= IXGBE_RT2CR_LSP; | 111 | reg |= IXGBE_RT2CR_LSP; |
172 | 112 | ||
173 | IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg); | 113 | IXGBE_WRITE_REG(hw, IXGBE_RT2CR(i), reg); |
@@ -195,9 +135,11 @@ s32 ixgbe_dcb_config_rx_arbiter_82598(struct ixgbe_hw *hw, | |||
195 | * Configure Tx Descriptor Arbiter and credits for each traffic class. | 135 | * Configure Tx Descriptor Arbiter and credits for each traffic class. |
196 | */ | 136 | */ |
197 | s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, | 137 | s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, |
198 | struct ixgbe_dcb_config *dcb_config) | 138 | u16 *refill, |
139 | u16 *max, | ||
140 | u8 *bwg_id, | ||
141 | u8 *prio_type) | ||
199 | { | 142 | { |
200 | struct tc_bw_alloc *p; | ||
201 | u32 reg, max_credits; | 143 | u32 reg, max_credits; |
202 | u8 i; | 144 | u8 i; |
203 | 145 | ||
@@ -205,10 +147,8 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, | |||
205 | 147 | ||
206 | /* Enable arbiter */ | 148 | /* Enable arbiter */ |
207 | reg &= ~IXGBE_DPMCS_ARBDIS; | 149 | reg &= ~IXGBE_DPMCS_ARBDIS; |
208 | if (!(dcb_config->round_robin_enable)) { | 150 | /* Enable DFP and Recycle mode */ |
209 | /* Enable DFP and Recycle mode */ | 151 | reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM); |
210 | reg |= (IXGBE_DPMCS_TDPAC | IXGBE_DPMCS_TRM); | ||
211 | } | ||
212 | reg |= IXGBE_DPMCS_TSOEF; | 152 | reg |= IXGBE_DPMCS_TSOEF; |
213 | /* Configure Max TSO packet size 34KB including payload and headers */ | 153 | /* Configure Max TSO packet size 34KB including payload and headers */ |
214 | reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT); | 154 | reg |= (0x4 << IXGBE_DPMCS_MTSOS_SHIFT); |
@@ -217,16 +157,15 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, | |||
217 | 157 | ||
218 | /* Configure traffic class credits and priority */ | 158 | /* Configure traffic class credits and priority */ |
219 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | 159 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { |
220 | p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG]; | 160 | max_credits = max[i]; |
221 | max_credits = dcb_config->tc_config[i].desc_credits_max; | ||
222 | reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT; | 161 | reg = max_credits << IXGBE_TDTQ2TCCR_MCL_SHIFT; |
223 | reg |= p->data_credits_refill; | 162 | reg |= refill[i]; |
224 | reg |= (u32)(p->bwg_id) << IXGBE_TDTQ2TCCR_BWG_SHIFT; | 163 | reg |= (u32)(bwg_id[i]) << IXGBE_TDTQ2TCCR_BWG_SHIFT; |
225 | 164 | ||
226 | if (p->prio_type == prio_group) | 165 | if (prio_type[i] == prio_group) |
227 | reg |= IXGBE_TDTQ2TCCR_GSP; | 166 | reg |= IXGBE_TDTQ2TCCR_GSP; |
228 | 167 | ||
229 | if (p->prio_type == prio_link) | 168 | if (prio_type[i] == prio_link) |
230 | reg |= IXGBE_TDTQ2TCCR_LSP; | 169 | reg |= IXGBE_TDTQ2TCCR_LSP; |
231 | 170 | ||
232 | IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg); | 171 | IXGBE_WRITE_REG(hw, IXGBE_TDTQ2TCCR(i), reg); |
@@ -243,9 +182,11 @@ s32 ixgbe_dcb_config_tx_desc_arbiter_82598(struct ixgbe_hw *hw, | |||
243 | * Configure Tx Data Arbiter and credits for each traffic class. | 182 | * Configure Tx Data Arbiter and credits for each traffic class. |
244 | */ | 183 | */ |
245 | s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, | 184 | s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, |
246 | struct ixgbe_dcb_config *dcb_config) | 185 | u16 *refill, |
186 | u16 *max, | ||
187 | u8 *bwg_id, | ||
188 | u8 *prio_type) | ||
247 | { | 189 | { |
248 | struct tc_bw_alloc *p; | ||
249 | u32 reg; | 190 | u32 reg; |
250 | u8 i; | 191 | u8 i; |
251 | 192 | ||
@@ -259,15 +200,14 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, | |||
259 | 200 | ||
260 | /* Configure traffic class credits and priority */ | 201 | /* Configure traffic class credits and priority */ |
261 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | 202 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { |
262 | p = &dcb_config->tc_config[i].path[DCB_TX_CONFIG]; | 203 | reg = refill[i]; |
263 | reg = p->data_credits_refill; | 204 | reg |= (u32)(max[i]) << IXGBE_TDPT2TCCR_MCL_SHIFT; |
264 | reg |= (u32)(p->data_credits_max) << IXGBE_TDPT2TCCR_MCL_SHIFT; | 205 | reg |= (u32)(bwg_id[i]) << IXGBE_TDPT2TCCR_BWG_SHIFT; |
265 | reg |= (u32)(p->bwg_id) << IXGBE_TDPT2TCCR_BWG_SHIFT; | ||
266 | 206 | ||
267 | if (p->prio_type == prio_group) | 207 | if (prio_type[i] == prio_group) |
268 | reg |= IXGBE_TDPT2TCCR_GSP; | 208 | reg |= IXGBE_TDPT2TCCR_GSP; |
269 | 209 | ||
270 | if (p->prio_type == prio_link) | 210 | if (prio_type[i] == prio_link) |
271 | reg |= IXGBE_TDPT2TCCR_LSP; | 211 | reg |= IXGBE_TDPT2TCCR_LSP; |
272 | 212 | ||
273 | IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg); | 213 | IXGBE_WRITE_REG(hw, IXGBE_TDPT2TCCR(i), reg); |
@@ -288,63 +228,57 @@ s32 ixgbe_dcb_config_tx_data_arbiter_82598(struct ixgbe_hw *hw, | |||
288 | * | 228 | * |
289 | * Configure Priority Flow Control for each traffic class. | 229 | * Configure Priority Flow Control for each traffic class. |
290 | */ | 230 | */ |
291 | s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, | 231 | s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en) |
292 | struct ixgbe_dcb_config *dcb_config) | ||
293 | { | 232 | { |
294 | u32 reg, rx_pba_size; | 233 | u32 reg, rx_pba_size; |
295 | u8 i; | 234 | u8 i; |
296 | 235 | ||
297 | if (!dcb_config->pfc_mode_enable) | 236 | if (pfc_en) { |
298 | goto out; | 237 | /* Enable Transmit Priority Flow Control */ |
299 | 238 | reg = IXGBE_READ_REG(hw, IXGBE_RMCS); | |
300 | /* Enable Transmit Priority Flow Control */ | 239 | reg &= ~IXGBE_RMCS_TFCE_802_3X; |
301 | reg = IXGBE_READ_REG(hw, IXGBE_RMCS); | 240 | /* correct the reporting of our flow control status */ |
302 | reg &= ~IXGBE_RMCS_TFCE_802_3X; | 241 | reg |= IXGBE_RMCS_TFCE_PRIORITY; |
303 | /* correct the reporting of our flow control status */ | 242 | IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); |
304 | reg |= IXGBE_RMCS_TFCE_PRIORITY; | 243 | |
305 | IXGBE_WRITE_REG(hw, IXGBE_RMCS, reg); | 244 | /* Enable Receive Priority Flow Control */ |
306 | 245 | reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); | |
307 | /* Enable Receive Priority Flow Control */ | 246 | reg &= ~IXGBE_FCTRL_RFCE; |
308 | reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); | 247 | reg |= IXGBE_FCTRL_RPFCE; |
309 | reg &= ~IXGBE_FCTRL_RFCE; | 248 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); |
310 | reg |= IXGBE_FCTRL_RPFCE; | 249 | |
311 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg); | 250 | /* Configure pause time */ |
251 | for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++) | ||
252 | IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800); | ||
253 | |||
254 | /* Configure flow control refresh threshold value */ | ||
255 | IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400); | ||
256 | } | ||
312 | 257 | ||
313 | /* | 258 | /* |
314 | * Configure flow control thresholds and enable priority flow control | 259 | * Configure flow control thresholds and enable priority flow control |
315 | * for each traffic class. | 260 | * for each traffic class. |
316 | */ | 261 | */ |
317 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { | 262 | for (i = 0; i < MAX_TRAFFIC_CLASS; i++) { |
318 | if (dcb_config->rx_pba_cfg == pba_equal) { | 263 | int enabled = pfc_en & (1 << i); |
319 | rx_pba_size = IXGBE_RXPBSIZE_64KB; | 264 | rx_pba_size = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)); |
320 | } else { | 265 | rx_pba_size >>= IXGBE_RXPBSIZE_SHIFT; |
321 | rx_pba_size = (i < 4) ? IXGBE_RXPBSIZE_80KB | 266 | reg = (rx_pba_size - hw->fc.low_water) << 10; |
322 | : IXGBE_RXPBSIZE_48KB; | ||
323 | } | ||
324 | 267 | ||
325 | reg = ((rx_pba_size >> 5) & 0xFFF0); | 268 | if (enabled == pfc_enabled_tx || |
326 | if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx || | 269 | enabled == pfc_enabled_full) |
327 | dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full) | ||
328 | reg |= IXGBE_FCRTL_XONE; | 270 | reg |= IXGBE_FCRTL_XONE; |
329 | 271 | ||
330 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg); | 272 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), reg); |
331 | 273 | ||
332 | reg = ((rx_pba_size >> 2) & 0xFFF0); | 274 | reg = (rx_pba_size - hw->fc.high_water) << 10; |
333 | if (dcb_config->tc_config[i].dcb_pfc == pfc_enabled_tx || | 275 | if (enabled == pfc_enabled_tx || |
334 | dcb_config->tc_config[i].dcb_pfc == pfc_enabled_full) | 276 | enabled == pfc_enabled_full) |
335 | reg |= IXGBE_FCRTH_FCEN; | 277 | reg |= IXGBE_FCRTH_FCEN; |
336 | 278 | ||
337 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); | 279 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg); |
338 | } | 280 | } |
339 | 281 | ||
340 | /* Configure pause time */ | ||
341 | for (i = 0; i < (MAX_TRAFFIC_CLASS >> 1); i++) | ||
342 | IXGBE_WRITE_REG(hw, IXGBE_FCTTV(i), 0x68006800); | ||
343 | |||
344 | /* Configure flow control refresh threshold value */ | ||
345 | IXGBE_WRITE_REG(hw, IXGBE_FCRTV, 0x3400); | ||
346 | |||
347 | out: | ||
348 | return 0; | 282 | return 0; |
349 | } | 283 | } |
350 | 284 | ||
@@ -355,7 +289,7 @@ out: | |||
355 | * Configure queue statistics registers, all queues belonging to same traffic | 289 | * Configure queue statistics registers, all queues belonging to same traffic |
356 | * class uses a single set of queue statistics counters. | 290 | * class uses a single set of queue statistics counters. |
357 | */ | 291 | */ |
358 | s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) | 292 | static s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) |
359 | { | 293 | { |
360 | u32 reg = 0; | 294 | u32 reg = 0; |
361 | u8 i = 0; | 295 | u8 i = 0; |
@@ -388,13 +322,16 @@ s32 ixgbe_dcb_config_tc_stats_82598(struct ixgbe_hw *hw) | |||
388 | * Configure dcb settings and enable dcb mode. | 322 | * Configure dcb settings and enable dcb mode. |
389 | */ | 323 | */ |
390 | s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, | 324 | s32 ixgbe_dcb_hw_config_82598(struct ixgbe_hw *hw, |
391 | struct ixgbe_dcb_config *dcb_config) | 325 | u8 rx_pba, u8 pfc_en, u16 *refill, |
326 | u16 *max, u8 *bwg_id, u8 *prio_type) | ||
392 | { | 327 | { |
393 | ixgbe_dcb_config_packet_buffers_82598(hw, dcb_config); | 328 | ixgbe_dcb_config_packet_buffers_82598(hw, rx_pba); |
394 | ixgbe_dcb_config_rx_arbiter_82598(hw, dcb_config); | 329 | ixgbe_dcb_config_rx_arbiter_82598(hw, refill, max, prio_type); |
395 | ixgbe_dcb_config_tx_desc_arbiter_82598(hw, dcb_config); | 330 | ixgbe_dcb_config_tx_desc_arbiter_82598(hw, refill, max, |
396 | ixgbe_dcb_config_tx_data_arbiter_82598(hw, dcb_config); | 331 | bwg_id, prio_type); |
397 | ixgbe_dcb_config_pfc_82598(hw, dcb_config); | 332 | ixgbe_dcb_config_tx_data_arbiter_82598(hw, refill, max, |
333 | bwg_id, prio_type); | ||
334 | ixgbe_dcb_config_pfc_82598(hw, pfc_en); | ||
398 | ixgbe_dcb_config_tc_stats_82598(hw); | 335 | ixgbe_dcb_config_tc_stats_82598(hw); |
399 | 336 | ||
400 | return 0; | 337 | return 0; |