Commit 614f4d166eee ("tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets") lowered the coherent DMA mask to 31 bits as a workaround for a spurious address overflow error in the hardware. The result of dma_set_coherent_mask() is fatal to probe, so on platforms that cannot satisfy such a mask the device fails to probe: tg3 0000:01:00.0: Unable to obtain 64 bit DMA for consistent allocations tg3 0000:01:00.0: probe with driver tg3 failed with error -5 This was reported on a Mac mini (Macmini6,2, BCM57766) running a kernel built without CONFIG_ZONE_DMA and with IOMMU passthrough as the default. Without CONFIG_ZONE_DMA, dma_direct_supported() only accepts a mask narrower than 32 bits if it covers the highest physical memory address, so with direct mapping a 31-bit coherent mask is rejected whenever memory extends above 2GB. Treat the 31-bit mask as best effort. If it is refused, warn and fall back to the mask used before 614f4d166eee, so that the device still probes. Platforms that accept the mask are unaffected. Where it is refused, 614f4d166eee never protected the device, it only stopped it from probing, so this restores the behaviour of kernels before that commit. Warn when a status block lands at an address matching the pattern described in 614f4d166eee, so that a resulting TX timeout can be identified. Fixes: 614f4d166eee ("tg3: Set coherent DMA mask bits to 31 for BCM57766 chipsets") Reported-by: Rui Salvaterra Link: https://lore.kernel.org/netdev/CALjTZvYKHWrD5m+RXimjxODvpFPw7Cq_EOEuzRi1PZT9_JxF+g@mail.gmail.com/ Signed-off-by: Pavan Chebbi --- drivers/net/ethernet/broadcom/tg3.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index 95827df4cf6a..2cf9d2ea069b 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -8867,6 +8867,13 @@ static int tg3_alloc_consistent(struct tg3 *tp) if (!tnapi->hw_status) goto err_out; + if (tg3_asic_rev(tp) == ASIC_REV_57766 && + (lower_32_bits(tnapi->status_mapping) & 0xffff0000) == + 0xffff0000) + dev_warn(&tp->pdev->dev, + "Status block at DMA address %pad may cause TX timeouts on this device\n", + &tnapi->status_mapping); + sblk = tnapi->hw_status; if (tg3_flag(tp, ENABLE_RSS)) { @@ -17756,6 +17763,7 @@ static int tg3_init_one(struct pci_dev *pdev, u64 dma_mask, persist_dma_mask; netdev_features_t features = 0; u8 addr[ETH_ALEN] __aligned(2); + u64 test_dma_mask = 0; err = pci_enable_device(pdev); if (err) { @@ -17895,15 +17903,22 @@ static int tg3_init_one(struct pci_dev *pdev, persist_dma_mask = dma_mask = DMA_BIT_MASK(64); if (tg3_asic_rev(tp) == ASIC_REV_57766) - persist_dma_mask = DMA_BIT_MASK(31); + test_dma_mask = DMA_BIT_MASK(31); /* Configure DMA attributes. */ if (dma_mask > DMA_BIT_MASK(32)) { err = dma_set_mask(&pdev->dev, dma_mask); if (!err) { features |= NETIF_F_HIGHDMA; - err = dma_set_coherent_mask(&pdev->dev, - persist_dma_mask); + if (!test_dma_mask || + dma_set_coherent_mask(&pdev->dev, + test_dma_mask)) { + if (test_dma_mask) + dev_warn(&pdev->dev, + "Unable to set 31 bit coherent DMA mask, workaround not applied\n"); + err = dma_set_coherent_mask(&pdev->dev, + persist_dma_mask); + } if (err < 0) { dev_err(&pdev->dev, "Unable to obtain 64 bit " "DMA for consistent allocations\n"); -- 2.52.0