Skip to content

Commit

Permalink
patch for tg3 driver to fix kernel hang during boot on Arista 7050QX-…
Browse files Browse the repository at this point in the history
…32 (sonic-net#12)
  • Loading branch information
Staphylo authored and lguohan committed Jan 23, 2017
1 parent 5b652fc commit 7f3b4e4
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 0 deletions.
60 changes: 60 additions & 0 deletions patch/driver-arista-net-tg3-access-regs-indirectly.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Fix kernel hangs seen and easily reproducable using ethtool -t
This issue is seen at least on Arista DCS-7050QX-32 SKUs

Index: linux-3.16/drivers/net/ethernet/broadcom/tg3.c
===================================================================
--- linux-3.16.orig/drivers/net/ethernet/broadcom/tg3.c
+++ linux-3.16/drivers/net/ethernet/broadcom/tg3.c
@@ -998,6 +998,7 @@ static void tg3_disable_ints(struct tg3
static void tg3_enable_ints(struct tg3 *tp)
{
int i;
+ static int first_called = 1;

tp->irq_sync = 0;
wmb();
@@ -1010,6 +1011,22 @@ static void tg3_enable_ints(struct tg3 *
struct tg3_napi *tnapi = &tp->napi[i];

tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);
+
+ /* Because Aboot with unpatched kernel accesses
+ * registers the old way, if Aboot shell uses the
+ * network at all and then boots a system, somehow the new
+ * way of accessing registers will fail to enable the
+ * interrupt, effectively disabling the interface.
+ *
+ * To enable the interrupt, redo the above write
+ * through mapped memory when this function is _first
+ * called_, otherwise kernel lockups may occur again.
+ */
+ if (first_called && tg3_flag(tp, ICH_WORKAROUND)) {
+ first_called = 0;
+ tg3_write32(tp, tnapi->int_mbox, tnapi->last_tag << 24);
+ }
+
if (tg3_flag(tp, 1SHOT_MSI))
tw32_mailbox_f(tnapi->int_mbox, tnapi->last_tag << 24);

@@ -16271,6 +16288,7 @@ static int tg3_get_invariants(struct tg3
if ((tp->pdev->bus->number == 0) &&
(tp->pdev->devfn == PCI_DEVFN(0x14, 0x6))) {
tg3_flag_set(tp, 4G_DMA_ONLY);
+ tg3_flag_set(tp, ICH_WORKAROUND);
}
}

@@ -16530,13 +16548,6 @@ static int tg3_get_invariants(struct tg3
tp->write32_mbox = tg3_write_indirect_mbox;
tp->write32_tx_mbox = tg3_write_indirect_mbox;
tp->write32_rx_mbox = tg3_write_indirect_mbox;
-
- iounmap(tp->regs);
- tp->regs = NULL;
-
- pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
- pci_cmd &= ~PCI_COMMAND_MEMORY;
- pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
}
if (tg3_asic_rev(tp) == ASIC_REV_5906) {
tp->read32_mbox = tg3_read32_mbox_5906;
57 changes: 57 additions & 0 deletions patch/driver-arista-net-tg3-dma-mask-4g-sb800.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
Force DMA accesses to be done in the 4G range due to a SB800 limitation
This issue is seen on Arista DCS-7050QX-32 SKUs

Index: linux-3.16/drivers/net/ethernet/broadcom/tg3.c
===================================================================
--- linux-3.16.orig/drivers/net/ethernet/broadcom/tg3.c
+++ linux-3.16/drivers/net/ethernet/broadcom/tg3.c
@@ -16264,6 +16264,16 @@ static int tg3_get_invariants(struct tg3
} while (bridge);
}

+ /* The embedded nic in ATI's SB800 can only dma to 32bit
+ * addresses. partno(noe) rev 5785041
+ */
+ if (tg3_asic_rev(tp) == ASIC_REV_5785) {
+ if ((tp->pdev->bus->number == 0) &&
+ (tp->pdev->devfn == PCI_DEVFN(0x14, 0x6))) {
+ tg3_flag_set(tp, 4G_DMA_ONLY);
+ }
+ }
+
if (tg3_asic_rev(tp) == ASIC_REV_5704 ||
tg3_asic_rev(tp) == ASIC_REV_5714)
tp->pdev_peer = tg3_find_peer(tp);
@@ -16789,8 +16799,9 @@ static int tg3_get_invariants(struct tg3

if (tg3_asic_rev(tp) == ASIC_REV_5705 &&
(grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788 ||
- grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M))
- tg3_flag_set(tp, IS_5788);
+ grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) {
+ tg3_flag_set(tp, 4G_DMA_ONLY);
+ }

if (!tg3_flag(tp, IS_5788) &&
tg3_asic_rev(tp) != ASIC_REV_5700)
@@ -17703,7 +17714,7 @@ static int tg3_init_one(struct pci_dev *
* On 64-bit systems without IOMMU, use 64-bit dma_mask and
* do DMA address check in tg3_start_xmit().
*/
- if (tg3_flag(tp, IS_5788))
+ if (tg3_flag(tp, 4G_DMA_ONLY))
persist_dma_mask = dma_mask = DMA_BIT_MASK(32);
else if (tg3_flag(tp, 40BIT_DMA_BUG)) {
persist_dma_mask = dma_mask = DMA_BIT_MASK(40);
Index: linux-3.16/drivers/net/ethernet/broadcom/tg3.h
===================================================================
--- linux-3.16.orig/drivers/net/ethernet/broadcom/tg3.h
+++ linux-3.16/drivers/net/ethernet/broadcom/tg3.h
@@ -3102,6 +3102,7 @@ enum TG3_FLAGS {
TG3_FLAG_ROBOSWITCH,
TG3_FLAG_ONE_DMA_AT_ONCE,
TG3_FLAG_RGMII_MODE,
+ TG3_FLAG_4G_DMA_ONLY,

/* Add new flags before this comment and TG3_FLAG_NUMBER_OF_FLAGS */
TG3_FLAG_NUMBER_OF_FLAGS, /* Last entry in enum TG3_FLAGS */
2 changes: 2 additions & 0 deletions patch/series
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ driver-support-sff-8436-eeprom-update.patch
driver-hwmon-pmbus-add-dps460-support.patch
driver-hwmon-pmbus-ucd9200-mlnx.patch
driver-arista-piix4-mux-patch.patch
driver-arista-net-tg3-dma-mask-4g-sb800.patch
driver-arista-net-tg3-access-regs-indirectly.patch

0 comments on commit 7f3b4e4

Please sign in to comment.