generic: 6.12: backport b53 patches from v6.18
authorÁlvaro Fernández Rojas <[email protected]>
Wed, 19 Nov 2025 08:21:39 +0000 (09:21 +0100)
committerÁlvaro Fernández Rojas <[email protected]>
Fri, 21 Nov 2025 20:42:55 +0000 (21:42 +0100)
These patches have been accepted for linux v6.18.

e57723fe536f net: dsa: b53: properly bound ARL searches for < 4 ARL bin chips
674b34c4c770 net: dsa: b53: fix ageing time for BCM53101
89eb9a62aed7 net: dsa: b53: fix reserved register access in b53_fdb_dump()
61730ac10ba9 net: dsa: b53: mmap: Implement bcm63268 gphy power control
7f95f04fe190 net: dsa: b53: mmap: Add gphy port to phy info for bcm63268
5ac00023852d net: dsa: b53: mmap: Implement bcm63xx ephy power control
e8e13073dff7 net: dsa: b53: mmap: Add register layout for bcm6368
c251304ab021 net: dsa: b53: mmap: Add register layout for bcm6318
aed2aaa3c963 net: dsa: b53: mmap: Add syscon reference and register layout for bcm63268
fcf02a462fab net: dsa: b53: Define chip IDs for more bcm63xx SoCs
be7a79145d85 net: dsa: b53: Add phy_enable(), phy_disable() methods
762e7e174da9 net: dsa: tag_brcm: do not mark link local traffic as offloaded

Signed-off-by: Álvaro Fernández Rojas <[email protected]>
13 files changed:
target/linux/bmips/patches-6.12/110-net-dsa-b53-bcm531x5-fix-cpu-rgmii-mode-interpretation.patch
target/linux/generic/backport-6.12/611-08-v6.18-net-dsa-b53-Add-phy_enable-phy_disable-methods.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-09-v6.18-net-dsa-b53-Define-chip-IDs-for-more-bcm63xx-SoCs.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-10-v6.18-net-dsa-b53-mmap-Add-syscon-reference-and-register-layout-for-bcm63268.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-11-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6318.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-12-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6368.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-13-v6.18-net-dsa-b53-mmap-Implement-bcm63xx-ephy-power-control.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-14-v6.18-net-dsa-b53-mmap-Add-gphy-port-to-phy-info-for-bcm63268.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-15-v6.18-net-dsa-b53-mmap-Implement-bcm63268-gphy-power-control.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-16-v6.18-net-dsa-b53-fix-reserved-register-access-in-b53_fdb_dump.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-17-v6.18-net-dsa-b53-fix-ageing-time-for-BCM53101.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-18-v6.18-net-dsa-b53-properly-bound-ARL-searches-for-4-ARL-bin-chips.patch [new file with mode: 0644]
target/linux/generic/backport-6.12/611-19-v6.18-net-dsa-tag_brcm-do-not-mark-link-local-traffic-as-offloaded.patch [new file with mode: 0644]

index e27c4cd98f55cff146e5069dd2978565f0324abd..fc2a9caadf78d2f54e56cc0dac000cbd49bae04a 100644 (file)
@@ -58,7 +58,7 @@ Signed-off-by: Jonas Gorski <[email protected]>
 +        the phy interface, but actually requires internal delays enabled.
 --- a/drivers/net/dsa/b53/b53_common.c
 +++ b/drivers/net/dsa/b53/b53_common.c
