aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorYi Zou <yi.zou@intel.com>2010-10-20 19:00:30 -0400
committerDavid S. Miller <davem@davemloft.net>2010-10-21 06:55:23 -0400
commit27ab76065c0c6734ea98ccc7080046a72d98455b (patch)
tree91dd4a0b7e282585f9363bee0a966f02b11fabf3 /drivers/net
parentde1036b1cea147c5049c65f5bd26fb451f1624cd (diff)
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)
604{ 604{
605 int rc = -EINVAL; 605 int rc = -EINVAL;
606 struct ixgbe_adapter *adapter = netdev_priv(netdev); 606 struct ixgbe_adapter *adapter = netdev_priv(netdev);
607 struct ixgbe_fcoe *fcoe = &adapter->fcoe;
607 608
608 609
609 if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE)) 610 if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE))
610 goto out_enable; 611 goto out_enable;
611 612
613 atomic_inc(&fcoe->refcnt);
612 if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED) 614 if (adapter->flags & IXGBE_FLAG_FCOE_ENABLED)
613 goto out_enable; 615 goto out_enable;
614 616
@@ -648,6 +650,7 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
648{ 650{
649 int rc = -EINVAL; 651 int rc = -EINVAL;
650 struct ixgbe_adapter *adapter = netdev_priv(netdev); 652 struct ixgbe_adapter *adapter = netdev_priv(netdev);
653 struct ixgbe_fcoe *fcoe = &adapter->fcoe;
651 654
652 if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE)) 655 if (!(adapter->flags & IXGBE_FLAG_FCOE_CAPABLE))
653 goto out_disable; 656 goto out_disable;
@@ -655,6 +658,9 @@ int ixgbe_fcoe_disable(struct net_device *netdev)
655 if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED)) 658 if (!(adapter->flags & IXGBE_FLAG_FCOE_ENABLED))
656 goto out_disable; 659 goto out_disable;
657 660
661 if (!atomic_dec_and_test(&fcoe->refcnt))
662 goto out_disable;
663
658 e_info(drv, "Disabling FCoE offload features.\n"); 664 e_info(drv, "Disabling FCoE offload features.\n");
659 netdev->features &= ~NETIF_F_FCOE_CRC; 665 netdev->features &= ~NETIF_F_FCOE_CRC;
660 netdev->features &= ~NETIF_F_FSO; 666 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 {
66 u8 tc; 66 u8 tc;
67 u8 up; 67 u8 up;
68#endif 68#endif
69 atomic_t refcnt;
69 spinlock_t lock; 70 spinlock_t lock;
70 struct pci_pool *pool; 71 struct pci_pool *pool;
71 struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX]; 72 struct ixgbe_fcoe_ddp ddp[IXGBE_FCOE_DDP_MAX];