aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/netxen/netxen_nic.h2
-rw-r--r--drivers/net/netxen/netxen_nic_main.c69
2 files changed, 42 insertions, 29 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index f86e05047d19..a9c1fcca5e75 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1254,7 +1254,7 @@ struct netxen_adapter {
1254 u8 mc_enabled; 1254 u8 mc_enabled;
1255 u8 max_mc_count; 1255 u8 max_mc_count;
1256 u8 rss_supported; 1256 u8 rss_supported;
1257 u8 resv2; 1257 u8 link_changed;
1258 u32 resv3; 1258 u32 resv3;
1259 1259
1260 u8 has_link_events; 1260 u8 has_link_events;
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 70c05c4c0cab..d24e1cb93a26 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -94,10 +94,6 @@ static struct pci_device_id netxen_pci_tbl[] __devinitdata = {
94 94
95MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); 95MODULE_DEVICE_TABLE(pci, netxen_pci_tbl);
96 96
97static struct workqueue_struct *netxen_workq;
98#define SCHEDULE_WORK(tp) queue_work(netxen_workq, tp)
99#define FLUSH_SCHEDULED_WORK() flush_workqueue(netxen_workq)
100
101static void netxen_watchdog(unsigned long); 97static void netxen_watchdog(unsigned long);
102 98
103static uint32_t crb_cmd_producer[4] = { 99static uint32_t crb_cmd_producer[4] = {
@@ -880,7 +876,6 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev)
880 spin_unlock(&adapter->tx_clean_lock); 876 spin_unlock(&adapter->tx_clean_lock);
881 877
882 del_timer_sync(&adapter->watchdog_timer); 878 del_timer_sync(&adapter->watchdog_timer);
883 FLUSH_SCHEDULED_WORK();
884} 879}
885 880
886 881
@@ -1177,6 +1172,9 @@ static void __devexit netxen_nic_remove(struct pci_dev *pdev)
1177 1172
1178 unregister_netdev(netdev); 1173 unregister_netdev(netdev);
1179 1174
1175 cancel_work_sync(&adapter->watchdog_task);
1176 cancel_work_sync(&adapter->tx_timeout_task);
1177
1180 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) { 1178 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) {
1181 netxen_nic_detach(adapter); 1179 netxen_nic_detach(adapter);
1182 } 1180 }
@@ -1211,6 +1209,9 @@ netxen_nic_suspend(struct pci_dev *pdev, pm_message_t state)
1211 if (netif_running(netdev)) 1209 if (netif_running(netdev))
1212 netxen_nic_down(adapter, netdev); 1210 netxen_nic_down(adapter, netdev);
1213 1211
1212 cancel_work_sync(&adapter->watchdog_task);
1213 cancel_work_sync(&adapter->tx_timeout_task);
1214
1214 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC) 1215 if (adapter->is_up == NETXEN_ADAPTER_UP_MAGIC)
1215 netxen_nic_detach(adapter); 1216 netxen_nic_detach(adapter);
1216 1217
@@ -1549,11 +1550,6 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
1549 "%s: Device temperature %d degrees C exceeds" 1550 "%s: Device temperature %d degrees C exceeds"
1550 " maximum allowed. Hardware has been shut down.\n", 1551 " maximum allowed. Hardware has been shut down.\n",
1551 netdev->name, temp_val); 1552 netdev->name, temp_val);
1552
1553 netif_device_detach(netdev);
1554 netxen_nic_down(adapter, netdev);
1555 netxen_nic_detach(adapter);
1556
1557 rv = 1; 1553 rv = 1;
1558 } else if (temp_state == NX_TEMP_WARN) { 1554 } else if (temp_state == NX_TEMP_WARN) {
1559 if (adapter->temp == NX_TEMP_NORMAL) { 1555 if (adapter->temp == NX_TEMP_NORMAL) {
@@ -1587,10 +1583,7 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
1587 netif_carrier_off(netdev); 1583 netif_carrier_off(netdev);
1588 netif_stop_queue(netdev); 1584 netif_stop_queue(netdev);
1589 } 1585 }
1590 1586 adapter->link_changed = !adapter->has_link_events;
1591 if (!adapter->has_link_events)
1592 netxen_nic_set_link_parameters(adapter);
1593
1594 } else if (!adapter->ahw.linkup && linkup) { 1587 } else if (!adapter->ahw.linkup && linkup) {
1595 printk(KERN_INFO "%s: %s NIC Link is up\n", 1588 printk(KERN_INFO "%s: %s NIC Link is up\n",
1596 netxen_nic_driver_name, netdev->name); 1589 netxen_nic_driver_name, netdev->name);
@@ -1599,9 +1592,7 @@ void netxen_advert_link_change(struct netxen_adapter *adapter, int linkup)
1599 netif_carrier_on(netdev); 1592 netif_carrier_on(netdev);
1600 netif_wake_queue(netdev); 1593 netif_wake_queue(netdev);
1601 } 1594 }
1602 1595 adapter->link_changed = !adapter->has_link_events;
1603 if (!adapter->has_link_events)
1604 netxen_nic_set_link_parameters(adapter);
1605 } 1596 }
1606} 1597}
1607 1598
@@ -1628,11 +1619,36 @@ static void netxen_nic_handle_phy_intr(struct netxen_adapter *adapter)
1628 netxen_advert_link_change(adapter, linkup); 1619 netxen_advert_link_change(adapter, linkup);
1629} 1620}
1630 1621
1622static void netxen_nic_thermal_shutdown(struct netxen_adapter *adapter)
1623{
1624 struct net_device *netdev = adapter->netdev;
1625
1626 netif_device_detach(netdev);
1627 netxen_nic_down(adapter, netdev);
1628 netxen_nic_detach(adapter);
1629}
1630
1631static void netxen_watchdog(unsigned long v) 1631static void netxen_watchdog(unsigned long v)
1632{ 1632{
1633 struct netxen_adapter *adapter = (struct netxen_adapter *)v; 1633 struct netxen_adapter *adapter = (struct netxen_adapter *)v;
1634 1634
1635 SCHEDULE_WORK(&adapter->watchdog_task); 1635 if (netxen_nic_check_temp(adapter))
1636 goto do_sched;
1637
1638 if (!adapter->has_link_events) {
1639 netxen_nic_handle_phy_intr(adapter);
1640
1641 if (adapter->link_changed)
1642 goto do_sched;
1643 }
1644
1645 if (netif_running(adapter->netdev))
1646 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
1647
1648 return;
1649
1650do_sched:
1651 schedule_work(&adapter->watchdog_task);
1636} 1652}
1637 1653
1638void netxen_watchdog_task(struct work_struct *work) 1654void netxen_watchdog_task(struct work_struct *work)
@@ -1640,11 +1656,13 @@ void netxen_watchdog_task(struct work_struct *work)
1640 struct netxen_adapter *adapter = 1656 struct netxen_adapter *adapter =
1641 container_of(work, struct netxen_adapter, watchdog_task); 1657 container_of(work, struct netxen_adapter, watchdog_task);
1642 1658
1643 if (netxen_nic_check_temp(adapter)) 1659 if (adapter->temp == NX_TEMP_PANIC) {
1660 netxen_nic_thermal_shutdown(adapter);
1644 return; 1661 return;
1662 }
1645 1663
1646 if (!adapter->has_link_events) 1664 if (adapter->link_changed)
1647 netxen_nic_handle_phy_intr(adapter); 1665 netxen_nic_set_link_parameters(adapter);
1648 1666
1649 if (netif_running(adapter->netdev)) 1667 if (netif_running(adapter->netdev))
1650 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); 1668 mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
@@ -1652,9 +1670,8 @@ void netxen_watchdog_task(struct work_struct *work)
1652 1670
1653static void netxen_tx_timeout(struct net_device *netdev) 1671static void netxen_tx_timeout(struct net_device *netdev)
1654{ 1672{
1655 struct netxen_adapter *adapter = (struct netxen_adapter *) 1673 struct netxen_adapter *adapter = netdev_priv(netdev);
1656 netdev_priv(netdev); 1674 schedule_work(&adapter->tx_timeout_task);
1657 SCHEDULE_WORK(&adapter->tx_timeout_task);
1658} 1675}
1659 1676
1660static void netxen_tx_timeout_task(struct work_struct *work) 1677static void netxen_tx_timeout_task(struct work_struct *work)
@@ -1811,9 +1828,6 @@ static int __init netxen_init_module(void)
1811{ 1828{
1812 printk(KERN_INFO "%s\n", netxen_nic_driver_string); 1829 printk(KERN_INFO "%s\n", netxen_nic_driver_string);
1813 1830
1814 if ((netxen_workq = create_singlethread_workqueue("netxen")) == NULL)
1815 return -ENOMEM;
1816
1817 return pci_register_driver(&netxen_driver); 1831 return pci_register_driver(&netxen_driver);
1818} 1832}
1819 1833
@@ -1822,7 +1836,6 @@ module_init(netxen_init_module);
1822static void __exit netxen_exit_module(void) 1836static void __exit netxen_exit_module(void)
1823{ 1837{
1824 pci_unregister_driver(&netxen_driver); 1838 pci_unregister_driver(&netxen_driver);
1825 destroy_workqueue(netxen_workq);
1826} 1839}
1827 1840
1828module_exit(netxen_exit_module); 1841module_exit(netxen_exit_module);