summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorYi Zou <yi.zou@intel.com>2010-10-20 23:00:30 +0000
committerDavid S. Miller <davem@davemloft.net>2010-10-21 03:55:23 -0700
commit27ab76065c0c6734ea98ccc7080046a72d98455b (patch)
tree91dd4a0b7e282585f9363bee0a966f02b11fabf3 /drivers/net
parentde1036b1cea147c5049c65f5bd26fb451f1624cd (diff)
downloadlinux-27ab76065c0c6734ea98ccc7080046a72d98455b.tar.gz
linux-27ab76065c0c6734ea98ccc7080046a72d98455b.tar.bz2
linux-27ab76065c0c6734ea98ccc7080046a72d98455b.zip
ixgbe: add a refcnt when turning on/off FCoE offload capability
The FCoE offload is enabled/disabled per adapter, but upper FCoE protocol stack could have multiple FCoE instances created on the same physical network interface, e.g., FCoE on multiple VLAN interfaces on the same physical network interface. In this case we want to turn on FCoE offload at the first request from ndo_fcoe_enable() but only turn off FCoE offload at the very last call to ndo_fcoe_disable(). This is fixed by adding a refcnt in the per adapter FCoE structure and tear down FCoE offload when refcnt decrements to zero. 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>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.c6
-rw-r--r--drivers/net/ixgbe/ixgbe_fcoe.h1
2 files changed, 7 insertions, 0 deletions
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.c b/drivers/net/ixgbe/ixgbe_fcoe.c
index 2f1de8b90f9e..05efa6a8ce8e 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.c
+++ b/drivers/net/ixgbe/ixgbe_fcoe.c
@@ -604,11 +604,13 @@ int ixgbe_fcoe_enable(struct net_device *netdev)
{
int rc = -EINVAL;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_fcoe *fcoe = &adapter->fcoe;
if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE))
goto out_enable;
+ atomic_inc(&fcoe->refcnt);
if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
goto out_enable;
@@ -648,6 +650,7 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
{
int rc = -EINVAL;
struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_fcoe *fcoe = &adapter->fcoe;
if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE))
goto out_disable;
@@ -655,6 +658,9 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
goto out_disable;
+ if (!atomic_dec_and_test(&fcoe->refcnt))
+ goto out_disable;
+
e_info(drv, "Disabling FCoE offload features.\n");
netdev->features &= ~NETIF_F_FCOE_CRC;
netdev->features &= ~NETIF_F_FSO;
diff --git a/drivers/net/ixgbe/ixgbe_fcoe.h b/drivers/net/ixgbe/ixgbe_fcoe.h
index abf4b2b3f252..4bc2c551c8db 100644
--- a/drivers/net/ixgbe/ixgbe_fcoe.h
+++ b/drivers/net/ixgbe/ixgbe_fcoe.h
@@ -66,6 +66,7 @@ struct ixgbe_fcoe {
u8 tc;
u8 up;
#endif
+ atomic_t refcnt;
spinlock_t lock;
struct pci_pool *pool;
struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX];