aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/netxen/netxen_nic.h4
-rw-r--r--drivers/net/netxen/netxen_nic_init.c4
-rw-r--r--drivers/net/netxen/netxen_nic_main.c69
3 files changed, 64 insertions, 13 deletions
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 7e3d2b932790..1ae46e8c2dc7 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -178,6 +178,7 @@
178 178
179#define MAX_BUFFERS_PER_CMD 32 179#define MAX_BUFFERS_PER_CMD 32
180#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + 4) 180#define TX_STOP_THRESH ((MAX_SKB_FRAGS >> 2) + 4)
181#define NX_MAX_TX_TIMEOUTS 2
181 182
182/* 183/*
183 * Following are the states of the Phantom. Phantom will set them and 184 * Following are the states of the Phantom. Phantom will set them and
@@ -1145,7 +1146,8 @@ struct netxen_adapter {
1145 u8 link_changed; 1146 u8 link_changed;
1146 u8 fw_wait_cnt; 1147 u8 fw_wait_cnt;
1147 u8 fw_fail_cnt; 1148 u8 fw_fail_cnt;
1148 u16 resv4; 1149 u8 tx_timeo_cnt;
1150 u8 need_fw_reset;
1149 1151
1150 u8 has_link_events; 1152 u8 has_link_events;
1151 u8 fw_type; 1153 u8 fw_type;
diff --git a/drivers/net/netxen/netxen_nic_init.c b/drivers/net/netxen/netxen_nic_init.c
index 8926b0e0c8bc..128d1b65402d 100644
--- a/drivers/net/netxen/netxen_nic_init.c
+++ b/drivers/net/netxen/netxen_nic_init.c
@@ -1434,8 +1434,10 @@ int netxen_process_cmd_ring(struct netxen_adapter *adapter)
1434 1434
1435 if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) { 1435 if (netif_queue_stopped(netdev) && netif_carrier_ok(netdev)) {
1436 __netif_tx_lock(tx_ring->txq, smp_processor_id()); 1436 __netif_tx_lock(tx_ring->txq, smp_processor_id());
1437 if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) 1437 if (netxen_tx_avail(tx_ring) > TX_STOP_THRESH) {
1438 netif_wake_queue(netdev); 1438 netif_wake_queue(netdev);
1439 adapter->tx_timeo_cnt = 0;
1440 }
1439 __netif_tx_unlock(tx_ring->txq); 1441 __netif_tx_unlock(tx_ring->txq);
1440 } 1442 }
1441 } 1443 }
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index e8574eeae58f..53bd44e808eb 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -66,7 +66,7 @@ static int netxen_nic_close(struct net_device *netdev);
66static netdev_tx_t netxen_nic_xmit_frame(struct sk_buff *, 66static netdev_tx_t netxen_nic_xmit_frame(struct sk_buff *,
67 struct net_device *); 67 struct net_device *);
68static void netxen_tx_timeout(struct net_device *netdev); 68static void netxen_tx_timeout(struct net_device *netdev);
69static void netxen_reset_task(struct work_struct *work); 69static void netxen_tx_timeout_task(struct work_struct *work);
70static void netxen_fw_poll_work(struct work_struct *work); 70static void netxen_fw_poll_work(struct work_struct *work);
71static void netxen_schedule_work(struct netxen_adapter *adapter, 71static void netxen_schedule_work(struct netxen_adapter *adapter,
72 work_func_t func, int delay); 72 work_func_t func, int delay);
@@ -875,6 +875,8 @@ wait_init:
875 875
876 netxen_check_options(adapter); 876 netxen_check_options(adapter);
877 877
878 adapter->need_fw_reset = 0;
879
878 /* fall through and release firmware */ 880 /* fall through and release firmware */
879 881
880err_out: 882err_out:
@@ -1183,7 +1185,7 @@ netxen_setup_netdev(struct netxen_adapter *adapter,
1183 1185
1184 netdev->irq = adapter->msix_entries[0].vector; 1186 netdev->irq = adapter->msix_entries[0].vector;
1185 1187
1186 INIT_WORK(&adapter->tx_timeout_task, netxen_reset_task); 1188 INIT_WORK(&adapter->tx_timeout_task, netxen_tx_timeout_task);
1187 1189
1188 if (netxen_read_mac_addr(adapter)) 1190 if (netxen_read_mac_addr(adapter))
1189 dev_warn(&pdev->dev, "failed to read mac addr\n"); 1191 dev_warn(&pdev->dev, "failed to read mac addr\n");
@@ -1882,7 +1884,7 @@ static void netxen_tx_timeout(struct net_device *netdev)
1882 schedule_work(&adapter->tx_timeout_task); 1884 schedule_work(&adapter->tx_timeout_task);
1883} 1885}
1884 1886
1885static void netxen_reset_task(struct work_struct *work) 1887static void netxen_tx_timeout_task(struct work_struct *work)
1886{ 1888{
1887 struct netxen_adapter *adapter = 1889 struct netxen_adapter *adapter =
1888 container_of(work, struct netxen_adapter, tx_timeout_task); 1890 container_of(work, struct netxen_adapter, tx_timeout_task);
@@ -1890,15 +1892,37 @@ static void netxen_reset_task(struct work_struct *work)
1890 if (!netif_running(adapter->netdev)) 1892 if (!netif_running(adapter->netdev))
1891 return; 1893 return;
1892 1894
1893 if (test_bit(__NX_RESETTING, &adapter->state)) 1895 if (test_and_set_bit(__NX_RESETTING, &adapter->state))
1894 return; 1896 return;
1895 1897
1896 netxen_napi_disable(adapter); 1898 if (++adapter->tx_timeo_cnt >= NX_MAX_TX_TIMEOUTS)
1899 goto request_reset;
1900
1901 if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) {
1902 /* try to scrub interrupt */
1903 netxen_napi_disable(adapter);
1897 1904
1898 adapter->netdev->trans_start = jiffies; 1905 adapter->netdev->trans_start = jiffies;
1899 1906
1900 netxen_napi_enable(adapter); 1907 netxen_napi_enable(adapter);
1901 netif_wake_queue(adapter->netdev); 1908
1909 netif_wake_queue(adapter->netdev);
1910
1911 goto done;
1912
1913 } else {
1914 if (!netxen_nic_reset_context(adapter)) {
1915 adapter->netdev->trans_start = jiffies;
1916 goto done;
1917 }
1918
1919 /* context reset failed, fall through for fw reset */
1920 }
1921
1922request_reset:
1923 adapter->need_fw_reset = 1;
1924done:
1925 clear_bit(__NX_RESETTING, &adapter->state);
1902} 1926}
1903 1927
1904struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev) 1928struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
@@ -2048,6 +2072,22 @@ nx_decr_dev_ref_cnt(struct netxen_adapter *adapter)
2048 return count; 2072 return count;
2049} 2073}
2050 2074
2075static void
2076nx_dev_request_reset(struct netxen_adapter *adapter)
2077{
2078 u32 state;
2079
2080 if (netxen_api_lock(adapter))
2081 return;
2082
2083 state = NXRD32(adapter, NX_CRB_DEV_STATE);
2084
2085 if (state != NX_DEV_INITALIZING)
2086 NXWR32(adapter, NX_CRB_DEV_STATE, NX_DEV_NEED_RESET);
2087
2088 netxen_api_unlock(adapter);
2089}
2090
2051static int 2091static int
2052netxen_can_start_firmware(struct netxen_adapter *adapter) 2092netxen_can_start_firmware(struct netxen_adapter *adapter)
2053{ 2093{
@@ -2133,9 +2173,11 @@ netxen_fwinit_work(struct work_struct *work)
2133 switch (dev_state) { 2173 switch (dev_state) {
2134 case NX_DEV_COLD: 2174 case NX_DEV_COLD:
2135 case NX_DEV_READY: 2175 case NX_DEV_READY:
2136 netxen_start_firmware(adapter); 2176 if (!netxen_start_firmware(adapter)) {
2137 netxen_schedule_work(adapter, netxen_attach_work, 0); 2177 netxen_schedule_work(adapter, netxen_attach_work, 0);
2138 return; 2178 return;
2179 }
2180 break;
2139 2181
2140 case NX_DEV_INITALIZING: 2182 case NX_DEV_INITALIZING:
2141 if (++adapter->fw_wait_cnt < FW_POLL_THRESH) { 2183 if (++adapter->fw_wait_cnt < FW_POLL_THRESH) {
@@ -2195,6 +2237,11 @@ netxen_check_health(struct netxen_adapter *adapter)
2195 if (netxen_nic_check_temp(adapter)) 2237 if (netxen_nic_check_temp(adapter))
2196 goto detach; 2238 goto detach;
2197 2239
2240 if (adapter->need_fw_reset) {
2241 nx_dev_request_reset(adapter);
2242 goto detach;
2243 }
2244
2198 state = NXRD32(adapter, NX_CRB_DEV_STATE); 2245 state = NXRD32(adapter, NX_CRB_DEV_STATE);
2199 if (state == NX_DEV_NEED_RESET) 2246 if (state == NX_DEV_NEED_RESET)
2200 goto detach; 2247 goto detach;