--- /dev/null
+From f9b3827ee66cfcf297d0acd6ecf33653a5f297ef Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 22 Feb 2021 14:30:10 -0800
+Subject: net: dsa: b53: Support setting learning on port
+
+From: Florian Fainelli <f.fainelli@gmail.com>
+
+commit f9b3827ee66cfcf297d0acd6ecf33653a5f297ef upstream.
+
+Add support for being able to set the learning attribute on port, and
+make sure that the standalone ports start up with learning disabled.
+
+We can remove the code in bcm_sf2 that configured the ports learning
+attribute because we want the standalone ports to have learning disabled
+by default and port 7 cannot be bridged, so its learning attribute will
+not change past its initial configuration.
+
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/net/dsa/b53/b53_common.c | 18 ++++++++++++++++++
+ drivers/net/dsa/b53/b53_regs.h | 1 +
+ drivers/net/dsa/bcm_sf2.c | 15 +--------------
+ 3 files changed, 20 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/dsa/b53/b53_common.c
++++ b/drivers/net/dsa/b53/b53_common.c
+@@ -510,6 +510,19 @@ void b53_imp_vlan_setup(struct dsa_switc
+ }
+ EXPORT_SYMBOL(b53_imp_vlan_setup);
+
++static void b53_port_set_learning(struct b53_device *dev, int port,
++ bool learning)
++{
++ u16 reg;
++
++ b53_read16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, ®);
++ if (learning)
++ reg &= ~BIT(port);
++ else
++ reg |= BIT(port);
++ b53_write16(dev, B53_CTRL_PAGE, B53_DIS_LEARNING, reg);
++}
++
+ int b53_enable_port(struct dsa_switch *ds, int port, struct phy_device *phy)
+ {
+ struct b53_device *dev = ds->priv;
+@@ -523,6 +536,7 @@ int b53_enable_port(struct dsa_switch *d
+ cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
+
+ b53_br_egress_floods(ds, port, true, true);
++ b53_port_set_learning(dev, port, false);
+
+ if (dev->ops->irq_enable)
+ ret = dev->ops->irq_enable(dev, port);
+@@ -656,6 +670,7 @@ static void b53_enable_cpu_port(struct b
+ b53_brcm_hdr_setup(dev->ds, port);
+
+ b53_br_egress_floods(dev->ds, port, true, true);
++ b53_port_set_learning(dev, port, false);
+ }
+
+ static void b53_enable_mib(struct b53_device *dev)
+@@ -1839,6 +1854,8 @@ int b53_br_join(struct dsa_switch *ds, i
+ b53_write16(dev, B53_PVLAN_PAGE, B53_PVLAN_PORT_MASK(port), pvlan);
+ dev->ports[port].vlan_ctl_mask = pvlan;
+
++ b53_port_set_learning(dev, port, true);
++
+ return 0;
+ }
+ EXPORT_SYMBOL(b53_br_join);
+@@ -1886,6 +1903,7 @@ void b53_br_leave(struct dsa_switch *ds,
+ vl->untag |= BIT(port) | BIT(cpu_port);
+ b53_set_vlan_entry(dev, pvid, vl);
+ }
++ b53_port_set_learning(dev, port, false);
+ }
+ EXPORT_SYMBOL(b53_br_leave);
+
+--- a/drivers/net/dsa/b53/b53_regs.h
++++ b/drivers/net/dsa/b53/b53_regs.h
+@@ -115,6 +115,7 @@
+ #define B53_UC_FLOOD_MASK 0x32
+ #define B53_MC_FLOOD_MASK 0x34
+ #define B53_IPMC_FLOOD_MASK 0x36
++#define B53_DIS_LEARNING 0x3c
+
+ /*
+ * Override Ports 0-7 State on devices with xMII interfaces (8 bit)
+--- a/drivers/net/dsa/bcm_sf2.c
++++ b/drivers/net/dsa/bcm_sf2.c
+@@ -222,23 +222,10 @@ static int bcm_sf2_port_setup(struct dsa
+ reg &= ~P_TXQ_PSM_VDD(port);
+ core_writel(priv, reg, CORE_MEM_PSM_VDD_CTRL);
+
+- /* Enable learning */
+- reg = core_readl(priv, CORE_DIS_LEARN);
+- reg &= ~BIT(port);
+- core_writel(priv, reg, CORE_DIS_LEARN);
+-
+ /* Enable Broadcom tags for that port if requested */
+- if (priv->brcm_tag_mask & BIT(port)) {
++ if (priv->brcm_tag_mask & BIT(port))
+ b53_brcm_hdr_setup(ds, port);
+
+- /* Disable learning on ASP port */
+- if (port == 7) {
+- reg = core_readl(priv, CORE_DIS_LEARN);
+- reg |= BIT(port);
+- core_writel(priv, reg, CORE_DIS_LEARN);
+- }
+- }
+-
+ /* Configure Traffic Class to QoS mapping, allow each priority to map
+ * to a different queue number
+ */