diff options
Diffstat (limited to 'drivers/net/netxen/netxen_nic_main.c')
-rw-r--r-- | drivers/net/netxen/netxen_nic_main.c | 73 |
1 files changed, 47 insertions, 26 deletions
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c index 27539ddf94c4..3cd8cfcf627b 100644 --- a/drivers/net/netxen/netxen_nic_main.c +++ b/drivers/net/netxen/netxen_nic_main.c | |||
@@ -215,13 +215,13 @@ netxen_napi_disable(struct netxen_adapter *adapter) | |||
215 | 215 | ||
216 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { | 216 | for (ring = 0; ring < adapter->max_sds_rings; ring++) { |
217 | sds_ring = &recv_ctx->sds_rings[ring]; | 217 | sds_ring = &recv_ctx->sds_rings[ring]; |
218 | napi_disable(&sds_ring->napi); | ||
219 | netxen_nic_disable_int(sds_ring); | 218 | netxen_nic_disable_int(sds_ring); |
220 | synchronize_irq(sds_ring->irq); | 219 | napi_synchronize(&sds_ring->napi); |
220 | napi_disable(&sds_ring->napi); | ||
221 | } | 221 | } |
222 | } | 222 | } |
223 | 223 | ||
224 | static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) | 224 | static int nx_set_dma_mask(struct netxen_adapter *adapter) |
225 | { | 225 | { |
226 | struct pci_dev *pdev = adapter->pdev; | 226 | struct pci_dev *pdev = adapter->pdev; |
227 | uint64_t mask, cmask; | 227 | uint64_t mask, cmask; |
@@ -229,19 +229,17 @@ static int nx_set_dma_mask(struct netxen_adapter *adapter, uint8_t revision_id) | |||
229 | adapter->pci_using_dac = 0; | 229 | adapter->pci_using_dac = 0; |
230 | 230 | ||
231 | mask = DMA_BIT_MASK(32); | 231 | mask = DMA_BIT_MASK(32); |
232 | /* | ||
233 | * Consistent DMA mask is set to 32 bit because it cannot be set to | ||
234 | * 35 bits. For P3 also leave it at 32 bits for now. Only the rings | ||
235 | * come off this pool. | ||
236 | */ | ||
237 | cmask = DMA_BIT_MASK(32); | 232 | cmask = DMA_BIT_MASK(32); |
238 | 233 | ||
234 | if (NX_IS_REVISION_P2(adapter->ahw.revision_id)) { | ||
239 | #ifndef CONFIG_IA64 | 235 | #ifndef CONFIG_IA64 |
240 | if (revision_id >= NX_P3_B0) | ||
241 | mask = DMA_BIT_MASK(39); | ||
242 | else if (revision_id == NX_P2_C1) | ||
243 | mask = DMA_BIT_MASK(35); | 236 | mask = DMA_BIT_MASK(35); |
244 | #endif | 237 | #endif |
238 | } else { | ||
239 | mask = DMA_BIT_MASK(39); | ||
240 | cmask = mask; | ||
241 | } | ||
242 | |||
245 | if (pci_set_dma_mask(pdev, mask) == 0 && | 243 | if (pci_set_dma_mask(pdev, mask) == 0 && |
246 | pci_set_consistent_dma_mask(pdev, cmask) == 0) { | 244 | pci_set_consistent_dma_mask(pdev, cmask) == 0) { |
247 | adapter->pci_using_dac = 1; | 245 | adapter->pci_using_dac = 1; |
@@ -256,7 +254,7 @@ static int | |||
256 | nx_update_dma_mask(struct netxen_adapter *adapter) | 254 | nx_update_dma_mask(struct netxen_adapter *adapter) |
257 | { | 255 | { |
258 | int change, shift, err; | 256 | int change, shift, err; |
259 | uint64_t mask, old_mask; | 257 | uint64_t mask, old_mask, old_cmask; |
260 | struct pci_dev *pdev = adapter->pdev; | 258 | struct pci_dev *pdev = adapter->pdev; |
261 | 259 | ||
262 | change = 0; | 260 | change = 0; |
@@ -272,14 +270,29 @@ nx_update_dma_mask(struct netxen_adapter *adapter) | |||
272 | 270 | ||
273 | if (change) { | 271 | if (change) { |
274 | old_mask = pdev->dma_mask; | 272 | old_mask = pdev->dma_mask; |
273 | old_cmask = pdev->dev.coherent_dma_mask; | ||
274 | |||
275 | mask = (1ULL<<(32+shift)) - 1; | 275 | mask = (1ULL<<(32+shift)) - 1; |
276 | 276 | ||
277 | err = pci_set_dma_mask(pdev, mask); | 277 | err = pci_set_dma_mask(pdev, mask); |
278 | if (err) | 278 | if (err) |
279 | return pci_set_dma_mask(pdev, old_mask); | 279 | goto err_out; |
280 | |||
281 | if (NX_IS_REVISION_P3(adapter->ahw.revision_id)) { | ||
282 | |||
283 | err = pci_set_consistent_dma_mask(pdev, mask); | ||
284 | if (err) | ||
285 | goto err_out; | ||
286 | } | ||
287 | dev_info(&pdev->dev, "using %d-bit dma mask\n", 32+shift); | ||
280 | } | 288 | } |
281 | 289 | ||
282 | return 0; | 290 | return 0; |
291 | |||
292 | err_out: | ||
293 | pci_set_dma_mask(pdev, old_mask); | ||
294 | pci_set_consistent_dma_mask(pdev, old_cmask); | ||
295 | return err; | ||
283 | } | 296 | } |
284 | 297 | ||
285 | static void netxen_check_options(struct netxen_adapter *adapter) | 298 | static void netxen_check_options(struct netxen_adapter *adapter) |
@@ -833,11 +846,11 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
833 | 846 | ||
834 | adapter->ahw.linkup = 0; | 847 | adapter->ahw.linkup = 0; |
835 | 848 | ||
836 | netxen_napi_enable(adapter); | ||
837 | |||
838 | if (adapter->max_sds_rings > 1) | 849 | if (adapter->max_sds_rings > 1) |
839 | netxen_config_rss(adapter, 1); | 850 | netxen_config_rss(adapter, 1); |
840 | 851 | ||
852 | netxen_napi_enable(adapter); | ||
853 | |||
841 | if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) | 854 | if (adapter->capabilities & NX_FW_CAPABILITY_LINK_NOTIFICATION) |
842 | netxen_linkevent_request(adapter, 1); | 855 | netxen_linkevent_request(adapter, 1); |
843 | else | 856 | else |
@@ -851,8 +864,9 @@ netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev) | |||
851 | static void | 864 | static void |
852 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | 865 | netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) |
853 | { | 866 | { |
867 | spin_lock(&adapter->tx_clean_lock); | ||
854 | netif_carrier_off(netdev); | 868 | netif_carrier_off(netdev); |
855 | netif_stop_queue(netdev); | 869 | netif_tx_disable(netdev); |
856 | 870 | ||
857 | if (adapter->stop_port) | 871 | if (adapter->stop_port) |
858 | adapter->stop_port(adapter); | 872 | adapter->stop_port(adapter); |
@@ -863,9 +877,10 @@ netxen_nic_down(struct netxen_adapter *adapter, struct net_device *netdev) | |||
863 | netxen_napi_disable(adapter); | 877 | netxen_napi_disable(adapter); |
864 | 878 | ||
865 | netxen_release_tx_buffers(adapter); | 879 | netxen_release_tx_buffers(adapter); |
880 | spin_unlock(&adapter->tx_clean_lock); | ||
866 | 881 | ||
867 | FLUSH_SCHEDULED_WORK(); | ||
868 | del_timer_sync(&adapter->watchdog_timer); | 882 | del_timer_sync(&adapter->watchdog_timer); |
883 | FLUSH_SCHEDULED_WORK(); | ||
869 | } | 884 | } |
870 | 885 | ||
871 | 886 | ||
@@ -943,8 +958,8 @@ err_out_free_sw: | |||
943 | static void | 958 | static void |
944 | netxen_nic_detach(struct netxen_adapter *adapter) | 959 | netxen_nic_detach(struct netxen_adapter *adapter) |
945 | { | 960 | { |
946 | netxen_release_rx_buffers(adapter); | ||
947 | netxen_free_hw_resources(adapter); | 961 | netxen_free_hw_resources(adapter); |
962 | netxen_release_rx_buffers(adapter); | ||
948 | netxen_nic_free_irq(adapter); | 963 | netxen_nic_free_irq(adapter); |
949 | netxen_free_sw_resources(adapter); | 964 | netxen_free_sw_resources(adapter); |
950 | 965 | ||
@@ -1004,7 +1019,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1004 | revision_id = pdev->revision; | 1019 | revision_id = pdev->revision; |
1005 | adapter->ahw.revision_id = revision_id; | 1020 | adapter->ahw.revision_id = revision_id; |
1006 | 1021 | ||
1007 | err = nx_set_dma_mask(adapter, revision_id); | 1022 | err = nx_set_dma_mask(adapter); |
1008 | if (err) | 1023 | if (err) |
1009 | goto err_out_free_netdev; | 1024 | goto err_out_free_netdev; |
1010 | 1025 | ||
@@ -1533,10 +1548,12 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1533 | printk(KERN_ALERT | 1548 | printk(KERN_ALERT |
1534 | "%s: Device temperature %d degrees C exceeds" | 1549 | "%s: Device temperature %d degrees C exceeds" |
1535 | " maximum allowed. Hardware has been shut down.\n", | 1550 | " maximum allowed. Hardware has been shut down.\n", |
1536 | netxen_nic_driver_name, temp_val); | 1551 | netdev->name, temp_val); |
1552 | |||
1553 | netif_device_detach(netdev); | ||
1554 | netxen_nic_down(adapter, netdev); | ||
1555 | netxen_nic_detach(adapter); | ||
1537 | 1556 | ||
1538 | netif_carrier_off(netdev); | ||
1539 | netif_stop_queue(netdev); | ||
1540 | rv = 1; | 1557 | rv = 1; |
1541 | } else if (temp_state == NX_TEMP_WARN) { | 1558 | } else if (temp_state == NX_TEMP_WARN) { |
1542 | if (adapter->temp == NX_TEMP_NORMAL) { | 1559 | if (adapter->temp == NX_TEMP_NORMAL) { |
@@ -1544,13 +1561,13 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter) | |||
1544 | "%s: Device temperature %d degrees C " | 1561 | "%s: Device temperature %d degrees C " |
1545 | "exceeds operating range." | 1562 | "exceeds operating range." |
1546 | " Immediate action needed.\n", | 1563 | " Immediate action needed.\n", |
1547 | netxen_nic_driver_name, temp_val); | 1564 | netdev->name, temp_val); |
1548 | } | 1565 | } |
1549 | } else { | 1566 | } else { |
1550 | if (adapter->temp == NX_TEMP_WARN) { | 1567 | if (adapter->temp == NX_TEMP_WARN) { |
1551 | printk(KERN_INFO | 1568 | printk(KERN_INFO |
1552 | "%s: Device temperature is now %d degrees C" | 1569 | "%s: Device temperature is now %d degrees C" |
1553 | " in normal range.\n", netxen_nic_driver_name, | 1570 | " in normal range.\n", netdev->name, |
1554 | temp_val); | 1571 | temp_val); |
1555 | } | 1572 | } |
1556 | } | 1573 | } |
@@ -1623,7 +1640,7 @@ void netxen_watchdog_task(struct work_struct *work) | |||
1623 | struct netxen_adapter *adapter = | 1640 | struct netxen_adapter *adapter = |
1624 | container_of(work, struct netxen_adapter, watchdog_task); | 1641 | container_of(work, struct netxen_adapter, watchdog_task); |
1625 | 1642 | ||
1626 | if ((adapter->portnum == 0) && netxen_nic_check_temp(adapter)) | 1643 | if (netxen_nic_check_temp(adapter)) |
1627 | return; | 1644 | return; |
1628 | 1645 | ||
1629 | if (!adapter->has_link_events) | 1646 | if (!adapter->has_link_events) |
@@ -1645,6 +1662,9 @@ static void netxen_tx_timeout_task(struct work_struct *work) | |||
1645 | struct netxen_adapter *adapter = | 1662 | struct netxen_adapter *adapter = |
1646 | container_of(work, struct netxen_adapter, tx_timeout_task); | 1663 | container_of(work, struct netxen_adapter, tx_timeout_task); |
1647 | 1664 | ||
1665 | if (!netif_running(adapter->netdev)) | ||
1666 | return; | ||
1667 | |||
1648 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", | 1668 | printk(KERN_ERR "%s %s: transmit timeout, resetting.\n", |
1649 | netxen_nic_driver_name, adapter->netdev->name); | 1669 | netxen_nic_driver_name, adapter->netdev->name); |
1650 | 1670 | ||
@@ -1757,7 +1777,8 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget) | |||
1757 | 1777 | ||
1758 | if ((work_done < budget) && tx_complete) { | 1778 | if ((work_done < budget) && tx_complete) { |
1759 | napi_complete(&sds_ring->napi); | 1779 | napi_complete(&sds_ring->napi); |
1760 | netxen_nic_enable_int(sds_ring); | 1780 | if (netif_running(adapter->netdev)) |
1781 | netxen_nic_enable_int(sds_ring); | ||
1761 | } | 1782 | } |
1762 | 1783 | ||
1763 | return work_done; | 1784 | return work_done; |