diff options
author | Eddie Wai <waie@broadcom.com> | 2010-11-24 08:48:54 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-11-28 13:47:19 -0500 |
commit | a5dac108d57072eec4d6745f32c162524509f2cb (patch) | |
tree | e5177d7c181866ecea357ef1a9c0109d7ca39b90 /drivers/net/bnx2.c | |
parent | 19eb5cc559f716dc98ce03a5bad6030fdc71e897 (diff) |
bnx2: Fix reset bug on 5709
The 5709 chip requires the BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE bit to be
cleared and polling for pending DMAs to complete before chip reset.
Without this step, we've seen NMIs during repeated resets of the chip.
Signed-off-by: Eddie Wai <waie@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bnx2.c')
-rw-r--r-- | drivers/net/bnx2.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 0de196da4d4..78f91ef4496 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c | |||
@@ -4640,13 +4640,28 @@ bnx2_reset_chip(struct bnx2 *bp, u32 reset_code) | |||
4640 | 4640 | ||
4641 | /* Wait for the current PCI transaction to complete before | 4641 | /* Wait for the current PCI transaction to complete before |
4642 | * issuing a reset. */ | 4642 | * issuing a reset. */ |
4643 | REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, | 4643 | if ((CHIP_NUM(bp) == CHIP_NUM_5706) || |
4644 | BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | | 4644 | (CHIP_NUM(bp) == CHIP_NUM_5708)) { |
4645 | BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | | 4645 | REG_WR(bp, BNX2_MISC_ENABLE_CLR_BITS, |
4646 | BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | | 4646 | BNX2_MISC_ENABLE_CLR_BITS_TX_DMA_ENABLE | |
4647 | BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); | 4647 | BNX2_MISC_ENABLE_CLR_BITS_DMA_ENGINE_ENABLE | |
4648 | val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); | 4648 | BNX2_MISC_ENABLE_CLR_BITS_RX_DMA_ENABLE | |
4649 | udelay(5); | 4649 | BNX2_MISC_ENABLE_CLR_BITS_HOST_COALESCE_ENABLE); |
4650 | val = REG_RD(bp, BNX2_MISC_ENABLE_CLR_BITS); | ||
4651 | udelay(5); | ||
4652 | } else { /* 5709 */ | ||
4653 | val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL); | ||
4654 | val &= ~BNX2_MISC_NEW_CORE_CTL_DMA_ENABLE; | ||
4655 | REG_WR(bp, BNX2_MISC_NEW_CORE_CTL, val); | ||
4656 | val = REG_RD(bp, BNX2_MISC_NEW_CORE_CTL); | ||
4657 | |||
4658 | for (i = 0; i < 100; i++) { | ||
4659 | msleep(1); | ||
4660 | val = REG_RD(bp, BNX2_PCICFG_DEVICE_CONTROL); | ||
4661 | if (!(val & BNX2_PCICFG_DEVICE_STATUS_NO_PEND)) | ||
4662 | break; | ||
4663 | } | ||
4664 | } | ||
4650 | 4665 | ||
4651 | /* Wait for the firmware to tell us it is ok to issue a reset. */ | 4666 | /* Wait for the firmware to tell us it is ok to issue a reset. */ |
4652 | bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1); | 4667 | bnx2_fw_sync(bp, BNX2_DRV_MSG_DATA_WAIT0 | reset_code, 1, 1); |