diff options
Diffstat (limited to 'drivers/net/ixgbe/ixgbe_82598.c')
-rw-r--r-- | drivers/net/ixgbe/ixgbe_82598.c | 177 |
1 files changed, 113 insertions, 64 deletions
diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c index f726a14d1a73..525bd87fea56 100644 --- a/drivers/net/ixgbe/ixgbe_82598.c +++ b/drivers/net/ixgbe/ixgbe_82598.c | |||
@@ -255,104 +255,75 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw) | |||
255 | } | 255 | } |
256 | 256 | ||
257 | /** | 257 | /** |
258 | * ixgbe_setup_fc_82598 - Configure flow control settings | 258 | * ixgbe_fc_enable_82598 - Enable flow control |
259 | * @hw: pointer to hardware structure | 259 | * @hw: pointer to hardware structure |
260 | * @packetbuf_num: packet buffer number (0-7) | 260 | * @packetbuf_num: packet buffer number (0-7) |
261 | * | 261 | * |
262 | * Configures the flow control settings based on SW configuration. This | 262 | * Enable flow control according to the current settings. |
263 | * function is used for 802.3x flow control configuration only. | ||
264 | **/ | 263 | **/ |
265 | static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num) | 264 | static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw, s32 packetbuf_num) |
266 | { | 265 | { |
267 | u32 frctl_reg; | 266 | s32 ret_val = 0; |
267 | u32 fctrl_reg; | ||
268 | u32 rmcs_reg; | 268 | u32 rmcs_reg; |
269 | u32 reg; | ||
269 | 270 | ||
270 | if (packetbuf_num < 0 || packetbuf_num > 7) { | 271 | fctrl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); |
271 | hw_dbg(hw, "Invalid packet buffer number [%d], expected range is" | 272 | fctrl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE); |
272 | " 0-7\n", packetbuf_num); | ||
273 | } | ||
274 | |||
275 | frctl_reg = IXGBE_READ_REG(hw, IXGBE_FCTRL); | ||
276 | frctl_reg &= ~(IXGBE_FCTRL_RFCE | IXGBE_FCTRL_RPFCE); | ||
277 | 273 | ||
278 | rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS); | 274 | rmcs_reg = IXGBE_READ_REG(hw, IXGBE_RMCS); |
279 | rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X); | 275 | rmcs_reg &= ~(IXGBE_RMCS_TFCE_PRIORITY | IXGBE_RMCS_TFCE_802_3X); |
280 | 276 | ||
281 | /* | 277 | /* |
282 | * 10 gig parts do not have a word in the EEPROM to determine the | 278 | * The possible values of fc.current_mode are: |
283 | * default flow control setting, so we explicitly set it to full. | ||
284 | */ | ||
285 | if (hw->fc.type == ixgbe_fc_default) | ||
286 | hw->fc.type = ixgbe_fc_full; | ||
287 | |||
288 | /* | ||
289 | * We want to save off the original Flow Control configuration just in | ||
290 | * case we get disconnected and then reconnected into a different hub | ||
291 | * or switch with different Flow Control capabilities. | ||
292 | */ | ||
293 | hw->fc.original_type = hw->fc.type; | ||
294 | |||
295 | /* | ||
296 | * The possible values of the "flow_control" parameter are: | ||
297 | * 0: Flow control is completely disabled | 279 | * 0: Flow control is completely disabled |
298 | * 1: Rx flow control is enabled (we can receive pause frames but not | 280 | * 1: Rx flow control is enabled (we can receive pause frames, |
299 | * send pause frames). | 281 | * but not send pause frames). |
300 | * 2: Tx flow control is enabled (we can send pause frames but we do not | 282 | * 2: Tx flow control is enabled (we can send pause frames but |
301 | * support receiving pause frames) | 283 | * we do not support receiving pause frames). |
302 | * 3: Both Rx and Tx flow control (symmetric) are enabled. | 284 | * 3: Both Rx and Tx flow control (symmetric) are enabled. |
303 | * other: Invalid. | 285 | * other: Invalid. |
304 | */ | 286 | */ |
305 | switch (hw->fc.type) { | 287 | switch (hw->fc.current_mode) { |
306 | case ixgbe_fc_none: | 288 | case ixgbe_fc_none: |
289 | /* Flow control completely disabled by software override. */ | ||
307 | break; | 290 | break; |
308 | case ixgbe_fc_rx_pause: | 291 | case ixgbe_fc_rx_pause: |
309 | /* | 292 | /* |
310 | * Rx Flow control is enabled, | 293 | * Rx Flow control is enabled and Tx Flow control is |
311 | * and Tx Flow control is disabled. | 294 | * disabled by software override. Since there really |
295 | * isn't a way to advertise that we are capable of RX | ||
296 | * Pause ONLY, we will advertise that we support both | ||
297 | * symmetric and asymmetric Rx PAUSE. Later, we will | ||
298 | * disable the adapter's ability to send PAUSE frames. | ||
312 | */ | 299 | */ |
313 | frctl_reg |= IXGBE_FCTRL_RFCE; | 300 | fctrl_reg |= IXGBE_FCTRL_RFCE; |
314 | break; | 301 | break; |
315 | case ixgbe_fc_tx_pause: | 302 | case ixgbe_fc_tx_pause: |
316 | /* | 303 | /* |
317 | * Tx Flow control is enabled, and Rx Flow control is disabled, | 304 | * Tx Flow control is enabled, and Rx Flow control is |
318 | * by a software over-ride. | 305 | * disabled by software override. |
319 | */ | 306 | */ |
320 | rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; | 307 | rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; |
321 | break; | 308 | break; |
322 | case ixgbe_fc_full: | 309 | case ixgbe_fc_full: |
323 | /* | 310 | /* Flow control (both Rx and Tx) is enabled by SW override. */ |
324 | * Flow control (both Rx and Tx) is enabled by a software | 311 | fctrl_reg |= IXGBE_FCTRL_RFCE; |
325 | * over-ride. | ||
326 | */ | ||
327 | frctl_reg |= IXGBE_FCTRL_RFCE; | ||
328 | rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; | 312 | rmcs_reg |= IXGBE_RMCS_TFCE_802_3X; |
329 | break; | 313 | break; |
330 | default: | 314 | default: |
331 | /* We should never get here. The value should be 0-3. */ | ||
332 | hw_dbg(hw, "Flow control param set incorrectly\n"); | 315 | hw_dbg(hw, "Flow control param set incorrectly\n"); |
316 | ret_val = -IXGBE_ERR_CONFIG; | ||
317 | goto out; | ||
333 | break; | 318 | break; |
334 | } | 319 | } |
335 | 320 | ||
336 | /* Enable 802.3x based flow control settings. */ | 321 | /* Enable 802.3x based flow control settings. */ |
337 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, frctl_reg); | 322 | IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg); |
338 | IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); | 323 | IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg); |
339 | 324 | ||
340 | /* | 325 | /* Set up and enable Rx high/low water mark thresholds, enable XON. */ |
341 | * Check for invalid software configuration, zeros are completely | 326 | if (hw->fc.current_mode & ixgbe_fc_tx_pause) { |
342 | * invalid for all parameters used past this point, and if we enable | ||
343 | * flow control with zero water marks, we blast flow control packets. | ||
344 | */ | ||
345 | if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { | ||
346 | hw_dbg(hw, "Flow control structure initialized incorrectly\n"); | ||
347 | return IXGBE_ERR_INVALID_LINK_SETTINGS; | ||
348 | } | ||
349 | |||
350 | /* | ||
351 | * We need to set up the Receive Threshold high and low water | ||
352 | * marks as well as (optionally) enabling the transmission of | ||
353 | * XON frames. | ||
354 | */ | ||
355 | if (hw->fc.type & ixgbe_fc_tx_pause) { | ||
356 | if (hw->fc.send_xon) { | 327 | if (hw->fc.send_xon) { |
357 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), | 328 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), |
358 | (hw->fc.low_water | IXGBE_FCRTL_XONE)); | 329 | (hw->fc.low_water | IXGBE_FCRTL_XONE)); |
@@ -360,14 +331,93 @@ static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num) | |||
360 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), | 331 | IXGBE_WRITE_REG(hw, IXGBE_FCRTL(packetbuf_num), |
361 | hw->fc.low_water); | 332 | hw->fc.low_water); |
362 | } | 333 | } |
334 | |||
363 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), | 335 | IXGBE_WRITE_REG(hw, IXGBE_FCRTH(packetbuf_num), |
364 | (hw->fc.high_water)|IXGBE_FCRTH_FCEN); | 336 | (hw->fc.high_water | IXGBE_FCRTH_FCEN)); |
365 | } | 337 | } |
366 | 338 | ||
367 | IXGBE_WRITE_REG(hw, IXGBE_FCTTV(0), hw->fc.pause_time); | 339 | /* Configure pause time (2 TCs per register) */ |
340 | reg = IXGBE_READ_REG(hw, IXGBE_FCTTV(packetbuf_num)); | ||
341 | if ((packetbuf_num & 1) == 0) | ||
342 | reg = (reg & 0xFFFF0000) | hw->fc.pause_time; | ||
343 | else | ||
344 | reg = (reg & 0x0000FFFF) | (hw->fc.pause_time << 16); | ||
345 | IXGBE_WRITE_REG(hw, IXGBE_FCTTV(packetbuf_num / 2), reg); | ||
346 | |||
368 | IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); | 347 | IXGBE_WRITE_REG(hw, IXGBE_FCRTV, (hw->fc.pause_time >> 1)); |
369 | 348 | ||
370 | return 0; | 349 | out: |
350 | return ret_val; | ||
351 | } | ||
352 | |||
353 | /** | ||
354 | * ixgbe_setup_fc_82598 - Configure flow control settings | ||
355 | * @hw: pointer to hardware structure | ||
356 | * @packetbuf_num: packet buffer number (0-7) | ||
357 | * | ||
358 | * Configures the flow control settings based on SW configuration. This | ||
359 | * function is used for 802.3x flow control configuration only. | ||
360 | **/ | ||
361 | static s32 ixgbe_setup_fc_82598(struct ixgbe_hw *hw, s32 packetbuf_num) | ||
362 | { | ||
363 | s32 ret_val = 0; | ||
364 | ixgbe_link_speed speed; | ||
365 | bool link_up; | ||
366 | |||
367 | /* Validate the packetbuf configuration */ | ||
368 | if (packetbuf_num < 0 || packetbuf_num > 7) { | ||
369 | hw_dbg(hw, "Invalid packet buffer number [%d], expected range is" | ||
370 | " 0-7\n", packetbuf_num); | ||
371 | ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; | ||
372 | goto out; | ||
373 | } | ||
374 | |||
375 | /* | ||
376 | * Validate the water mark configuration. Zero water marks are invalid | ||
377 | * because it causes the controller to just blast out fc packets. | ||
378 | */ | ||
379 | if (!hw->fc.low_water || !hw->fc.high_water || !hw->fc.pause_time) { | ||
380 | hw_dbg(hw, "Invalid water mark configuration\n"); | ||
381 | ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; | ||
382 | goto out; | ||
383 | } | ||
384 | |||
385 | /* | ||
386 | * Validate the requested mode. Strict IEEE mode does not allow | ||
387 | * ixgbe_fc_rx_pause because it will cause testing anomalies. | ||
388 | */ | ||
389 | if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) { | ||
390 | hw_dbg(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n"); | ||
391 | ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS; | ||
392 | goto out; | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | * 10gig parts do not have a word in the EEPROM to determine the | ||
397 | * default flow control setting, so we explicitly set it to full. | ||
398 | */ | ||
399 | if (hw->fc.requested_mode == ixgbe_fc_default) | ||
400 | hw->fc.requested_mode = ixgbe_fc_full; | ||
401 | |||
402 | /* | ||
403 | * Save off the requested flow control mode for use later. Depending | ||
404 | * on the link partner's capabilities, we may or may not use this mode. | ||
405 | */ | ||
406 | |||
407 | hw->fc.current_mode = hw->fc.requested_mode; | ||
408 | |||
409 | /* Decide whether to use autoneg or not. */ | ||
410 | hw->mac.ops.check_link(hw, &speed, &link_up, false); | ||
411 | if (hw->phy.multispeed_fiber && (speed == IXGBE_LINK_SPEED_1GB_FULL)) | ||
412 | ret_val = ixgbe_fc_autoneg(hw); | ||
413 | |||
414 | if (ret_val) | ||
415 | goto out; | ||
416 | |||
417 | ret_val = ixgbe_fc_enable_82598(hw, packetbuf_num); | ||
418 | |||
419 | out: | ||
420 | return ret_val; | ||
371 | } | 421 | } |
372 | 422 | ||
373 | /** | 423 | /** |
@@ -414,7 +464,6 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw) | |||
414 | * case we get disconnected and then reconnected into a different hub | 464 | * case we get disconnected and then reconnected into a different hub |
415 | * or switch with different Flow Control capabilities. | 465 | * or switch with different Flow Control capabilities. |
416 | */ | 466 | */ |
417 | hw->fc.original_type = hw->fc.type; | ||
418 | ixgbe_setup_fc_82598(hw, 0); | 467 | ixgbe_setup_fc_82598(hw, 0); |
419 | 468 | ||
420 | /* Add delay to filter out noises during initial link setup */ | 469 | /* Add delay to filter out noises during initial link setup */ |