ixgbe: properly toggling netdev feature flags when disabling FCoE
authorYi Zou <yi.zou@intel.com>
Mon, 19 Jul 2010 13:59:52 +0000 (13:59 +0000)
committerDavid S. Miller <davem@davemloft.net>
Tue, 20 Jul 2010 03:23:37 +0000 (20:23 -0700)
When FCoE is disabled, there is a race condition that FCoE offload is
turned off but the FCoE protocol driver is still queuing I/O thinking
offload support still exists. This patch toggles off corresponding FCoE
netdev feature flags and notify the FCoE stack first, allowing FCoE
protocol stack driver to update its flags upon NETDEV_FEAT_CHANGE so no
I/O will be using offload.

Also, indicate FCoE offload flags in vlan_features in ixgbe_probe once
and do not toggle them in ixgbe_fcoe_enable/disable so when FCoE is
created on the VLAN interface, vlan_transfer_features() would properly
update the VLAN netdev features flag and notify the FCoE protocol driver
for NETDEV_FEAT_CHANGE.

Signed-off-by: Yi Zou <yi.zou@intel.com>
Tested-by: Ross Brattain <ross.b.brattain@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ixgbe/ixgbe_fcoe.c
drivers/net/ixgbe/ixgbe_main.c

index f6ef4cd0a12aec763b5ca6675343f8741db41a1d..1737d2bddc19a54e89a9feb0dabd1fb3b43f2498 100644 (file)
@@ -622,9 +622,6 @@ int ixgbe_fcoe_enable(struct net_device *netdev)
        netdev->features |= NETIF_F_FCOE_CRC;
        netdev->features |= NETIF_F_FSO;
        netdev->features |= NETIF_F_FCOE_MTU;
-       netdev->vlan_features |= NETIF_F_FCOE_CRC;
-       netdev->vlan_features |= NETIF_F_FSO;
-       netdev->vlan_features |= NETIF_F_FCOE_MTU;
        netdev->fcoe_ddp_xid = IXGBE_FCOE_DDP_MAX - 1;
 
        ixgbe_init_interrupt_scheme(adapter);
@@ -658,24 +655,20 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
                goto out_disable;
 
        e_info(drv, "Disabling FCoE offload features.\n");
+       netdev->features &= ~NETIF_F_FCOE_CRC;
+       netdev->features &= ~NETIF_F_FSO;
+       netdev->features &= ~NETIF_F_FCOE_MTU;
+       netdev->fcoe_ddp_xid = 0;
+       netdev_features_change(netdev);
+
        if (netif_running(netdev))
                netdev->netdev_ops->ndo_stop(netdev);
 
        ixgbe_clear_interrupt_scheme(adapter);
-
        adapter->flags &= ~IXGBE_FLAG_FCOE_ENABLED;
        adapter->ring_feature[RING_F_FCOE].indices = 0;
-       netdev->features &= ~NETIF_F_FCOE_CRC;
-       netdev->features &= ~NETIF_F_FSO;
-       netdev->features &= ~NETIF_F_FCOE_MTU;
-       netdev->vlan_features &= ~NETIF_F_FCOE_CRC;
-       netdev->vlan_features &= ~NETIF_F_FSO;
-       netdev->vlan_features &= ~NETIF_F_FCOE_MTU;
-       netdev->fcoe_ddp_xid = 0;
-
        ixgbe_cleanup_fcoe(adapter);
        ixgbe_init_interrupt_scheme(adapter);
-       netdev_features_change(netdev);
 
        if (netif_running(netdev))
                netdev->netdev_ops->ndo_open(netdev);
index 813d2cb5b4d09b6e13baaeab0ee80c094e744bb4..7d619d620f2e7b94861a6e346a89fa6d58dd8daf 100644 (file)
@@ -6740,6 +6740,11 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
                                adapter->flags &= ~IXGBE_FLAG_FCOE_CAPABLE;
                }
        }
+       if (adapter->flags & IXGBE_FLAG_FCOE_CAPABLE) {
+               netdev->vlan_features |= NETIF_F_FCOE_CRC;
+               netdev->vlan_features |= NETIF_F_FSO;
+               netdev->vlan_features |= NETIF_F_FCOE_MTU;
+       }
 #endif /* IXGBE_FCOE */
        if (pci_using_dac)
                netdev->features |= NETIF_F_HIGHDMA;