* [PATCH net v2 1/4] tg3: Don't fail probe if 31-bit coherent DMA mask is unsupported
2026-11-11 12:39 [PATCH net v2 0/4] tg3: Bug fixes Pavan Chebbi
@ 2026-11-11 12:39 ` Pavan Chebbi
2026-11-11 12:39 ` [PATCH net v2 2/4] tg3: Select PLL clock when preparing for shutdown Pavan Chebbi
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Pavan Chebbi @ 2026-11-11 12:39 UTC (permalink / raw)
To: michael.chan, kuba
Cc: andrew+netdev, andrew.gospodarek, davem, edumazet, netdev, pabeni,
Pavan Chebbi, Rui Salvaterra
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 <rsalvaterra@gmail.com>
Link: https://lore.kernel.org/netdev/CALjTZvYKHWrD5m+RXimjxODvpFPw7Cq_EOEuzRi1PZT9_JxF+g@mail.gmail.com/
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
---
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
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH net v2 2/4] tg3: Select PLL clock when preparing for shutdown
2026-11-11 12:39 [PATCH net v2 0/4] tg3: Bug fixes Pavan Chebbi
2026-11-11 12:39 ` [PATCH net v2 1/4] tg3: Don't fail probe if 31-bit coherent DMA mask is unsupported Pavan Chebbi
@ 2026-11-11 12:39 ` Pavan Chebbi
2026-11-11 12:39 ` [PATCH net v2 3/4] tg3: Skip querying for management FW when no NCSI present Pavan Chebbi
2026-11-11 12:39 ` [PATCH net v2 4/4] tg3: Fix heap overflow in unbuffered NVRAM write path Pavan Chebbi
3 siblings, 0 replies; 5+ messages in thread
From: Pavan Chebbi @ 2026-11-11 12:39 UTC (permalink / raw)
To: michael.chan, kuba
Cc: andrew+netdev, andrew.gospodarek, davem, edumazet, netdev, pabeni,
Pavan Chebbi, Somnath Kotur, Kalesh AP
When the 5720 was linked up at 1G before power down, it may fail to
wake up on a single Magic packet. This is a hardware issue, which can
be avoided by locking the PLL clock source before shutdown.
On system suspend or power off with Wake-on-LAN enabled, if the last
link speed recorded before power down was 1G, set
CPMU_PLL_TLP_CLCK_SRC_NCSI_PLL in TG3_CPMU_PLL_CTRL_STAT, so that the
NCSI PLL locks on the TLP clock. The setting is cleared on resume and
at probe.
This was reported by a user, who confirmed that this change fixes it.
Fixes: ba1f3c76d760 ("tg3: Enable 5720 support")
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 35 +++++++++++++++++++++++++++++
drivers/net/ethernet/broadcom/tg3.h | 6 ++++-
2 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 2cf9d2ea069b..98338c0792e8 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -4267,8 +4267,38 @@ static void tg3_power_down_prepare(struct tg3 *tp)
return;
}
+static void tg3_ncsi_pll_tlp_clk(struct tg3 *tp, bool enable)
+{
+ u32 val;
+
+ if (tg3_asic_rev(tp) != ASIC_REV_5720)
+ return;
+
+ /* The register is shared by both functions of the device. */
+ if (tg3_ape_lock(tp, TG3_APE_LOCK_GPIO))
+ return;
+
+ val = tr32(TG3_CPMU_PLL_CTRL_STAT);
+ if (enable)
+ val |= CPMU_PLL_TLP_CLCK_SRC_NCSI_PLL;
+ else
+ val &= ~CPMU_PLL_TLP_CLCK_SRC_NCSI_PLL;
+ tw32(TG3_CPMU_PLL_CTRL_STAT, val);
+
+ tg3_ape_unlock(tp, TG3_APE_LOCK_GPIO);
+}
+
+static void tg3_wol_select_pll_clk(struct tg3 *tp)
+{
+ if (device_may_wakeup(&tp->pdev->dev) &&
+ tg3_flag(tp, WOL_ENABLE) &&
+ tp->link_config.active_speed == SPEED_1000)
+ tg3_ncsi_pll_tlp_clk(tp, true);
+}
+
static void tg3_power_down(struct tg3 *tp)
{
+ tg3_wol_select_pll_clk(tp);
pci_wake_from_d3(tp->pdev, tg3_flag(tp, WOL_ENABLE));
pci_set_power_state(tp->pdev, PCI_D3hot);
}
@@ -17886,6 +17916,8 @@ static int tg3_init_one(struct pci_dev *pdev,
goto err_out_apeunmap;
}
+ tg3_ncsi_pll_tlp_clk(tp, false);
+
/* The EPB bridge inside 5714, 5715, and 5780 and any
* device behind the EPB cannot support DMA addresses > 40-bit.
* On 64-bit systems with IOMMU, use 40-bit dma_mask.
@@ -18222,6 +18254,7 @@ static int tg3_suspend(struct device *device)
tg3_full_unlock(tp);
tg3_power_down_prepare(tp);
+ tg3_wol_select_pll_clk(tp);
unlock:
rtnl_unlock();
@@ -18241,6 +18274,8 @@ static int tg3_resume(struct device *device)
netif_device_attach(dev);
+ tg3_ncsi_pll_tlp_clk(tp, false);
+
netdev_lock(dev);
tg3_full_lock(tp, 0);
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index a9e7f88fa26d..631bacc515ab 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -1168,7 +1168,11 @@
#define CPMU_CLCK_STAT_MAC_CLCK_62_5 0x00000000
#define CPMU_CLCK_STAT_MAC_CLCK_12_5 0x00110000
#define CPMU_CLCK_STAT_MAC_CLCK_6_25 0x00130000
-/* 0x3634 --> 0x365c unused */
+/* 0x3634 unused */
+
+#define TG3_CPMU_PLL_CTRL_STAT 0x00003638
+#define CPMU_PLL_TLP_CLCK_SRC_NCSI_PLL 0x04000000
+/* 0x363c --> 0x365c unused */
#define TG3_CPMU_MUTEX_REQ 0x0000365c
#define CPMU_MUTEX_REQ_DRIVER 0x00001000
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH net v2 3/4] tg3: Skip querying for management FW when no NCSI present
2026-11-11 12:39 [PATCH net v2 0/4] tg3: Bug fixes Pavan Chebbi
2026-11-11 12:39 ` [PATCH net v2 1/4] tg3: Don't fail probe if 31-bit coherent DMA mask is unsupported Pavan Chebbi
2026-11-11 12:39 ` [PATCH net v2 2/4] tg3: Select PLL clock when preparing for shutdown Pavan Chebbi
@ 2026-11-11 12:39 ` Pavan Chebbi
2026-11-11 12:39 ` [PATCH net v2 4/4] tg3: Fix heap overflow in unbuffered NVRAM write path Pavan Chebbi
3 siblings, 0 replies; 5+ messages in thread
From: Pavan Chebbi @ 2026-11-11 12:39 UTC (permalink / raw)
To: michael.chan, kuba
Cc: andrew+netdev, andrew.gospodarek, davem, edumazet, netdev, pabeni,
Pavan Chebbi, Somnath Kotur
On BCM5719/BCM5720, when the NCSI component is missing in the NVRAM,
driver should not assume that "DASH" management FW is running by
default. In this case if user runs ethtool -i command, invalid string
"DASH" and garbage DASH FW version is being displayed. However, the
5719/20 chipset cannot have any "DASH" management firmware running.
Hence skip querying the APE FW version registers and adding the "DASH"
string to the tp->fw_ver if NCSI is not present. Just report the
bootcode version.
This was seen by a user. With this change, ethtool -i displays only the
bootcode version.
Fixes: ecc796486f0a ("tg3: Detect APE firmware types")
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 98338c0792e8..4becd1a0b009 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -16045,19 +16045,21 @@ static void tg3_probe_ncsi(struct tg3 *tp)
static void tg3_read_dash_ver(struct tg3 *tp)
{
- int vlen;
- u32 apedata;
char *fwtype;
-
- apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION);
+ u32 apedata;
+ int vlen;
if (tg3_flag(tp, APE_HAS_NCSI))
fwtype = "NCSI";
else if (tp->pdev->device == TG3PCI_DEVICE_TIGON3_5725)
fwtype = "SMASH";
+ else if (tg3_asic_rev(tp) == ASIC_REV_5719 ||
+ tg3_asic_rev(tp) == ASIC_REV_5720)
+ return;
else
fwtype = "DASH";
+ apedata = tg3_ape_read32(tp, TG3_APE_FW_VERSION);
vlen = strlen(tp->fw_ver);
snprintf(&tp->fw_ver[vlen], TG3_VER_SIZE - vlen, " %s v%d.%d.%d.%d",
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread* [PATCH net v2 4/4] tg3: Fix heap overflow in unbuffered NVRAM write path
2026-11-11 12:39 [PATCH net v2 0/4] tg3: Bug fixes Pavan Chebbi
` (2 preceding siblings ...)
2026-11-11 12:39 ` [PATCH net v2 3/4] tg3: Skip querying for management FW when no NCSI present Pavan Chebbi
@ 2026-11-11 12:39 ` Pavan Chebbi
3 siblings, 0 replies; 5+ messages in thread
From: Pavan Chebbi @ 2026-11-11 12:39 UTC (permalink / raw)
To: michael.chan, kuba
Cc: andrew+netdev, andrew.gospodarek, davem, edumazet, netdev, pabeni,
Shravya KN, Vishvambar Panth S, Pavan Chebbi
From: Shravya KN <shravya.k-n@broadcom.com>
tg3_nvram_write_block_unbuffered() reads a whole NVRAM page into a
buffer of pagesize bytes, copies the caller's data into it at page_off,
and writes the page back. The copy size was clamped to pagesize rather
than to the room left in the page, pagesize - page_off, so a write at an
offset that is not page aligned, as ETHTOOL_SEEPROM allows, copies past
the end of the buffer and corrupts the kernel heap.
Clamp size to pagesize - page_off. Also advance buf by size on each
iteration. Without this, a write that spans more than one page
programmed every page after the first with the data of the first page,
and a write that did not start on a page boundary lost the tail of the
data without reporting an error.
Reject a zero nvram_pagesize, which would otherwise make the new size
calculation wrap.
This was found by an AI code review scan. It has not been observed on
hardware, but it can be reached with ethtool -E on devices with
unbuffered flash.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reviewed-by: Vishvambar Panth S <vishvambar.panth-s@broadcom.com>
Reviewed-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: Shravya KN <shravya.k-n@broadcom.com>
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 4becd1a0b009..7558f4f164ac 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -3379,6 +3379,9 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
u32 nvram_cmd;
u8 *tmp;
+ if (!pagesize)
+ return -EINVAL;
+
tmp = kmalloc(pagesize, GFP_KERNEL);
if (tmp == NULL)
return -ENOMEM;
@@ -3399,13 +3402,14 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len,
break;
page_off = offset & pagemask;
- size = pagesize;
+ size = pagesize - page_off;
if (len < size)
size = len;
len -= size;
memcpy(tmp + page_off, buf, size);
+ buf += size;
offset = offset + (pagesize - page_off);
--
2.52.0
^ permalink raw reply related [flat|nested] 5+ messages in thread