aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/tg3.c
diff options
context:
space:
mode:
authorGavin Shan <shangw@linux.vnet.ibm.com>2013-06-25 03:24:32 -0400
committerDavid S. Miller <davem@davemloft.net>2013-06-25 20:00:40 -0400
commit6d446ec32f169c6a5d9bc90684a8082a6cbe90f6 (patch)
tree5c43bb12f31bbe9ccc96c837349a4ade53256087 /drivers/net/ethernet/broadcom/tg3.c
parentdc8482926e2b1006ed6962ac8388cb92aed4efc7 (diff)
net/tg3: Avoid delay during MMIO access
When the EEH error is the result of a fenced host bridge, MMIO accesses can be very slow (milliseconds) to timeout and return all 1's, thus causing the driver various timeout loops to take way too long and trigger soft-lockup warnings (in addition to taking minutes to recover). It might be worthwhile to check if for any of these cases, ffffffff is a valid possible value, and if not, bail early since that means the HW is either gone or isolated. In the meantime, checking that the PCI channel is offline would be workaround of the problem. Cc: <stable@vger.kernel.org> # v3.0+ Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index c777b9013164..a13463e8a2c3 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -744,6 +744,9 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
744 status = tg3_ape_read32(tp, gnt + off); 744 status = tg3_ape_read32(tp, gnt + off);
745 if (status == bit) 745 if (status == bit)
746 break; 746 break;
747 if (pci_channel_offline(tp->pdev))
748 break;
749
747 udelay(10); 750 udelay(10);
748 } 751 }
749 752
@@ -1635,6 +1638,9 @@ static void tg3_wait_for_event_ack(struct tg3 *tp)
1635 for (i = 0; i < delay_cnt; i++) { 1638 for (i = 0; i < delay_cnt; i++) {
1636 if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT)) 1639 if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
1637 break; 1640 break;
1641 if (pci_channel_offline(tp->pdev))
1642 break;
1643
1638 udelay(8); 1644 udelay(8);
1639 } 1645 }
1640} 1646}
@@ -1813,6 +1819,9 @@ static int tg3_poll_fw(struct tg3 *tp)
1813 for (i = 0; i < 200; i++) { 1819 for (i = 0; i < 200; i++) {
1814 if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE) 1820 if (tr32(VCPU_STATUS) & VCPU_STATUS_INIT_DONE)
1815 return 0; 1821 return 0;
1822 if (pci_channel_offline(tp->pdev))
1823 return -ENODEV;
1824
1816 udelay(100); 1825 udelay(100);
1817 } 1826 }
1818 return -ENODEV; 1827 return -ENODEV;
@@ -1823,6 +1832,15 @@ static int tg3_poll_fw(struct tg3 *tp)
1823 tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val); 1832 tg3_read_mem(tp, NIC_SRAM_FIRMWARE_MBOX, &val);
1824 if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1) 1833 if (val == ~NIC_SRAM_FIRMWARE_MBOX_MAGIC1)
1825 break; 1834 break;
1835 if (pci_channel_offline(tp->pdev)) {
1836 if (!tg3_flag(tp, NO_FWARE_REPORTED)) {
1837 tg3_flag_set(tp, NO_FWARE_REPORTED);
1838 netdev_info(tp->dev, "No firmware running\n");
1839 }
1840
1841 break;
1842 }
1843
1826 udelay(10); 1844 udelay(10);
1827 } 1845 }
1828 1846
@@ -3520,6 +3538,8 @@ static int tg3_pause_cpu(struct tg3 *tp, u32 cpu_base)
3520 tw32(cpu_base + CPU_MODE, CPU_MODE_HALT); 3538 tw32(cpu_base + CPU_MODE, CPU_MODE_HALT);
3521 if (tr32(cpu_base + CPU_MODE) & CPU_MODE_HALT) 3539 if (tr32(cpu_base + CPU_MODE) & CPU_MODE_HALT)
3522 break; 3540 break;
3541 if (pci_channel_offline(tp->pdev))
3542 return -EBUSY;
3523 } 3543 }
3524 3544
3525 return (i == iters) ? -EBUSY : 0; 3545 return (i == iters) ? -EBUSY : 0;
@@ -8589,6 +8609,14 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, boo
8589 tw32_f(ofs, val); 8609 tw32_f(ofs, val);
8590 8610
8591 for (i = 0; i < MAX_WAIT_CNT; i++) { 8611 for (i = 0; i < MAX_WAIT_CNT; i++) {
8612 if (pci_channel_offline(tp->pdev)) {
8613 dev_err(&tp->pdev->dev,
8614 "tg3_stop_block device offline, "
8615 "ofs=%lx enable_bit=%x\n",
8616 ofs, enable_bit);
8617 return -ENODEV;
8618 }
8619
8592 udelay(100); 8620 udelay(100);
8593 val = tr32(ofs); 8621 val = tr32(ofs);
8594 if ((val & enable_bit) == 0) 8622 if ((val & enable_bit) == 0)
@@ -8612,6 +8640,13 @@ static int tg3_abort_hw(struct tg3 *tp, bool silent)
8612 8640
8613 tg3_disable_ints(tp); 8641 tg3_disable_ints(tp);
8614 8642
8643 if (pci_channel_offline(tp->pdev)) {
8644 tp->rx_mode &= ~(RX_MODE_ENABLE | TX_MODE_ENABLE);
8645 tp->mac_mode &= ~MAC_MODE_TDE_ENABLE;
8646 err = -ENODEV;
8647 goto err_no_dev;
8648 }
8649
8615 tp->rx_mode &= ~RX_MODE_ENABLE; 8650 tp->rx_mode &= ~RX_MODE_ENABLE;
8616 tw32_f(MAC_RX_MODE, tp->rx_mode); 8651 tw32_f(MAC_RX_MODE, tp->rx_mode);
8617 udelay(10); 8652 udelay(10);
@@ -8660,6 +8695,7 @@ static int tg3_abort_hw(struct tg3 *tp, bool silent)
8660 err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent); 8695 err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent);
8661 err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent); 8696 err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent);
8662 8697
8698err_no_dev:
8663 for (i = 0; i < tp->irq_cnt; i++) { 8699 for (i = 0; i < tp->irq_cnt; i++) {
8664 struct tg3_napi *tnapi = &tp->napi[i]; 8700 struct tg3_napi *tnapi = &tp->napi[i];
8665 if (tnapi->hw_status) 8701 if (tnapi->hw_status)