aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Fastabend <john.r.fastabend@intel.com>2011-01-31 21:10:20 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-02-11 11:43:14 -0500
commit53bb9f80b3be855a369a8a580621cda8e3bbaae2 (patch)
tree2f84cce0899166fa395ddb21d3621bd023bf274d
parent6b78bb1d46cfae6502826ec31a6e9f7222ab3cb4 (diff)
ixgbe: DCB, only reprogram HW if the FCoE priority is changed
If the FCoE priority is not changing do not set the RESET and APP_UPCHG bits. This causes unneeded HW resets and which can cause unneeded LLDP frames and negotiations. The current check is not sufficient because the FCoE priority can change twice during a negotiation which results in the bits being set. This occurs when the switch changes the priority or when the link is reset with switches that do not include the APP priority until after PFC has been negotiated. This results in set_app being called with the local APP priority. Then the negotiation completes and set_app is called again with the peer APP priority. The check fails so the device is reset and the above occurs again resulting in an endless loop of resets. By only resetting the device if the APP priority has really changed we short circuit the loop. Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Tested-by: Ross Brattain <ross.b.brattain@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
-rw-r--r--drivers/net/ixgbe/ixgbe_dcb_nl.c38
1 files changed, 26 insertions, 12 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c
index bf566e8a455e..48058359ba69 100644
--- a/drivers/net/ixgbe/ixgbe_dcb_nl.c
+++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c
@@ -353,6 +353,7 @@ static void ixgbe_dcbnl_get_pfc_cfg(struct net_device *netdev, int priority,
353static u8 ixgbe_dcbnl_set_all(struct net_device *netdev) 353static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
354{ 354{
355 struct ixgbe_adapter *adapter = netdev_priv(netdev); 355 struct ixgbe_adapter *adapter = netdev_priv(netdev);
356 bool do_reset;
356 int ret; 357 int ret;
357 358
358 if (!adapter->dcb_set_bitmap) 359 if (!adapter->dcb_set_bitmap)
@@ -368,7 +369,9 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
368 * Only take down the adapter if the configuration change 369 * Only take down the adapter if the configuration change
369 * requires a reset. 370 * requires a reset.
370 */ 371 */
371 if (adapter->dcb_set_bitmap & BIT_RESETLINK) { 372 do_reset = adapter->dcb_set_bitmap & (BIT_RESETLINK | BIT_APP_UPCHG);
373
374 if (do_reset) {
372 while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state)) 375 while (test_and_set_bit(__IXGBE_RESETTING, &adapter->state))
373 msleep(1); 376 msleep(1);
374 377
@@ -408,7 +411,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
408 } 411 }
409 } 412 }
410 413
411 if (adapter->dcb_set_bitmap & BIT_RESETLINK) { 414 if (do_reset) {
412 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) { 415 if (adapter->dcb_set_bitmap & BIT_APP_UPCHG) {
413 ixgbe_init_interrupt_scheme(adapter); 416 ixgbe_init_interrupt_scheme(adapter);
414 if (netif_running(netdev)) 417 if (netif_running(netdev))
@@ -430,7 +433,7 @@ static u8 ixgbe_dcbnl_set_all(struct net_device *netdev)
430 if (adapter->dcb_cfg.pfc_mode_enable) 433 if (adapter->dcb_cfg.pfc_mode_enable)
431 adapter->hw.fc.current_mode = ixgbe_fc_pfc; 434 adapter->hw.fc.current_mode = ixgbe_fc_pfc;
432 435
433 if (adapter->dcb_set_bitmap & BIT_RESETLINK) 436 if (do_reset)
434 clear_bit(__IXGBE_RESETTING, &adapter->state); 437 clear_bit(__IXGBE_RESETTING, &adapter->state);
435 adapter->dcb_set_bitmap = 0x00; 438 adapter->dcb_set_bitmap = 0x00;
436 return ret; 439 return ret;
@@ -568,18 +571,29 @@ static u8 ixgbe_dcbnl_setapp(struct net_device *netdev,
568 case DCB_APP_IDTYPE_ETHTYPE: 571 case DCB_APP_IDTYPE_ETHTYPE:
569#ifdef IXGBE_FCOE 572#ifdef IXGBE_FCOE
570 if (id == ETH_P_FCOE) { 573 if (id == ETH_P_FCOE) {
571 u8 tc; 574 u8 old_tc;
572 struct ixgbe_adapter *adapter; 575 struct ixgbe_adapter *adapter = netdev_priv(netdev);
573 576
574 adapter = netdev_priv(netdev); 577 /* Get current programmed tc */
575 tc = adapter->fcoe.tc; 578 old_tc = adapter->fcoe.tc;
576 rval = ixgbe_fcoe_setapp(adapter, up); 579 rval = ixgbe_fcoe_setapp(adapter, up);
577 if ((!rval) && (tc != adapter->fcoe.tc) && 580
578 (adapter->flags & IXGBE_FLAG_DCB_ENABLED) && 581 if (rval ||
579 (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) { 582 !(adapter->flags & IXGBE_FLAG_DCB_ENABLED) ||
583 !(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
584 break;
585
586 /* The FCoE application priority may be changed multiple
587 * times in quick sucession with switches that build up
588 * TLVs. To avoid creating uneeded device resets this
589 * checks the actual HW configuration and clears
590 * BIT_APP_UPCHG if a HW configuration change is not
591 * need
592 */
593 if (old_tc == adapter->fcoe.tc)
594 adapter->dcb_set_bitmap &= ~BIT_APP_UPCHG;
595 else
580 adapter->dcb_set_bitmap |= BIT_APP_UPCHG; 596 adapter->dcb_set_bitmap |= BIT_APP_UPCHG;
581 adapter->dcb_set_bitmap |= BIT_RESETLINK;
582 }
583 } 597 }
584#endif 598#endif
585 break; 599 break;