generic: 6.1, 6.6: mt7530: import accepted patches
authorDaniel Golle <daniel@makrotopia.org>
Tue, 23 Apr 2024 12:11:52 +0000 (13:11 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Wed, 24 Apr 2024 20:05:46 +0000 (21:05 +0100)
Import patches for the MT7530 DSA driver from net-next tree:
 cae425cb43fe net: dsa: allow DSA switch drivers to provide their own phylink mac ops
 dd0c9855b413 net: dsa: introduce dsa_phylink_to_port()
 7c5e37d7ee78 net: dsa: mt7530: simplify core operations
 868ff5f4944a net: dsa: mt7530-mdio: read PHY address of switch from device tree
 2c606d138518 net: dsa: mt7530: fix port mirroring for MT7988 SoC switch
 d59cf049c837 net: dsa: mt7530: fix mirroring frames received on local port
 62d6d91db98a net: dsa: mt7530: provide own phylink MAC operations

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
14 files changed:
target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patc [new file with mode: 0644]
target/linux/generic/backport-6.1/790-50-v6.10-net-dsa-mt7530-fix-mirroring-frames-received-on-loca.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch [new file with mode: 0644]
target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/763-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/764-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/790-33-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/790-34-v6.10-net-dsa-mt7530-fix-mirroring-frames-received-on-loca.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/790-35-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/790-36-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch [new file with mode: 0644]
target/linux/generic/backport-6.6/790-37-v6.10-net-dsa-mt7530-simplify-core-operations.patch [new file with mode: 0644]

diff --git a/target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch b/target/linux/generic/backport-6.1/765-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch
new file mode 100644 (file)
index 0000000..4cef719
--- /dev/null
@@ -0,0 +1,99 @@
+From f13b2b33c7674fa0988dfaa9adb95d7d912b489f Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 10 Apr 2024 20:42:38 +0100
+Subject: [PATCH 1/2] net: dsa: introduce dsa_phylink_to_port()
+
+We convert from a phylink_config struct to a dsa_port struct in many
+places, let's provide a helper for this.
+
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/E1rudqA-006K9B-85@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/net/dsa.h |  6 ++++++
+ net/dsa/port.c    | 12 ++++++------
+ 2 files changed, 12 insertions(+), 6 deletions(-)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -337,6 +337,12 @@ struct dsa_port {
+       struct list_head        vlans;
+ };
++static inline struct dsa_port *
++dsa_phylink_to_port(struct phylink_config *config)
++{
++      return container_of(config, struct dsa_port, pl_config);
++}
++
+ /* TODO: ideally DSA ports would have a single dp->link_dp member,
+  * and no dst->rtable nor this struct dsa_link would be needed,
+  * but this would require some more complex tree walking,
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -1552,7 +1552,7 @@ static void dsa_port_phylink_validate(st
+                                     unsigned long *supported,
+                                     struct phylink_link_state *state)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct dsa_switch *ds = dp->ds;
+       if (!ds->ops->phylink_validate) {
+@@ -1567,7 +1567,7 @@ static void dsa_port_phylink_validate(st
+ static void dsa_port_phylink_mac_pcs_get_state(struct phylink_config *config,
+                                              struct phylink_link_state *state)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct dsa_switch *ds = dp->ds;
+       int err;
+@@ -1589,7 +1589,7 @@ static struct phylink_pcs *
+ dsa_port_phylink_mac_select_pcs(struct phylink_config *config,
+                               phy_interface_t interface)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
+       struct dsa_switch *ds = dp->ds;
+@@ -1603,7 +1603,7 @@ static void dsa_port_phylink_mac_config(
+                                       unsigned int mode,
+                                       const struct phylink_link_state *state)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct dsa_switch *ds = dp->ds;
+       if (!ds->ops->phylink_mac_config)
+@@ -1614,7 +1614,7 @@ static void dsa_port_phylink_mac_config(
+ static void dsa_port_phylink_mac_an_restart(struct phylink_config *config)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct dsa_switch *ds = dp->ds;
+       if (!ds->ops->phylink_mac_an_restart)
+@@ -1627,7 +1627,7 @@ static void dsa_port_phylink_mac_link_do
+                                          unsigned int mode,
+                                          phy_interface_t interface)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct phy_device *phydev = NULL;
+       struct dsa_switch *ds = dp->ds;
+@@ -1650,7 +1650,7 @@ static void dsa_port_phylink_mac_link_up
+                                        int speed, int duplex,
+                                        bool tx_pause, bool rx_pause)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct dsa_switch *ds = dp->ds;
+       if (!ds->ops->phylink_mac_link_up) {
diff --git a/target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch b/target/linux/generic/backport-6.1/766-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch
new file mode 100644 (file)
index 0000000..51250ac
--- /dev/null
@@ -0,0 +1,117 @@
+From c22d8240fcd73a1c3ec8dcb055bd583fb970c375 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 10 Apr 2024 20:42:43 +0100
+Subject: [PATCH 2/2] net: dsa: allow DSA switch drivers to provide their own
+ phylink mac ops
+
+Rather than having a shim for each and every phylink MAC operation,
+allow DSA switch drivers to provide their own ops structure. When a
+DSA driver provides the phylink MAC operations, the shimmed ops must
+not be provided, so fail an attempt to register a switch with both
+the phylink_mac_ops in struct dsa_switch and the phylink_mac_*
+operations populated in dsa_switch_ops populated.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://lore.kernel.org/r/E1rudqF-006K9H-Cc@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/net/dsa.h |  5 +++++
+ net/dsa/dsa.c     | 11 +++++++++++
+ net/dsa/port.c    | 26 ++++++++++++++++++++------
+ 3 files changed, 36 insertions(+), 6 deletions(-)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -468,6 +468,11 @@ struct dsa_switch {
+       const struct dsa_switch_ops     *ops;
+       /*
++       * Allow a DSA switch driver to override the phylink MAC ops
++       */
++      const struct phylink_mac_ops    *phylink_mac_ops;
++
++      /*
+        * Slave mii_bus and devices for the individual ports.
+        */
+       u32                     phys_mii_mask;
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -1675,6 +1675,7 @@ static const struct phylink_mac_ops dsa_
+ int dsa_port_phylink_create(struct dsa_port *dp)
+ {
++      const struct phylink_mac_ops *mac_ops;
+       struct dsa_switch *ds = dp->ds;
+       phy_interface_t mode;
+       struct phylink *pl;
+@@ -1694,8 +1695,12 @@ int dsa_port_phylink_create(struct dsa_p
+       if (ds->ops->phylink_get_caps)
+               ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
+-      pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
+-                          mode, &dsa_port_phylink_mac_ops);
++      mac_ops = &dsa_port_phylink_mac_ops;
++      if (ds->phylink_mac_ops)
++              mac_ops = ds->phylink_mac_ops;
++
++      pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
++                          mac_ops);
+       if (IS_ERR(pl)) {
+               pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
+               return PTR_ERR(pl);
+@@ -1961,12 +1966,23 @@ static void dsa_shared_port_validate_of(
+               dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
+ }
++static void dsa_shared_port_link_down(struct dsa_port *dp)
++{
++      struct dsa_switch *ds = dp->ds;
++
++      if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down)
++              ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
++                                                 PHY_INTERFACE_MODE_NA);
++      else if (ds->ops->phylink_mac_link_down)
++              ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
++                                             PHY_INTERFACE_MODE_NA);
++}
++
+ int dsa_shared_port_link_register_of(struct dsa_port *dp)
+ {
+       struct dsa_switch *ds = dp->ds;
+       bool missing_link_description;
+       bool missing_phy_mode;
+-      int port = dp->index;
+       dsa_shared_port_validate_of(dp, &missing_phy_mode,
+                                   &missing_link_description);
+@@ -1982,9 +1998,7 @@ int dsa_shared_port_link_register_of(str
+                                "Skipping phylink registration for %s port %d\n",
+                                dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
+               } else {
+-                      if (ds->ops->phylink_mac_link_down)
+-                              ds->ops->phylink_mac_link_down(ds, port,
+-                                      MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
++                      dsa_shared_port_link_down(dp);
+                       return dsa_shared_port_phylink_register(dp);
+               }
+--- a/net/dsa/dsa2.c
++++ b/net/dsa/dsa2.c
+@@ -1736,6 +1736,15 @@ static int dsa_switch_probe(struct dsa_s
+       if (!ds->num_ports)
+               return -EINVAL;
++      if (ds->phylink_mac_ops) {
++              if (ds->ops->phylink_mac_select_pcs ||
++                  ds->ops->phylink_mac_config ||
++                  ds->ops->phylink_mac_link_down ||
++                  ds->ops->phylink_mac_link_up ||
++                  ds->ops->adjust_link)
++                      return -EINVAL;
++      }
++
+       if (np) {
+               err = dsa_switch_parse_of(ds, np);
+               if (err)
diff --git a/target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patc b/target/linux/generic/backport-6.1/790-49-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patc
new file mode 100644 (file)
index 0000000..ca2657d
--- /dev/null
@@ -0,0 +1,135 @@
+From 5754b3bdcd872aa229881b8f07f84a8404c7d72a Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Fri, 12 Apr 2024 16:15:34 +0100
+Subject: [PATCH 1/5] net: dsa: mt7530: provide own phylink MAC operations
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Convert mt753x to provide its own phylink MAC operations, thus avoiding
+the shim layer in DSA's port.c
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Link: https://lore.kernel.org/r/E1rvIco-006bQu-Fq@rmk-PC.armlinux.org.uk
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 46 +++++++++++++++++++++++++---------------
+ 1 file changed, 29 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2841,28 +2841,34 @@ mt7531_mac_config(struct dsa_switch *ds,
+ }
+ static struct phylink_pcs *
+-mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
++mt753x_phylink_mac_select_pcs(struct phylink_config *config,
+                             phy_interface_t interface)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct dsa_port *dp = dsa_phylink_to_port(config);
++      struct mt7530_priv *priv = dp->ds->priv;
+       switch (interface) {
+       case PHY_INTERFACE_MODE_TRGMII:
+-              return &priv->pcs[port].pcs;
++              return &priv->pcs[dp->index].pcs;
+       case PHY_INTERFACE_MODE_SGMII:
+       case PHY_INTERFACE_MODE_1000BASEX:
+       case PHY_INTERFACE_MODE_2500BASEX:
+-              return priv->ports[port].sgmii_pcs;
++              return priv->ports[dp->index].sgmii_pcs;
+       default:
+               return NULL;
+       }
+ }
+ static void
+-mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
++mt753x_phylink_mac_config(struct phylink_config *config, unsigned int mode,
+                         const struct phylink_link_state *state)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct dsa_port *dp = dsa_phylink_to_port(config);
++      struct dsa_switch *ds = dp->ds;
++      struct mt7530_priv *priv;
++      int port = dp->index;
++
++      priv = ds->priv;
+       if ((port == 5 || port == 6) && priv->info->mac_port_config)
+               priv->info->mac_port_config(ds, port, mode, state->interface);
+@@ -2872,23 +2878,25 @@ mt753x_phylink_mac_config(struct dsa_swi
+               mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
+ }
+-static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
++static void mt753x_phylink_mac_link_down(struct phylink_config *config,
+                                        unsigned int mode,
+                                        phy_interface_t interface)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct dsa_port *dp = dsa_phylink_to_port(config);
++      struct mt7530_priv *priv = dp->ds->priv;
+-      mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
++      mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
+ }
+-static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
++static void mt753x_phylink_mac_link_up(struct phylink_config *config,
++                                     struct phy_device *phydev,
+                                      unsigned int mode,
+                                      phy_interface_t interface,
+-                                     struct phy_device *phydev,
+                                      int speed, int duplex,
+                                      bool tx_pause, bool rx_pause)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct dsa_port *dp = dsa_phylink_to_port(config);
++      struct mt7530_priv *priv = dp->ds->priv;
+       u32 mcr;
+       mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
+@@ -2923,7 +2931,7 @@ static void mt753x_phylink_mac_link_up(s
+               }
+       }
+-      mt7530_set(priv, MT7530_PMCR_P(port), mcr);
++      mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr);
+ }
+ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
+@@ -3148,16 +3156,19 @@ const struct dsa_switch_ops mt7530_switc
+       .port_mirror_add        = mt753x_port_mirror_add,
+       .port_mirror_del        = mt753x_port_mirror_del,
+       .phylink_get_caps       = mt753x_phylink_get_caps,
+-      .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
+-      .phylink_mac_config     = mt753x_phylink_mac_config,
+-      .phylink_mac_link_down  = mt753x_phylink_mac_link_down,
+-      .phylink_mac_link_up    = mt753x_phylink_mac_link_up,
+       .get_mac_eee            = mt753x_get_mac_eee,
+       .set_mac_eee            = mt753x_set_mac_eee,
+       .master_state_change    = mt753x_conduit_state_change,
+ };
+ EXPORT_SYMBOL_GPL(mt7530_switch_ops);
++static const struct phylink_mac_ops mt753x_phylink_mac_ops = {
++      .mac_select_pcs = mt753x_phylink_mac_select_pcs,
++      .mac_config     = mt753x_phylink_mac_config,
++      .mac_link_down  = mt753x_phylink_mac_link_down,
++      .mac_link_up    = mt753x_phylink_mac_link_up,
++};
++
+ const struct mt753x_info mt753x_table[] = {
+       [ID_MT7621] = {
+               .id = ID_MT7621,
+@@ -3227,6 +3238,7 @@ mt7530_probe_common(struct mt7530_priv *
+       priv->dev = dev;
+       priv->ds->priv = priv;
+       priv->ds->ops = &mt7530_switch_ops;
++      priv->ds->phylink_mac_ops = &mt753x_phylink_mac_ops;
+       mutex_init(&priv->reg_mutex);
+       dev_set_drvdata(dev, priv);
diff --git a/target/linux/generic/backport-6.1/790-50-v6.10-net-dsa-mt7530-fix-mirroring-frames-received-on-loca.patch b/target/linux/generic/backport-6.1/790-50-v6.10-net-dsa-mt7530-fix-mirroring-frames-received-on-loca.patch
new file mode 100644 (file)
index 0000000..7640a9c
--- /dev/null
@@ -0,0 +1,70 @@
+From d4097ddef078a113643a6dcde01e99741f852adb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
+Date: Sat, 13 Apr 2024 16:01:39 +0300
+Subject: [PATCH 2/5] net: dsa: mt7530: fix mirroring frames received on local
+ port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This switch intellectual property provides a bit on the ARL global control
+register which controls allowing mirroring frames which are received on the
+local port (monitor port). This bit is unset after reset.
+
+This ability must be enabled to fully support the port mirroring feature on
+this switch intellectual property.
+
+Therefore, this patch fixes the traffic not being reflected on a port,
+which would be configured like below:
+
+  tc qdisc add dev swp0 clsact
+
+  tc filter add dev swp0 ingress matchall skip_sw \
+  action mirred egress mirror dev swp0
+
+As a side note, this configuration provides the hairpinning feature for a
+single port.
+
+Fixes: 37feab6076aa ("net: dsa: mt7530: add support for port mirroring")
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/mt7530.c | 6 ++++++
+ drivers/net/dsa/mt7530.h | 4 ++++
+ 2 files changed, 10 insertions(+)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2471,6 +2471,9 @@ mt7530_setup(struct dsa_switch *ds)
+                          PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+       }
++      /* Allow mirroring frames received on the local port (monitor port). */
++      mt7530_set(priv, MT753X_AGC, LOCAL_EN);
++
+       /* Setup VLAN ID 0 for VLAN-unaware bridges */
+       ret = mt7530_setup_vlan0(priv);
+       if (ret)
+@@ -2582,6 +2585,9 @@ mt7531_setup_common(struct dsa_switch *d
+                          PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+       }
++      /* Allow mirroring frames received on the local port (monitor port). */
++      mt7530_set(priv, MT753X_AGC, LOCAL_EN);
++
+       /* Flush the FDB table */
+       ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
+       if (ret < 0)
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -32,6 +32,10 @@ enum mt753x_id {
+ #define SYSC_REG_RSTCTRL              0x34
+ #define  RESET_MCM                    BIT(2)
++/* Register for ARL global control */
++#define MT753X_AGC                    0xc
++#define  LOCAL_EN                     BIT(7)
++
+ /* Registers to mac forward control for unknown frames */
+ #define MT7530_MFC                    0x10
+ #define  BC_FFP(x)                    (((x) & 0xff) << 24)
diff --git a/target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch b/target/linux/generic/backport-6.1/790-51-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch
new file mode 100644 (file)
index 0000000..304ea21
--- /dev/null
@@ -0,0 +1,49 @@
+From 019a17a5e76940ea86114838d1d638d4dc8d3750 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
+Date: Sat, 13 Apr 2024 16:01:40 +0300
+Subject: [PATCH 3/5] net: dsa: mt7530: fix port mirroring for MT7988 SoC
+ switch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version)
+v0.1" document shows bits 16 to 18 as the MIRROR_PORT field of the CPU
+forward control register. Currently, the MT7530 DSA subdriver configures
+bits 0 to 2 of the CPU forward control register which breaks the port
+mirroring feature for the MT7988 SoC switch.
+
+Fix this by using the MT7531_MIRROR_PORT_GET() and MT7531_MIRROR_PORT_SET()
+macros which utilise the correct bits.
+
+Fixes: 110c18bfed41 ("net: dsa: mt7530: introduce driver for MT7988 built-in switch")
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Acked-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/mt7530.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -1876,14 +1876,16 @@ mt7530_port_vlan_del(struct dsa_switch *
+ static int mt753x_mirror_port_get(unsigned int id, u32 val)
+ {
+-      return (id == ID_MT7531) ? MT7531_MIRROR_PORT_GET(val) :
+-                                 MIRROR_PORT(val);
++      return (id == ID_MT7531 || id == ID_MT7988) ?
++                     MT7531_MIRROR_PORT_GET(val) :
++                     MIRROR_PORT(val);
+ }
+ static int mt753x_mirror_port_set(unsigned int id, u32 val)
+ {
+-      return (id == ID_MT7531) ? MT7531_MIRROR_PORT_SET(val) :
+-                                 MIRROR_PORT(val);
++      return (id == ID_MT7531 || id == ID_MT7988) ?
++                     MT7531_MIRROR_PORT_SET(val) :
++                     MIRROR_PORT(val);
+ }
+ static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
diff --git a/target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch b/target/linux/generic/backport-6.1/790-52-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch
new file mode 100644 (file)
index 0000000..6b6a255
--- /dev/null
@@ -0,0 +1,238 @@
+From 5053a6cf1d50d785078562470d2a63695a9f3bf2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
+Date: Thu, 18 Apr 2024 08:35:30 +0300
+Subject: [PATCH 4/5] net: dsa: mt7530-mdio: read PHY address of switch from
+ device tree
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Read the PHY address the switch listens on from the reg property of the
+switch node on the device tree. This change brings support for MT7530
+switches on boards with such bootstrapping configuration where the switch
+listens on a different PHY address than the hardcoded PHY address on the
+driver, 31.
+
+As described on the "MT7621 Programming Guide v0.4" document, the MT7530
+switch and its PHYs can be configured to listen on the range of 7-12,
+15-20, 23-28, and 31 and 0-4 PHY addresses.
+
+There are operations where the switch PHY registers are used. For the PHY
+address of the control PHY, transform the MT753X_CTRL_PHY_ADDR constant
+into a macro and use it. The PHY address for the control PHY is 0 when the
+switch listens on 31. In any other case, it is one greater than the PHY
+address the switch listens on.
+
+Reviewed-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530-mdio.c | 28 +++++++++++++-------------
+ drivers/net/dsa/mt7530.c      | 37 +++++++++++++++++++++++------------
+ drivers/net/dsa/mt7530.h      |  4 +++-
+ 3 files changed, 41 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/dsa/mt7530-mdio.c
++++ b/drivers/net/dsa/mt7530-mdio.c
+@@ -18,7 +18,8 @@
+ static int
+ mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
+ {
+-      struct mii_bus *bus = context;
++      struct mt7530_priv *priv = context;
++      struct mii_bus *bus = priv->bus;
+       u16 page, r, lo, hi;
+       int ret;
+@@ -27,36 +28,35 @@ mt7530_regmap_write(void *context, unsig
+       lo = val & 0xffff;
+       hi = val >> 16;
+-      /* MT7530 uses 31 as the pseudo port */
+-      ret = bus->write(bus, 0x1f, 0x1f, page);
++      ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
+       if (ret < 0)
+               return ret;
+-      ret = bus->write(bus, 0x1f, r,  lo);
++      ret = bus->write(bus, priv->mdiodev->addr, r, lo);
+       if (ret < 0)
+               return ret;
+-      ret = bus->write(bus, 0x1f, 0x10, hi);
++      ret = bus->write(bus, priv->mdiodev->addr, 0x10, hi);
+       return ret;
+ }
+ static int
+ mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
+ {
+-      struct mii_bus *bus = context;
++      struct mt7530_priv *priv = context;
++      struct mii_bus *bus = priv->bus;
+       u16 page, r, lo, hi;
+       int ret;
+       page = (reg >> 6) & 0x3ff;
+       r = (reg >> 2) & 0xf;
+-      /* MT7530 uses 31 as the pseudo port */
+-      ret = bus->write(bus, 0x1f, 0x1f, page);
++      ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
+       if (ret < 0)
+               return ret;
+-      lo = bus->read(bus, 0x1f, r);
+-      hi = bus->read(bus, 0x1f, 0x10);
++      lo = bus->read(bus, priv->mdiodev->addr, r);
++      hi = bus->read(bus, priv->mdiodev->addr, 0x10);
+       *val = (hi << 16) | (lo & 0xffff);
+@@ -107,8 +107,7 @@ mt7531_create_sgmii(struct mt7530_priv *
+               mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
+               mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
+-              regmap = devm_regmap_init(priv->dev,
+-                                        &mt7530_regmap_bus, priv->bus,
++              regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
+                                         mt7531_pcs_config[i]);
+               if (IS_ERR(regmap)) {
+                       ret = PTR_ERR(regmap);
+@@ -153,6 +152,7 @@ mt7530_probe(struct mdio_device *mdiodev
+       priv->bus = mdiodev->bus;
+       priv->dev = &mdiodev->dev;
++      priv->mdiodev = mdiodev;
+       ret = mt7530_probe_common(priv);
+       if (ret)
+@@ -203,8 +203,8 @@ mt7530_probe(struct mdio_device *mdiodev
+       regmap_config->reg_stride = 4;
+       regmap_config->max_register = MT7530_CREV;
+       regmap_config->disable_locking = true;
+-      priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
+-                                      priv->bus, regmap_config);
++      priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
++                                      regmap_config);
+       if (IS_ERR(priv->regmap))
+               return PTR_ERR(priv->regmap);
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -86,22 +86,26 @@ core_read_mmd_indirect(struct mt7530_pri
+       int value, ret;
+       /* Write the desired MMD Devad */
+-      ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_CTRL, devad);
+       if (ret < 0)
+               goto err;
+       /* Write the desired MMD register address */
+-      ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_DATA, prtad);
+       if (ret < 0)
+               goto err;
+       /* Select the Function : DATA with no post increment */
+-      ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
+       if (ret < 0)
+               goto err;
+       /* Read the content of the MMD's selected register */
+-      value = bus->read(bus, 0, MII_MMD_DATA);
++      value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                        MII_MMD_DATA);
+       return value;
+ err:
+@@ -118,22 +122,26 @@ core_write_mmd_indirect(struct mt7530_pr
+       int ret;
+       /* Write the desired MMD Devad */
+-      ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_CTRL, devad);
+       if (ret < 0)
+               goto err;
+       /* Write the desired MMD register address */
+-      ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_DATA, prtad);
+       if (ret < 0)
+               goto err;
+       /* Select the Function : DATA with no post increment */
+-      ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
+       if (ret < 0)
+               goto err;
+       /* Write the data into MMD's selected register */
+-      ret = bus->write(bus, 0, MII_MMD_DATA, data);
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_DATA, data);
+ err:
+       if (ret < 0)
+               dev_err(&bus->dev,
+@@ -2670,16 +2678,19 @@ mt7531_setup(struct dsa_switch *ds)
+        * phy_[read,write]_mmd_indirect is called, we provide our own
+        * mt7531_ind_mmd_phy_[read,write] to complete this function.
+        */
+-      val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR,
++      val = mt7531_ind_c45_phy_read(priv,
++                                    MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+                                     MDIO_MMD_VEND2, CORE_PLL_GROUP4);
+       val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
+       val &= ~MT7531_PHY_PLL_OFF;
+-      mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2,
+-                               CORE_PLL_GROUP4, val);
++      mt7531_ind_c45_phy_write(priv,
++                               MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                               MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
+       /* Disable EEE advertisement on the switch PHYs. */
+-      for (i = MT753X_CTRL_PHY_ADDR;
+-           i < MT753X_CTRL_PHY_ADDR + MT7530_NUM_PHYS; i++) {
++      for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
++           i < MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr) + MT7530_NUM_PHYS;
++           i++) {
+               mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
+                                        0);
+       }
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -629,7 +629,7 @@ enum mt7531_clk_skew {
+ #define  MT7531_PHY_PLL_OFF           BIT(5)
+ #define  MT7531_PHY_PLL_BYPASS_MODE   BIT(4)
+-#define MT753X_CTRL_PHY_ADDR          0
++#define MT753X_CTRL_PHY_ADDR(addr)    ((addr + 1) & 0x1f)
+ #define CORE_PLL_GROUP5                       0x404
+ #define  RG_LCDDS_PCW_NCPO1(x)                ((x) & 0xffff)
+@@ -771,6 +771,7 @@ struct mt753x_info {
+  * @irq_enable:               IRQ enable bits, synced to SYS_INT_EN
+  * @create_sgmii:     Pointer to function creating SGMII PCS instance(s)
+  * @active_cpu_ports: Holding the active CPU ports
++ * @mdiodev:          The pointer to the MDIO device structure
+  */
+ struct mt7530_priv {
+       struct device           *dev;
+@@ -797,6 +798,7 @@ struct mt7530_priv {
+       u32 irq_enable;
+       int (*create_sgmii)(struct mt7530_priv *priv);
+       u8 active_cpu_ports;
++      struct mdio_device *mdiodev;
+ };
+ struct mt7530_hw_vlan_entry {
diff --git a/target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch b/target/linux/generic/backport-6.1/790-53-v6.10-net-dsa-mt7530-simplify-core-operations.patch
new file mode 100644 (file)
index 0000000..d9d70f1
--- /dev/null
@@ -0,0 +1,186 @@
+From 9764a08b3d260f4e7799d34bbfe64463db940d74 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
+Date: Thu, 18 Apr 2024 08:35:31 +0300
+Subject: [PATCH 5/5] net: dsa: mt7530: simplify core operations
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The core_rmw() function calls core_read_mmd_indirect() to read the
+requested register, and then calls core_write_mmd_indirect() to write the
+requested value to the register. Because Clause 22 is used to access Clause
+45 registers, some operations on core_write_mmd_indirect() are
+unnecessarily run. Get rid of core_read_mmd_indirect() and
+core_write_mmd_indirect(), and run only the necessary operations on
+core_write() and core_rmw().
+
+Reviewed-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 108 ++++++++++++++++-----------------------
+ 1 file changed, 43 insertions(+), 65 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -74,116 +74,94 @@ static const struct mt7530_mib_desc mt75
+       MIB_DESC(1, 0xb8, "RxArlDrop"),
+ };
+-/* Since phy_device has not yet been created and
+- * phy_{read,write}_mmd_indirect is not available, we provide our own
+- * core_{read,write}_mmd_indirect with core_{clear,write,set} wrappers
+- * to complete this function.
+- */
+-static int
+-core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad)
++static void
++mt7530_mutex_lock(struct mt7530_priv *priv)
++{
++      if (priv->bus)
++              mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
++}
++
++static void
++mt7530_mutex_unlock(struct mt7530_priv *priv)
++{
++      if (priv->bus)
++              mutex_unlock(&priv->bus->mdio_lock);
++}
++
++static void
++core_write(struct mt7530_priv *priv, u32 reg, u32 val)
+ {
+       struct mii_bus *bus = priv->bus;
+-      int value, ret;
++      int ret;
++
++      mt7530_mutex_lock(priv);
+       /* Write the desired MMD Devad */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_CTRL, devad);
++                       MII_MMD_CTRL, MDIO_MMD_VEND2);
+       if (ret < 0)
+               goto err;
+       /* Write the desired MMD register address */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_DATA, prtad);
++                       MII_MMD_DATA, reg);
+       if (ret < 0)
+               goto err;
+       /* Select the Function : DATA with no post increment */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
++                       MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
+       if (ret < 0)
+               goto err;
+-      /* Read the content of the MMD's selected register */
+-      value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                        MII_MMD_DATA);
+-
+-      return value;
++      /* Write the data into MMD's selected register */
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_DATA, val);
+ err:
+-      dev_err(&bus->dev,  "failed to read mmd register\n");
++      if (ret < 0)
++              dev_err(&bus->dev, "failed to write mmd register\n");
+-      return ret;
++      mt7530_mutex_unlock(priv);
+ }
+-static int
+-core_write_mmd_indirect(struct mt7530_priv *priv, int prtad,
+-                      int devad, u32 data)
++static void
++core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
+ {
+       struct mii_bus *bus = priv->bus;
++      u32 val;
+       int ret;
++      mt7530_mutex_lock(priv);
++
+       /* Write the desired MMD Devad */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_CTRL, devad);
++                       MII_MMD_CTRL, MDIO_MMD_VEND2);
+       if (ret < 0)
+               goto err;
+       /* Write the desired MMD register address */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_DATA, prtad);
++                       MII_MMD_DATA, reg);
+       if (ret < 0)
+               goto err;
+       /* Select the Function : DATA with no post increment */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
++                       MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
+       if (ret < 0)
+               goto err;
++      /* Read the content of the MMD's selected register */
++      val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                      MII_MMD_DATA);
++      val &= ~mask;
++      val |= set;
+       /* Write the data into MMD's selected register */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_DATA, data);
++                       MII_MMD_DATA, val);
+ err:
+       if (ret < 0)
+-              dev_err(&bus->dev,
+-                      "failed to write mmd register\n");
+-      return ret;
+-}
+-
+-static void
+-mt7530_mutex_lock(struct mt7530_priv *priv)
+-{
+-      if (priv->bus)
+-              mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+-}
+-
+-static void
+-mt7530_mutex_unlock(struct mt7530_priv *priv)
+-{
+-      if (priv->bus)
+-              mutex_unlock(&priv->bus->mdio_lock);
+-}
+-
+-static void
+-core_write(struct mt7530_priv *priv, u32 reg, u32 val)
+-{
+-      mt7530_mutex_lock(priv);
+-
+-      core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
+-
+-      mt7530_mutex_unlock(priv);
+-}
+-
+-static void
+-core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
+-{
+-      u32 val;
+-
+-      mt7530_mutex_lock(priv);
+-
+-      val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
+-      val &= ~mask;
+-      val |= set;
+-      core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
++              dev_err(&bus->dev, "failed to write mmd register\n");
+       mt7530_mutex_unlock(priv);
+ }
diff --git a/target/linux/generic/backport-6.6/763-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch b/target/linux/generic/backport-6.6/763-v6.10-net-dsa-introduce-dsa_phylink_to_port.patch
new file mode 100644 (file)
index 0000000..0e7ace9
--- /dev/null
@@ -0,0 +1,90 @@
+From f13b2b33c7674fa0988dfaa9adb95d7d912b489f Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 10 Apr 2024 20:42:38 +0100
+Subject: [PATCH 1/2] net: dsa: introduce dsa_phylink_to_port()
+
+We convert from a phylink_config struct to a dsa_port struct in many
+places, let's provide a helper for this.
+
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Link: https://lore.kernel.org/r/E1rudqA-006K9B-85@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/net/dsa.h |  6 ++++++
+ net/dsa/port.c    | 12 ++++++------
+ 2 files changed, 12 insertions(+), 6 deletions(-)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -327,6 +327,12 @@ struct dsa_port {
+       };
+ };
++static inline struct dsa_port *
++dsa_phylink_to_port(struct phylink_config *config)
++{
++      return container_of(config, struct dsa_port, pl_config);
++}
++
+ /* TODO: ideally DSA ports would have a single dp->link_dp member,
+  * and no dst->rtable nor this struct dsa_link would be needed,
+  * but this would require some more complex tree walking,
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -1572,7 +1572,7 @@ static struct phylink_pcs *
+ dsa_port_phylink_mac_select_pcs(struct phylink_config *config,
+                               phy_interface_t interface)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct phylink_pcs *pcs = ERR_PTR(-EOPNOTSUPP);
+       struct dsa_switch *ds = dp->ds;
+@@ -1586,7 +1586,7 @@ static int dsa_port_phylink_mac_prepare(
+                                       unsigned int mode,
+                                       phy_interface_t interface)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct dsa_switch *ds = dp->ds;
+       int err = 0;
+@@ -1601,7 +1601,7 @@ static void dsa_port_phylink_mac_config(
+                                       unsigned int mode,
+                                       const struct phylink_link_state *state)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct dsa_switch *ds = dp->ds;
+       if (!ds->ops->phylink_mac_config)
+@@ -1614,7 +1614,7 @@ static int dsa_port_phylink_mac_finish(s
+                                      unsigned int mode,
+                                      phy_interface_t interface)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct dsa_switch *ds = dp->ds;
+       int err = 0;
+@@ -1629,7 +1629,7 @@ static void dsa_port_phylink_mac_link_do
+                                          unsigned int mode,
+                                          phy_interface_t interface)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct phy_device *phydev = NULL;
+       struct dsa_switch *ds = dp->ds;
+@@ -1652,7 +1652,7 @@ static void dsa_port_phylink_mac_link_up
+                                        int speed, int duplex,
+                                        bool tx_pause, bool rx_pause)
+ {
+-      struct dsa_port *dp = container_of(config, struct dsa_port, pl_config);
++      struct dsa_port *dp = dsa_phylink_to_port(config);
+       struct dsa_switch *ds = dp->ds;
+       if (!ds->ops->phylink_mac_link_up) {
diff --git a/target/linux/generic/backport-6.6/764-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch b/target/linux/generic/backport-6.6/764-v6.10-net-dsa-allow-DSA-switch-drivers-to-provide-their-ow.patch
new file mode 100644 (file)
index 0000000..7c9ab16
--- /dev/null
@@ -0,0 +1,119 @@
+From c22d8240fcd73a1c3ec8dcb055bd583fb970c375 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 10 Apr 2024 20:42:43 +0100
+Subject: [PATCH 2/2] net: dsa: allow DSA switch drivers to provide their own
+ phylink mac ops
+
+Rather than having a shim for each and every phylink MAC operation,
+allow DSA switch drivers to provide their own ops structure. When a
+DSA driver provides the phylink MAC operations, the shimmed ops must
+not be provided, so fail an attempt to register a switch with both
+the phylink_mac_ops in struct dsa_switch and the phylink_mac_*
+operations populated in dsa_switch_ops populated.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Link: https://lore.kernel.org/r/E1rudqF-006K9H-Cc@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/net/dsa.h |  5 +++++
+ net/dsa/dsa.c     | 11 +++++++++++
+ net/dsa/port.c    | 26 ++++++++++++++++++++------
+ 3 files changed, 36 insertions(+), 6 deletions(-)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -458,6 +458,11 @@ struct dsa_switch {
+       const struct dsa_switch_ops     *ops;
+       /*
++       * Allow a DSA switch driver to override the phylink MAC ops
++       */
++      const struct phylink_mac_ops    *phylink_mac_ops;
++
++      /*
+        * Slave mii_bus and devices for the individual ports.
+        */
+       u32                     phys_mii_mask;
+--- a/net/dsa/dsa.c
++++ b/net/dsa/dsa.c
+@@ -1510,6 +1510,17 @@ static int dsa_switch_probe(struct dsa_s
+       if (!ds->num_ports)
+               return -EINVAL;
++      if (ds->phylink_mac_ops) {
++              if (ds->ops->phylink_mac_select_pcs ||
++                  ds->ops->phylink_mac_prepare ||
++                  ds->ops->phylink_mac_config ||
++                  ds->ops->phylink_mac_finish ||
++                  ds->ops->phylink_mac_link_down ||
++                  ds->ops->phylink_mac_link_up ||
++                  ds->ops->adjust_link)
++                      return -EINVAL;
++      }
++
+       if (np) {
+               err = dsa_switch_parse_of(ds, np);
+               if (err)
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -1677,6 +1677,7 @@ static const struct phylink_mac_ops dsa_
+ int dsa_port_phylink_create(struct dsa_port *dp)
+ {
++      const struct phylink_mac_ops *mac_ops;
+       struct dsa_switch *ds = dp->ds;
+       phy_interface_t mode;
+       struct phylink *pl;
+@@ -1700,8 +1701,12 @@ int dsa_port_phylink_create(struct dsa_p
+               }
+       }
+-      pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
+-                          mode, &dsa_port_phylink_mac_ops);
++      mac_ops = &dsa_port_phylink_mac_ops;
++      if (ds->phylink_mac_ops)
++              mac_ops = ds->phylink_mac_ops;
++
++      pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn), mode,
++                          mac_ops);
+       if (IS_ERR(pl)) {
+               pr_err("error creating PHYLINK: %ld\n", PTR_ERR(pl));
+               return PTR_ERR(pl);
+@@ -1967,12 +1972,23 @@ static void dsa_shared_port_validate_of(
+               dn, dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
+ }
++static void dsa_shared_port_link_down(struct dsa_port *dp)
++{
++      struct dsa_switch *ds = dp->ds;
++
++      if (ds->phylink_mac_ops && ds->phylink_mac_ops->mac_link_down)
++              ds->phylink_mac_ops->mac_link_down(&dp->pl_config, MLO_AN_FIXED,
++                                                 PHY_INTERFACE_MODE_NA);
++      else if (ds->ops->phylink_mac_link_down)
++              ds->ops->phylink_mac_link_down(ds, dp->index, MLO_AN_FIXED,
++                                             PHY_INTERFACE_MODE_NA);
++}
++
+ int dsa_shared_port_link_register_of(struct dsa_port *dp)
+ {
+       struct dsa_switch *ds = dp->ds;
+       bool missing_link_description;
+       bool missing_phy_mode;
+-      int port = dp->index;
+       dsa_shared_port_validate_of(dp, &missing_phy_mode,
+                                   &missing_link_description);
+@@ -1988,9 +2004,7 @@ int dsa_shared_port_link_register_of(str
+                                "Skipping phylink registration for %s port %d\n",
+                                dsa_port_is_cpu(dp) ? "CPU" : "DSA", dp->index);
+               } else {
+-                      if (ds->ops->phylink_mac_link_down)
+-                              ds->ops->phylink_mac_link_down(ds, port,
+-                                      MLO_AN_FIXED, PHY_INTERFACE_MODE_NA);
++                      dsa_shared_port_link_down(dp);
+                       return dsa_shared_port_phylink_register(dp);
+               }
diff --git a/target/linux/generic/backport-6.6/790-33-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch b/target/linux/generic/backport-6.6/790-33-v6.10-net-dsa-mt7530-provide-own-phylink-MAC-operations.patch
new file mode 100644 (file)
index 0000000..7cbdc9e
--- /dev/null
@@ -0,0 +1,135 @@
+From 5754b3bdcd872aa229881b8f07f84a8404c7d72a Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Fri, 12 Apr 2024 16:15:34 +0100
+Subject: [PATCH 1/5] net: dsa: mt7530: provide own phylink MAC operations
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Convert mt753x to provide its own phylink MAC operations, thus avoiding
+the shim layer in DSA's port.c
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Link: https://lore.kernel.org/r/E1rvIco-006bQu-Fq@rmk-PC.armlinux.org.uk
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 46 +++++++++++++++++++++++++---------------
+ 1 file changed, 29 insertions(+), 17 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2850,28 +2850,34 @@ mt7531_mac_config(struct dsa_switch *ds,
+ }
+ static struct phylink_pcs *
+-mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
++mt753x_phylink_mac_select_pcs(struct phylink_config *config,
+                             phy_interface_t interface)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct dsa_port *dp = dsa_phylink_to_port(config);
++      struct mt7530_priv *priv = dp->ds->priv;
+       switch (interface) {
+       case PHY_INTERFACE_MODE_TRGMII:
+-              return &priv->pcs[port].pcs;
++              return &priv->pcs[dp->index].pcs;
+       case PHY_INTERFACE_MODE_SGMII:
+       case PHY_INTERFACE_MODE_1000BASEX:
+       case PHY_INTERFACE_MODE_2500BASEX:
+-              return priv->ports[port].sgmii_pcs;
++              return priv->ports[dp->index].sgmii_pcs;
+       default:
+               return NULL;
+       }
+ }
+ static void
+-mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
++mt753x_phylink_mac_config(struct phylink_config *config, unsigned int mode,
+                         const struct phylink_link_state *state)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct dsa_port *dp = dsa_phylink_to_port(config);
++      struct dsa_switch *ds = dp->ds;
++      struct mt7530_priv *priv;
++      int port = dp->index;
++
++      priv = ds->priv;
+       if ((port == 5 || port == 6) && priv->info->mac_port_config)
+               priv->info->mac_port_config(ds, port, mode, state->interface);
+@@ -2881,23 +2887,25 @@ mt753x_phylink_mac_config(struct dsa_swi
+               mt7530_set(priv, MT7530_PMCR_P(port), PMCR_EXT_PHY);
+ }
+-static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
++static void mt753x_phylink_mac_link_down(struct phylink_config *config,
+                                        unsigned int mode,
+                                        phy_interface_t interface)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct dsa_port *dp = dsa_phylink_to_port(config);
++      struct mt7530_priv *priv = dp->ds->priv;
+-      mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
++      mt7530_clear(priv, MT7530_PMCR_P(dp->index), PMCR_LINK_SETTINGS_MASK);
+ }
+-static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
++static void mt753x_phylink_mac_link_up(struct phylink_config *config,
++                                     struct phy_device *phydev,
+                                      unsigned int mode,
+                                      phy_interface_t interface,
+-                                     struct phy_device *phydev,
+                                      int speed, int duplex,
+                                      bool tx_pause, bool rx_pause)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct dsa_port *dp = dsa_phylink_to_port(config);
++      struct mt7530_priv *priv = dp->ds->priv;
+       u32 mcr;
+       mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
+@@ -2932,7 +2940,7 @@ static void mt753x_phylink_mac_link_up(s
+               }
+       }
+-      mt7530_set(priv, MT7530_PMCR_P(port), mcr);
++      mt7530_set(priv, MT7530_PMCR_P(dp->index), mcr);
+ }
+ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
+@@ -3152,16 +3160,19 @@ const struct dsa_switch_ops mt7530_switc
+       .port_mirror_add        = mt753x_port_mirror_add,
+       .port_mirror_del        = mt753x_port_mirror_del,
+       .phylink_get_caps       = mt753x_phylink_get_caps,
+-      .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
+-      .phylink_mac_config     = mt753x_phylink_mac_config,
+-      .phylink_mac_link_down  = mt753x_phylink_mac_link_down,
+-      .phylink_mac_link_up    = mt753x_phylink_mac_link_up,
+       .get_mac_eee            = mt753x_get_mac_eee,
+       .set_mac_eee            = mt753x_set_mac_eee,
+       .master_state_change    = mt753x_conduit_state_change,
+ };
+ EXPORT_SYMBOL_GPL(mt7530_switch_ops);
++static const struct phylink_mac_ops mt753x_phylink_mac_ops = {
++      .mac_select_pcs = mt753x_phylink_mac_select_pcs,
++      .mac_config     = mt753x_phylink_mac_config,
++      .mac_link_down  = mt753x_phylink_mac_link_down,
++      .mac_link_up    = mt753x_phylink_mac_link_up,
++};
++
+ const struct mt753x_info mt753x_table[] = {
+       [ID_MT7621] = {
+               .id = ID_MT7621,
+@@ -3239,6 +3250,7 @@ mt7530_probe_common(struct mt7530_priv *
+       priv->dev = dev;
+       priv->ds->priv = priv;
+       priv->ds->ops = &mt7530_switch_ops;
++      priv->ds->phylink_mac_ops = &mt753x_phylink_mac_ops;
+       mutex_init(&priv->reg_mutex);
+       dev_set_drvdata(dev, priv);
diff --git a/target/linux/generic/backport-6.6/790-34-v6.10-net-dsa-mt7530-fix-mirroring-frames-received-on-loca.patch b/target/linux/generic/backport-6.6/790-34-v6.10-net-dsa-mt7530-fix-mirroring-frames-received-on-loca.patch
new file mode 100644 (file)
index 0000000..11f9a68
--- /dev/null
@@ -0,0 +1,70 @@
+From d4097ddef078a113643a6dcde01e99741f852adb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
+Date: Sat, 13 Apr 2024 16:01:39 +0300
+Subject: [PATCH 2/5] net: dsa: mt7530: fix mirroring frames received on local
+ port
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This switch intellectual property provides a bit on the ARL global control
+register which controls allowing mirroring frames which are received on the
+local port (monitor port). This bit is unset after reset.
+
+This ability must be enabled to fully support the port mirroring feature on
+this switch intellectual property.
+
+Therefore, this patch fixes the traffic not being reflected on a port,
+which would be configured like below:
+
+  tc qdisc add dev swp0 clsact
+
+  tc filter add dev swp0 ingress matchall skip_sw \
+  action mirred egress mirror dev swp0
+
+As a side note, this configuration provides the hairpinning feature for a
+single port.
+
+Fixes: 37feab6076aa ("net: dsa: mt7530: add support for port mirroring")
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/mt7530.c | 6 ++++++
+ drivers/net/dsa/mt7530.h | 4 ++++
+ 2 files changed, 10 insertions(+)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2480,6 +2480,9 @@ mt7530_setup(struct dsa_switch *ds)
+                          PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+       }
++      /* Allow mirroring frames received on the local port (monitor port). */
++      mt7530_set(priv, MT753X_AGC, LOCAL_EN);
++
+       /* Setup VLAN ID 0 for VLAN-unaware bridges */
+       ret = mt7530_setup_vlan0(priv);
+       if (ret)
+@@ -2591,6 +2594,9 @@ mt7531_setup_common(struct dsa_switch *d
+                          PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+       }
++      /* Allow mirroring frames received on the local port (monitor port). */
++      mt7530_set(priv, MT753X_AGC, LOCAL_EN);
++
+       /* Flush the FDB table */
+       ret = mt7530_fdb_cmd(priv, MT7530_FDB_FLUSH, NULL);
+       if (ret < 0)
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -32,6 +32,10 @@ enum mt753x_id {
+ #define SYSC_REG_RSTCTRL              0x34
+ #define  RESET_MCM                    BIT(2)
++/* Register for ARL global control */
++#define MT753X_AGC                    0xc
++#define  LOCAL_EN                     BIT(7)
++
+ /* Registers to mac forward control for unknown frames */
+ #define MT7530_MFC                    0x10
+ #define  BC_FFP(x)                    (((x) & 0xff) << 24)
diff --git a/target/linux/generic/backport-6.6/790-35-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch b/target/linux/generic/backport-6.6/790-35-v6.10-net-dsa-mt7530-fix-port-mirroring-for-MT7988-SoC-swi.patch
new file mode 100644 (file)
index 0000000..d5ba8ef
--- /dev/null
@@ -0,0 +1,49 @@
+From 019a17a5e76940ea86114838d1d638d4dc8d3750 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
+Date: Sat, 13 Apr 2024 16:01:40 +0300
+Subject: [PATCH 3/5] net: dsa: mt7530: fix port mirroring for MT7988 SoC
+ switch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The "MT7988A Wi-Fi 7 Generation Router Platform: Datasheet (Open Version)
+v0.1" document shows bits 16 to 18 as the MIRROR_PORT field of the CPU
+forward control register. Currently, the MT7530 DSA subdriver configures
+bits 0 to 2 of the CPU forward control register which breaks the port
+mirroring feature for the MT7988 SoC switch.
+
+Fix this by using the MT7531_MIRROR_PORT_GET() and MT7531_MIRROR_PORT_SET()
+macros which utilise the correct bits.
+
+Fixes: 110c18bfed41 ("net: dsa: mt7530: introduce driver for MT7988 built-in switch")
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Acked-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/mt7530.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -1883,14 +1883,16 @@ mt7530_port_vlan_del(struct dsa_switch *
+ static int mt753x_mirror_port_get(unsigned int id, u32 val)
+ {
+-      return (id == ID_MT7531) ? MT7531_MIRROR_PORT_GET(val) :
+-                                 MIRROR_PORT(val);
++      return (id == ID_MT7531 || id == ID_MT7988) ?
++                     MT7531_MIRROR_PORT_GET(val) :
++                     MIRROR_PORT(val);
+ }
+ static int mt753x_mirror_port_set(unsigned int id, u32 val)
+ {
+-      return (id == ID_MT7531) ? MT7531_MIRROR_PORT_SET(val) :
+-                                 MIRROR_PORT(val);
++      return (id == ID_MT7531 || id == ID_MT7988) ?
++                     MT7531_MIRROR_PORT_SET(val) :
++                     MIRROR_PORT(val);
+ }
+ static int mt753x_port_mirror_add(struct dsa_switch *ds, int port,
diff --git a/target/linux/generic/backport-6.6/790-36-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch b/target/linux/generic/backport-6.6/790-36-v6.10-net-dsa-mt7530-mdio-read-PHY-address-of-switch-from-.patch
new file mode 100644 (file)
index 0000000..a6cbb0f
--- /dev/null
@@ -0,0 +1,238 @@
+From 5053a6cf1d50d785078562470d2a63695a9f3bf2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
+Date: Thu, 18 Apr 2024 08:35:30 +0300
+Subject: [PATCH 4/5] net: dsa: mt7530-mdio: read PHY address of switch from
+ device tree
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Read the PHY address the switch listens on from the reg property of the
+switch node on the device tree. This change brings support for MT7530
+switches on boards with such bootstrapping configuration where the switch
+listens on a different PHY address than the hardcoded PHY address on the
+driver, 31.
+
+As described on the "MT7621 Programming Guide v0.4" document, the MT7530
+switch and its PHYs can be configured to listen on the range of 7-12,
+15-20, 23-28, and 31 and 0-4 PHY addresses.
+
+There are operations where the switch PHY registers are used. For the PHY
+address of the control PHY, transform the MT753X_CTRL_PHY_ADDR constant
+into a macro and use it. The PHY address for the control PHY is 0 when the
+switch listens on 31. In any other case, it is one greater than the PHY
+address the switch listens on.
+
+Reviewed-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530-mdio.c | 28 +++++++++++++-------------
+ drivers/net/dsa/mt7530.c      | 37 +++++++++++++++++++++++------------
+ drivers/net/dsa/mt7530.h      |  4 +++-
+ 3 files changed, 41 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/dsa/mt7530-mdio.c
++++ b/drivers/net/dsa/mt7530-mdio.c
+@@ -18,7 +18,8 @@
+ static int
+ mt7530_regmap_write(void *context, unsigned int reg, unsigned int val)
+ {
+-      struct mii_bus *bus = context;
++      struct mt7530_priv *priv = context;
++      struct mii_bus *bus = priv->bus;
+       u16 page, r, lo, hi;
+       int ret;
+@@ -27,36 +28,35 @@ mt7530_regmap_write(void *context, unsig
+       lo = val & 0xffff;
+       hi = val >> 16;
+-      /* MT7530 uses 31 as the pseudo port */
+-      ret = bus->write(bus, 0x1f, 0x1f, page);
++      ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
+       if (ret < 0)
+               return ret;
+-      ret = bus->write(bus, 0x1f, r,  lo);
++      ret = bus->write(bus, priv->mdiodev->addr, r, lo);
+       if (ret < 0)
+               return ret;
+-      ret = bus->write(bus, 0x1f, 0x10, hi);
++      ret = bus->write(bus, priv->mdiodev->addr, 0x10, hi);
+       return ret;
+ }
+ static int
+ mt7530_regmap_read(void *context, unsigned int reg, unsigned int *val)
+ {
+-      struct mii_bus *bus = context;
++      struct mt7530_priv *priv = context;
++      struct mii_bus *bus = priv->bus;
+       u16 page, r, lo, hi;
+       int ret;
+       page = (reg >> 6) & 0x3ff;
+       r = (reg >> 2) & 0xf;
+-      /* MT7530 uses 31 as the pseudo port */
+-      ret = bus->write(bus, 0x1f, 0x1f, page);
++      ret = bus->write(bus, priv->mdiodev->addr, 0x1f, page);
+       if (ret < 0)
+               return ret;
+-      lo = bus->read(bus, 0x1f, r);
+-      hi = bus->read(bus, 0x1f, 0x10);
++      lo = bus->read(bus, priv->mdiodev->addr, r);
++      hi = bus->read(bus, priv->mdiodev->addr, 0x10);
+       *val = (hi << 16) | (lo & 0xffff);
+@@ -107,8 +107,7 @@ mt7531_create_sgmii(struct mt7530_priv *
+               mt7531_pcs_config[i]->unlock = mt7530_mdio_regmap_unlock;
+               mt7531_pcs_config[i]->lock_arg = &priv->bus->mdio_lock;
+-              regmap = devm_regmap_init(priv->dev,
+-                                        &mt7530_regmap_bus, priv->bus,
++              regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
+                                         mt7531_pcs_config[i]);
+               if (IS_ERR(regmap)) {
+                       ret = PTR_ERR(regmap);
+@@ -153,6 +152,7 @@ mt7530_probe(struct mdio_device *mdiodev
+       priv->bus = mdiodev->bus;
+       priv->dev = &mdiodev->dev;
++      priv->mdiodev = mdiodev;
+       ret = mt7530_probe_common(priv);
+       if (ret)
+@@ -203,8 +203,8 @@ mt7530_probe(struct mdio_device *mdiodev
+       regmap_config->reg_stride = 4;
+       regmap_config->max_register = MT7530_CREV;
+       regmap_config->disable_locking = true;
+-      priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus,
+-                                      priv->bus, regmap_config);
++      priv->regmap = devm_regmap_init(priv->dev, &mt7530_regmap_bus, priv,
++                                      regmap_config);
+       if (IS_ERR(priv->regmap))
+               return PTR_ERR(priv->regmap);
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -86,22 +86,26 @@ core_read_mmd_indirect(struct mt7530_pri
+       int value, ret;
+       /* Write the desired MMD Devad */
+-      ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_CTRL, devad);
+       if (ret < 0)
+               goto err;
+       /* Write the desired MMD register address */
+-      ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_DATA, prtad);
+       if (ret < 0)
+               goto err;
+       /* Select the Function : DATA with no post increment */
+-      ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
+       if (ret < 0)
+               goto err;
+       /* Read the content of the MMD's selected register */
+-      value = bus->read(bus, 0, MII_MMD_DATA);
++      value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                        MII_MMD_DATA);
+       return value;
+ err:
+@@ -118,22 +122,26 @@ core_write_mmd_indirect(struct mt7530_pr
+       int ret;
+       /* Write the desired MMD Devad */
+-      ret = bus->write(bus, 0, MII_MMD_CTRL, devad);
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_CTRL, devad);
+       if (ret < 0)
+               goto err;
+       /* Write the desired MMD register address */
+-      ret = bus->write(bus, 0, MII_MMD_DATA, prtad);
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_DATA, prtad);
+       if (ret < 0)
+               goto err;
+       /* Select the Function : DATA with no post increment */
+-      ret = bus->write(bus, 0, MII_MMD_CTRL, (devad | MII_MMD_CTRL_NOINCR));
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
+       if (ret < 0)
+               goto err;
+       /* Write the data into MMD's selected register */
+-      ret = bus->write(bus, 0, MII_MMD_DATA, data);
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_DATA, data);
+ err:
+       if (ret < 0)
+               dev_err(&bus->dev,
+@@ -2679,16 +2687,19 @@ mt7531_setup(struct dsa_switch *ds)
+        * phy_[read,write]_mmd_indirect is called, we provide our own
+        * mt7531_ind_mmd_phy_[read,write] to complete this function.
+        */
+-      val = mt7531_ind_c45_phy_read(priv, MT753X_CTRL_PHY_ADDR,
++      val = mt7531_ind_c45_phy_read(priv,
++                                    MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+                                     MDIO_MMD_VEND2, CORE_PLL_GROUP4);
+       val |= MT7531_RG_SYSPLL_DMY2 | MT7531_PHY_PLL_BYPASS_MODE;
+       val &= ~MT7531_PHY_PLL_OFF;
+-      mt7531_ind_c45_phy_write(priv, MT753X_CTRL_PHY_ADDR, MDIO_MMD_VEND2,
+-                               CORE_PLL_GROUP4, val);
++      mt7531_ind_c45_phy_write(priv,
++                               MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                               MDIO_MMD_VEND2, CORE_PLL_GROUP4, val);
+       /* Disable EEE advertisement on the switch PHYs. */
+-      for (i = MT753X_CTRL_PHY_ADDR;
+-           i < MT753X_CTRL_PHY_ADDR + MT7530_NUM_PHYS; i++) {
++      for (i = MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr);
++           i < MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr) + MT7530_NUM_PHYS;
++           i++) {
+               mt7531_ind_c45_phy_write(priv, i, MDIO_MMD_AN, MDIO_AN_EEE_ADV,
+                                        0);
+       }
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -629,7 +629,7 @@ enum mt7531_clk_skew {
+ #define  MT7531_PHY_PLL_OFF           BIT(5)
+ #define  MT7531_PHY_PLL_BYPASS_MODE   BIT(4)
+-#define MT753X_CTRL_PHY_ADDR          0
++#define MT753X_CTRL_PHY_ADDR(addr)    ((addr + 1) & 0x1f)
+ #define CORE_PLL_GROUP5                       0x404
+ #define  RG_LCDDS_PCW_NCPO1(x)                ((x) & 0xffff)
+@@ -778,6 +778,7 @@ struct mt753x_info {
+  * @irq_enable:               IRQ enable bits, synced to SYS_INT_EN
+  * @create_sgmii:     Pointer to function creating SGMII PCS instance(s)
+  * @active_cpu_ports: Holding the active CPU ports
++ * @mdiodev:          The pointer to the MDIO device structure
+  */
+ struct mt7530_priv {
+       struct device           *dev;
+@@ -804,6 +805,7 @@ struct mt7530_priv {
+       u32 irq_enable;
+       int (*create_sgmii)(struct mt7530_priv *priv);
+       u8 active_cpu_ports;
++      struct mdio_device *mdiodev;
+ };
+ struct mt7530_hw_vlan_entry {
diff --git a/target/linux/generic/backport-6.6/790-37-v6.10-net-dsa-mt7530-simplify-core-operations.patch b/target/linux/generic/backport-6.6/790-37-v6.10-net-dsa-mt7530-simplify-core-operations.patch
new file mode 100644 (file)
index 0000000..d9d70f1
--- /dev/null
@@ -0,0 +1,186 @@
+From 9764a08b3d260f4e7799d34bbfe64463db940d74 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ar=C4=B1n=C3=A7=20=C3=9CNAL?= <arinc.unal@arinc9.com>
+Date: Thu, 18 Apr 2024 08:35:31 +0300
+Subject: [PATCH 5/5] net: dsa: mt7530: simplify core operations
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The core_rmw() function calls core_read_mmd_indirect() to read the
+requested register, and then calls core_write_mmd_indirect() to write the
+requested value to the register. Because Clause 22 is used to access Clause
+45 registers, some operations on core_write_mmd_indirect() are
+unnecessarily run. Get rid of core_read_mmd_indirect() and
+core_write_mmd_indirect(), and run only the necessary operations on
+core_write() and core_rmw().
+
+Reviewed-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: Arınç ÜNAL <arinc.unal@arinc9.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 108 ++++++++++++++++-----------------------
+ 1 file changed, 43 insertions(+), 65 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -74,116 +74,94 @@ static const struct mt7530_mib_desc mt75
+       MIB_DESC(1, 0xb8, "RxArlDrop"),
+ };
+-/* Since phy_device has not yet been created and
+- * phy_{read,write}_mmd_indirect is not available, we provide our own
+- * core_{read,write}_mmd_indirect with core_{clear,write,set} wrappers
+- * to complete this function.
+- */
+-static int
+-core_read_mmd_indirect(struct mt7530_priv *priv, int prtad, int devad)
++static void
++mt7530_mutex_lock(struct mt7530_priv *priv)
++{
++      if (priv->bus)
++              mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
++}
++
++static void
++mt7530_mutex_unlock(struct mt7530_priv *priv)
++{
++      if (priv->bus)
++              mutex_unlock(&priv->bus->mdio_lock);
++}
++
++static void
++core_write(struct mt7530_priv *priv, u32 reg, u32 val)
+ {
+       struct mii_bus *bus = priv->bus;
+-      int value, ret;
++      int ret;
++
++      mt7530_mutex_lock(priv);
+       /* Write the desired MMD Devad */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_CTRL, devad);
++                       MII_MMD_CTRL, MDIO_MMD_VEND2);
+       if (ret < 0)
+               goto err;
+       /* Write the desired MMD register address */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_DATA, prtad);
++                       MII_MMD_DATA, reg);
+       if (ret < 0)
+               goto err;
+       /* Select the Function : DATA with no post increment */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
++                       MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
+       if (ret < 0)
+               goto err;
+-      /* Read the content of the MMD's selected register */
+-      value = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                        MII_MMD_DATA);
+-
+-      return value;
++      /* Write the data into MMD's selected register */
++      ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                       MII_MMD_DATA, val);
+ err:
+-      dev_err(&bus->dev,  "failed to read mmd register\n");
++      if (ret < 0)
++              dev_err(&bus->dev, "failed to write mmd register\n");
+-      return ret;
++      mt7530_mutex_unlock(priv);
+ }
+-static int
+-core_write_mmd_indirect(struct mt7530_priv *priv, int prtad,
+-                      int devad, u32 data)
++static void
++core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
+ {
+       struct mii_bus *bus = priv->bus;
++      u32 val;
+       int ret;
++      mt7530_mutex_lock(priv);
++
+       /* Write the desired MMD Devad */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_CTRL, devad);
++                       MII_MMD_CTRL, MDIO_MMD_VEND2);
+       if (ret < 0)
+               goto err;
+       /* Write the desired MMD register address */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_DATA, prtad);
++                       MII_MMD_DATA, reg);
+       if (ret < 0)
+               goto err;
+       /* Select the Function : DATA with no post increment */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_CTRL, devad | MII_MMD_CTRL_NOINCR);
++                       MII_MMD_CTRL, MDIO_MMD_VEND2 | MII_MMD_CTRL_NOINCR);
+       if (ret < 0)
+               goto err;
++      /* Read the content of the MMD's selected register */
++      val = bus->read(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
++                      MII_MMD_DATA);
++      val &= ~mask;
++      val |= set;
+       /* Write the data into MMD's selected register */
+       ret = bus->write(bus, MT753X_CTRL_PHY_ADDR(priv->mdiodev->addr),
+-                       MII_MMD_DATA, data);
++                       MII_MMD_DATA, val);
+ err:
+       if (ret < 0)
+-              dev_err(&bus->dev,
+-                      "failed to write mmd register\n");
+-      return ret;
+-}
+-
+-static void
+-mt7530_mutex_lock(struct mt7530_priv *priv)
+-{
+-      if (priv->bus)
+-              mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED);
+-}
+-
+-static void
+-mt7530_mutex_unlock(struct mt7530_priv *priv)
+-{
+-      if (priv->bus)
+-              mutex_unlock(&priv->bus->mdio_lock);
+-}
+-
+-static void
+-core_write(struct mt7530_priv *priv, u32 reg, u32 val)
+-{
+-      mt7530_mutex_lock(priv);
+-
+-      core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
+-
+-      mt7530_mutex_unlock(priv);
+-}
+-
+-static void
+-core_rmw(struct mt7530_priv *priv, u32 reg, u32 mask, u32 set)
+-{
+-      u32 val;
+-
+-      mt7530_mutex_lock(priv);
+-
+-      val = core_read_mmd_indirect(priv, reg, MDIO_MMD_VEND2);
+-      val &= ~mask;
+-      val |= set;
+-      core_write_mmd_indirect(priv, reg, MDIO_MMD_VEND2, val);
++              dev_err(&bus->dev, "failed to write mmd register\n");
+       mt7530_mutex_unlock(priv);
+ }