aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/bnx2x_main.c')
-rw-r--r--drivers/net/bnx2x_main.c95
1 files changed, 83 insertions, 12 deletions
diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
index a8eb3c4a47c8..fce745148ff9 100644
--- a/drivers/net/bnx2x_main.c
+++ b/drivers/net/bnx2x_main.c
@@ -59,8 +59,8 @@
59#include "bnx2x.h" 59#include "bnx2x.h"
60#include "bnx2x_init.h" 60#include "bnx2x_init.h"
61 61
62#define DRV_MODULE_VERSION "1.45.21" 62#define DRV_MODULE_VERSION "1.45.22"
63#define DRV_MODULE_RELDATE "2008/09/03" 63#define DRV_MODULE_RELDATE "2008/09/09"
64#define BNX2X_BC_VER 0x040200 64#define BNX2X_BC_VER 0x040200
65 65
66/* Time in jiffies before concluding the transmitter is hung */ 66/* Time in jiffies before concluding the transmitter is hung */
@@ -649,15 +649,16 @@ static void bnx2x_int_disable(struct bnx2x *bp)
649 BNX2X_ERR("BUG! proper val not read from IGU!\n"); 649 BNX2X_ERR("BUG! proper val not read from IGU!\n");
650} 650}
651 651
652static void bnx2x_int_disable_sync(struct bnx2x *bp) 652static void bnx2x_int_disable_sync(struct bnx2x *bp, int disable_hw)
653{ 653{
654 int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0; 654 int msix = (bp->flags & USING_MSIX_FLAG) ? 1 : 0;
655 int i; 655 int i;
656 656
657 /* disable interrupt handling */ 657 /* disable interrupt handling */
658 atomic_inc(&bp->intr_sem); 658 atomic_inc(&bp->intr_sem);
659 /* prevent the HW from sending interrupts */ 659 if (disable_hw)
660 bnx2x_int_disable(bp); 660 /* prevent the HW from sending interrupts */
661 bnx2x_int_disable(bp);
661 662
662 /* make sure all ISRs are done */ 663 /* make sure all ISRs are done */
663 if (msix) { 664 if (msix) {
@@ -6086,9 +6087,9 @@ static void bnx2x_netif_start(struct bnx2x *bp)
6086 } 6087 }
6087} 6088}
6088 6089
6089static void bnx2x_netif_stop(struct bnx2x *bp) 6090static void bnx2x_netif_stop(struct bnx2x *bp, int disable_hw)
6090{ 6091{
6091 bnx2x_int_disable_sync(bp); 6092 bnx2x_int_disable_sync(bp, disable_hw);
6092 if (netif_running(bp->dev)) { 6093 if (netif_running(bp->dev)) {
6093 bnx2x_napi_disable(bp); 6094 bnx2x_napi_disable(bp);
6094 netif_tx_disable(bp->dev); 6095 netif_tx_disable(bp->dev);
@@ -6475,7 +6476,7 @@ load_rings_free:
6475 for_each_queue(bp, i) 6476 for_each_queue(bp, i)
6476 bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE); 6477 bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
6477load_int_disable: 6478load_int_disable:
6478 bnx2x_int_disable_sync(bp); 6479 bnx2x_int_disable_sync(bp, 1);
6479 /* Release IRQs */ 6480 /* Release IRQs */
6480 bnx2x_free_irq(bp); 6481 bnx2x_free_irq(bp);
6481load_error: 6482load_error:
@@ -6650,7 +6651,7 @@ static int bnx2x_nic_unload(struct bnx2x *bp, int unload_mode)
6650 bp->rx_mode = BNX2X_RX_MODE_NONE; 6651 bp->rx_mode = BNX2X_RX_MODE_NONE;
6651 bnx2x_set_storm_rx_mode(bp); 6652 bnx2x_set_storm_rx_mode(bp);
6652 6653
6653 bnx2x_netif_stop(bp); 6654 bnx2x_netif_stop(bp, 1);
6654 if (!netif_running(bp->dev)) 6655 if (!netif_running(bp->dev))
6655 bnx2x_napi_disable(bp); 6656 bnx2x_napi_disable(bp);
6656 del_timer_sync(&bp->timer); 6657 del_timer_sync(&bp->timer);
@@ -8791,7 +8792,7 @@ static int bnx2x_test_loopback(struct bnx2x *bp, u8 link_up)
8791 if (!netif_running(bp->dev)) 8792 if (!netif_running(bp->dev))
8792 return BNX2X_LOOPBACK_FAILED; 8793 return BNX2X_LOOPBACK_FAILED;
8793 8794
8794 bnx2x_netif_stop(bp); 8795 bnx2x_netif_stop(bp, 1);
8795 8796
8796 if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) { 8797 if (bnx2x_run_loopback(bp, BNX2X_MAC_LOOPBACK, link_up)) {
8797 DP(NETIF_MSG_PROBE, "MAC loopback failed\n"); 8798 DP(NETIF_MSG_PROBE, "MAC loopback failed\n");
@@ -10346,6 +10347,74 @@ static int bnx2x_resume(struct pci_dev *pdev)
10346 return rc; 10347 return rc;
10347} 10348}
10348 10349
10350static int bnx2x_eeh_nic_unload(struct bnx2x *bp)
10351{
10352 int i;
10353
10354 bp->state = BNX2X_STATE_ERROR;
10355
10356 bp->rx_mode = BNX2X_RX_MODE_NONE;
10357
10358 bnx2x_netif_stop(bp, 0);
10359
10360 del_timer_sync(&bp->timer);
10361 bp->stats_state = STATS_STATE_DISABLED;
10362 DP(BNX2X_MSG_STATS, "stats_state - DISABLED\n");
10363
10364 /* Release IRQs */
10365 bnx2x_free_irq(bp);
10366
10367 if (CHIP_IS_E1(bp)) {
10368 struct mac_configuration_cmd *config =
10369 bnx2x_sp(bp, mcast_config);
10370
10371 for (i = 0; i < config->hdr.length_6b; i++)
10372 CAM_INVALIDATE(config->config_table[i]);
10373 }
10374
10375 /* Free SKBs, SGEs, TPA pool and driver internals */
10376 bnx2x_free_skbs(bp);
10377 for_each_queue(bp, i)
10378 bnx2x_free_rx_sge_range(bp, bp->fp + i, NUM_RX_SGE);
10379 bnx2x_free_mem(bp);
10380
10381 bp->state = BNX2X_STATE_CLOSED;
10382
10383 netif_carrier_off(bp->dev);
10384
10385 return 0;
10386}
10387
10388static void bnx2x_eeh_recover(struct bnx2x *bp)
10389{
10390 u32 val;
10391
10392 mutex_init(&bp->port.phy_mutex);
10393
10394 bp->common.shmem_base = REG_RD(bp, MISC_REG_SHARED_MEM_ADDR);
10395 bp->link_params.shmem_base = bp->common.shmem_base;
10396 BNX2X_DEV_INFO("shmem offset is 0x%x\n", bp->common.shmem_base);
10397
10398 if (!bp->common.shmem_base ||
10399 (bp->common.shmem_base < 0xA0000) ||
10400 (bp->common.shmem_base >= 0xC0000)) {
10401 BNX2X_DEV_INFO("MCP not active\n");
10402 bp->flags |= NO_MCP_FLAG;
10403 return;
10404 }
10405
10406 val = SHMEM_RD(bp, validity_map[BP_PORT(bp)]);
10407 if ((val & (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
10408 != (SHR_MEM_VALIDITY_DEV_INFO | SHR_MEM_VALIDITY_MB))
10409 BNX2X_ERR("BAD MCP validity signature\n");
10410
10411 if (!BP_NOMCP(bp)) {
10412 bp->fw_seq = (SHMEM_RD(bp, func_mb[BP_FUNC(bp)].drv_mb_header)
10413 & DRV_MSG_SEQ_NUMBER_MASK);
10414 BNX2X_DEV_INFO("fw_seq 0x%08x\n", bp->fw_seq);
10415 }
10416}
10417
10349/** 10418/**
10350 * bnx2x_io_error_detected - called when PCI error is detected 10419 * bnx2x_io_error_detected - called when PCI error is detected
10351 * @pdev: Pointer to PCI device 10420 * @pdev: Pointer to PCI device
@@ -10365,7 +10434,7 @@ static pci_ers_result_t bnx2x_io_error_detected(struct pci_dev *pdev,
10365 netif_device_detach(dev); 10434 netif_device_detach(dev);
10366 10435
10367 if (netif_running(dev)) 10436 if (netif_running(dev))
10368 bnx2x_nic_unload(bp, UNLOAD_CLOSE); 10437 bnx2x_eeh_nic_unload(bp);
10369 10438
10370 pci_disable_device(pdev); 10439 pci_disable_device(pdev);
10371 10440
@@ -10420,8 +10489,10 @@ static void bnx2x_io_resume(struct pci_dev *pdev)
10420 10489
10421 rtnl_lock(); 10490 rtnl_lock();
10422 10491
10492 bnx2x_eeh_recover(bp);
10493
10423 if (netif_running(dev)) 10494 if (netif_running(dev))
10424 bnx2x_nic_load(bp, LOAD_OPEN); 10495 bnx2x_nic_load(bp, LOAD_NORMAL);
10425 10496
10426 netif_device_attach(dev); 10497 netif_device_attach(dev);
10427 10498