diff options
-rw-r--r-- | drivers/net/netxen/netxen_nic.h | 2 | ||||
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 69 |
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 | ||
95 | MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); | 95 | MODULE_DEVICE_TABLE(pci, netxen_pci_tbl); |
96 | 96 | ||
97 | static 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 | |||
101 | static void netxen_watchdog(unsigned long); | 97 | static void netxen_watchdog(unsigned long); |
102 | 98 | ||
103 | static uint32_t crb_cmd_producer[4] = { | 99 | static 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 | ||
1622 | static 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 | |||
1631 | static void netxen_watchdog(unsigned long v) | 1631 | static 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 | |||
1650 | do_sched: | ||
1651 | schedule_work(&adapter->watchdog_task); | ||
1636 | } | 1652 | } |
1637 | 1653 | ||
1638 | void netxen_watchdog_task(struct work_struct *work) | 1654 | void 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 | ||
1653 | static void netxen_tx_timeout(struct net_device *netdev) | 1671 | static 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 | ||
1660 | static void netxen_tx_timeout_task(struct work_struct *work) | 1677 | static 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); | |||
1822 | static void __exit netxen_exit_module(void) | 1836 | static 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 | ||
1828 | module_exit(netxen_exit_module); | 1841 | module_exit(netxen_exit_module); |