From 7f3b4e4949aa39481221a0ebf88d055676091916 Mon Sep 17 00:00:00 2001 From: Samuel Angebault Date: Mon, 23 Jan 2017 15:06:59 -0800 Subject: [PATCH] patch for tg3 driver to fix kernel hang during boot on Arista 7050QX-32 (#12) --- ...rista-net-tg3-access-regs-indirectly.patch | 60 +++++++++++++++++++ ...ver-arista-net-tg3-dma-mask-4g-sb800.patch | 57 ++++++++++++++++++ patch/series | 2 + 3 files changed, 119 insertions(+) create mode 100644 patch/driver-arista-net-tg3-access-regs-indirectly.patch create mode 100644 patch/driver-arista-net-tg3-dma-mask-4g-sb800.patch diff --git a/patch/driver-arista-net-tg3-access-regs-indirectly.patch b/patch/driver-arista-net-tg3-access-regs-indirectly.patch new file mode 100644 index 000000000000..23fecc37d1b4 --- /dev/null +++ b/patch/driver-arista-net-tg3-access-regs-indirectly.patch @@ -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; diff --git a/patch/driver-arista-net-tg3-dma-mask-4g-sb800.patch b/patch/driver-arista-net-tg3-dma-mask-4g-sb800.patch new file mode 100644 index 000000000000..e90c0c4a9745 --- /dev/null +++ b/patch/driver-arista-net-tg3-dma-mask-4g-sb800.patch @@ -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 */ diff --git a/patch/series b/patch/series index 334e242931c0..c502859dd18b 100644 --- a/patch/series +++ b/patch/series @@ -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