aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/netxen/netxen_nic_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r--drivers/net/netxen/netxen_nic_main.c49
1 files changed, 39 insertions, 10 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index e5d187fce51b..f4996846a234 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -946,8 +946,9 @@ netxen_nic_init_coalesce_defaults(struct netxen_adapter *adapter)
NETXEN_DEFAULT_INTR_COALESCE_TX_PACKETS;
}
+/* with rtnl_lock */
static int
-netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
+__netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
{
int err;
@@ -988,14 +989,32 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
return 0;
}
+/* Usage: During resume and firmware recovery module.*/
+
+static inline int
+netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+ int err = 0;
+
+ rtnl_lock();
+ if (netif_running(netdev))
+ err = __netxen_nic_up(adapter, netdev);
+ rtnl_unlock();
+
+ return err;
+}
+
+/* with rtnl_lock */
static void
-netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
+__netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
{
if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC)
return;
- clear_bit(__NX_DEV_UP, &adapter->state);
+ if (!test_and_clear_bit(__NX_DEV_UP, &adapter->state))
+ return;
+ smp_mb();
spin_lock(&adapter->tx_clean_lock);
netif_carrier_off(netdev);
netif_tx_disable(netdev);
@@ -1014,6 +1033,17 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
spin_unlock(&adapter->tx_clean_lock);
}
+/* Usage: During suspend and firmware recovery module */
+
+static inline void
+netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
+{
+ rtnl_lock();
+ if (netif_running(netdev))
+ __netxen_nic_down(adapter, netdev);
+ rtnl_unlock();
+
+}
static int
netxen_nic_attach(struct netxen_adapter *adapter)
@@ -1122,14 +1152,14 @@ netxen_nic_reset_context(struct netxen_adapter *adapter)
netif_device_detach(netdev);
if (netif_running(netdev))
- netxen_nic_down(adapter, netdev);
+ __netxen_nic_down(adapter, netdev);
netxen_nic_detach(adapter);
if (netif_running(netdev)) {
err = netxen_nic_attach(adapter);
if (!err)
- err = netxen_nic_up(adapter, netdev);
+ err = __netxen_nic_up(adapter, netdev);
if (err)
goto done;
@@ -1499,7 +1529,7 @@ static int netxen_nic_open(struct net_device *netdev)
if (err)
return err;
- err = netxen_nic_up(adapter, netdev);
+ err = __netxen_nic_up(adapter, netdev);
if (err)
goto err_out;
@@ -1519,7 +1549,7 @@ static int netxen_nic_close(struct net_device *netdev)
{
struct netxen_adapter *adapter = netdev_priv(netdev);
- netxen_nic_down(adapter, netdev);
+ __netxen_nic_down(adapter, netdev);
return 0;
}
@@ -2025,7 +2055,7 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget)
if ((work_done < budget) && tx_complete) {
napi_complete(&sds_ring->napi);
- if (netif_running(adapter->netdev))
+ if (test_bit(__NX_DEV_UP, &adapter->state))
netxen_nic_enable_int(sds_ring);
}
@@ -2210,8 +2240,7 @@ netxen_detach_work(struct work_struct *work)
netif_device_detach(netdev);
- if (netif_running(netdev))
- netxen_nic_down(adapter, netdev);
+ netxen_nic_down(adapter, netdev);
netxen_nic_detach(adapter);