-@@ -1435,6 +1435,16 @@ static void b53_adjust_531x5_rgmii(struc
+@@ -1447,6 +1447,16 @@ static void b53_adjust_531x5_rgmii(struc
        else
                off = B53_RGMII_CTRL_P(port);
  
@@ -75,7 +75,7 @@ Signed-off-by: Jonas Gorski <[email protected]>
        /* Configure the port RGMII clock delay by DLL disabled and
         * tx_clk aligned timing (restoring to reset defaults)
         */
-@@ -1446,19 +1456,24 @@ static void b53_adjust_531x5_rgmii(struc
+@@ -1458,19 +1468,24 @@ static void b53_adjust_531x5_rgmii(struc
         * account for this internal delay that is inserted, otherwise
         * the switch won't be able to receive correctly.
         *
diff --git a/target/linux/generic/backport-6.12/611-08-v6.18-net-dsa-b53-Add-phy_enable-phy_disable-methods.patch b/target/linux/generic/backport-6.12/611-08-v6.18-net-dsa-b53-Add-phy_enable-phy_disable-methods.patch
new file mode 100644 (file)
index 0000000..14106e3
--- /dev/null
@@ -0,0 +1,50 @@
+From be7a79145d85af1a9d65a45560b9243b13a67782 Mon Sep 17 00:00:00 2001
+From: Kyle Hendry <[email protected]>
+Date: Wed, 23 Jul 2025 20:52:40 -0700
+Subject: [PATCH] net: dsa: b53: Add phy_enable(), phy_disable() methods
+
+Add phy enable/disable to b53 ops to be called when
+enabling/disabling ports.
+
+Signed-off-by: Kyle Hendry <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_common.c | 6 ++++++
+ drivers/net/dsa/b53/b53_priv.h   | 2 ++
+ 2 files changed, 8 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -689,6 +689,9 @@ int b53_enable_port(struct dsa_switch *d
+       cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
++      if (dev->ops->phy_enable)
++              dev->ops->phy_enable(dev, port);
++
+       if (dev->ops->irq_enable)
+               ret = dev->ops->irq_enable(dev, port);
+       if (ret)
+@@ -727,6 +730,9 @@ void b53_disable_port(struct dsa_switch
+       reg |= PORT_CTRL_RX_DISABLE | PORT_CTRL_TX_DISABLE;
+       b53_write8(dev, B53_CTRL_PAGE, B53_PORT_CTRL(port), reg);
++      if (dev->ops->phy_disable)
++              dev->ops->phy_disable(dev, port);
++
+       if (dev->ops->irq_disable)
+               dev->ops->irq_disable(dev, port);
+ }
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -45,6 +45,8 @@ struct b53_io_ops {
+       int (*phy_write16)(struct b53_device *dev, int addr, int reg, u16 value);
+       int (*irq_enable)(struct b53_device *dev, int port);
+       void (*irq_disable)(struct b53_device *dev, int port);
++      void (*phy_enable)(struct b53_device *dev, int port);
++      void (*phy_disable)(struct b53_device *dev, int port);
+       void (*phylink_get_caps)(struct b53_device *dev, int port,
+                                struct phylink_config *config);
+       struct phylink_pcs *(*phylink_mac_select_pcs)(struct b53_device *dev,
diff --git a/target/linux/generic/backport-6.12/611-09-v6.18-net-dsa-b53-Define-chip-IDs-for-more-bcm63xx-SoCs.patch b/target/linux/generic/backport-6.12/611-09-v6.18-net-dsa-b53-Define-chip-IDs-for-more-bcm63xx-SoCs.patch
new file mode 100644 (file)
index 0000000..87ce5f9
--- /dev/null
@@ -0,0 +1,124 @@
+From fcf02a462fab52fbfcb24e617dd940745afd0dff Mon Sep 17 00:00:00 2001
+From: Kyle Hendry <[email protected]>
+Date: Wed, 23 Jul 2025 20:52:42 -0700
+Subject: [PATCH] net: dsa: b53: Define chip IDs for more bcm63xx SoCs
+
+Add defines for bcm6318, bcm6328, bcm6362, bcm6368 chip IDs,
+update tables and switch init.
+
+Signed-off-by: Kyle Hendry <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_common.c | 21 ++++++---------------
+ drivers/net/dsa/b53/b53_mmap.c   |  8 ++++----
+ drivers/net/dsa/b53/b53_priv.h   | 13 +++++++++++--
+ 3 files changed, 21 insertions(+), 21 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1419,7 +1419,7 @@ static void b53_adjust_63xx_rgmii(struct
+       b53_read8(dev, B53_CTRL_PAGE, B53_RGMII_CTRL_P(port), &rgmii_ctrl);
+       rgmii_ctrl &= ~(RGMII_CTRL_DLL_RXC | RGMII_CTRL_DLL_TXC);
+-      if (is63268(dev))
++      if (is6318_268(dev))
+               rgmii_ctrl |= RGMII_CTRL_MII_OVERRIDE;
+       rgmii_ctrl |= RGMII_CTRL_ENABLE_GMII;
+@@ -2801,19 +2801,6 @@ static const struct b53_chip_data b53_sw
+               .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
+       },
+       {
+-              .chip_id = BCM63268_DEVICE_ID,
+-              .dev_name = "BCM63268",
+-              .vlans = 4096,
+-              .enabled_ports = 0, /* pdata must provide them */
+-              .arl_bins = 4,
+-              .arl_buckets = 1024,
+-              .imp_port = 8,
+-              .vta_regs = B53_VTA_REGS_63XX,
+-              .duplex_reg = B53_DUPLEX_STAT_63XX,
+-              .jumbo_pm_reg = B53_JUMBO_PORT_MASK_63XX,
+-              .jumbo_size_reg = B53_JUMBO_MAX_SIZE_63XX,
+-      },
+-      {
+               .chip_id = BCM53010_DEVICE_ID,
+               .dev_name = "BCM53010",
+               .vlans = 4096,
+@@ -2962,13 +2949,17 @@ static const struct b53_chip_data b53_sw
+ static int b53_switch_init(struct b53_device *dev)
+ {
++      u32 chip_id = dev->chip_id;
+       unsigned int i;
+       int ret;
++      if (is63xx(dev))
++              chip_id = BCM63XX_DEVICE_ID;
++
+       for (i = 0; i < ARRAY_SIZE(b53_switch_chips); i++) {
+               const struct b53_chip_data *chip = &b53_switch_chips[i];
+-              if (chip->chip_id == dev->chip_id) {
++              if (chip->chip_id == chip_id) {
+                       if (!dev->enabled_ports)
+                               dev->enabled_ports = chip->enabled_ports;
+                       dev->name = chip->dev_name;
+--- a/drivers/net/dsa/b53/b53_mmap.c
++++ b/drivers/net/dsa/b53/b53_mmap.c
+@@ -348,16 +348,16 @@ static const struct of_device_id b53_mma
+               .data = (void *)BCM63XX_DEVICE_ID,
+       }, {
+               .compatible = "brcm,bcm6318-switch",
+-              .data = (void *)BCM63268_DEVICE_ID,
++              .data = (void *)BCM6318_DEVICE_ID,
+       }, {
+               .compatible = "brcm,bcm6328-switch",
+-              .data = (void *)BCM63XX_DEVICE_ID,
++              .data = (void *)BCM6328_DEVICE_ID,
+       }, {
+               .compatible = "brcm,bcm6362-switch",
+-              .data = (void *)BCM63XX_DEVICE_ID,
++              .data = (void *)BCM6362_DEVICE_ID,
+       }, {
+               .compatible = "brcm,bcm6368-switch",
+-              .data = (void *)BCM63XX_DEVICE_ID,
++              .data = (void *)BCM6368_DEVICE_ID,
+       }, {
+               .compatible = "brcm,bcm63268-switch",
+               .data = (void *)BCM63268_DEVICE_ID,
+--- a/drivers/net/dsa/b53/b53_priv.h
++++ b/drivers/net/dsa/b53/b53_priv.h
+@@ -73,6 +73,10 @@ enum {
+       BCM53125_DEVICE_ID = 0x53125,
+       BCM53128_DEVICE_ID = 0x53128,
+       BCM63XX_DEVICE_ID = 0x6300,
++      BCM6318_DEVICE_ID = 0x6318,
++      BCM6328_DEVICE_ID = 0x6328,
++      BCM6362_DEVICE_ID = 0x6362,
++      BCM6368_DEVICE_ID = 0x6368,
+       BCM63268_DEVICE_ID = 0x63268,
+       BCM53010_DEVICE_ID = 0x53010,
+       BCM53011_DEVICE_ID = 0x53011,
+@@ -220,12 +224,17 @@ static inline int is531x5(struct b53_dev
+ static inline int is63xx(struct b53_device *dev)
+ {
+       return dev->chip_id == BCM63XX_DEVICE_ID ||
++              dev->chip_id == BCM6318_DEVICE_ID ||
++              dev->chip_id == BCM6328_DEVICE_ID ||
++              dev->chip_id == BCM6362_DEVICE_ID ||
++              dev->chip_id == BCM6368_DEVICE_ID ||
+               dev->chip_id == BCM63268_DEVICE_ID;
+ }
+-static inline int is63268(struct b53_device *dev)
++static inline int is6318_268(struct b53_device *dev)
+ {
+-      return dev->chip_id == BCM63268_DEVICE_ID;
++      return dev->chip_id == BCM6318_DEVICE_ID ||
++              dev->chip_id == BCM63268_DEVICE_ID;
+ }
+ static inline int is5301x(struct b53_device *dev)
diff --git a/target/linux/generic/backport-6.12/611-10-v6.18-net-dsa-b53-mmap-Add-syscon-reference-and-register-layout-for-bcm63268.patch b/target/linux/generic/backport-6.12/611-10-v6.18-net-dsa-b53-mmap-Add-syscon-reference-and-register-layout-for-bcm63268.patch
new file mode 100644 (file)
index 0000000..92e540d
--- /dev/null
@@ -0,0 +1,69 @@
+From aed2aaa3c963f8aabbfa061a177022fee826ebfb Mon Sep 17 00:00:00 2001
+From: Kyle Hendry <[email protected]>
+Date: Wed, 23 Jul 2025 20:52:43 -0700
+Subject: [PATCH] net: dsa: b53: mmap: Add syscon reference and register layout
+ for bcm63268
+
+On bcm63xx SoCs there are registers that control the PHYs in
+the GPIO controller. Allow the b53 driver to access them
+by passing in the syscon through the device tree.
+
+Add a structure to describe the ephy control register
+and add register info for bcm63268.
+
+Signed-off-by: Kyle Hendry <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_mmap.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_mmap.c
++++ b/drivers/net/dsa/b53/b53_mmap.c
+@@ -21,13 +21,32 @@
+ #include <linux/module.h>
+ #include <linux/of.h>
+ #include <linux/io.h>
++#include <linux/mfd/syscon.h>
+ #include <linux/platform_device.h>
+ #include <linux/platform_data/b53.h>
+ #include "b53_priv.h"
++struct b53_phy_info {
++      u32 ephy_enable_mask;
++      u32 ephy_port_mask;
++      u32 ephy_bias_bit;
++      const u32 *ephy_offset;
++};
++
+ struct b53_mmap_priv {
+       void __iomem *regs;
++      struct regmap *gpio_ctrl;
++      const struct b53_phy_info *phy_info;
++};
++
++static const u32 bcm63268_ephy_offsets[] = {4, 9, 14};
++
++static const struct b53_phy_info bcm63268_ephy_info = {
++      .ephy_enable_mask = GENMASK(4, 0),
++      .ephy_port_mask = GENMASK((ARRAY_SIZE(bcm63268_ephy_offsets) - 1), 0),
++      .ephy_bias_bit = 24,
++      .ephy_offset = bcm63268_ephy_offsets,
+ };
+ static int b53_mmap_read8(struct b53_device *dev, u8 page, u8 reg, u8 *val)
+@@ -313,6 +332,12 @@ static int b53_mmap_probe(struct platfor
+       priv->regs = pdata->regs;
++      priv->gpio_ctrl = syscon_regmap_lookup_by_phandle(np, "brcm,gpio-ctrl");
++      if (!IS_ERR(priv->gpio_ctrl)) {
++              if (pdata->chip_id == BCM63268_DEVICE_ID)
++                      priv->phy_info = &bcm63268_ephy_info;
++      }
++
+       dev = b53_switch_alloc(&pdev->dev, &b53_mmap_ops, priv);
+       if (!dev)
+               return -ENOMEM;
diff --git a/target/linux/generic/backport-6.12/611-11-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6318.patch b/target/linux/generic/backport-6.12/611-11-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6318.patch
new file mode 100644 (file)
index 0000000..f6c1cba
--- /dev/null
@@ -0,0 +1,47 @@
+From c251304ab021ff21c77e83e0babcb9eb76f8787a Mon Sep 17 00:00:00 2001
+From: Kyle Hendry <[email protected]>
+Date: Wed, 23 Jul 2025 20:52:44 -0700
+Subject: [PATCH] net: dsa: b53: mmap: Add register layout for bcm6318
+
+Add ephy register info for bcm6318, which also applies to
+bcm6328 and bcm6362.
+
+Signed-off-by: Kyle Hendry <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_mmap.c | 15 ++++++++++++++-
+ 1 file changed, 14 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/b53/b53_mmap.c
++++ b/drivers/net/dsa/b53/b53_mmap.c
+@@ -40,6 +40,15 @@ struct b53_mmap_priv {
+       const struct b53_phy_info *phy_info;
+ };
++static const u32 bcm6318_ephy_offsets[] = {4, 5, 6, 7};
++
++static const struct b53_phy_info bcm6318_ephy_info = {
++      .ephy_enable_mask = BIT(0) | BIT(4) | BIT(8) | BIT(12) | BIT(16),
++      .ephy_port_mask = GENMASK((ARRAY_SIZE(bcm6318_ephy_offsets) - 1), 0),
++      .ephy_bias_bit = 24,
++      .ephy_offset = bcm6318_ephy_offsets,
++};
++
+ static const u32 bcm63268_ephy_offsets[] = {4, 9, 14};
+ static const struct b53_phy_info bcm63268_ephy_info = {
+@@ -334,7 +343,11 @@ static int b53_mmap_probe(struct platfor
+       priv->gpio_ctrl = syscon_regmap_lookup_by_phandle(np, "brcm,gpio-ctrl");
+       if (!IS_ERR(priv->gpio_ctrl)) {
+-              if (pdata->chip_id == BCM63268_DEVICE_ID)
++              if (pdata->chip_id == BCM6318_DEVICE_ID ||
++                  pdata->chip_id == BCM6328_DEVICE_ID ||
++                  pdata->chip_id == BCM6362_DEVICE_ID)
++                      priv->phy_info = &bcm6318_ephy_info;
++              else if (pdata->chip_id == BCM63268_DEVICE_ID)
+                       priv->phy_info = &bcm63268_ephy_info;
+       }
diff --git a/target/linux/generic/backport-6.12/611-12-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6368.patch b/target/linux/generic/backport-6.12/611-12-v6.18-net-dsa-b53-mmap-Add-register-layout-for-bcm6368.patch
new file mode 100644 (file)
index 0000000..f703804
--- /dev/null
@@ -0,0 +1,42 @@
+From e8e13073dff7052b144d002bae2cfe9ddfa27e2a Mon Sep 17 00:00:00 2001
+From: Kyle Hendry <[email protected]>
+Date: Wed, 23 Jul 2025 20:52:45 -0700
+Subject: [PATCH] net: dsa: b53: mmap: Add register layout for bcm6368
+
+Add ephy register info for bcm6368.
+
+Signed-off-by: Kyle Hendry <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_mmap.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_mmap.c
++++ b/drivers/net/dsa/b53/b53_mmap.c
+@@ -49,6 +49,15 @@ static const struct b53_phy_info bcm6318
+       .ephy_offset = bcm6318_ephy_offsets,
+ };
++static const u32 bcm6368_ephy_offsets[] = {2, 3, 4, 5};
++
++static const struct b53_phy_info bcm6368_ephy_info = {
++      .ephy_enable_mask = BIT(0),
++      .ephy_port_mask = GENMASK((ARRAY_SIZE(bcm6368_ephy_offsets) - 1), 0),
++      .ephy_bias_bit = 0,
++      .ephy_offset = bcm6368_ephy_offsets,
++};
++
+ static const u32 bcm63268_ephy_offsets[] = {4, 9, 14};
+ static const struct b53_phy_info bcm63268_ephy_info = {
+@@ -347,6 +356,8 @@ static int b53_mmap_probe(struct platfor
+                   pdata->chip_id == BCM6328_DEVICE_ID ||
+                   pdata->chip_id == BCM6362_DEVICE_ID)
+                       priv->phy_info = &bcm6318_ephy_info;
++              else if (pdata->chip_id == BCM6368_DEVICE_ID)
++                      priv->phy_info = &bcm6368_ephy_info;
+               else if (pdata->chip_id == BCM63268_DEVICE_ID)
+                       priv->phy_info = &bcm63268_ephy_info;
+       }
diff --git a/target/linux/generic/backport-6.12/611-13-v6.18-net-dsa-b53-mmap-Implement-bcm63xx-ephy-power-control.patch b/target/linux/generic/backport-6.12/611-13-v6.18-net-dsa-b53-mmap-Implement-bcm63xx-ephy-power-control.patch
new file mode 100644 (file)
index 0000000..bf3aeb7
--- /dev/null
@@ -0,0 +1,100 @@
+From 5ac00023852d960528a0c1d10ae6c17893fc4113 Mon Sep 17 00:00:00 2001
+From: Kyle Hendry <[email protected]>
+Date: Wed, 23 Jul 2025 20:52:46 -0700
+Subject: [PATCH] net: dsa: b53: mmap: Implement bcm63xx ephy power control
+
+Implement the phy enable/disable calls for b53 mmap, and
+set the power down registers in the ephy control register
+appropriately.
+
+Signed-off-by: Kyle Hendry <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_mmap.c | 50 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_mmap.c
++++ b/drivers/net/dsa/b53/b53_mmap.c
+@@ -24,9 +24,12 @@
+ #include <linux/mfd/syscon.h>
+ #include <linux/platform_device.h>
+ #include <linux/platform_data/b53.h>
++#include <linux/regmap.h>
+ #include "b53_priv.h"
++#define BCM63XX_EPHY_REG 0x3C
++
+ struct b53_phy_info {
+       u32 ephy_enable_mask;
+       u32 ephy_port_mask;
+@@ -38,6 +41,7 @@ struct b53_mmap_priv {
+       void __iomem *regs;
+       struct regmap *gpio_ctrl;
+       const struct b53_phy_info *phy_info;
++      u32 phys_enabled;
+ };
+ static const u32 bcm6318_ephy_offsets[] = {4, 5, 6, 7};
+@@ -266,6 +270,50 @@ static int b53_mmap_phy_write16(struct b
+       return -EIO;
+ }
++static int bcm63xx_ephy_set(struct b53_device *dev, int port, bool enable)
++{
++      struct b53_mmap_priv *priv = dev->priv;
++      const struct b53_phy_info *info = priv->phy_info;
++      struct regmap *gpio_ctrl = priv->gpio_ctrl;
++      u32 mask, val;
++
++      if (enable) {
++              mask = (info->ephy_enable_mask << info->ephy_offset[port])
++                              | BIT(info->ephy_bias_bit);
++              val = 0;
++      } else {
++              mask = (info->ephy_enable_mask << info->ephy_offset[port]);
++              if (!((priv->phys_enabled & ~BIT(port)) & info->ephy_port_mask))
++                      mask |= BIT(info->ephy_bias_bit);
++              val = mask;
++      }
++      return regmap_update_bits(gpio_ctrl, BCM63XX_EPHY_REG, mask, val);
++}
++
++static void b53_mmap_phy_enable(struct b53_device *dev, int port)
++{
++      struct b53_mmap_priv *priv = dev->priv;
++      int ret = 0;
++
++      if (priv->phy_info && (BIT(port) & priv->phy_info->ephy_port_mask))
++              ret = bcm63xx_ephy_set(dev, port, true);
++
++      if (!ret)
++              priv->phys_enabled |= BIT(port);
++}
++
++static void b53_mmap_phy_disable(struct b53_device *dev, int port)
++{
++      struct b53_mmap_priv *priv = dev->priv;
++      int ret = 0;
++
++      if (priv->phy_info && (BIT(port) & priv->phy_info->ephy_port_mask))
++              ret = bcm63xx_ephy_set(dev, port, false);
++
++      if (!ret)
++              priv->phys_enabled &= ~BIT(port);
++}
++
+ static const struct b53_io_ops b53_mmap_ops = {
+       .read8 = b53_mmap_read8,
+       .read16 = b53_mmap_read16,
+@@ -279,6 +327,8 @@ static const struct b53_io_ops b53_mmap_
+       .write64 = b53_mmap_write64,
+       .phy_read16 = b53_mmap_phy_read16,
+       .phy_write16 = b53_mmap_phy_write16,
++      .phy_enable = b53_mmap_phy_enable,
++      .phy_disable = b53_mmap_phy_disable,
+ };
+ static int b53_mmap_probe_of(struct platform_device *pdev,
diff --git a/target/linux/generic/backport-6.12/611-14-v6.18-net-dsa-b53-mmap-Add-gphy-port-to-phy-info-for-bcm63268.patch b/target/linux/generic/backport-6.12/611-14-v6.18-net-dsa-b53-mmap-Add-gphy-port-to-phy-info-for-bcm63268.patch
new file mode 100644 (file)
index 0000000..9aa99d2
--- /dev/null
@@ -0,0 +1,33 @@
+From 7f95f04fe1903a31b61085e3ab1b4730f9d72941 Mon Sep 17 00:00:00 2001
+From: Kyle Hendry <[email protected]>
+Date: Wed, 13 Aug 2025 17:25:27 -0700
+Subject: [PATCH] net: dsa: b53: mmap: Add gphy port to phy info for bcm63268
+
+Add gphy mask to bcm63xx phy info struct and add data for bcm63268
+
+Signed-off-by: Kyle Hendry <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_mmap.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/net/dsa/b53/b53_mmap.c
++++ b/drivers/net/dsa/b53/b53_mmap.c
+@@ -31,6 +31,7 @@
+ #define BCM63XX_EPHY_REG 0x3C
+ struct b53_phy_info {
++      u32 gphy_port_mask;
+       u32 ephy_enable_mask;
+       u32 ephy_port_mask;
+       u32 ephy_bias_bit;
+@@ -65,6 +66,7 @@ static const struct b53_phy_info bcm6368
+ static const u32 bcm63268_ephy_offsets[] = {4, 9, 14};
+ static const struct b53_phy_info bcm63268_ephy_info = {
++      .gphy_port_mask = BIT(3),
+       .ephy_enable_mask = GENMASK(4, 0),
+       .ephy_port_mask = GENMASK((ARRAY_SIZE(bcm63268_ephy_offsets) - 1), 0),
+       .ephy_bias_bit = 24,
diff --git a/target/linux/generic/backport-6.12/611-15-v6.18-net-dsa-b53-mmap-Implement-bcm63268-gphy-power-control.patch b/target/linux/generic/backport-6.12/611-15-v6.18-net-dsa-b53-mmap-Implement-bcm63268-gphy-power-control.patch
new file mode 100644 (file)
index 0000000..8dda51e
--- /dev/null
@@ -0,0 +1,77 @@
+From 61730ac10ba90c52563861a0119504f6a9be9868 Mon Sep 17 00:00:00 2001
+From: Kyle Hendry <[email protected]>
+Date: Wed, 13 Aug 2025 17:25:28 -0700
+Subject: [PATCH] net: dsa: b53: mmap: Implement bcm63268 gphy power control
+
+Add check for gphy in enable/disable phy calls and set power bits
+in gphy control register.
+
+Signed-off-by: Kyle Hendry <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_mmap.c | 33 +++++++++++++++++++++++++++++----
+ 1 file changed, 29 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_mmap.c
++++ b/drivers/net/dsa/b53/b53_mmap.c
+@@ -29,6 +29,10 @@
+ #include "b53_priv.h"
+ #define BCM63XX_EPHY_REG 0x3C
++#define BCM63268_GPHY_REG 0x54
++
++#define GPHY_CTRL_LOW_PWR     BIT(3)
++#define GPHY_CTRL_IDDQ_BIAS   BIT(0)
+ struct b53_phy_info {
+       u32 gphy_port_mask;
+@@ -292,13 +296,30 @@ static int bcm63xx_ephy_set(struct b53_d
+       return regmap_update_bits(gpio_ctrl, BCM63XX_EPHY_REG, mask, val);
+ }
++static int bcm63268_gphy_set(struct b53_device *dev, bool enable)
++{
++      struct b53_mmap_priv *priv = dev->priv;
++      struct regmap *gpio_ctrl = priv->gpio_ctrl;
++      u32 mask = GPHY_CTRL_IDDQ_BIAS | GPHY_CTRL_LOW_PWR;
++      u32 val = 0;
++
++      if (!enable)
++              val = mask;
++
++      return regmap_update_bits(gpio_ctrl, BCM63268_GPHY_REG, mask, val);
++}
++
+ static void b53_mmap_phy_enable(struct b53_device *dev, int port)
+ {
+       struct b53_mmap_priv *priv = dev->priv;
+       int ret = 0;
+-      if (priv->phy_info && (BIT(port) & priv->phy_info->ephy_port_mask))
+-              ret = bcm63xx_ephy_set(dev, port, true);
++      if (priv->phy_info) {
++              if (BIT(port) & priv->phy_info->ephy_port_mask)
++                      ret = bcm63xx_ephy_set(dev, port, true);
++              else if (BIT(port) & priv->phy_info->gphy_port_mask)
++                      ret = bcm63268_gphy_set(dev, true);
++      }
+       if (!ret)
+               priv->phys_enabled |= BIT(port);
+@@ -309,8 +330,12 @@ static void b53_mmap_phy_disable(struct
+       struct b53_mmap_priv *priv = dev->priv;
+       int ret = 0;
+-      if (priv->phy_info && (BIT(port) & priv->phy_info->ephy_port_mask))
+-              ret = bcm63xx_ephy_set(dev, port, false);
++      if (priv->phy_info) {
++              if (BIT(port) & priv->phy_info->ephy_port_mask)
++                      ret = bcm63xx_ephy_set(dev, port, false);
++              else if (BIT(port) & priv->phy_info->gphy_port_mask)
++                      ret = bcm63268_gphy_set(dev, false);
++      }
+       if (!ret)
+               priv->phys_enabled &= ~BIT(port);
diff --git a/target/linux/generic/backport-6.12/611-16-v6.18-net-dsa-b53-fix-reserved-register-access-in-b53_fdb_dump.patch b/target/linux/generic/backport-6.12/611-16-v6.18-net-dsa-b53-fix-reserved-register-access-in-b53_fdb_dump.patch
new file mode 100644 (file)
index 0000000..7ca5458
--- /dev/null
@@ -0,0 +1,72 @@
+From 89eb9a62aed77b409663ba1eac152e8f758815b7 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <[email protected]>
+Date: Fri, 15 Aug 2025 22:18:09 +0200
+Subject: [PATCH] net: dsa: b53: fix reserved register access in b53_fdb_dump()
+
+When BCM5325 support was added in c45655386e53 ("net: dsa: b53: add
+support for FDB operations on 5325/5365"), the register used for ARL access
+was made conditional on the chip.
+
+But in b53_fdb_dump(), instead of the register argument the page
+argument was replaced, causing it to write to a reserved page 0x50 on
+!BCM5325*. Writing to this page seems to completely lock the switch up:
+
+[   89.680000] b53-switch spi0.1 lan2: Link is Down
+[   89.680000] WARNING: CPU: 1 PID: 26 at drivers/net/phy/phy.c:1350 _phy_state_machine+0x1bc/0x454
+[   89.720000] phy_check_link_status+0x0/0x114: returned: -5
+[   89.730000] Modules linked in: nft_fib_inet nf_flow_table_inet nft_reject_ipv6 nft_reject_ipv4 nft_reject_inet nft_reject nft_redir nft_quota nft_numgen nft_nat nft_masq nft_log nft_limit nft_hash nft_flow_offload nft_fib_ipv6 nft_fib_ipv4 nft_fib nft_ct nft_chain_nat nf_tables nf_nat nf_flow_table nf_conntrack nfnetlink nf_reject_ipv6 nf_reject_ipv4 nf_log_syslog nf_defrag_ipv6 nf_defrag_ipv4 cls_flower sch_tbf sch_ingress sch_htb sch_hfsc em_u32 cls_u32 cls_route cls_matchall cls_fw cls_flow cls_basic act_skbedit act_mirred act_gact vrf md5 crc32c_cryptoapi
+[   89.780000] CPU: 1 UID: 0 PID: 26 Comm: kworker/u10:0 Tainted: G        W           6.16.0-rc1+ #0 NONE
+[   89.780000] Tainted: [W]=WARN
+[   89.780000] Hardware name: Netgear DGND3700 v1
+[   89.780000] Workqueue: events_power_efficient phy_state_machine
+[   89.780000] Stack : 809c762c 8006b050 00000001 820a9ce3 0000114c 000affff 805d22d0 8200ba00
+[   89.780000]         82005000 6576656e 74735f70 6f776572 5f656666 10008b00 820a9cb8 82088700
+[   89.780000]         00000000 00000000 809c762c 820a9a98 00000000 00000000 ffffefff 80a7a76c
+[   89.780000]         80a70000 820a9af8 80a70000 80a70000 80a70000 00000000 809c762c 820a9dd4
+[   89.780000]         00000000 805d1494 80a029e4 80a70000 00000003 00000000 00000004 81a60004
+[   89.780000]         ...
+[   89.780000] Call Trace:
+[   89.780000] [<800228b8>] show_stack+0x38/0x118
+[   89.780000] [<8001afc4>] dump_stack_lvl+0x6c/0xac
+[   89.780000] [<80046b90>] __warn+0x9c/0x114
+[   89.780000] [<80046da8>] warn_slowpath_fmt+0x1a0/0x1b0
+[   89.780000] [<805d1494>] _phy_state_machine+0x1bc/0x454
+[   89.780000] [<805d22fc>] phy_state_machine+0x2c/0x70
+[   89.780000] [<80066b08>] process_one_work+0x1e8/0x3e0
+[   89.780000] [<80067a1c>] worker_thread+0x354/0x4e4
+[   89.780000] [<800706cc>] kthread+0x130/0x274
+[   89.780000] [<8001d808>] ret_from_kernel_thread+0x14/0x1c
+
+And any further accesses fail:
+
+[  120.790000] b53-switch spi0.1: timeout waiting for ARL to finish: 0x81
+[  120.800000] b53-switch spi0.1: port 2 failed to add 2c:b0:5d:27:9a:bd vid 3 to fdb: -145
+[  121.010000] b53-switch spi0.1: timeout waiting for ARL to finish: 0xbf
+[  121.020000] b53-switch spi0.1: port 3 failed to add 2c:b0:5d:27:9a:bd vid 3 to fdb: -145
+
+Restore the correct page B53_ARLIO_PAGE again, and move the offset
+argument to the correct place.
+
+*On BCM5325, this became a write to the MIB page of Port 1. Still
+a reserved offset, but likely less brokenness from that write.
+
+Fixes: c45655386e53 ("net: dsa: b53: add support for FDB operations on 5325/5365")
+Signed-off-by: Jonas Gorski <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2097,7 +2097,7 @@ int b53_fdb_dump(struct dsa_switch *ds,
+       /* Start search operation */
+       reg = ARL_SRCH_STDN;
+-      b53_write8(priv, offset, B53_ARL_SRCH_CTL, reg);
++      b53_write8(priv, B53_ARLIO_PAGE, offset, reg);
+       do {
+               ret = b53_arl_search_wait(priv);
diff --git a/target/linux/generic/backport-6.12/611-17-v6.18-net-dsa-b53-fix-ageing-time-for-BCM53101.patch b/target/linux/generic/backport-6.12/611-17-v6.18-net-dsa-b53-fix-ageing-time-for-BCM53101.patch
new file mode 100644 (file)
index 0000000..112fba7
--- /dev/null
@@ -0,0 +1,77 @@
+From 674b34c4c770551e916ae707829c7faea4782d3a Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <[email protected]>
+Date: Fri, 5 Sep 2025 14:45:07 +0200
+Subject: [PATCH] net: dsa: b53: fix ageing time for BCM53101
+
+For some reason Broadcom decided that BCM53101 uses 0.5s increments for
+the ageing time register, but kept the field width the same [1]. Due to
+this, the actual ageing time was always half of what was configured.
+
+Fix this by adapting the limits and value calculation for BCM53101.
+
+So far it looks like this is the only chip with the increased tick
+speed:
+
+$ grep -l -r "Specifies the aging time in 0.5 seconds" cdk/PKG/chip | sort
+cdk/PKG/chip/bcm53101/bcm53101_a0_defs.h
+
+$ grep -l -r "Specifies the aging time in seconds" cdk/PKG/chip | sort
+cdk/PKG/chip/bcm53010/bcm53010_a0_defs.h
+cdk/PKG/chip/bcm53020/bcm53020_a0_defs.h
+cdk/PKG/chip/bcm53084/bcm53084_a0_defs.h
+cdk/PKG/chip/bcm53115/bcm53115_a0_defs.h
+cdk/PKG/chip/bcm53118/bcm53118_a0_defs.h
+cdk/PKG/chip/bcm53125/bcm53125_a0_defs.h
+cdk/PKG/chip/bcm53128/bcm53128_a0_defs.h
+cdk/PKG/chip/bcm53134/bcm53134_a0_defs.h
+cdk/PKG/chip/bcm53242/bcm53242_a0_defs.h
+cdk/PKG/chip/bcm53262/bcm53262_a0_defs.h
+cdk/PKG/chip/bcm53280/bcm53280_a0_defs.h
+cdk/PKG/chip/bcm53280/bcm53280_b0_defs.h
+cdk/PKG/chip/bcm53600/bcm53600_a0_defs.h
+cdk/PKG/chip/bcm89500/bcm89500_a0_defs.h
+
+[1] https://github.com/Broadcom/OpenMDK/blob/a5d3fc9b12af3eeb68f2ca0ce7ec4056cd14d6c2/cdk/PKG/chip/bcm53101/bcm53101_a0_defs.h#L28966
+
+Fixes: e39d14a760c0 ("net: dsa: b53: implement setting ageing time")
+Signed-off-by: Jonas Gorski <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_common.c | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -1273,9 +1273,15 @@ static int b53_setup(struct dsa_switch *
+        */
+       ds->untag_vlan_aware_bridge_pvid = true;
+-      /* Ageing time is set in seconds */
+-      ds->ageing_time_min = 1 * 1000;
+-      ds->ageing_time_max = AGE_TIME_MAX * 1000;
++      if (dev->chip_id == BCM53101_DEVICE_ID) {
++              /* BCM53101 uses 0.5 second increments */
++              ds->ageing_time_min = 1 * 500;
++              ds->ageing_time_max = AGE_TIME_MAX * 500;
++      } else {
++              /* Everything else uses 1 second increments */
++              ds->ageing_time_min = 1 * 1000;
++              ds->ageing_time_max = AGE_TIME_MAX * 1000;
++      }
+       ret = b53_reset_switch(dev);
+       if (ret) {
+@@ -2584,7 +2590,10 @@ int b53_set_ageing_time(struct dsa_switc
+       else
+               reg = B53_AGING_TIME_CONTROL;
+-      atc = DIV_ROUND_CLOSEST(msecs, 1000);
++      if (dev->chip_id == BCM53101_DEVICE_ID)
++              atc = DIV_ROUND_CLOSEST(msecs, 500);
++      else
++              atc = DIV_ROUND_CLOSEST(msecs, 1000);
+       if (!is5325(dev) && !is5365(dev))
+               atc |= AGE_CHANGE;
diff --git a/target/linux/generic/backport-6.12/611-18-v6.18-net-dsa-b53-properly-bound-ARL-searches-for-4-ARL-bin-chips.patch b/target/linux/generic/backport-6.12/611-18-v6.18-net-dsa-b53-properly-bound-ARL-searches-for-4-ARL-bin-chips.patch
new file mode 100644 (file)
index 0000000..03dc36b
--- /dev/null
@@ -0,0 +1,61 @@
+From e57723fe536f040cc2635ec1545dd0a7919a321e Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <[email protected]>
+Date: Sun, 2 Nov 2025 11:07:58 +0100
+Subject: [PATCH] net: dsa: b53: properly bound ARL searches for < 4 ARL bin
+ chips
+
+When iterating over the ARL table we stop at max ARL entries / 2, but
+this is only valid if the chip actually returns 2 results at once. For
+chips with only one result register we will stop before reaching the end
+of the table if it is more than half full.
+
+Fix this by only dividing the maximum results by two if we have a chip
+with more than one result register (i.e. those with 4 ARL bins).
+
+Fixes: cd169d799bee ("net: dsa: b53: Bound check ARL searches")
+Signed-off-by: Jonas Gorski <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ drivers/net/dsa/b53/b53_common.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -2087,13 +2087,16 @@ static int b53_fdb_copy(int port, const
+ int b53_fdb_dump(struct dsa_switch *ds, int port,
+                dsa_fdb_dump_cb_t *cb, void *data)
+ {
++      unsigned int count = 0, results_per_hit = 1;
+       struct b53_device *priv = ds->priv;
+       struct b53_arl_entry results[2];
+-      unsigned int count = 0;
+       u8 offset;
+       int ret;
+       u8 reg;
++      if (priv->num_arl_bins > 2)
++              results_per_hit = 2;
++
+       mutex_lock(&priv->arl_mutex);
+       if (is5325(priv) || is5365(priv))
+@@ -2115,7 +2118,7 @@ int b53_fdb_dump(struct dsa_switch *ds,
+               if (ret)
+                       break;
+-              if (priv->num_arl_bins > 2) {
++              if (results_per_hit == 2) {
+                       b53_arl_search_rd(priv, 1, &results[1]);
+                       ret = b53_fdb_copy(port, &results[1], cb, data);
+                       if (ret)
+@@ -2125,7 +2128,7 @@ int b53_fdb_dump(struct dsa_switch *ds,
+                               break;
+               }
+-      } while (count++ < b53_max_arl_entries(priv) / 2);
++      } while (count++ < b53_max_arl_entries(priv) / results_per_hit);
+       mutex_unlock(&priv->arl_mutex);
diff --git a/target/linux/generic/backport-6.12/611-19-v6.18-net-dsa-tag_brcm-do-not-mark-link-local-traffic-as-offloaded.patch b/target/linux/generic/backport-6.12/611-19-v6.18-net-dsa-tag_brcm-do-not-mark-link-local-traffic-as-offloaded.patch
new file mode 100644 (file)
index 0000000..7c3d062
--- /dev/null
@@ -0,0 +1,59 @@
+From 762e7e174da91cf4babfe77e45bc6b67334b1503 Mon Sep 17 00:00:00 2001
+From: Jonas Gorski <[email protected]>
+Date: Sun, 9 Nov 2025 14:46:35 +0100
+Subject: [PATCH] net: dsa: tag_brcm: do not mark link local traffic as
+ offloaded
+
+Broadcom switches locally terminate link local traffic and do not
+forward it, so we should not mark it as offloaded.
+
+In some situations we still want/need to flood this traffic, e.g. if STP
+is disabled, or it is explicitly enabled via the group_fwd_mask. But if
+the skb is marked as offloaded, the kernel will assume this was already
+done in hardware, and the packets never reach other bridge ports.
+
+So ensure that link local traffic is never marked as offloaded, so that
+the kernel can forward/flood these packets in software if needed.
+
+Since the local termination in not configurable, check the destination
+MAC, and never mark packets as offloaded if it is a link local ether
+address.
+
+While modern switches set the tag reason code to BRCM_EG_RC_PROT_TERM
+for trapped link local traffic, they also set it for link local traffic
+that is flooded (01:80:c2:00:00:10 to 01:80:c2:00:00:2f), so we cannot
+use it and need to look at the destination address for them as well.
+
+Fixes: 964dbf186eaa ("net: dsa: tag_brcm: add support for legacy tags")
+Fixes: 0e62f543bed0 ("net: dsa: Fix duplicate frames flooded by learning")
+Signed-off-by: Jonas Gorski <[email protected]>
+Reviewed-by: Vladimir Oltean <[email protected]>
+Reviewed-by: Florian Fainelli <[email protected]>
+Link: https://patch.msgid.link/[email protected]
+Signed-off-by: Jakub Kicinski <[email protected]>
+---
+ net/dsa/tag_brcm.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/net/dsa/tag_brcm.c
++++ b/net/dsa/tag_brcm.c
+@@ -176,7 +176,8 @@ static struct sk_buff *brcm_tag_rcv_ll(s
+       /* Remove Broadcom tag and update checksum */
+       skb_pull_rcsum(skb, BRCM_TAG_LEN);
+-      dsa_default_offload_fwd_mark(skb);
++      if (likely(!is_link_local_ether_addr(eth_hdr(skb)->h_dest)))
++              dsa_default_offload_fwd_mark(skb);
+       return skb;
+ }
+@@ -250,7 +251,8 @@ static struct sk_buff *brcm_leg_tag_rcv(
+       /* Remove Broadcom tag and update checksum */
+       skb_pull_rcsum(skb, len);
+-      dsa_default_offload_fwd_mark(skb);
++      if (likely(!is_link_local_ether_addr(eth_hdr(skb)->h_dest)))
++              dsa_default_offload_fwd_mark(skb);
+       dsa_strip_etype_header(skb, len);