kernel: backport generic phylink validate
authorDaniel Golle <daniel@makrotopia.org>
Mon, 25 Jul 2022 00:31:20 +0000 (02:31 +0200)
committerDaniel Golle <daniel@makrotopia.org>
Tue, 30 Aug 2022 12:36:28 +0000 (13:36 +0100)
Backport generic phylink validate series and make use of it for
mtk_eth_soc Ethernet driver as well as mt7530 DSA driver.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
56 files changed:
target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-15-v5.19-net-mtk_eth_soc-move-MAC_MCR-setting-to-mac_finish.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/765-1-net-next-net-dsa-reorder-PHY-initialization-with-MTU-setup-in.patch
target/linux/generic/backport-5.15/765-2-net-next-net-dsa-merge-rtnl_lock-sections-in-dsa_slave_create.patch
target/linux/generic/backport-5.15/766-01-net-dsa-provide-switch-operations-for-tracking-the-m.patch
target/linux/generic/pending-5.15/702-net-ethernet-mtk_eth_soc-enable-threaded-NAPI.patch
target/linux/generic/pending-5.15/703-phy-add-detach-callback-to-struct-phy_driver.patch
target/linux/mediatek/patches-5.15/510-net-mediatek-add-flow-offload-for-mt7623.patch
target/linux/mediatek/patches-5.15/703-v5.17-net-ethernet-mtk_eth_soc-implement-Clause-45-MDIO-ac.patch
target/linux/mediatek/patches-5.15/704-net-ethernet-mtk_eth_soc-announce-2500baseT.patch [deleted file]
target/linux/ramips/patches-5.15/700-net-ethernet-mediatek-support-net-labels.patch
target/linux/ramips/patches-5.15/720-Revert-net-phy-simplify-phy_link_change-arguments.patch
target/linux/ramips/patches-5.15/721-NET-no-auto-carrier-off-support.patch

diff --git a/target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch b/target/linux/generic/backport-5.15/703-01-v5.16-net-phylink-add-MAC-phy_interface_t-bitmap.patch
new file mode 100644 (file)
index 0000000..b72faec
--- /dev/null
@@ -0,0 +1,24 @@
+From 38c310eb46f5f80213a92093af11af270c209a76 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Tue, 26 Oct 2021 11:06:06 +0100
+Subject: [PATCH] net: phylink: add MAC phy_interface_t bitmap
+
+Add a phy_interface_t bitmap so the MAC driver can specifiy which PHY
+interface modes it supports.
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ include/linux/phylink.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -76,6 +76,7 @@ struct phylink_config {
+       bool ovr_an_inband;
+       void (*get_fixed_state)(struct phylink_config *config,
+                               struct phylink_link_state *state);
++      DECLARE_PHY_INTERFACE_MASK(supported_interfaces);
+ };
+ /**
diff --git a/target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch b/target/linux/generic/backport-5.15/703-02-v5.16-net-phylink-use-supported_interfaces-for-phylink-val.patch
new file mode 100644 (file)
index 0000000..8996fc8
--- /dev/null
@@ -0,0 +1,98 @@
+From d25f3a74f30aace819163dfa54f2a4b8ca1dc932 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 26 Oct 2021 11:06:11 +0100
+Subject: [PATCH] net: phylink: use supported_interfaces for phylink
+ validation
+
+If the network device supplies a supported interface bitmap, we can use
+that during phylink's validation to simplify MAC drivers in two ways by
+using the supported_interfaces bitmap to:
+
+1. reject unsupported interfaces before calling into the MAC driver.
+2. generate the set of all supported link modes across all supported
+   interfaces (used mainly for SFP, but also some 10G PHYs.)
+
+Suggested-by: Sean Anderson <sean.anderson@seco.com>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phylink.c | 36 ++++++++++++++++++++++++++++++++++++
+ include/linux/phylink.h   | 12 ++++++++++--
+ 2 files changed, 46 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -155,9 +155,45 @@ static const char *phylink_an_mode_str(u
+       return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
+ }
++static int phylink_validate_any(struct phylink *pl, unsigned long *supported,
++                              struct phylink_link_state *state)
++{
++      __ETHTOOL_DECLARE_LINK_MODE_MASK(all_adv) = { 0, };
++      __ETHTOOL_DECLARE_LINK_MODE_MASK(all_s) = { 0, };
++      __ETHTOOL_DECLARE_LINK_MODE_MASK(s);
++      struct phylink_link_state t;
++      int intf;
++
++      for (intf = 0; intf < PHY_INTERFACE_MODE_MAX; intf++) {
++              if (test_bit(intf, pl->config->supported_interfaces)) {
++                      linkmode_copy(s, supported);
++
++                      t = *state;
++                      t.interface = intf;
++                      pl->mac_ops->validate(pl->config, s, &t);
++                      linkmode_or(all_s, all_s, s);
++                      linkmode_or(all_adv, all_adv, t.advertising);
++              }
++      }
++
++      linkmode_copy(supported, all_s);
++      linkmode_copy(state->advertising, all_adv);
++
++      return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
++}
++
+ static int phylink_validate(struct phylink *pl, unsigned long *supported,
+                           struct phylink_link_state *state)
+ {
++      if (!phy_interface_empty(pl->config->supported_interfaces)) {
++              if (state->interface == PHY_INTERFACE_MODE_NA)
++                      return phylink_validate_any(pl, supported, state);
++
++              if (!test_bit(state->interface,
++                            pl->config->supported_interfaces))
++                      return -EINVAL;
++      }
++
+       pl->mac_ops->validate(pl->config, supported, state);
+       return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -67,6 +67,8 @@ enum phylink_op_type {
+  * @ovr_an_inband: if true, override PCS to MLO_AN_INBAND
+  * @get_fixed_state: callback to execute to determine the fixed link state,
+  *                 if MAC link is at %MLO_AN_FIXED mode.
++ * @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx
++ *                        are supported by the MAC/PCS.
+  */
+ struct phylink_config {
+       struct device *dev;
+@@ -134,8 +136,14 @@ struct phylink_mac_ops {
+  * based on @state->advertising and/or @state->speed and update
+  * @state->interface accordingly. See phylink_helper_basex_speed().
+  *
+- * When @state->interface is %PHY_INTERFACE_MODE_NA, phylink expects the
+- * MAC driver to return all supported link modes.
++ * When @config->supported_interfaces has been set, phylink will iterate
++ * over the supported interfaces to determine the full capability of the
++ * MAC. The validation function must not print errors if @state->interface
++ * is set to an unexpected value.
++ *
++ * When @config->supported_interfaces is empty, phylink will call this
++ * function with @state->interface set to %PHY_INTERFACE_MODE_NA, and
++ * expects the MAC driver to return all supported link modes.
+  *
+  * If the @state->interface mode is not supported, then the @supported
+  * mask must be cleared.
diff --git a/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch b/target/linux/generic/backport-5.15/703-03-v5.16-net-dsa-populate-supported_interfaces-member.patch
new file mode 100644 (file)
index 0000000..83d1f7e
--- /dev/null
@@ -0,0 +1,63 @@
+From c07c6e8eb4b38bae921f9e2f108d1e7f8e14226e Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Marek=20Beh=C3=BAn?= <kabel@kernel.org>
+Date: Thu, 28 Oct 2021 18:00:14 +0100
+Subject: [PATCH] net: dsa: populate supported_interfaces member
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add a new DSA switch operation, phylink_get_interfaces, which should
+fill in which PHY_INTERFACE_MODE_* are supported by given port.
+
+Use this before phylink_create() to fill phylinks supported_interfaces
+member, allowing phylink to determine which PHY_INTERFACE_MODEs are
+supported.
+
+Signed-off-by: Marek BehĂºn <kabel@kernel.org>
+[tweaked patch and description to add more complete support -- rmk]
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ include/net/dsa.h | 2 ++
+ net/dsa/port.c    | 4 ++++
+ net/dsa/slave.c   | 4 ++++
+ 3 files changed, 10 insertions(+)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -626,6 +626,8 @@ struct dsa_switch_ops {
+       /*
+        * PHYLINK integration
+        */
++      void    (*phylink_get_interfaces)(struct dsa_switch *ds, int port,
++                                        unsigned long *supported_interfaces);
+       void    (*phylink_validate)(struct dsa_switch *ds, int port,
+                                   unsigned long *supported,
+                                   struct phylink_link_state *state);
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -1172,6 +1172,10 @@ static int dsa_port_phylink_register(str
+       dp->pl_config.type = PHYLINK_DEV;
+       dp->pl_config.pcs_poll = ds->pcs_poll;
++      if (ds->ops->phylink_get_interfaces)
++              ds->ops->phylink_get_interfaces(ds, dp->index,
++                                      dp->pl_config.supported_interfaces);
++
+       dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn),
+                               mode, &dsa_port_phylink_mac_ops);
+       if (IS_ERR(dp->pl)) {
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -1837,6 +1837,10 @@ static int dsa_slave_phy_setup(struct ne
+               dp->pl_config.poll_fixed_state = true;
+       }
++      if (ds->ops->phylink_get_interfaces)
++              ds->ops->phylink_get_interfaces(ds, dp->index,
++                                      dp->pl_config.supported_interfaces);
++
+       dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode,
+                               &dsa_port_phylink_mac_ops);
+       if (IS_ERR(dp->pl)) {
diff --git a/target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch b/target/linux/generic/backport-5.15/703-04-v5.17-net-dsa-consolidate-phylink-creation.patch
new file mode 100644 (file)
index 0000000..8b58c83
--- /dev/null
@@ -0,0 +1,149 @@
+From 21bd64bd717dedac96f53b668144cbe37d3c12d4 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 30 Nov 2021 13:09:55 +0000
+Subject: [PATCH] net: dsa: consolidate phylink creation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The code in port.c and slave.c creating the phylink instance is very
+similar - let's consolidate this into a single function.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Marek BehĂºn <kabel@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ net/dsa/dsa_priv.h |  2 +-
+ net/dsa/port.c     | 44 ++++++++++++++++++++++++++++----------------
+ net/dsa/slave.c    | 19 +++----------------
+ 3 files changed, 32 insertions(+), 33 deletions(-)
+
+--- a/net/dsa/dsa_priv.h
++++ b/net/dsa/dsa_priv.h
+@@ -260,13 +260,13 @@ int dsa_port_mrp_add_ring_role(const str
+                              const struct switchdev_obj_ring_role_mrp *mrp);
+ int dsa_port_mrp_del_ring_role(const struct dsa_port *dp,
+                              const struct switchdev_obj_ring_role_mrp *mrp);
++int dsa_port_phylink_create(struct dsa_port *dp);
+ int dsa_port_link_register_of(struct dsa_port *dp);
+ void dsa_port_link_unregister_of(struct dsa_port *dp);
+ int dsa_port_hsr_join(struct dsa_port *dp, struct net_device *hsr);
+ void dsa_port_hsr_leave(struct dsa_port *dp, struct net_device *hsr);
+ int dsa_port_tag_8021q_vlan_add(struct dsa_port *dp, u16 vid, bool broadcast);
+ void dsa_port_tag_8021q_vlan_del(struct dsa_port *dp, u16 vid, bool broadcast);
+-extern const struct phylink_mac_ops dsa_port_phylink_mac_ops;
+ static inline bool dsa_port_offloads_bridge_port(struct dsa_port *dp,
+                                                const struct net_device *dev)
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -1076,7 +1076,7 @@ static void dsa_port_phylink_mac_link_up
+                                    speed, duplex, tx_pause, rx_pause);
+ }
+-const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
++static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
+       .validate = dsa_port_phylink_validate,
+       .mac_pcs_get_state = dsa_port_phylink_mac_pcs_get_state,
+       .mac_config = dsa_port_phylink_mac_config,
+@@ -1085,6 +1085,30 @@ const struct phylink_mac_ops dsa_port_ph
+       .mac_link_up = dsa_port_phylink_mac_link_up,
+ };
++int dsa_port_phylink_create(struct dsa_port *dp)
++{
++      struct dsa_switch *ds = dp->ds;
++      phy_interface_t mode;
++      int err;
++
++      err = of_get_phy_mode(dp->dn, &mode);
++      if (err)
++              mode = PHY_INTERFACE_MODE_NA;
++
++      if (ds->ops->phylink_get_interfaces)
++              ds->ops->phylink_get_interfaces(ds, dp->index,
++                                      dp->pl_config.supported_interfaces);
++
++      dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
++                              mode, &dsa_port_phylink_mac_ops);
++      if (IS_ERR(dp->pl)) {
++              pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
++              return PTR_ERR(dp->pl);
++      }
++
++      return 0;
++}
++
+ static int dsa_port_setup_phy_of(struct dsa_port *dp, bool enable)
+ {
+       struct dsa_switch *ds = dp->ds;
+@@ -1161,27 +1185,15 @@ static int dsa_port_phylink_register(str
+ {
+       struct dsa_switch *ds = dp->ds;
+       struct device_node *port_dn = dp->dn;
+-      phy_interface_t mode;
+       int err;
+-      err = of_get_phy_mode(port_dn, &mode);
+-      if (err)
+-              mode = PHY_INTERFACE_MODE_NA;
+-
+       dp->pl_config.dev = ds->dev;
+       dp->pl_config.type = PHYLINK_DEV;
+       dp->pl_config.pcs_poll = ds->pcs_poll;
+-      if (ds->ops->phylink_get_interfaces)
+-              ds->ops->phylink_get_interfaces(ds, dp->index,
+-                                      dp->pl_config.supported_interfaces);
+-
+-      dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn),
+-                              mode, &dsa_port_phylink_mac_ops);
+-      if (IS_ERR(dp->pl)) {
+-              pr_err("error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
+-              return PTR_ERR(dp->pl);
+-      }
++      err = dsa_port_phylink_create(dp);
++      if (err)
++              return err;
+       err = phylink_of_phy_connect(dp->pl, port_dn, 0);
+       if (err && err != -ENODEV) {
+--- a/net/dsa/slave.c
++++ b/net/dsa/slave.c
+@@ -1817,14 +1817,9 @@ static int dsa_slave_phy_setup(struct ne
+       struct dsa_port *dp = dsa_slave_to_port(slave_dev);
+       struct device_node *port_dn = dp->dn;
+       struct dsa_switch *ds = dp->ds;
+-      phy_interface_t mode;
+       u32 phy_flags = 0;
+       int ret;
+-      ret = of_get_phy_mode(port_dn, &mode);
+-      if (ret)
+-              mode = PHY_INTERFACE_MODE_NA;
+-
+       dp->pl_config.dev = &slave_dev->dev;
+       dp->pl_config.type = PHYLINK_NETDEV;
+@@ -1837,17 +1832,9 @@ static int dsa_slave_phy_setup(struct ne
+               dp->pl_config.poll_fixed_state = true;
+       }
+-      if (ds->ops->phylink_get_interfaces)
+-              ds->ops->phylink_get_interfaces(ds, dp->index,
+-                                      dp->pl_config.supported_interfaces);
+-
+-      dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(port_dn), mode,
+-                              &dsa_port_phylink_mac_ops);
+-      if (IS_ERR(dp->pl)) {
+-              netdev_err(slave_dev,
+-                         "error creating PHYLINK: %ld\n", PTR_ERR(dp->pl));
+-              return PTR_ERR(dp->pl);
+-      }
++      ret = dsa_port_phylink_create(dp);
++      if (ret)
++              return ret;
+       if (ds->ops->get_phy_flags)
+               phy_flags = ds->ops->get_phy_flags(ds, dp->index);
diff --git a/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch b/target/linux/generic/backport-5.15/703-05-v5.17-net-dsa-replace-phylink_get_interfaces-with-phylink_.patch
new file mode 100644 (file)
index 0000000..4cea599
--- /dev/null
@@ -0,0 +1,51 @@
+From 072eea6c22b2af680c3949e64f9adde278c71e68 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 30 Nov 2021 13:10:01 +0000
+Subject: [PATCH] net: dsa: replace phylink_get_interfaces() with
+ phylink_get_caps()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Phylink needs slightly more information than phylink_get_interfaces()
+allows us to get from the DSA drivers - we need the MAC capabilities.
+Replace the phylink_get_interfaces() method with phylink_get_caps() to
+allow DSA drivers to fill in the phylink_config MAC capabilities field
+as well.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Marek BehĂºn <kabel@kernel.org>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/net/dsa.h | 4 ++--
+ net/dsa/port.c    | 5 ++---
+ 2 files changed, 4 insertions(+), 5 deletions(-)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -626,8 +626,8 @@ struct dsa_switch_ops {
+       /*
+        * PHYLINK integration
+        */
+-      void    (*phylink_get_interfaces)(struct dsa_switch *ds, int port,
+-                                        unsigned long *supported_interfaces);
++      void    (*phylink_get_caps)(struct dsa_switch *ds, int port,
++                                  struct phylink_config *config);
+       void    (*phylink_validate)(struct dsa_switch *ds, int port,
+                                   unsigned long *supported,
+                                   struct phylink_link_state *state);
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -1095,9 +1095,8 @@ int dsa_port_phylink_create(struct dsa_p
+       if (err)
+               mode = PHY_INTERFACE_MODE_NA;
+-      if (ds->ops->phylink_get_interfaces)
+-              ds->ops->phylink_get_interfaces(ds, dp->index,
+-                                      dp->pl_config.supported_interfaces);
++      if (ds->ops->phylink_get_caps)
++              ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
+       dp->pl = phylink_create(&dp->pl_config, of_fwnode_handle(dp->dn),
+                               mode, &dsa_port_phylink_mac_ops);
diff --git a/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch b/target/linux/generic/backport-5.15/703-06-v5.18-net-dsa-add-support-for-phylink-mac_select_pcs.patch
new file mode 100644 (file)
index 0000000..a28d14d
--- /dev/null
@@ -0,0 +1,59 @@
+From bde018222c6b084ac32933a9f933581dd83da18e Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 17 Feb 2022 18:30:35 +0000
+Subject: [PATCH] net: dsa: add support for phylink mac_select_pcs()
+
+Add DSA support for the phylink mac_select_pcs() method so DSA drivers
+can return provide phylink with the appropriate PCS for the PHY
+interface mode.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ include/net/dsa.h |  3 +++
+ net/dsa/port.c    | 15 +++++++++++++++
+ 2 files changed, 18 insertions(+)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -631,6 +631,9 @@ struct dsa_switch_ops {
+       void    (*phylink_validate)(struct dsa_switch *ds, int port,
+                                   unsigned long *supported,
+                                   struct phylink_link_state *state);
++      struct phylink_pcs *(*phylink_mac_select_pcs)(struct dsa_switch *ds,
++                                                    int port,
++                                                    phy_interface_t iface);
+       int     (*phylink_mac_link_state)(struct dsa_switch *ds, int port,
+                                         struct phylink_link_state *state);
+       void    (*phylink_mac_config)(struct dsa_switch *ds, int port,
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -1012,6 +1012,20 @@ static void dsa_port_phylink_mac_pcs_get
+       }
+ }
++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_switch *ds = dp->ds;
++      struct phylink_pcs *pcs = NULL;
++
++      if (ds->ops->phylink_mac_select_pcs)
++              pcs = ds->ops->phylink_mac_select_pcs(ds, dp->index, interface);
++
++      return pcs;
++}
++
+ static void dsa_port_phylink_mac_config(struct phylink_config *config,
+                                       unsigned int mode,
+                                       const struct phylink_link_state *state)
+@@ -1078,6 +1092,7 @@ static void dsa_port_phylink_mac_link_up
+ static const struct phylink_mac_ops dsa_port_phylink_mac_ops = {
+       .validate = dsa_port_phylink_validate,
++      .mac_select_pcs = dsa_port_phylink_mac_select_pcs,
+       .mac_pcs_get_state = dsa_port_phylink_mac_pcs_get_state,
+       .mac_config = dsa_port_phylink_mac_config,
+       .mac_an_restart = dsa_port_phylink_mac_an_restart,
diff --git a/target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch b/target/linux/generic/backport-5.15/703-07-v5.16-net-phy-add-phy_interface_t-bitmap-support.patch
new file mode 100644 (file)
index 0000000..1a7817b
--- /dev/null
@@ -0,0 +1,61 @@
+From 8e20f591f204f8db7f1182918f8e2285d3f589e0 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 26 Oct 2021 11:06:01 +0100
+Subject: [PATCH] net: phy: add phy_interface_t bitmap support
+
+Add support for a bitmap for phy interface modes, which includes:
+- a macro to declare the interface bitmap
+- an inline helper to zero the interface bitmap
+- an inline helper to detect an empty interface bitmap
+- inline helpers to do a bitwise AND and OR operations on two interface
+  bitmaps
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ include/linux/phy.h | 34 ++++++++++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+--- a/include/linux/phy.h
++++ b/include/linux/phy.h
+@@ -155,6 +155,40 @@ typedef enum {
+       PHY_INTERFACE_MODE_MAX,
+ } phy_interface_t;
++/* PHY interface mode bitmap handling */
++#define DECLARE_PHY_INTERFACE_MASK(name) \
++      DECLARE_BITMAP(name, PHY_INTERFACE_MODE_MAX)
++
++static inline void phy_interface_zero(unsigned long *intf)
++{
++      bitmap_zero(intf, PHY_INTERFACE_MODE_MAX);
++}
++
++static inline bool phy_interface_empty(const unsigned long *intf)
++{
++      return bitmap_empty(intf, PHY_INTERFACE_MODE_MAX);
++}
++
++static inline void phy_interface_and(unsigned long *dst, const unsigned long *a,
++                                   const unsigned long *b)
++{
++      bitmap_and(dst, a, b, PHY_INTERFACE_MODE_MAX);
++}
++
++static inline void phy_interface_or(unsigned long *dst, const unsigned long *a,
++                                  const unsigned long *b)
++{
++      bitmap_or(dst, a, b, PHY_INTERFACE_MODE_MAX);
++}
++
++static inline void phy_interface_set_rgmii(unsigned long *intf)
++{
++      __set_bit(PHY_INTERFACE_MODE_RGMII, intf);
++      __set_bit(PHY_INTERFACE_MODE_RGMII_ID, intf);
++      __set_bit(PHY_INTERFACE_MODE_RGMII_RXID, intf);
++      __set_bit(PHY_INTERFACE_MODE_RGMII_TXID, intf);
++}
++
+ /*
+  * phy_supported_speeds - return all speeds currently supported by a PHY device
+  */
diff --git a/target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch b/target/linux/generic/backport-5.15/703-08-v5.17-net-phylink-add-mac_select_pcs-method-to-phylink_mac.patch
new file mode 100644 (file)
index 0000000..e1cfc3f
--- /dev/null
@@ -0,0 +1,197 @@
+From d1e86325af377129adb7fc6f34eb044ca6068b47 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 15 Dec 2021 15:34:15 +0000
+Subject: [PATCH] net: phylink: add mac_select_pcs() method to phylink_mac_ops
+
+mac_select_pcs() allows us to have an explicit point to query which
+PCS the MAC wishes to use for a particular PHY interface mode, thereby
+allowing us to add support to validate the link settings with the PCS.
+
+Phylink will also use this to select the PCS to be used during a major
+configuration event without the MAC driver needing to call
+phylink_set_pcs().
+
+Note that if mac_select_pcs() is present, the supported_interfaces
+bitmap must be filled in; this avoids mac_select_pcs() being called
+with PHY_INTERFACE_MODE_NA when we want to get support for all
+interface types. Phylink will return an error in phylink_create()
+unless this condition is satisfied.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phylink.c | 68 +++++++++++++++++++++++++++++++++------
+ include/linux/phylink.h   | 18 +++++++++++
+ 2 files changed, 77 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -155,6 +155,23 @@ static const char *phylink_an_mode_str(u
+       return mode < ARRAY_SIZE(modestr) ? modestr[mode] : "unknown";
+ }
++static int phylink_validate_mac_and_pcs(struct phylink *pl,
++                                      unsigned long *supported,
++                                      struct phylink_link_state *state)
++{
++      struct phylink_pcs *pcs;
++
++      if (pl->mac_ops->mac_select_pcs) {
++              pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
++              if (IS_ERR(pcs))
++                      return PTR_ERR(pcs);
++      }
++
++      pl->mac_ops->validate(pl->config, supported, state);
++
++      return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
++}
++
+ static int phylink_validate_any(struct phylink *pl, unsigned long *supported,
+                               struct phylink_link_state *state)
+ {
+@@ -170,9 +187,10 @@ static int phylink_validate_any(struct p
+                       t = *state;
+                       t.interface = intf;
+-                      pl->mac_ops->validate(pl->config, s, &t);
+-                      linkmode_or(all_s, all_s, s);
+-                      linkmode_or(all_adv, all_adv, t.advertising);
++                      if (!phylink_validate_mac_and_pcs(pl, s, &t)) {
++                              linkmode_or(all_s, all_s, s);
++                              linkmode_or(all_adv, all_adv, t.advertising);
++                      }
+               }
+       }
+@@ -194,9 +212,7 @@ static int phylink_validate(struct phyli
+                       return -EINVAL;
+       }
+-      pl->mac_ops->validate(pl->config, supported, state);
+-
+-      return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
++      return phylink_validate_mac_and_pcs(pl, supported, state);
+ }
+ static int phylink_parse_fixedlink(struct phylink *pl,
+@@ -486,10 +502,21 @@ static void phylink_mac_pcs_an_restart(s
+ static void phylink_major_config(struct phylink *pl, bool restart,
+                                 const struct phylink_link_state *state)
+ {
++      struct phylink_pcs *pcs = NULL;
+       int err;
+       phylink_dbg(pl, "major config %s\n", phy_modes(state->interface));
++      if (pl->mac_ops->mac_select_pcs) {
++              pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
++              if (IS_ERR(pcs)) {
++                      phylink_err(pl,
++                                  "mac_select_pcs unexpectedly failed: %pe\n",
++                                  pcs);
++                      return;
++              }
++      }
++
+       if (pl->mac_ops->mac_prepare) {
+               err = pl->mac_ops->mac_prepare(pl->config, pl->cur_link_an_mode,
+                                              state->interface);
+@@ -500,6 +527,12 @@ static void phylink_major_config(struct
+               }
+       }
++      /* If we have a new PCS, switch to the new PCS after preparing the MAC
++       * for the change.
++       */
++      if (pcs)
++              phylink_set_pcs(pl, pcs);
++
+       phylink_mac_config(pl, state);
+       if (pl->pcs_ops) {
+@@ -879,6 +912,14 @@ struct phylink *phylink_create(struct ph
+       struct phylink *pl;
+       int ret;
++      /* Validate the supplied configuration */
++      if (mac_ops->mac_select_pcs &&
++          phy_interface_empty(config->supported_interfaces)) {
++              dev_err(config->dev,
++                      "phylink: error: empty supported_interfaces but mac_select_pcs() method present\n");
++              return ERR_PTR(-EINVAL);
++      }
++
+       pl = kzalloc(sizeof(*pl), GFP_KERNEL);
+       if (!pl)
+               return ERR_PTR(-ENOMEM);
+@@ -946,9 +987,10 @@ EXPORT_SYMBOL_GPL(phylink_create);
+  * @pl: a pointer to a &struct phylink returned from phylink_create()
+  * @pcs: a pointer to the &struct phylink_pcs
+  *
+- * Bind the MAC PCS to phylink.  This may be called after phylink_create(),
+- * in mac_prepare() or mac_config() methods if it is desired to dynamically
+- * change the PCS.
++ * Bind the MAC PCS to phylink.  This may be called after phylink_create().
++ * If it is desired to dynamically change the PCS, then the preferred method
++ * is to use mac_select_pcs(), but it may also be called in mac_prepare()
++ * or mac_config().
+  *
+  * Please note that there are behavioural changes with the mac_config()
+  * callback if a PCS is present (denoting a newer setup) so removing a PCS
+@@ -959,6 +1001,14 @@ void phylink_set_pcs(struct phylink *pl,
+ {
+       pl->pcs = pcs;
+       pl->pcs_ops = pcs->ops;
++
++      if (!pl->phylink_disable_state &&
++          pl->cfg_link_an_mode == MLO_AN_INBAND) {
++              if (pl->config->pcs_poll || pcs->poll)
++                      mod_timer(&pl->link_poll, jiffies + HZ);
++              else
++                      del_timer(&pl->link_poll);
++      }
+ }
+ EXPORT_SYMBOL_GPL(phylink_set_pcs);
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -84,6 +84,7 @@ struct phylink_config {
+ /**
+  * struct phylink_mac_ops - MAC operations structure.
+  * @validate: Validate and update the link configuration.
++ * @mac_select_pcs: Select a PCS for the interface mode.
+  * @mac_pcs_get_state: Read the current link state from the hardware.
+  * @mac_prepare: prepare for a major reconfiguration of the interface.
+  * @mac_config: configure the MAC for the selected mode and state.
+@@ -98,6 +99,8 @@ struct phylink_mac_ops {
+       void (*validate)(struct phylink_config *config,
+                        unsigned long *supported,
+                        struct phylink_link_state *state);
++      struct phylink_pcs *(*mac_select_pcs)(struct phylink_config *config,
++                                            phy_interface_t interface);
+       void (*mac_pcs_get_state)(struct phylink_config *config,
+                                 struct phylink_link_state *state);
+       int (*mac_prepare)(struct phylink_config *config, unsigned int mode,
+@@ -150,6 +153,21 @@ struct phylink_mac_ops {
+  */
+ void validate(struct phylink_config *config, unsigned long *supported,
+             struct phylink_link_state *state);
++/**
++ * mac_select_pcs: Select a PCS for the interface mode.
++ * @config: a pointer to a &struct phylink_config.
++ * @interface: PHY interface mode for PCS
++ *
++ * Return the &struct phylink_pcs for the specified interface mode, or
++ * NULL if none is required, or an error pointer on error.
++ *
++ * This must not modify any state. It is used to query which PCS should
++ * be used. Phylink will use this during validation to ensure that the
++ * configuration is valid, and when setting a configuration to internally
++ * set the PCS that will be used.
++ */
++struct phylink_pcs *mac_select_pcs(struct phylink_config *config,
++                                 phy_interface_t interface);
+ /**
+  * mac_pcs_get_state() - Read the current inband link state from the hardware
diff --git a/target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch b/target/linux/generic/backport-5.15/703-09-v5.17-net-phylink-add-generic-validate-implementation.patch
new file mode 100644 (file)
index 0000000..73c8b41
--- /dev/null
@@ -0,0 +1,341 @@
+From 34ae2c09d46a2d0abd907e139b466f798e4095a8 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 15 Nov 2021 10:00:27 +0000
+Subject: [PATCH] net: phylink: add generic validate implementation
+
+Add a generic validate() implementation using the supported_interfaces
+and a bitmask of MAC pause/speed/duplex capabilities. This allows us
+to entirely eliminate many driver private validate() implementations.
+
+We expose the underlying phylink_get_linkmodes() function so that
+drivers which have special needs can still benefit from conversion.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phylink.c | 252 ++++++++++++++++++++++++++++++++++++++
+ include/linux/phylink.h   |  31 +++++
+ 2 files changed, 283 insertions(+)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -172,6 +172,258 @@ static int phylink_validate_mac_and_pcs(
+       return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
+ }
++static void phylink_caps_to_linkmodes(unsigned long *linkmodes,
++                                    unsigned long caps)
++{
++      if (caps & MAC_SYM_PAUSE)
++              __set_bit(ETHTOOL_LINK_MODE_Pause_BIT, linkmodes);
++
++      if (caps & MAC_ASYM_PAUSE)
++              __set_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT, linkmodes);
++
++      if (caps & MAC_10HD)
++              __set_bit(ETHTOOL_LINK_MODE_10baseT_Half_BIT, linkmodes);
++
++      if (caps & MAC_10FD)
++              __set_bit(ETHTOOL_LINK_MODE_10baseT_Full_BIT, linkmodes);
++
++      if (caps & MAC_100HD) {
++              __set_bit(ETHTOOL_LINK_MODE_100baseT_Half_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100baseFX_Half_BIT, linkmodes);
++      }
++
++      if (caps & MAC_100FD) {
++              __set_bit(ETHTOOL_LINK_MODE_100baseT_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100baseT1_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100baseFX_Full_BIT, linkmodes);
++      }
++
++      if (caps & MAC_1000HD)
++              __set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, linkmodes);
++
++      if (caps & MAC_1000FD) {
++              __set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_1000baseT1_Full_BIT, linkmodes);
++      }
++
++      if (caps & MAC_2500FD) {
++              __set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, linkmodes);
++      }
++
++      if (caps & MAC_5000FD)
++              __set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, linkmodes);
++
++      if (caps & MAC_10000FD) {
++              __set_bit(ETHTOOL_LINK_MODE_10000baseT_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_10000baseKX4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_10000baseR_FEC_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_10000baseCR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_10000baseSR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_10000baseLR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_10000baseLRM_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_10000baseER_Full_BIT, linkmodes);
++      }
++
++      if (caps & MAC_25000FD) {
++              __set_bit(ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_25000baseSR_Full_BIT, linkmodes);
++      }
++
++      if (caps & MAC_40000FD) {
++              __set_bit(ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_40000baseSR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_40000baseLR4_Full_BIT, linkmodes);
++      }
++
++      if (caps & MAC_50000FD) {
++              __set_bit(ETHTOOL_LINK_MODE_50000baseCR2_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_50000baseKR2_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_50000baseSR2_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_50000baseKR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_50000baseSR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_50000baseCR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_50000baseLR_ER_FR_Full_BIT,
++                        linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_50000baseDR_Full_BIT, linkmodes);
++      }
++
++      if (caps & MAC_56000FD) {
++              __set_bit(ETHTOOL_LINK_MODE_56000baseKR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_56000baseCR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_56000baseSR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_56000baseLR4_Full_BIT, linkmodes);
++      }
++
++      if (caps & MAC_100000FD) {
++              __set_bit(ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseSR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseLR4_ER4_Full_BIT,
++                        linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseKR2_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseSR2_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseCR2_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseLR2_ER2_FR2_Full_BIT,
++                        linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseDR2_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseKR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseSR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseLR_ER_FR_Full_BIT,
++                        linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseCR_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_100000baseDR_Full_BIT, linkmodes);
++      }
++
++      if (caps & MAC_200000FD) {
++              __set_bit(ETHTOOL_LINK_MODE_200000baseKR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_200000baseSR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_200000baseLR4_ER4_FR4_Full_BIT,
++                        linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_200000baseDR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_200000baseCR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_200000baseKR2_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_200000baseSR2_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_200000baseLR2_ER2_FR2_Full_BIT,
++                        linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_200000baseDR2_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_200000baseCR2_Full_BIT, linkmodes);
++      }
++
++      if (caps & MAC_400000FD) {
++              __set_bit(ETHTOOL_LINK_MODE_400000baseKR8_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_400000baseSR8_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_400000baseLR8_ER8_FR8_Full_BIT,
++                        linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_400000baseDR8_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_400000baseCR8_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_400000baseKR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_400000baseSR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_400000baseLR4_ER4_FR4_Full_BIT,
++                        linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_400000baseDR4_Full_BIT, linkmodes);
++              __set_bit(ETHTOOL_LINK_MODE_400000baseCR4_Full_BIT, linkmodes);
++      }
++}
++
++/**
++ * phylink_get_linkmodes() - get acceptable link modes
++ * @linkmodes: ethtool linkmode mask (must be already initialised)
++ * @interface: phy interface mode defined by &typedef phy_interface_t
++ * @mac_capabilities: bitmask of MAC capabilities
++ *
++ * Set all possible pause, speed and duplex linkmodes in @linkmodes that
++ * are supported by the @interface mode and @mac_capabilities. @linkmodes
++ * must have been initialised previously.
++ */
++void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
++                         unsigned long mac_capabilities)
++{
++      unsigned long caps = MAC_SYM_PAUSE | MAC_ASYM_PAUSE;
++
++      switch (interface) {
++      case PHY_INTERFACE_MODE_USXGMII:
++              caps |= MAC_10000FD | MAC_5000FD | MAC_2500FD;
++              fallthrough;
++
++      case PHY_INTERFACE_MODE_RGMII_TXID:
++      case PHY_INTERFACE_MODE_RGMII_RXID:
++      case PHY_INTERFACE_MODE_RGMII_ID:
++      case PHY_INTERFACE_MODE_RGMII:
++      case PHY_INTERFACE_MODE_QSGMII:
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_GMII:
++              caps |= MAC_1000HD | MAC_1000FD;
++              fallthrough;
++
++      case PHY_INTERFACE_MODE_REVRMII:
++      case PHY_INTERFACE_MODE_RMII:
++      case PHY_INTERFACE_MODE_REVMII:
++      case PHY_INTERFACE_MODE_MII:
++              caps |= MAC_10HD | MAC_10FD;
++              fallthrough;
++
++      case PHY_INTERFACE_MODE_100BASEX:
++              caps |= MAC_100HD | MAC_100FD;
++              break;
++
++      case PHY_INTERFACE_MODE_TBI:
++      case PHY_INTERFACE_MODE_MOCA:
++      case PHY_INTERFACE_MODE_RTBI:
++      case PHY_INTERFACE_MODE_1000BASEX:
++              caps |= MAC_1000HD;
++              fallthrough;
++      case PHY_INTERFACE_MODE_TRGMII:
++              caps |= MAC_1000FD;
++              break;
++
++      case PHY_INTERFACE_MODE_2500BASEX:
++              caps |= MAC_2500FD;
++              break;
++
++      case PHY_INTERFACE_MODE_5GBASER:
++              caps |= MAC_5000FD;
++              break;
++
++      case PHY_INTERFACE_MODE_XGMII:
++      case PHY_INTERFACE_MODE_RXAUI:
++      case PHY_INTERFACE_MODE_XAUI:
++      case PHY_INTERFACE_MODE_10GBASER:
++      case PHY_INTERFACE_MODE_10GKR:
++              caps |= MAC_10000FD;
++              break;
++
++      case PHY_INTERFACE_MODE_25GBASER:
++              caps |= MAC_25000FD;
++              break;
++
++      case PHY_INTERFACE_MODE_XLGMII:
++              caps |= MAC_40000FD;
++              break;
++
++      case PHY_INTERFACE_MODE_INTERNAL:
++              caps |= ~0;
++              break;
++
++      case PHY_INTERFACE_MODE_NA:
++      case PHY_INTERFACE_MODE_MAX:
++      case PHY_INTERFACE_MODE_SMII:
++              break;
++      }
++
++      phylink_caps_to_linkmodes(linkmodes, caps & mac_capabilities);
++}
++EXPORT_SYMBOL_GPL(phylink_get_linkmodes);
++
++/**
++ * phylink_generic_validate() - generic validate() callback implementation
++ * @config: a pointer to a &struct phylink_config.
++ * @supported: ethtool bitmask for supported link modes.
++ * @state: a pointer to a &struct phylink_link_state.
++ *
++ * Generic implementation of the validate() callback that MAC drivers can
++ * use when they pass the range of supported interfaces and MAC capabilities.
++ * This makes use of phylink_get_linkmodes().
++ */
++void phylink_generic_validate(struct phylink_config *config,
++                            unsigned long *supported,
++                            struct phylink_link_state *state)
++{
++      __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
++
++      phylink_set_port_modes(mask);
++      phylink_set(mask, Autoneg);
++      phylink_get_linkmodes(mask, state->interface, config->mac_capabilities);
++
++      linkmode_and(supported, supported, mask);
++      linkmode_and(state->advertising, state->advertising, mask);
++}
++EXPORT_SYMBOL_GPL(phylink_generic_validate);
++
+ static int phylink_validate_any(struct phylink *pl, unsigned long *supported,
+                               struct phylink_link_state *state)
+ {
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -20,6 +20,29 @@ enum {
+       MLO_AN_PHY = 0, /* Conventional PHY */
+       MLO_AN_FIXED,   /* Fixed-link mode */
+       MLO_AN_INBAND,  /* In-band protocol */
++
++      MAC_SYM_PAUSE   = BIT(0),
++      MAC_ASYM_PAUSE  = BIT(1),
++      MAC_10HD        = BIT(2),
++      MAC_10FD        = BIT(3),
++      MAC_10          = MAC_10HD | MAC_10FD,
++      MAC_100HD       = BIT(4),
++      MAC_100FD       = BIT(5),
++      MAC_100         = MAC_100HD | MAC_100FD,
++      MAC_1000HD      = BIT(6),
++      MAC_1000FD      = BIT(7),
++      MAC_1000        = MAC_1000HD | MAC_1000FD,
++      MAC_2500FD      = BIT(8),
++      MAC_5000FD      = BIT(9),
++      MAC_10000FD     = BIT(10),
++      MAC_20000FD     = BIT(11),
++      MAC_25000FD     = BIT(12),
++      MAC_40000FD     = BIT(13),
++      MAC_50000FD     = BIT(14),
++      MAC_56000FD     = BIT(15),
++      MAC_100000FD    = BIT(16),
++      MAC_200000FD    = BIT(17),
++      MAC_400000FD    = BIT(18),
+ };
+ static inline bool phylink_autoneg_inband(unsigned int mode)
+@@ -69,6 +92,7 @@ enum phylink_op_type {
+  *                 if MAC link is at %MLO_AN_FIXED mode.
+  * @supported_interfaces: bitmap describing which PHY_INTERFACE_MODE_xxx
+  *                        are supported by the MAC/PCS.
++ * @mac_capabilities: MAC pause/speed/duplex capabilities.
+  */
+ struct phylink_config {
+       struct device *dev;
+@@ -79,6 +103,7 @@ struct phylink_config {
+       void (*get_fixed_state)(struct phylink_config *config,
+                               struct phylink_link_state *state);
+       DECLARE_PHY_INTERFACE_MASK(supported_interfaces);
++      unsigned long mac_capabilities;
+ };
+ /**
+@@ -460,6 +485,12 @@ void pcs_link_up(struct phylink_pcs *pcs
+                phy_interface_t interface, int speed, int duplex);
+ #endif
++void phylink_get_linkmodes(unsigned long *linkmodes, phy_interface_t interface,
++                         unsigned long mac_capabilities);
++void phylink_generic_validate(struct phylink_config *config,
++                            unsigned long *supported,
++                            struct phylink_link_state *state);
++
+ struct phylink *phylink_create(struct phylink_config *, struct fwnode_handle *,
+                              phy_interface_t iface,
+                              const struct phylink_mac_ops *mac_ops);
diff --git a/target/linux/generic/backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch b/target/linux/generic/backport-5.15/703-10-v5.16-net-dsa-introduce-helpers-for-iterating-through-port.patch
new file mode 100644 (file)
index 0000000..a556235
--- /dev/null
@@ -0,0 +1,68 @@
+From 82b318983c515f29b8b3a0dad9f6a5fe8a68a7f4 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Wed, 20 Oct 2021 20:49:49 +0300
+Subject: [PATCH] net: dsa: introduce helpers for iterating through ports using
+ dp
+
+Since the DSA conversion from the ds->ports array into the dst->ports
+list, the DSA API has encouraged driver writers, as well as the core
+itself, to write inefficient code.
+
+Currently, code that wants to filter by a specific type of port when
+iterating, like {!unused, user, cpu, dsa}, uses the dsa_is_*_port helper.
+Under the hood, this uses dsa_to_port which iterates again through
+dst->ports. But the driver iterates through the port list already, so
+the complexity is quadratic for the typical case of a single-switch
+tree.
+
+This patch introduces some iteration helpers where the iterator is
+already a struct dsa_port *dp, so that the other variant of the
+filtering functions, dsa_port_is_{unused,user,cpu_dsa}, can be used
+directly on the iterator. This eliminates the second lookup.
+
+These functions can be used both by the core and by drivers.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ include/net/dsa.h | 28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+--- a/include/net/dsa.h
++++ b/include/net/dsa.h
+@@ -476,6 +476,34 @@ static inline bool dsa_is_user_port(stru
+       return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_USER;
+ }
++#define dsa_tree_for_each_user_port(_dp, _dst) \
++      list_for_each_entry((_dp), &(_dst)->ports, list) \
++              if (dsa_port_is_user((_dp)))
++
++#define dsa_switch_for_each_port(_dp, _ds) \
++      list_for_each_entry((_dp), &(_ds)->dst->ports, list) \
++              if ((_dp)->ds == (_ds))
++
++#define dsa_switch_for_each_port_safe(_dp, _next, _ds) \
++      list_for_each_entry_safe((_dp), (_next), &(_ds)->dst->ports, list) \
++              if ((_dp)->ds == (_ds))
++
++#define dsa_switch_for_each_port_continue_reverse(_dp, _ds) \
++      list_for_each_entry_continue_reverse((_dp), &(_ds)->dst->ports, list) \
++              if ((_dp)->ds == (_ds))
++
++#define dsa_switch_for_each_available_port(_dp, _ds) \
++      dsa_switch_for_each_port((_dp), (_ds)) \
++              if (!dsa_port_is_unused((_dp)))
++
++#define dsa_switch_for_each_user_port(_dp, _ds) \
++      dsa_switch_for_each_port((_dp), (_ds)) \
++              if (dsa_port_is_user((_dp)))
++
++#define dsa_switch_for_each_cpu_port(_dp, _ds) \
++      dsa_switch_for_each_port((_dp), (_ds)) \
++              if (dsa_port_is_cpu((_dp)))
++
+ static inline u32 dsa_user_ports(struct dsa_switch *ds)
+ {
+       u32 mask = 0;
diff --git a/target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch b/target/linux/generic/backport-5.15/703-11-v5.17-net-phylink-add-pcs_validate-method.patch
new file mode 100644 (file)
index 0000000..add2e6e
--- /dev/null
@@ -0,0 +1,106 @@
+From 0d22d4b626a4eaa3196019092eb6c1919e9f8caa Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 15 Dec 2021 15:34:20 +0000
+Subject: [PATCH] net: phylink: add pcs_validate() method
+
+Add a hook for PCS to validate the link parameters. This avoids MAC
+drivers having to have knowledge of their PCS in their validate()
+method, thereby allowing several MAC drivers to be simplfied.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/phy/phylink.c | 31 +++++++++++++++++++++++++++++++
+ include/linux/phylink.h   | 20 ++++++++++++++++++++
+ 2 files changed, 51 insertions(+)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -160,13 +160,44 @@ static int phylink_validate_mac_and_pcs(
+                                       struct phylink_link_state *state)
+ {
+       struct phylink_pcs *pcs;
++      int ret;
++      /* Get the PCS for this interface mode */
+       if (pl->mac_ops->mac_select_pcs) {
+               pcs = pl->mac_ops->mac_select_pcs(pl->config, state->interface);
+               if (IS_ERR(pcs))
+                       return PTR_ERR(pcs);
++      } else {
++              pcs = pl->pcs;
+       }
++      if (pcs) {
++              /* The PCS, if present, must be setup before phylink_create()
++               * has been called. If the ops is not initialised, print an
++               * error and backtrace rather than oopsing the kernel.
++               */
++              if (!pcs->ops) {
++                      phylink_err(pl, "interface %s: uninitialised PCS\n",
++                                  phy_modes(state->interface));
++                      dump_stack();
++                      return -EINVAL;
++              }
++
++              /* Validate the link parameters with the PCS */
++              if (pcs->ops->pcs_validate) {
++                      ret = pcs->ops->pcs_validate(pcs, supported, state);
++                      if (ret < 0 || phylink_is_empty_linkmode(supported))
++                              return -EINVAL;
++
++                      /* Ensure the advertising mask is a subset of the
++                       * supported mask.
++                       */
++                      linkmode_and(state->advertising, state->advertising,
++                                   supported);
++              }
++      }
++
++      /* Then validate the link parameters with the MAC */
+       pl->mac_ops->validate(pl->config, supported, state);
+       return phylink_is_empty_linkmode(supported) ? -EINVAL : 0;
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -396,6 +396,7 @@ struct phylink_pcs {
+ /**
+  * struct phylink_pcs_ops - MAC PCS operations structure.
++ * @pcs_validate: validate the link configuration.
+  * @pcs_get_state: read the current MAC PCS link state from the hardware.
+  * @pcs_config: configure the MAC PCS for the selected mode and state.
+  * @pcs_an_restart: restart 802.3z BaseX autonegotiation.
+@@ -403,6 +404,8 @@ struct phylink_pcs {
+  *               (where necessary).
+  */
+ struct phylink_pcs_ops {
++      int (*pcs_validate)(struct phylink_pcs *pcs, unsigned long *supported,
++                          const struct phylink_link_state *state);
+       void (*pcs_get_state)(struct phylink_pcs *pcs,
+                             struct phylink_link_state *state);
+       int (*pcs_config)(struct phylink_pcs *pcs, unsigned int mode,
+@@ -416,6 +419,23 @@ struct phylink_pcs_ops {
+ #if 0 /* For kernel-doc purposes only. */
+ /**
++ * pcs_validate() - validate the link configuration.
++ * @pcs: a pointer to a &struct phylink_pcs.
++ * @supported: ethtool bitmask for supported link modes.
++ * @state: a const pointer to a &struct phylink_link_state.
++ *
++ * Validate the interface mode, and advertising's autoneg bit, removing any
++ * media ethtool link modes that would not be supportable from the supported
++ * mask. Phylink will propagate the changes to the advertising mask. See the
++ * &struct phylink_mac_ops validate() method.
++ *
++ * Returns -EINVAL if the interface mode/autoneg mode is not supported.
++ * Returns non-zero positive if the link state can be supported.
++ */
++int pcs_validate(struct phylink_pcs *pcs, unsigned long *supported,
++               const struct phylink_link_state *state);
++
++/**
+  * pcs_get_state() - Read the current inband link state from the hardware
+  * @pcs: a pointer to a &struct phylink_pcs.
+  * @state: a pointer to a &struct phylink_link_state.
diff --git a/target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch b/target/linux/generic/backport-5.15/703-12-v5.17-net-phylink-add-legacy_pre_march2020-indicator.patch
new file mode 100644 (file)
index 0000000..6fbde12
--- /dev/null
@@ -0,0 +1,43 @@
+From 3e5b1feccea7db576353ffc302f78d522e4116e6 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 9 Dec 2021 13:11:32 +0000
+Subject: [PATCH] net: phylink: add legacy_pre_march2020 indicator
+
+Add a boolean to phylink_config to indicate whether a driver has not
+been updated for the changes in commit 7cceb599d15d ("net: phylink:
+avoid mac_config calls"), and thus are reliant on the old behaviour.
+
+We were currently keying the phylink behaviour on the presence of a
+PCS, but this is sub-optimal for modern drivers that may not have a
+PCS.
+
+This commit merely introduces the new flag, but does not add any use,
+since we need all legacy drivers to set this flag before it can be
+used. Once these legacy drivers have been updated, we can remove this
+flag.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ include/linux/phylink.h | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -84,6 +84,8 @@ enum phylink_op_type {
+  * struct phylink_config - PHYLINK configuration structure
+  * @dev: a pointer to a struct device associated with the MAC
+  * @type: operation type of PHYLINK instance
++ * @legacy_pre_march2020: driver has not been updated for March 2020 updates
++ *    (See commit 7cceb599d15d ("net: phylink: avoid mac_config calls")
+  * @pcs_poll: MAC PCS cannot provide link change interrupt
+  * @poll_fixed_state: if true, starts link_poll,
+  *                  if MAC link is at %MLO_AN_FIXED mode.
+@@ -97,6 +99,7 @@ enum phylink_op_type {
+ struct phylink_config {
+       struct device *dev;
+       enum phylink_op_type type;
++      bool legacy_pre_march2020;
+       bool pcs_poll;
+       bool poll_fixed_state;
+       bool ovr_an_inband;
diff --git a/target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch b/target/linux/generic/backport-5.15/703-13-v5.17-net-dsa-mark-DSA-phylink-as-legacy_pre_march2020.patch
new file mode 100644 (file)
index 0000000..dff0db5
--- /dev/null
@@ -0,0 +1,36 @@
+From 0a9f0794d9bd67e590a9488afe87fbb0419d9539 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 9 Dec 2021 13:11:38 +0000
+Subject: [PATCH] net: dsa: mark DSA phylink as legacy_pre_march2020
+
+The majority of DSA drivers do not make use of the PCS support, and
+thus operate in legacy mode. In order to preserve this behaviour in
+future, we need to set the legacy_pre_march2020 flag so phylink knows
+this may require the legacy calls.
+
+There are some DSA drivers that do make use of PCS support, and these
+will continue operating as before - legacy_pre_march2020 will not
+prevent split-PCS support enabling the newer phylink behaviour.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ net/dsa/port.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- a/net/dsa/port.c
++++ b/net/dsa/port.c
+@@ -1110,6 +1110,13 @@ int dsa_port_phylink_create(struct dsa_p
+       if (err)
+               mode = PHY_INTERFACE_MODE_NA;
++      /* Presence of phylink_mac_link_state or phylink_mac_an_restart is
++       * an indicator of a legacy phylink driver.
++       */
++      if (ds->ops->phylink_mac_link_state ||
++          ds->ops->phylink_mac_an_restart)
++              dp->pl_config.legacy_pre_march2020 = true;
++
+       if (ds->ops->phylink_get_caps)
+               ds->ops->phylink_get_caps(ds, dp->index, &dp->pl_config);
diff --git a/target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch b/target/linux/generic/backport-5.15/703-14-v5.17-net-phylink-use-legacy_pre_march2020.patch
new file mode 100644 (file)
index 0000000..361fa10
--- /dev/null
@@ -0,0 +1,115 @@
+From 001f4261fe4d5ae710cf1f445b6cae6d9d3ae26e Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 9 Dec 2021 13:11:48 +0000
+Subject: [PATCH] net: phylink: use legacy_pre_march2020
+
+Use the legacy flag to indicate whether we should operate in legacy
+mode. This allows us to stop using the presence of a PCS as an
+indicator to the age of the phylink user, and make PCS presence
+optional.
+
+Legacy mode involves:
+1) calling mac_config() whenever the link comes up
+2) calling mac_config() whenever the inband advertisement changes,
+   possibly followed by a call to mac_an_restart()
+3) making use of mac_an_restart()
+4) making use of mac_pcs_get_state()
+
+All the above functionality was moved to a seperate "PCS" block of
+operations in March 2020.
+
+Update the documents to indicate that the differences that this flag
+makes.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/phylink.c | 12 ++++++------
+ include/linux/phylink.h   | 17 +++++++++++++++++
+ 2 files changed, 23 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/phy/phylink.c
++++ b/drivers/net/phy/phylink.c
+@@ -777,7 +777,7 @@ static void phylink_mac_pcs_an_restart(s
+           phylink_autoneg_inband(pl->cur_link_an_mode)) {
+               if (pl->pcs_ops)
+                       pl->pcs_ops->pcs_an_restart(pl->pcs);
+-              else
++              else if (pl->config->legacy_pre_march2020)
+                       pl->mac_ops->mac_an_restart(pl->config);
+       }
+ }
+@@ -855,7 +855,7 @@ static int phylink_change_inband_advert(
+       if (test_bit(PHYLINK_DISABLE_STOPPED, &pl->phylink_disable_state))
+               return 0;
+-      if (!pl->pcs_ops) {
++      if (!pl->pcs_ops && pl->config->legacy_pre_march2020) {
+               /* Legacy method */
+               phylink_mac_config(pl, &pl->link_config);
+               phylink_mac_pcs_an_restart(pl);
+@@ -900,7 +900,8 @@ static void phylink_mac_pcs_get_state(st
+       if (pl->pcs_ops)
+               pl->pcs_ops->pcs_get_state(pl->pcs, state);
+-      else if (pl->mac_ops->mac_pcs_get_state)
++      else if (pl->mac_ops->mac_pcs_get_state &&
++               pl->config->legacy_pre_march2020)
+               pl->mac_ops->mac_pcs_get_state(pl->config, state);
+       else
+               state->link = 0;
+@@ -1094,12 +1095,11 @@ static void phylink_resolve(struct work_
+                       }
+                       phylink_major_config(pl, false, &link_state);
+                       pl->link_config.interface = link_state.interface;
+-              } else if (!pl->pcs_ops) {
++              } else if (!pl->pcs_ops && pl->config->legacy_pre_march2020) {
+                       /* The interface remains unchanged, only the speed,
+                        * duplex or pause settings have changed. Call the
+                        * old mac_config() method to configure the MAC/PCS
+-                       * only if we do not have a PCS installed (an
+-                       * unconverted user.)
++                       * only if we do not have a legacy MAC driver.
+                        */
+                       phylink_mac_config(pl, &link_state);
+               }
+--- a/include/linux/phylink.h
++++ b/include/linux/phylink.h
+@@ -208,6 +208,10 @@ struct phylink_pcs *mac_select_pcs(struc
+  * negotiation completion state in @state->an_complete, and link up state
+  * in @state->link. If possible, @state->lp_advertising should also be
+  * populated.
++ *
++ * Note: This is a legacy method. This function will not be called unless
++ * legacy_pre_march2020 is set in &struct phylink_config and there is no
++ * PCS attached.
+  */
+ void mac_pcs_get_state(struct phylink_config *config,
+                      struct phylink_link_state *state);
+@@ -248,6 +252,15 @@ int mac_prepare(struct phylink_config *c
+  * guaranteed to be correct, and so any mac_config() implementation must
+  * never reference these fields.
+  *
++ * Note: For legacy March 2020 drivers (drivers with legacy_pre_march2020 set
++ * in their &phylnk_config and which don't have a PCS), this function will be
++ * called on each link up event, and to also change the in-band advert. For
++ * non-legacy drivers, it will only be called to reconfigure the MAC for a
++ * "major" change in e.g. interface mode. It will not be called for changes
++ * in speed, duplex or pause modes or to change the in-band advertisement.
++ * In any case, it is strongly preferred that speed, duplex and pause settings
++ * are handled in the mac_link_up() method and not in this method.
++ *
+  * (this requires a rewrite - please refer to mac_link_up() for situations
+  *  where the PCS and MAC are not tightly integrated.)
+  *
+@@ -332,6 +345,10 @@ int mac_finish(struct phylink_config *co
+ /**
+  * mac_an_restart() - restart 802.3z BaseX autonegotiation
+  * @config: a pointer to a &struct phylink_config.
++ *
++ * Note: This is a legacy method. This function will not be called unless
++ * legacy_pre_march2020 is set in &struct phylink_config and there is no
++ * PCS attached.
+  */
+ void mac_an_restart(struct phylink_config *config);
diff --git a/target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch b/target/linux/generic/backport-5.15/704-01-v5.17-net-mtk_eth_soc-populate-supported_interfaces-member.patch
new file mode 100644 (file)
index 0000000..43e1f9c
--- /dev/null
@@ -0,0 +1,43 @@
+From 83800d29f0c578e82554e7d4c6bfdbdf9b6cf428 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 16 Nov 2021 10:06:43 +0000
+Subject: [PATCH] net: mtk_eth_soc: populate supported_interfaces member
+
+Populate the phy interface mode bitmap for the Mediatek driver with
+interfaces modes supported by the MAC.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 20 ++++++++++++++++++++
+ 1 file changed, 20 insertions(+)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3352,6 +3352,26 @@ static int mtk_add_mac(struct mtk_eth *e
+       mac->phylink_config.dev = &eth->netdev[id]->dev;
+       mac->phylink_config.type = PHYLINK_NETDEV;
++      __set_bit(PHY_INTERFACE_MODE_MII,
++                mac->phylink_config.supported_interfaces);
++      __set_bit(PHY_INTERFACE_MODE_GMII,
++                mac->phylink_config.supported_interfaces);
++
++      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII))
++              phy_interface_set_rgmii(mac->phylink_config.supported_interfaces);
++
++      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) && !mac->id)
++              __set_bit(PHY_INTERFACE_MODE_TRGMII,
++                        mac->phylink_config.supported_interfaces);
++
++      if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) {
++              __set_bit(PHY_INTERFACE_MODE_SGMII,
++                        mac->phylink_config.supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_1000BASEX,
++                        mac->phylink_config.supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_2500BASEX,
++                        mac->phylink_config.supported_interfaces);
++      }
+       phylink = phylink_create(&mac->phylink_config,
+                                of_fwnode_handle(mac->of_node),
diff --git a/target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch b/target/linux/generic/backport-5.15/704-02-v5.17-net-mtk_eth_soc-remove-interface-checks-in-mtk_valid.patch
new file mode 100644 (file)
index 0000000..05a84c4
--- /dev/null
@@ -0,0 +1,75 @@
+From db81ca153814475d7e07365d46a4d1134bd122e2 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 16 Nov 2021 10:06:48 +0000
+Subject: [PATCH] net: mtk_eth_soc: remove interface checks in mtk_validate()
+
+As phylink checks the interface mode against the supported_interfaces
+bitmap, we no longer need to validate the interface mode, nor handle
+PHY_INTERFACE_MODE_NA in the validation function. Remove these to
+simplify the implementation.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 34 ---------------------
+ 1 file changed, 34 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -567,24 +567,8 @@ static void mtk_validate(struct phylink_
+                        unsigned long *supported,
+                        struct phylink_link_state *state)
+ {
+-      struct mtk_mac *mac = container_of(config, struct mtk_mac,
+-                                         phylink_config);
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+-      if (state->interface != PHY_INTERFACE_MODE_NA &&
+-          state->interface != PHY_INTERFACE_MODE_MII &&
+-          state->interface != PHY_INTERFACE_MODE_GMII &&
+-          !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII) &&
+-            phy_interface_mode_is_rgmii(state->interface)) &&
+-          !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_TRGMII) &&
+-            !mac->id && state->interface == PHY_INTERFACE_MODE_TRGMII) &&
+-          !(MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII) &&
+-            (state->interface == PHY_INTERFACE_MODE_SGMII ||
+-             phy_interface_mode_is_8023z(state->interface)))) {
+-              linkmode_zero(supported);
+-              return;
+-      }
+-
+       phylink_set_port_modes(mask);
+       phylink_set(mask, Autoneg);
+@@ -611,7 +595,6 @@ static void mtk_validate(struct phylink_
+       case PHY_INTERFACE_MODE_MII:
+       case PHY_INTERFACE_MODE_RMII:
+       case PHY_INTERFACE_MODE_REVMII:
+-      case PHY_INTERFACE_MODE_NA:
+       default:
+               phylink_set(mask, 10baseT_Half);
+               phylink_set(mask, 10baseT_Full);
+@@ -620,23 +603,6 @@ static void mtk_validate(struct phylink_
+               break;
+       }
+-      if (state->interface == PHY_INTERFACE_MODE_NA) {
+-              if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) {
+-                      phylink_set(mask, 1000baseT_Full);
+-                      phylink_set(mask, 1000baseX_Full);
+-                      phylink_set(mask, 2500baseX_Full);
+-              }
+-              if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) {
+-                      phylink_set(mask, 1000baseT_Full);
+-                      phylink_set(mask, 1000baseT_Half);
+-                      phylink_set(mask, 1000baseX_Full);
+-              }
+-              if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_GEPHY)) {
+-                      phylink_set(mask, 1000baseT_Full);
+-                      phylink_set(mask, 1000baseT_Half);
+-              }
+-      }
+-
+       phylink_set(mask, Pause);
+       phylink_set(mask, Asym_Pause);
diff --git a/target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch b/target/linux/generic/backport-5.15/704-03-v5.17-net-mtk_eth_soc-drop-use-of-phylink_helper_basex_spe.patch
new file mode 100644 (file)
index 0000000..a3cfab7
--- /dev/null
@@ -0,0 +1,42 @@
+From 71d927494463c4f016d828e1134da26b7e961af5 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 16 Nov 2021 10:06:53 +0000
+Subject: [PATCH] net: mtk_eth_soc: drop use of phylink_helper_basex_speed()
+
+Now that we have a better method to select SFP interface modes, we
+no longer need to use phylink_helper_basex_speed() in a driver's
+validation function, and we can also get rid of our hack to indicate
+both 1000base-X and 2500base-X if the comphy is present to make that
+work. Remove this hack and use of phylink_helper_basex_speed().
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -577,8 +577,9 @@ static void mtk_validate(struct phylink_
+               phylink_set(mask, 1000baseT_Full);
+               break;
+       case PHY_INTERFACE_MODE_1000BASEX:
+-      case PHY_INTERFACE_MODE_2500BASEX:
+               phylink_set(mask, 1000baseX_Full);
++              break;
++      case PHY_INTERFACE_MODE_2500BASEX:
+               phylink_set(mask, 2500baseX_Full);
+               break;
+       case PHY_INTERFACE_MODE_GMII:
+@@ -608,11 +609,6 @@ static void mtk_validate(struct phylink_
+       linkmode_and(supported, supported, mask);
+       linkmode_and(state->advertising, state->advertising, mask);
+-
+-      /* We can only operate at 2500BaseX or 1000BaseX. If requested
+-       * to advertise both, only report advertising at 2500BaseX.
+-       */
+-      phylink_helper_basex_speed(state);
+ }
+ static const struct phylink_mac_ops mtk_phylink_ops = {
diff --git a/target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch b/target/linux/generic/backport-5.15/704-04-v5.17-net-mtk_eth_soc-use-phylink_generic_validate.patch
new file mode 100644 (file)
index 0000000..7f3734a
--- /dev/null
@@ -0,0 +1,84 @@
+From a4238f6ce151afa331375d74a5033b76da637644 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 16 Nov 2021 10:06:58 +0000
+Subject: [PATCH] net: mtk_eth_soc: use phylink_generic_validate()
+
+mtk_eth_soc has no special behaviour in its validation implementation,
+so can be switched to phylink_generic_validate().
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 53 ++-------------------
+ 1 file changed, 4 insertions(+), 49 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -563,56 +563,8 @@ static void mtk_mac_link_up(struct phyli
+       mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
+ }
+-static void mtk_validate(struct phylink_config *config,
+-                       unsigned long *supported,
+-                       struct phylink_link_state *state)
+-{
+-      __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+-
+-      phylink_set_port_modes(mask);
+-      phylink_set(mask, Autoneg);
+-
+-      switch (state->interface) {
+-      case PHY_INTERFACE_MODE_TRGMII:
+-              phylink_set(mask, 1000baseT_Full);
+-              break;
+-      case PHY_INTERFACE_MODE_1000BASEX:
+-              phylink_set(mask, 1000baseX_Full);
+-              break;
+-      case PHY_INTERFACE_MODE_2500BASEX:
+-              phylink_set(mask, 2500baseX_Full);
+-              break;
+-      case PHY_INTERFACE_MODE_GMII:
+-      case PHY_INTERFACE_MODE_RGMII:
+-      case PHY_INTERFACE_MODE_RGMII_ID:
+-      case PHY_INTERFACE_MODE_RGMII_RXID:
+-      case PHY_INTERFACE_MODE_RGMII_TXID:
+-              phylink_set(mask, 1000baseT_Half);
+-              fallthrough;
+-      case PHY_INTERFACE_MODE_SGMII:
+-              phylink_set(mask, 1000baseT_Full);
+-              phylink_set(mask, 1000baseX_Full);
+-              fallthrough;
+-      case PHY_INTERFACE_MODE_MII:
+-      case PHY_INTERFACE_MODE_RMII:
+-      case PHY_INTERFACE_MODE_REVMII:
+-      default:
+-              phylink_set(mask, 10baseT_Half);
+-              phylink_set(mask, 10baseT_Full);
+-              phylink_set(mask, 100baseT_Half);
+-              phylink_set(mask, 100baseT_Full);
+-              break;
+-      }
+-
+-      phylink_set(mask, Pause);
+-      phylink_set(mask, Asym_Pause);
+-
+-      linkmode_and(supported, supported, mask);
+-      linkmode_and(state->advertising, state->advertising, mask);
+-}
+-
+ static const struct phylink_mac_ops mtk_phylink_ops = {
+-      .validate = mtk_validate,
++      .validate = phylink_generic_validate,
+       .mac_pcs_get_state = mtk_mac_pcs_get_state,
+       .mac_an_restart = mtk_mac_an_restart,
+       .mac_config = mtk_mac_config,
+@@ -3314,6 +3266,9 @@ static int mtk_add_mac(struct mtk_eth *e
+       mac->phylink_config.dev = &eth->netdev[id]->dev;
+       mac->phylink_config.type = PHYLINK_NETDEV;
++      mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
++              MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
++
+       __set_bit(PHY_INTERFACE_MODE_MII,
+                 mac->phylink_config.supported_interfaces);
+       __set_bit(PHY_INTERFACE_MODE_GMII,
diff --git a/target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch b/target/linux/generic/backport-5.15/704-05-v5.17-net-mtk_eth_soc-mark-as-a-legacy_pre_march2020-drive.patch
new file mode 100644 (file)
index 0000000..6aa99ac
--- /dev/null
@@ -0,0 +1,29 @@
+From b06515367facfadcf5e70cf6f39db749cf4eb5e3 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Thu, 9 Dec 2021 13:11:43 +0000
+Subject: [PATCH] net: mtk_eth_soc: mark as a legacy_pre_march2020 driver
+
+mtk_eth_soc has not been updated for commit 7cceb599d15d ("net: phylink:
+avoid mac_config calls"), and makes use of state->speed and
+state->duplex in contravention of the phylink documentation. This makes
+reliant on the legacy behaviours, so mark it as a legacy driver.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3266,6 +3266,10 @@ static int mtk_add_mac(struct mtk_eth *e
+       mac->phylink_config.dev = &eth->netdev[id]->dev;
+       mac->phylink_config.type = PHYLINK_NETDEV;
++      /* This driver makes use of state->speed/state->duplex in
++       * mac_config
++       */
++      mac->phylink_config.legacy_pre_march2020 = true;
+       mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+               MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
diff --git a/target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch b/target/linux/generic/backport-5.15/704-06-v5.19-eth-mtk_eth_soc-remove-a-copy-of-the-NAPI_POLL_WEIGH.patch
new file mode 100644 (file)
index 0000000..e5f70e3
--- /dev/null
@@ -0,0 +1,40 @@
+From 889e3691b9d6573de133da1f5e78f590e52152cd Mon Sep 17 00:00:00 2001
+From: Jakub Kicinski <kuba@kernel.org>
+Date: Thu, 28 Apr 2022 14:23:13 -0700
+Subject: [PATCH] eth: mtk_eth_soc: remove a copy of the NAPI_POLL_WEIGHT
+ define
+
+Defining local versions of NAPI_POLL_WEIGHT with the same
+values in the drivers just makes refactoring harder.
+
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 4 ++--
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
+ 2 files changed, 2 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3565,9 +3565,9 @@ static int mtk_probe(struct platform_dev
+        */
+       init_dummy_netdev(&eth->dummy_dev);
+       netif_napi_add(&eth->dummy_dev, &eth->tx_napi, mtk_napi_tx,
+-                     MTK_NAPI_WEIGHT);
++                     NAPI_POLL_WEIGHT);
+       netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_napi_rx,
+-                     MTK_NAPI_WEIGHT);
++                     NAPI_POLL_WEIGHT);
+       platform_set_drvdata(pdev, eth);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -25,7 +25,6 @@
+ #define MTK_TX_DMA_BUF_LEN    0x3fff
+ #define MTK_TX_DMA_BUF_LEN_V2 0xffff
+ #define MTK_DMA_SIZE          512
+-#define MTK_NAPI_WEIGHT               64
+ #define MTK_MAC_COUNT         2
+ #define MTK_RX_ETH_HLEN               (ETH_HLEN + ETH_FCS_LEN)
+ #define MTK_RX_HLEN           (NET_SKB_PAD + MTK_RX_ETH_HLEN + NET_IP_ALIGN)
diff --git a/target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch b/target/linux/generic/backport-5.15/704-07-v5.19-mtk_eth_soc-remove-unused-mac-mode.patch
new file mode 100644 (file)
index 0000000..4d896cd
--- /dev/null
@@ -0,0 +1,35 @@
+From 0600bdde1fae75fb9bad72033d28edddc72b44b2 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:54:31 +0100
+Subject: [PATCH 01/12] net: mtk_eth_soc: remove unused mac->mode
+
+mac->mode is only ever written to in one location, and is thus
+superflous. Remove it.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 1 -
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 1 -
+ 2 files changed, 2 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -3261,7 +3261,6 @@ static int mtk_add_mac(struct mtk_eth *e
+       /* mac config is not set */
+       mac->interface = PHY_INTERFACE_MODE_NA;
+-      mac->mode = MLO_AN_PHY;
+       mac->speed = SPEED_UNKNOWN;
+       mac->phylink_config.dev = &eth->netdev[id]->dev;
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1085,7 +1085,6 @@ struct mtk_eth {
+ struct mtk_mac {
+       int                             id;
+       phy_interface_t                 interface;
+-      unsigned int                    mode;
+       int                             speed;
+       struct device_node              *of_node;
+       struct phylink                  *phylink;
diff --git a/target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch b/target/linux/generic/backport-5.15/704-08-v5.19-net-mtk_eth_soc-remove-unused-sgmii-flags.patch
new file mode 100644 (file)
index 0000000..39aa241
--- /dev/null
@@ -0,0 +1,40 @@
+From 5a7a2f4b29d7546244da7d8bbc1962fce5b230f2 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:54:36 +0100
+Subject: [PATCH 02/12] net: mtk_eth_soc: remove unused sgmii flags
+
+The "flags" member of struct mtk_sgmii appears to be unused, as are
+the MTK_SGMII_PHYSPEED_* and MTK_HAS_FLAGS() macros. Remove them.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 --------
+ 1 file changed, 8 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -956,23 +956,15 @@ struct mtk_soc_data {
+ /* currently no SoC has more than 2 macs */
+ #define MTK_MAX_DEVS                  2
+-#define MTK_SGMII_PHYSPEED_AN          BIT(31)
+-#define MTK_SGMII_PHYSPEED_MASK        GENMASK(2, 0)
+-#define MTK_SGMII_PHYSPEED_1000        BIT(0)
+-#define MTK_SGMII_PHYSPEED_2500        BIT(1)
+-#define MTK_HAS_FLAGS(flags, _x)       (((flags) & (_x)) == (_x))
+-
+ /* struct mtk_sgmii -  This is the structure holding sgmii regmap and its
+  *                     characteristics
+  * @regmap:            The register map pointing at the range used to setup
+  *                     SGMII modes
+- * @flags:             The enum refers to which mode the sgmii wants to run on
+  * @ana_rgc3:          The offset refers to register ANA_RGC3 related to regmap
+  */
+ struct mtk_sgmii {
+       struct regmap   *regmap[MTK_MAX_DEVS];
+-      u32             flags[MTK_MAX_DEVS];
+       u32             ana_rgc3;
+ };
diff --git a/target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch b/target/linux/generic/backport-5.15/704-09-v5.19-net-mtk_eth_soc-add-mask-and-update-PCS-speed-defini.patch
new file mode 100644 (file)
index 0000000..f2e1f86
--- /dev/null
@@ -0,0 +1,40 @@
+From bc5e93e0cd22e360eda23859b939280205567580 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:54:42 +0100
+Subject: [PATCH 03/12] net: mtk_eth_soc: add mask and update PCS speed
+ definitions
+
+The PCS speed setting is a two bit field, but it is defined as two
+separate bits. Add a bitfield mask for the speed definitions, an
+ use the FIELD_PREP() macro to define each PCS speed.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -17,6 +17,7 @@
+ #include <linux/phylink.h>
+ #include <linux/rhashtable.h>
+ #include <linux/dim.h>
++#include <linux/bitfield.h>
+ #include "mtk_ppe.h"
+ #define MTK_QDMA_PAGE_SIZE    2048
+@@ -473,9 +474,10 @@
+ #define SGMSYS_SGMII_MODE             0x20
+ #define SGMII_IF_MODE_BIT0            BIT(0)
+ #define SGMII_SPEED_DUPLEX_AN         BIT(1)
+-#define SGMII_SPEED_10                        0x0
+-#define SGMII_SPEED_100                       BIT(2)
+-#define SGMII_SPEED_1000              BIT(3)
++#define SGMII_SPEED_MASK              GENMASK(3, 2)
++#define SGMII_SPEED_10                        FIELD_PREP(SGMII_SPEED_MASK, 0)
++#define SGMII_SPEED_100                       FIELD_PREP(SGMII_SPEED_MASK, 1)
++#define SGMII_SPEED_1000              FIELD_PREP(SGMII_SPEED_MASK, 2)
+ #define SGMII_DUPLEX_FULL             BIT(4)
+ #define SGMII_IF_MODE_BIT5            BIT(5)
+ #define SGMII_REMOTE_FAULT_DIS                BIT(8)
diff --git a/target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch b/target/linux/generic/backport-5.15/704-10-v5.19-net-mtk_eth_soc-correct-802.3z-speed-setting.patch
new file mode 100644 (file)
index 0000000..fb1ee4e
--- /dev/null
@@ -0,0 +1,60 @@
+From 7da3f901f8ecb425105fad39a0f5de73306abe52 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:54:47 +0100
+Subject: [PATCH 04/12] net: mtk_eth_soc: correct 802.3z speed setting
+
+Phylink does not guarantee that state->speed will be set correctly in
+the mac_config() call, so it's a bug that the driver makes use of it.
+Moreover, it is making use of it in a function that is only ever called
+for 1000BASE-X and 2500BASE-X which operate at a fixed speed which
+happens to be the same setting irrespective of the interface mode. We
+can simply remove the switch statement and just set the SGMII interface
+speed.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c | 18 +++++-------------
+ 1 file changed, 5 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -34,6 +34,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
+       return 0;
+ }
++/* For SGMII interface mode */
+ int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
+ {
+       unsigned int val;
+@@ -60,6 +61,9 @@ int mtk_sgmii_setup_mode_an(struct mtk_s
+       return 0;
+ }
++/* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
++ * fixed speed.
++ */
+ int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
+                              const struct phylink_link_state *state)
+ {
+@@ -82,19 +86,7 @@ int mtk_sgmii_setup_mode_force(struct mt
+       /* SGMII force mode setting */
+       regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
+       val &= ~SGMII_IF_MODE_MASK;
+-
+-      switch (state->speed) {
+-      case SPEED_10:
+-              val |= SGMII_SPEED_10;
+-              break;
+-      case SPEED_100:
+-              val |= SGMII_SPEED_100;
+-              break;
+-      case SPEED_2500:
+-      case SPEED_1000:
+-              val |= SGMII_SPEED_1000;
+-              break;
+-      }
++      val |= SGMII_SPEED_1000;
+       if (state->duplex == DUPLEX_FULL)
+               val |= SGMII_DUPLEX_FULL;
diff --git a/target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch b/target/linux/generic/backport-5.15/704-11-v5.19-net-mtk_eth_soc-correct-802.3z-duplex-setting.patch
new file mode 100644 (file)
index 0000000..140ff3c
--- /dev/null
@@ -0,0 +1,101 @@
+From a459187390bb221827f9c07866c3a5ffbdf9622b Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:54:52 +0100
+Subject: [PATCH 05/12] net: mtk_eth_soc: correct 802.3z duplex setting
+
+Phylink does not guarantee that state->duplex will be set correctly in
+the mac_config() call, so it's a bug that the driver makes use of it.
+
+Move the 802.3z PCS duplex configuration to mac_link_up().
+
+Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 16 +++++++++++----
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  1 +
+ drivers/net/ethernet/mediatek/mtk_sgmii.c   | 22 +++++++++++++++------
+ 3 files changed, 29 insertions(+), 10 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -532,8 +532,18 @@ static void mtk_mac_link_up(struct phyli
+ {
+       struct mtk_mac *mac = container_of(config, struct mtk_mac,
+                                          phylink_config);
+-      u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
++      u32 mcr;
++      if (phy_interface_mode_is_8023z(interface)) {
++              struct mtk_eth *eth = mac->hw;
++
++              /* Decide how GMAC and SGMIISYS be mapped */
++              int sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
++                         0 : mac->id;
++              mtk_sgmii_link_up(eth->sgmii, sid, speed, duplex);
++      }
++
++      mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+       mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
+                MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
+                MAC_MCR_FORCE_RX_FC);
+@@ -3265,9 +3275,7 @@ static int mtk_add_mac(struct mtk_eth *e
+       mac->phylink_config.dev = &eth->netdev[id]->dev;
+       mac->phylink_config.type = PHYLINK_NETDEV;
+-      /* This driver makes use of state->speed/state->duplex in
+-       * mac_config
+-       */
++      /* This driver makes use of state->speed in mac_config */
+       mac->phylink_config.legacy_pre_march2020 = true;
+       mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+               MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1103,6 +1103,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
+ int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id);
+ int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
+                              const struct phylink_link_state *state);
++void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
+ void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
+ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -83,14 +83,10 @@ int mtk_sgmii_setup_mode_force(struct mt
+       val &= ~SGMII_AN_ENABLE;
+       regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val);
+-      /* SGMII force mode setting */
++      /* Set the speed etc but leave the duplex unchanged */
+       regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
+-      val &= ~SGMII_IF_MODE_MASK;
++      val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
+       val |= SGMII_SPEED_1000;
+-
+-      if (state->duplex == DUPLEX_FULL)
+-              val |= SGMII_DUPLEX_FULL;
+-
+       regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
+       /* Release PHYA power down state */
+@@ -101,6 +97,20 @@ int mtk_sgmii_setup_mode_force(struct mt
+       return 0;
+ }
++/* For 1000BASE-X and 2500BASE-X interface modes */
++void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
++{
++      unsigned int val;
++
++      /* SGMII force duplex setting */
++      regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
++      val &= ~SGMII_DUPLEX_FULL;
++      if (duplex == DUPLEX_FULL)
++              val |= SGMII_DUPLEX_FULL;
++
++      regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
++}
++
+ void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
+ {
+       struct mtk_sgmii *ss = eth->sgmii;
diff --git a/target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch b/target/linux/generic/backport-5.15/704-12-v5.19-net-mtk_eth_soc-stop-passing-phylink-state-to-sgmii-.patch
new file mode 100644 (file)
index 0000000..56b5e43
--- /dev/null
@@ -0,0 +1,60 @@
+From 4ce5a0bd3958ed248f0325bfcb95339f7c74feb2 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:54:57 +0100
+Subject: [PATCH 06/12] net: mtk_eth_soc: stop passing phylink state to sgmii
+ setup
+
+Now that mtk_sgmii_setup_mode_force() only uses the interface mode
+from the phylink state, pass just the interface mode into this
+function.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 2 +-
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h | 2 +-
+ drivers/net/ethernet/mediatek/mtk_sgmii.c   | 4 ++--
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -437,7 +437,7 @@ static void mtk_mac_config(struct phylin
+               /* Setup SGMIISYS with the determined property */
+               if (state->interface != PHY_INTERFACE_MODE_SGMII)
+                       err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
+-                                                       state);
++                                                       state->interface);
+               else if (phylink_autoneg_inband(mode))
+                       err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1102,7 +1102,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
+                  u32 ana_rgc3);
+ int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id);
+ int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
+-                             const struct phylink_link_state *state);
++                             phy_interface_t interface);
+ void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
+ void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -65,7 +65,7 @@ int mtk_sgmii_setup_mode_an(struct mtk_s
+  * fixed speed.
+  */
+ int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
+-                             const struct phylink_link_state *state)
++                             phy_interface_t interface)
+ {
+       unsigned int val;
+@@ -74,7 +74,7 @@ int mtk_sgmii_setup_mode_force(struct mt
+       regmap_read(ss->regmap[id], ss->ana_rgc3, &val);
+       val &= ~RG_PHY_SPEED_MASK;
+-      if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
++      if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val |= RG_PHY_SPEED_3_125G;
+       regmap_write(ss->regmap[id], ss->ana_rgc3, val);
diff --git a/target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch b/target/linux/generic/backport-5.15/704-13-v5.19-net-mtk_eth_soc-provide-mtk_sgmii_config.patch
new file mode 100644 (file)
index 0000000..4c91cf6
--- /dev/null
@@ -0,0 +1,89 @@
+From 1ec619ee4a052fb9ac48b57554ac2722a0bfe73c Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:55:02 +0100
+Subject: [PATCH 07/12] net: mtk_eth_soc: provide mtk_sgmii_config()
+
+Provide mtk_sgmii_config() to wrap up the decisions about which SGMII
+configuration will be called.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c |  7 +------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  5 ++---
+ drivers/net/ethernet/mediatek/mtk_sgmii.c   | 20 +++++++++++++++++---
+ 3 files changed, 20 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -435,12 +435,7 @@ static void mtk_mac_config(struct phylin
+                      0 : mac->id;
+               /* Setup SGMIISYS with the determined property */
+-              if (state->interface != PHY_INTERFACE_MODE_SGMII)
+-                      err = mtk_sgmii_setup_mode_force(eth->sgmii, sid,
+-                                                       state->interface);
+-              else if (phylink_autoneg_inband(mode))
+-                      err = mtk_sgmii_setup_mode_an(eth->sgmii, sid);
+-
++              err = mtk_sgmii_config(eth->sgmii, sid, mode, state->interface);
+               if (err)
+                       goto init_err;
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1100,9 +1100,8 @@ u32 mtk_r32(struct mtk_eth *eth, unsigne
+ int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
+                  u32 ana_rgc3);
+-int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id);
+-int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
+-                             phy_interface_t interface);
++int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
++                   phy_interface_t interface);
+ void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
+ void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -35,7 +35,7 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
+ }
+ /* For SGMII interface mode */
+-int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
++static int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
+ {
+       unsigned int val;
+@@ -64,8 +64,8 @@ int mtk_sgmii_setup_mode_an(struct mtk_s
+ /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
+  * fixed speed.
+  */
+-int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
+-                             phy_interface_t interface)
++static int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
++                                    phy_interface_t interface)
+ {
+       unsigned int val;
+@@ -97,6 +97,20 @@ int mtk_sgmii_setup_mode_force(struct mt
+       return 0;
+ }
++int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
++                   phy_interface_t interface)
++{
++      int err = 0;
++
++      /* Setup SGMIISYS with the determined property */
++      if (interface != PHY_INTERFACE_MODE_SGMII)
++              err = mtk_sgmii_setup_mode_force(ss, id, interface);
++      else if (phylink_autoneg_inband(mode))
++              err = mtk_sgmii_setup_mode_an(ss, id);
++
++      return err;
++}
++
+ /* For 1000BASE-X and 2500BASE-X interface modes */
+ void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
+ {
diff --git a/target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch b/target/linux/generic/backport-5.15/704-14-v5.19-net-mtk_eth_soc-add-fixme-comment-for-state-speed-us.patch
new file mode 100644 (file)
index 0000000..8080a2c
--- /dev/null
@@ -0,0 +1,38 @@
+From 650a49bc65df6b0e0051a8f62d7c22d95a8f350d Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:55:07 +0100
+Subject: [PATCH 08/12] net: mtk_eth_soc: add fixme comment for state->speed
+ use
+
+Add a fixme comment for the last remaining incorrect usage of
+state->speed in the mac_config() method, which is strangely in a code
+path which is only run when the PHY interface mode changes.
+
+This means if we are in RGMII mode, changes in state->speed will not
+cause the INTF_MODE, TRGMII_RCK_CTRL and TRGMII_TCK_CTRL registers to
+be set according to the speed, nor will the TRGPLL clock be set to the
+correct value.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -374,6 +374,14 @@ static void mtk_mac_config(struct phylin
+                                                             state->interface))
+                                       goto err_phy;
+                       } else {
++                              /* FIXME: this is incorrect. Not only does it
++                               * use state->speed (which is not guaranteed
++                               * to be correct) but it also makes use of it
++                               * in a code path that will only be reachable
++                               * when the PHY interface mode changes, not
++                               * when the speed changes. Consequently, RGMII
++                               * is probably broken.
++                               */
+                               mtk_gmac0_rgmii_adjust(mac->hw,
+                                                      state->interface,
+                                                      state->speed);
diff --git a/target/linux/generic/backport-5.15/704-15-v5.19-net-mtk_eth_soc-move-MAC_MCR-setting-to-mac_finish.patch b/target/linux/generic/backport-5.15/704-15-v5.19-net-mtk_eth_soc-move-MAC_MCR-setting-to-mac_finish.patch
new file mode 100644 (file)
index 0000000..368db4c
--- /dev/null
@@ -0,0 +1,79 @@
+From 0e37ad71b2ff772009595002da2860999e98e14e Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:55:12 +0100
+Subject: [PATCH 09/12] net: mtk_eth_soc: move MAC_MCR setting to mac_finish()
+
+Move the setting of the MTK_MAC_MCR register from the end of mac_config
+into the phylink mac_finish() method, to keep it as the very last write
+that is done during configuration.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 33 ++++++++++++++-------
+ 1 file changed, 22 insertions(+), 11 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -316,8 +316,8 @@ static void mtk_mac_config(struct phylin
+       struct mtk_mac *mac = container_of(config, struct mtk_mac,
+                                          phylink_config);
+       struct mtk_eth *eth = mac->hw;
+-      u32 mcr_cur, mcr_new, sid, i;
+       int val, ge_mode, err = 0;
++      u32 sid, i;
+       /* MT76x8 has no hardware settings between for the MAC */
+       if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
+@@ -455,16 +455,6 @@ static void mtk_mac_config(struct phylin
+               return;
+       }
+-      /* Setup gmac */
+-      mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+-      mcr_new = mcr_cur;
+-      mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
+-                 MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK;
+-
+-      /* Only update control register when needed! */
+-      if (mcr_new != mcr_cur)
+-              mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
+-
+       return;
+ err_phy:
+@@ -477,6 +467,26 @@ init_err:
+               mac->id, phy_modes(state->interface), err);
+ }
++static int mtk_mac_finish(struct phylink_config *config, unsigned int mode,
++                        phy_interface_t interface)
++{
++      struct mtk_mac *mac = container_of(config, struct mtk_mac,
++                                         phylink_config);
++      u32 mcr_cur, mcr_new;
++
++      /* Setup gmac */
++      mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
++      mcr_new = mcr_cur;
++      mcr_new |= MAC_MCR_IPG_CFG | MAC_MCR_FORCE_MODE |
++                 MAC_MCR_BACKOFF_EN | MAC_MCR_BACKPR_EN | MAC_MCR_FORCE_LINK;
++
++      /* Only update control register when needed! */
++      if (mcr_new != mcr_cur)
++              mtk_w32(mac->hw, mcr_new, MTK_MAC_MCR(mac->id));
++
++      return 0;
++}
++
+ static void mtk_mac_pcs_get_state(struct phylink_config *config,
+                                 struct phylink_link_state *state)
+ {
+@@ -581,6 +591,7 @@ static const struct phylink_mac_ops mtk_
+       .mac_pcs_get_state = mtk_mac_pcs_get_state,
+       .mac_an_restart = mtk_mac_an_restart,
+       .mac_config = mtk_mac_config,
++      .mac_finish = mtk_mac_finish,
+       .mac_link_down = mtk_mac_link_down,
+       .mac_link_up = mtk_mac_link_up,
+ };
diff --git a/target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch b/target/linux/generic/backport-5.15/704-16-v5.19-net-mtk_eth_soc-move-restoration-of-SYSCFG0-to-mac_f.patch
new file mode 100644 (file)
index 0000000..ad6ec60
--- /dev/null
@@ -0,0 +1,57 @@
+From 21089867278deb2a110b685e3cd33f64f9ce41e2 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:55:17 +0100
+Subject: [PATCH 10/12] net: mtk_eth_soc: move restoration of SYSCFG0 to
+ mac_finish()
+
+The SGMIISYS configuration is performed while ETHSYS_SYSCFG0 is in a
+disabled state. In order to preserve this when we switch to phylink_pcs
+we need to move the restoration of this register to the mac_finish()
+callback.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 11 +++++++++--
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  1 +
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -447,8 +447,8 @@ static void mtk_mac_config(struct phylin
+               if (err)
+                       goto init_err;
+-              regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
+-                                 SYSCFG0_SGMII_MASK, val);
++              /* Save the syscfg0 value for mac_finish */
++              mac->syscfg0 = val;
+       } else if (phylink_autoneg_inband(mode)) {
+               dev_err(eth->dev,
+                       "In-band mode not supported in non SGMII mode!\n");
+@@ -472,8 +472,15 @@ static int mtk_mac_finish(struct phylink
+ {
+       struct mtk_mac *mac = container_of(config, struct mtk_mac,
+                                          phylink_config);
++      struct mtk_eth *eth = mac->hw;
+       u32 mcr_cur, mcr_new;
++      /* Enable SGMII */
++      if (interface == PHY_INTERFACE_MODE_SGMII ||
++          phy_interface_mode_is_8023z(interface))
++              regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
++                                 SYSCFG0_SGMII_MASK, mac->syscfg0);
++
+       /* Setup gmac */
+       mcr_cur = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+       mcr_new = mcr_cur;
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -1087,6 +1087,7 @@ struct mtk_mac {
+       struct mtk_hw_stats             *hw_stats;
+       __be32                          hwlro_ip[MTK_MAX_LRO_IP_CNT];
+       int                             hwlro_ip_cnt;
++      unsigned int                    syscfg0;
+ };
+ /* the struct describing the SoC. these are declared in the soc_xyz.c files */
diff --git a/target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch b/target/linux/generic/backport-5.15/704-17-v5.19-net-mtk_eth_soc-convert-code-structure-to-suit-split.patch
new file mode 100644 (file)
index 0000000..623658f
--- /dev/null
@@ -0,0 +1,254 @@
+From 901f3fbe13c3e56f0742e02717ccbfabbc95c463 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:55:22 +0100
+Subject: [PATCH 11/12] net: mtk_eth_soc: convert code structure to suit split
+ PCS support
+
+Provide a mtk_pcs structure which encapsulates everything that the PCS
+functions need (the regmap and ana_rgc3 offset), and use this in the
+PCS functions. Provide shim functions to convert from the existing
+"mtk_sgmii_*" interface to the converted PCS functions.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  15 ++-
+ drivers/net/ethernet/mediatek/mtk_sgmii.c   | 123 +++++++++++---------
+ 2 files changed, 79 insertions(+), 59 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -958,16 +958,23 @@ struct mtk_soc_data {
+ /* currently no SoC has more than 2 macs */
+ #define MTK_MAX_DEVS                  2
+-/* struct mtk_sgmii -  This is the structure holding sgmii regmap and its
+- *                     characteristics
++/* struct mtk_pcs -    This structure holds each sgmii regmap and associated
++ *                     data
+  * @regmap:            The register map pointing at the range used to setup
+  *                     SGMII modes
+  * @ana_rgc3:          The offset refers to register ANA_RGC3 related to regmap
+  */
++struct mtk_pcs {
++      struct regmap   *regmap;
++      u32             ana_rgc3;
++};
++/* struct mtk_sgmii -  This is the structure holding sgmii regmap and its
++ *                     characteristics
++ * @pcs                Array of individual PCS structures
++ */
+ struct mtk_sgmii {
+-      struct regmap   *regmap[MTK_MAX_DEVS];
+-      u32             ana_rgc3;
++      struct mtk_pcs  pcs[MTK_MAX_DEVS];
+ };
+ /* struct mtk_eth -   This is the main datasructure for holding the state
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -9,90 +9,71 @@
+ #include <linux/mfd/syscon.h>
+ #include <linux/of.h>
++#include <linux/phylink.h>
+ #include <linux/regmap.h>
+ #include "mtk_eth_soc.h"
+-int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
+-{
+-      struct device_node *np;
+-      int i;
+-
+-      ss->ana_rgc3 = ana_rgc3;
+-
+-      for (i = 0; i < MTK_MAX_DEVS; i++) {
+-              np = of_parse_phandle(r, "mediatek,sgmiisys", i);
+-              if (!np)
+-                      break;
+-
+-              ss->regmap[i] = syscon_node_to_regmap(np);
+-              of_node_put(np);
+-              if (IS_ERR(ss->regmap[i]))
+-                      return PTR_ERR(ss->regmap[i]);
+-      }
+-
+-      return 0;
+-}
+-
+ /* For SGMII interface mode */
+-static int mtk_sgmii_setup_mode_an(struct mtk_sgmii *ss, int id)
++static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
+ {
+       unsigned int val;
+-      if (!ss->regmap[id])
++      if (!mpcs->regmap)
+               return -EINVAL;
+       /* Setup the link timer and QPHY power up inside SGMIISYS */
+-      regmap_write(ss->regmap[id], SGMSYS_PCS_LINK_TIMER,
++      regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
+                    SGMII_LINK_TIMER_DEFAULT);
+-      regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
++      regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
+       val |= SGMII_REMOTE_FAULT_DIS;
+-      regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
++      regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
+-      regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val);
++      regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
+       val |= SGMII_AN_RESTART;
+-      regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val);
++      regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
+-      regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val);
++      regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
+       val &= ~SGMII_PHYA_PWD;
+-      regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val);
++      regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
+       return 0;
++
+ }
+ /* For 1000BASE-X and 2500BASE-X interface modes, which operate at a
+  * fixed speed.
+  */
+-static int mtk_sgmii_setup_mode_force(struct mtk_sgmii *ss, int id,
+-                                    phy_interface_t interface)
++static int mtk_pcs_setup_mode_force(struct mtk_pcs *mpcs,
++                                  phy_interface_t interface)
+ {
+       unsigned int val;
+-      if (!ss->regmap[id])
++      if (!mpcs->regmap)
+               return -EINVAL;
+-      regmap_read(ss->regmap[id], ss->ana_rgc3, &val);
++      regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
+       val &= ~RG_PHY_SPEED_MASK;
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+               val |= RG_PHY_SPEED_3_125G;
+-      regmap_write(ss->regmap[id], ss->ana_rgc3, val);
++      regmap_write(mpcs->regmap, mpcs->ana_rgc3, val);
+       /* Disable SGMII AN */
+-      regmap_read(ss->regmap[id], SGMSYS_PCS_CONTROL_1, &val);
++      regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
+       val &= ~SGMII_AN_ENABLE;
+-      regmap_write(ss->regmap[id], SGMSYS_PCS_CONTROL_1, val);
++      regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
+       /* Set the speed etc but leave the duplex unchanged */
+-      regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
++      regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
+       val &= SGMII_DUPLEX_FULL | ~SGMII_IF_MODE_MASK;
+       val |= SGMII_SPEED_1000;
+-      regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
++      regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
+       /* Release PHYA power down state */
+-      regmap_read(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, &val);
++      regmap_read(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, &val);
+       val &= ~SGMII_PHYA_PWD;
+-      regmap_write(ss->regmap[id], SGMSYS_QPHY_PWR_STATE_CTRL, val);
++      regmap_write(mpcs->regmap, SGMSYS_QPHY_PWR_STATE_CTRL, val);
+       return 0;
+ }
+@@ -100,44 +81,76 @@ static int mtk_sgmii_setup_mode_force(st
+ int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
+                    phy_interface_t interface)
+ {
++      struct mtk_pcs *mpcs = &ss->pcs[id];
+       int err = 0;
+       /* Setup SGMIISYS with the determined property */
+       if (interface != PHY_INTERFACE_MODE_SGMII)
+-              err = mtk_sgmii_setup_mode_force(ss, id, interface);
++              err = mtk_pcs_setup_mode_force(mpcs, interface);
+       else if (phylink_autoneg_inband(mode))
+-              err = mtk_sgmii_setup_mode_an(ss, id);
++              err = mtk_pcs_setup_mode_an(mpcs);
+       return err;
+ }
+-/* For 1000BASE-X and 2500BASE-X interface modes */
+-void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
++static void mtk_pcs_restart_an(struct mtk_pcs *mpcs)
++{
++      unsigned int val;
++
++      if (!mpcs->regmap)
++              return;
++
++      regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
++      val |= SGMII_AN_RESTART;
++      regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
++}
++
++static void mtk_pcs_link_up(struct mtk_pcs *mpcs, int speed, int duplex)
+ {
+       unsigned int val;
+       /* SGMII force duplex setting */
+-      regmap_read(ss->regmap[id], SGMSYS_SGMII_MODE, &val);
++      regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
+       val &= ~SGMII_DUPLEX_FULL;
+       if (duplex == DUPLEX_FULL)
+               val |= SGMII_DUPLEX_FULL;
+-      regmap_write(ss->regmap[id], SGMSYS_SGMII_MODE, val);
++      regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
++}
++
++/* For 1000BASE-X and 2500BASE-X interface modes */
++void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
++{
++      mtk_pcs_link_up(&ss->pcs[id], speed, duplex);
++}
++
++int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
++{
++      struct device_node *np;
++      int i;
++
++      for (i = 0; i < MTK_MAX_DEVS; i++) {
++              np = of_parse_phandle(r, "mediatek,sgmiisys", i);
++              if (!np)
++                      break;
++
++              ss->pcs[i].ana_rgc3 = ana_rgc3;
++              ss->pcs[i].regmap = syscon_node_to_regmap(np);
++              of_node_put(np);
++              if (IS_ERR(ss->pcs[i].regmap))
++                      return PTR_ERR(ss->pcs[i].regmap);
++      }
++
++      return 0;
+ }
+ void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
+ {
+-      struct mtk_sgmii *ss = eth->sgmii;
+-      unsigned int val, sid;
++      unsigned int sid;
+       /* Decide how GMAC and SGMIISYS be mapped */
+       sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
+              0 : mac_id;
+-      if (!ss->regmap[sid])
+-              return;
+-
+-      regmap_read(ss->regmap[sid], SGMSYS_PCS_CONTROL_1, &val);
+-      val |= SGMII_AN_RESTART;
+-      regmap_write(ss->regmap[sid], SGMSYS_PCS_CONTROL_1, val);
++      mtk_pcs_restart_an(&eth->sgmii->pcs[sid]);
+ }
diff --git a/target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch b/target/linux/generic/backport-5.15/704-18-v5.19-net-mtk_eth_soc-partially-convert-to-phylink_pcs.patch
new file mode 100644 (file)
index 0000000..df675e2
--- /dev/null
@@ -0,0 +1,262 @@
+From 14a44ab0330d290fade1403a920e299cc56d7300 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Wed, 18 May 2022 15:55:28 +0100
+Subject: [PATCH 12/12] net: mtk_eth_soc: partially convert to phylink_pcs
+
+Partially convert mtk_eth_soc to phylink_pcs, moving the configuration,
+link up and AN restart over. However, it seems mac_pcs_get_state()
+doesn't actually get the state from the PCS, so we can't convert that
+over without a better understanding of the hardware.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/ethernet/mediatek/mtk_eth_soc.c | 49 ++++++++----------
+ drivers/net/ethernet/mediatek/mtk_eth_soc.h |  7 ++-
+ drivers/net/ethernet/mediatek/mtk_sgmii.c   | 55 +++++++++++----------
+ 3 files changed, 53 insertions(+), 58 deletions(-)
+
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+@@ -310,6 +310,25 @@ static void mtk_gmac0_rgmii_adjust(struc
+       mtk_w32(eth, val, TRGMII_TCK_CTRL);
+ }
++static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
++                                            phy_interface_t interface)
++{
++      struct mtk_mac *mac = container_of(config, struct mtk_mac,
++                                         phylink_config);
++      struct mtk_eth *eth = mac->hw;
++      unsigned int sid;
++
++      if (interface == PHY_INTERFACE_MODE_SGMII ||
++          phy_interface_mode_is_8023z(interface)) {
++              sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
++                     0 : mac->id;
++
++              return mtk_sgmii_select_pcs(eth->sgmii, sid);
++      }
++
++      return NULL;
++}
++
+ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
+                          const struct phylink_link_state *state)
+ {
+@@ -317,7 +336,7 @@ static void mtk_mac_config(struct phylin
+                                          phylink_config);
+       struct mtk_eth *eth = mac->hw;
+       int val, ge_mode, err = 0;
+-      u32 sid, i;
++      u32 i;
+       /* MT76x8 has no hardware settings between for the MAC */
+       if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) &&
+@@ -438,15 +457,6 @@ static void mtk_mac_config(struct phylin
+                                  SYSCFG0_SGMII_MASK,
+                                  ~(u32)SYSCFG0_SGMII_MASK);
+-              /* Decide how GMAC and SGMIISYS be mapped */
+-              sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
+-                     0 : mac->id;
+-
+-              /* Setup SGMIISYS with the determined property */
+-              err = mtk_sgmii_config(eth->sgmii, sid, mode, state->interface);
+-              if (err)
+-                      goto init_err;
+-
+               /* Save the syscfg0 value for mac_finish */
+               mac->syscfg0 = val;
+       } else if (phylink_autoneg_inband(mode)) {
+@@ -526,14 +536,6 @@ static void mtk_mac_pcs_get_state(struct
+               state->pause |= MLO_PAUSE_TX;
+ }
+-static void mtk_mac_an_restart(struct phylink_config *config)
+-{
+-      struct mtk_mac *mac = container_of(config, struct mtk_mac,
+-                                         phylink_config);
+-
+-      mtk_sgmii_restart_an(mac->hw, mac->id);
+-}
+-
+ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
+                             phy_interface_t interface)
+ {
+@@ -554,15 +556,6 @@ static void mtk_mac_link_up(struct phyli
+                                          phylink_config);
+       u32 mcr;
+-      if (phy_interface_mode_is_8023z(interface)) {
+-              struct mtk_eth *eth = mac->hw;
+-
+-              /* Decide how GMAC and SGMIISYS be mapped */
+-              int sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
+-                         0 : mac->id;
+-              mtk_sgmii_link_up(eth->sgmii, sid, speed, duplex);
+-      }
+-
+       mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
+       mcr &= ~(MAC_MCR_SPEED_100 | MAC_MCR_SPEED_1000 |
+                MAC_MCR_FORCE_DPX | MAC_MCR_FORCE_TX_FC |
+@@ -595,8 +588,8 @@ static void mtk_mac_link_up(struct phyli
+ static const struct phylink_mac_ops mtk_phylink_ops = {
+       .validate = phylink_generic_validate,
++      .mac_select_pcs = mtk_mac_select_pcs,
+       .mac_pcs_get_state = mtk_mac_pcs_get_state,
+-      .mac_an_restart = mtk_mac_an_restart,
+       .mac_config = mtk_mac_config,
+       .mac_finish = mtk_mac_finish,
+       .mac_link_down = mtk_mac_link_down,
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+@@ -963,10 +963,12 @@ struct mtk_soc_data {
+  * @regmap:            The register map pointing at the range used to setup
+  *                     SGMII modes
+  * @ana_rgc3:          The offset refers to register ANA_RGC3 related to regmap
++ * @pcs:               Phylink PCS structure
+  */
+ struct mtk_pcs {
+       struct regmap   *regmap;
+       u32             ana_rgc3;
++      struct phylink_pcs pcs;
+ };
+ /* struct mtk_sgmii -  This is the structure holding sgmii regmap and its
+@@ -1106,12 +1108,9 @@ void mtk_stats_update_mac(struct mtk_mac
+ void mtk_w32(struct mtk_eth *eth, u32 val, unsigned reg);
+ u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
++struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id);
+ int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *np,
+                  u32 ana_rgc3);
+-int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
+-                   phy_interface_t interface);
+-void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex);
+-void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id);
+ int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
+ int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
+--- a/drivers/net/ethernet/mediatek/mtk_sgmii.c
++++ b/drivers/net/ethernet/mediatek/mtk_sgmii.c
+@@ -14,14 +14,16 @@
+ #include "mtk_eth_soc.h"
++static struct mtk_pcs *pcs_to_mtk_pcs(struct phylink_pcs *pcs)
++{
++      return container_of(pcs, struct mtk_pcs, pcs);
++}
++
+ /* For SGMII interface mode */
+ static int mtk_pcs_setup_mode_an(struct mtk_pcs *mpcs)
+ {
+       unsigned int val;
+-      if (!mpcs->regmap)
+-              return -EINVAL;
+-
+       /* Setup the link timer and QPHY power up inside SGMIISYS */
+       regmap_write(mpcs->regmap, SGMSYS_PCS_LINK_TIMER,
+                    SGMII_LINK_TIMER_DEFAULT);
+@@ -50,9 +52,6 @@ static int mtk_pcs_setup_mode_force(stru
+ {
+       unsigned int val;
+-      if (!mpcs->regmap)
+-              return -EINVAL;
+-
+       regmap_read(mpcs->regmap, mpcs->ana_rgc3, &val);
+       val &= ~RG_PHY_SPEED_MASK;
+       if (interface == PHY_INTERFACE_MODE_2500BASEX)
+@@ -78,10 +77,12 @@ static int mtk_pcs_setup_mode_force(stru
+       return 0;
+ }
+-int mtk_sgmii_config(struct mtk_sgmii *ss, int id, unsigned int mode,
+-                   phy_interface_t interface)
++static int mtk_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
++                        phy_interface_t interface,
++                        const unsigned long *advertising,
++                        bool permit_pause_to_mac)
+ {
+-      struct mtk_pcs *mpcs = &ss->pcs[id];
++      struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
+       int err = 0;
+       /* Setup SGMIISYS with the determined property */
+@@ -93,22 +94,25 @@ int mtk_sgmii_config(struct mtk_sgmii *s
+       return err;
+ }
+-static void mtk_pcs_restart_an(struct mtk_pcs *mpcs)
++static void mtk_pcs_restart_an(struct phylink_pcs *pcs)
+ {
++      struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
+       unsigned int val;
+-      if (!mpcs->regmap)
+-              return;
+-
+       regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &val);
+       val |= SGMII_AN_RESTART;
+       regmap_write(mpcs->regmap, SGMSYS_PCS_CONTROL_1, val);
+ }
+-static void mtk_pcs_link_up(struct mtk_pcs *mpcs, int speed, int duplex)
++static void mtk_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
++                          phy_interface_t interface, int speed, int duplex)
+ {
++      struct mtk_pcs *mpcs = pcs_to_mtk_pcs(pcs);
+       unsigned int val;
++      if (!phy_interface_mode_is_8023z(interface))
++              return;
++
+       /* SGMII force duplex setting */
+       regmap_read(mpcs->regmap, SGMSYS_SGMII_MODE, &val);
+       val &= ~SGMII_DUPLEX_FULL;
+@@ -118,11 +122,11 @@ static void mtk_pcs_link_up(struct mtk_p
+       regmap_write(mpcs->regmap, SGMSYS_SGMII_MODE, val);
+ }
+-/* For 1000BASE-X and 2500BASE-X interface modes */
+-void mtk_sgmii_link_up(struct mtk_sgmii *ss, int id, int speed, int duplex)
+-{
+-      mtk_pcs_link_up(&ss->pcs[id], speed, duplex);
+-}
++static const struct phylink_pcs_ops mtk_pcs_ops = {
++      .pcs_config = mtk_pcs_config,
++      .pcs_an_restart = mtk_pcs_restart_an,
++      .pcs_link_up = mtk_pcs_link_up,
++};
+ int mtk_sgmii_init(struct mtk_sgmii *ss, struct device_node *r, u32 ana_rgc3)
+ {
+@@ -139,18 +143,17 @@ int mtk_sgmii_init(struct mtk_sgmii *ss,
+               of_node_put(np);
+               if (IS_ERR(ss->pcs[i].regmap))
+                       return PTR_ERR(ss->pcs[i].regmap);
++
++              ss->pcs[i].pcs.ops = &mtk_pcs_ops;
+       }
+       return 0;
+ }
+-void mtk_sgmii_restart_an(struct mtk_eth *eth, int mac_id)
++struct phylink_pcs *mtk_sgmii_select_pcs(struct mtk_sgmii *ss, int id)
+ {
+-      unsigned int sid;
+-
+-      /* Decide how GMAC and SGMIISYS be mapped */
+-      sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
+-             0 : mac_id;
++      if (!ss->pcs[id].regmap)
++              return NULL;
+-      mtk_pcs_restart_an(&eth->sgmii->pcs[sid]);
++      return &ss->pcs[id].pcs;
+ }
diff --git a/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch b/target/linux/generic/backport-5.15/705-01-v5.17-net-dsa-mt7530-iterate-using-dsa_switch_for_each_use.patch
new file mode 100644 (file)
index 0000000..7456710
--- /dev/null
@@ -0,0 +1,106 @@
+From 505560028b6deb9b4385cf6100f05ca6f4aacaf8 Mon Sep 17 00:00:00 2001
+From: Vladimir Oltean <vladimir.oltean@nxp.com>
+Date: Mon, 6 Dec 2021 18:57:49 +0200
+Subject: [PATCH 01/13] net: dsa: mt7530: iterate using
+ dsa_switch_for_each_user_port in bridging ops
+
+Avoid repeated calls to dsa_to_port() (some hidden behind dsa_is_user_port
+and some in plain sight) by keeping two struct dsa_port references: one
+to the port passed as argument, and another to the other ports of the
+switch that we're iterating over.
+
+dsa_to_port(ds, i) gets replaced by other_dp, i gets replaced by
+other_port which is derived from other_dp->index, dsa_is_user_port is
+handled by the DSA iterator.
+
+Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/mt7530.c | 52 +++++++++++++++++++++++-----------------
+ 1 file changed, 30 insertions(+), 22 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -1188,27 +1188,31 @@ static int
+ mt7530_port_bridge_join(struct dsa_switch *ds, int port,
+                       struct net_device *bridge)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
+       u32 port_bitmap = BIT(MT7530_CPU_PORT);
+-      int i;
++      struct mt7530_priv *priv = ds->priv;
+       mutex_lock(&priv->reg_mutex);
+-      for (i = 0; i < MT7530_NUM_PORTS; i++) {
++      dsa_switch_for_each_user_port(other_dp, ds) {
++              int other_port = other_dp->index;
++
++              if (dp == other_dp)
++                      continue;
++
+               /* Add this port to the port matrix of the other ports in the
+                * same bridge. If the port is disabled, port matrix is kept
+                * and not being setup until the port becomes enabled.
+                */
+-              if (dsa_is_user_port(ds, i) && i != port) {
+-                      if (dsa_to_port(ds, i)->bridge_dev != bridge)
+-                              continue;
+-                      if (priv->ports[i].enable)
+-                              mt7530_set(priv, MT7530_PCR_P(i),
+-                                         PCR_MATRIX(BIT(port)));
+-                      priv->ports[i].pm |= PCR_MATRIX(BIT(port));
++              if (other_dp->bridge_dev != bridge)
++                      continue;
+-                      port_bitmap |= BIT(i);
+-              }
++              if (priv->ports[other_port].enable)
++                      mt7530_set(priv, MT7530_PCR_P(other_port),
++                                 PCR_MATRIX(BIT(port)));
++              priv->ports[other_port].pm |= PCR_MATRIX(BIT(port));
++
++              port_bitmap |= BIT(other_port);
+       }
+       /* Add the all other ports to this port matrix. */
+@@ -1301,24 +1305,28 @@ static void
+ mt7530_port_bridge_leave(struct dsa_switch *ds, int port,
+                        struct net_device *bridge)
+ {
++      struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
+       struct mt7530_priv *priv = ds->priv;
+-      int i;
+       mutex_lock(&priv->reg_mutex);
+-      for (i = 0; i < MT7530_NUM_PORTS; i++) {
++      dsa_switch_for_each_user_port(other_dp, ds) {
++              int other_port = other_dp->index;
++
++              if (dp == other_dp)
++                      continue;
++
+               /* Remove this port from the port matrix of the other ports
+                * in the same bridge. If the port is disabled, port matrix
+                * is kept and not being setup until the port becomes enabled.
+                */
+-              if (dsa_is_user_port(ds, i) && i != port) {
+-                      if (dsa_to_port(ds, i)->bridge_dev != bridge)
+-                              continue;
+-                      if (priv->ports[i].enable)
+-                              mt7530_clear(priv, MT7530_PCR_P(i),
+-                                           PCR_MATRIX(BIT(port)));
+-                      priv->ports[i].pm &= ~PCR_MATRIX(BIT(port));
+-              }
++              if (other_dp->bridge_dev != bridge)
++                      continue;
++
++              if (priv->ports[other_port].enable)
++                      mt7530_clear(priv, MT7530_PCR_P(other_port),
++                                   PCR_MATRIX(BIT(port)));
++              priv->ports[other_port].pm &= ~PCR_MATRIX(BIT(port));
+       }
+       /* Set the cpu port to be the only one in the port matrix of
diff --git a/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch b/target/linux/generic/backport-5.15/705-02-v5.19-net-dsa-mt7530-populate-supported_interfaces-and-mac.patch
new file mode 100644 (file)
index 0000000..690cc78
--- /dev/null
@@ -0,0 +1,166 @@
+From a1da54bcd664fc27169386db966575675ac3ccb0 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 11 Apr 2022 10:46:01 +0100
+Subject: [PATCH 02/13] net: dsa: mt7530: populate supported_interfaces and
+ mac_capabilities
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Populate the supported interfaces and MAC capabilities for mt7530,
+mt7531 and mt7621 DSA switches. Filling this in will enable phylink
+to pre-check the PHY interface mode against the the supported
+interfaces bitmap prior to calling the validate function, and will
+eventually allow us to convert to using the generic validation.
+
+Tested-by: Marek BehĂºn <kabel@kernel.org>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 74 ++++++++++++++++++++++++++++++++++++++++
+ drivers/net/dsa/mt7530.h |  2 ++
+ 2 files changed, 76 insertions(+)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2385,6 +2385,32 @@ mt7531_setup(struct dsa_switch *ds)
+       return 0;
+ }
++static void mt7530_mac_port_get_caps(struct dsa_switch *ds, int port,
++                                   struct phylink_config *config)
++{
++      switch (port) {
++      case 0 ... 4: /* Internal phy */
++              __set_bit(PHY_INTERFACE_MODE_GMII,
++                        config->supported_interfaces);
++              break;
++
++      case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
++              phy_interface_set_rgmii(config->supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_MII,
++                        config->supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_GMII,
++                        config->supported_interfaces);
++              break;
++
++      case 6: /* 1st cpu port */
++              __set_bit(PHY_INTERFACE_MODE_RGMII,
++                        config->supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_TRGMII,
++                        config->supported_interfaces);
++              break;
++      }
++}
++
+ static bool
+ mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
+                         const struct phylink_link_state *state)
+@@ -2421,6 +2447,37 @@ static bool mt7531_is_rgmii_port(struct
+       return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
+ }
++static void mt7531_mac_port_get_caps(struct dsa_switch *ds, int port,
++                                   struct phylink_config *config)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      switch (port) {
++      case 0 ... 4: /* Internal phy */
++              __set_bit(PHY_INTERFACE_MODE_GMII,
++                        config->supported_interfaces);
++              break;
++
++      case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
++              if (mt7531_is_rgmii_port(priv, port)) {
++                      phy_interface_set_rgmii(config->supported_interfaces);
++                      break;
++              }
++              fallthrough;
++
++      case 6: /* 1st cpu port supports sgmii/8023z only */
++              __set_bit(PHY_INTERFACE_MODE_SGMII,
++                        config->supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_1000BASEX,
++                        config->supported_interfaces);
++              __set_bit(PHY_INTERFACE_MODE_2500BASEX,
++                        config->supported_interfaces);
++
++              config->mac_capabilities |= MAC_2500FD;
++              break;
++      }
++}
++
+ static bool
+ mt7531_phy_mode_supported(struct dsa_switch *ds, int port,
+                         const struct phylink_link_state *state)
+@@ -2899,6 +2956,18 @@ mt7531_cpu_port_config(struct dsa_switch
+       return 0;
+ }
++static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
++                                  struct phylink_config *config)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      /* This switch only supports full-duplex at 1Gbps */
++      config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
++                                 MAC_10 | MAC_100 | MAC_1000FD;
++
++      priv->info->mac_port_get_caps(ds, port, config);
++}
++
+ static void
+ mt7530_mac_port_validate(struct dsa_switch *ds, int port,
+                        unsigned long *supported)
+@@ -3134,6 +3203,7 @@ static const struct dsa_switch_ops mt753
+       .port_vlan_del          = mt7530_port_vlan_del,
+       .port_mirror_add        = mt753x_port_mirror_add,
+       .port_mirror_del        = mt753x_port_mirror_del,
++      .phylink_get_caps       = mt753x_phylink_get_caps,
+       .phylink_validate       = mt753x_phylink_validate,
+       .phylink_mac_link_state = mt753x_phylink_mac_link_state,
+       .phylink_mac_config     = mt753x_phylink_mac_config,
+@@ -3151,6 +3221,7 @@ static const struct mt753x_info mt753x_t
+               .phy_read = mt7530_phy_read,
+               .phy_write = mt7530_phy_write,
+               .pad_setup = mt7530_pad_clk_setup,
++              .mac_port_get_caps = mt7530_mac_port_get_caps,
+               .phy_mode_supported = mt7530_phy_mode_supported,
+               .mac_port_validate = mt7530_mac_port_validate,
+               .mac_port_get_state = mt7530_phylink_mac_link_state,
+@@ -3162,6 +3233,7 @@ static const struct mt753x_info mt753x_t
+               .phy_read = mt7530_phy_read,
+               .phy_write = mt7530_phy_write,
+               .pad_setup = mt7530_pad_clk_setup,
++              .mac_port_get_caps = mt7530_mac_port_get_caps,
+               .phy_mode_supported = mt7530_phy_mode_supported,
+               .mac_port_validate = mt7530_mac_port_validate,
+               .mac_port_get_state = mt7530_phylink_mac_link_state,
+@@ -3174,6 +3246,7 @@ static const struct mt753x_info mt753x_t
+               .phy_write = mt7531_ind_phy_write,
+               .pad_setup = mt7531_pad_setup,
+               .cpu_port_config = mt7531_cpu_port_config,
++              .mac_port_get_caps = mt7531_mac_port_get_caps,
+               .phy_mode_supported = mt7531_phy_mode_supported,
+               .mac_port_validate = mt7531_mac_port_validate,
+               .mac_port_get_state = mt7531_phylink_mac_link_state,
+@@ -3236,6 +3309,7 @@ mt7530_probe(struct mdio_device *mdiodev
+        */
+       if (!priv->info->sw_setup || !priv->info->pad_setup ||
+           !priv->info->phy_read || !priv->info->phy_write ||
++          !priv->info->mac_port_get_caps ||
+           !priv->info->phy_mode_supported ||
+           !priv->info->mac_port_validate ||
+           !priv->info->mac_port_get_state || !priv->info->mac_port_config)
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -769,6 +769,8 @@ struct mt753x_info {
+       int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
+       int (*pad_setup)(struct dsa_switch *ds, phy_interface_t interface);
+       int (*cpu_port_config)(struct dsa_switch *ds, int port);
++      void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
++                                struct phylink_config *config);
+       bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
+                                  const struct phylink_link_state *state);
+       void (*mac_port_validate)(struct dsa_switch *ds, int port,
diff --git a/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch b/target/linux/generic/backport-5.15/705-03-v5.19-net-dsa-mt7530-remove-interface-checks.patch
new file mode 100644 (file)
index 0000000..60eee01
--- /dev/null
@@ -0,0 +1,172 @@
+From e3f6719e2269868ca129b05da50cd55786848954 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 11 Apr 2022 10:46:06 +0100
+Subject: [PATCH 03/13] net: dsa: mt7530: remove interface checks
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+As phylink checks the interface mode against the supported_interfaces
+bitmap, we no longer need to validate the interface mode, nor handle
+PHY_INTERFACE_MODE_NA in the validation function. Remove these to
+simplify the implementation.
+
+Tested-by: Marek BehĂºn <kabel@kernel.org>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 82 ----------------------------------------
+ drivers/net/dsa/mt7530.h |  2 -
+ 2 files changed, 84 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2411,37 +2411,6 @@ static void mt7530_mac_port_get_caps(str
+       }
+ }
+-static bool
+-mt7530_phy_mode_supported(struct dsa_switch *ds, int port,
+-                        const struct phylink_link_state *state)
+-{
+-      struct mt7530_priv *priv = ds->priv;
+-
+-      switch (port) {
+-      case 0 ... 4: /* Internal phy */
+-              if (state->interface != PHY_INTERFACE_MODE_GMII)
+-                      return false;
+-              break;
+-      case 5: /* 2nd cpu port with phy of port 0 or 4 / external phy */
+-              if (!phy_interface_mode_is_rgmii(state->interface) &&
+-                  state->interface != PHY_INTERFACE_MODE_MII &&
+-                  state->interface != PHY_INTERFACE_MODE_GMII)
+-                      return false;
+-              break;
+-      case 6: /* 1st cpu port */
+-              if (state->interface != PHY_INTERFACE_MODE_RGMII &&
+-                  state->interface != PHY_INTERFACE_MODE_TRGMII)
+-                      return false;
+-              break;
+-      default:
+-              dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
+-                      port);
+-              return false;
+-      }
+-
+-      return true;
+-}
+-
+ static bool mt7531_is_rgmii_port(struct mt7530_priv *priv, u32 port)
+ {
+       return (port == 5) && (priv->p5_intf_sel != P5_INTF_SEL_GMAC5_SGMII);
+@@ -2478,44 +2447,6 @@ static void mt7531_mac_port_get_caps(str
+       }
+ }
+-static bool
+-mt7531_phy_mode_supported(struct dsa_switch *ds, int port,
+-                        const struct phylink_link_state *state)
+-{
+-      struct mt7530_priv *priv = ds->priv;
+-
+-      switch (port) {
+-      case 0 ... 4: /* Internal phy */
+-              if (state->interface != PHY_INTERFACE_MODE_GMII)
+-                      return false;
+-              break;
+-      case 5: /* 2nd cpu port supports either rgmii or sgmii/8023z */
+-              if (mt7531_is_rgmii_port(priv, port))
+-                      return phy_interface_mode_is_rgmii(state->interface);
+-              fallthrough;
+-      case 6: /* 1st cpu port supports sgmii/8023z only */
+-              if (state->interface != PHY_INTERFACE_MODE_SGMII &&
+-                  !phy_interface_mode_is_8023z(state->interface))
+-                      return false;
+-              break;
+-      default:
+-              dev_err(priv->dev, "%s: unsupported port: %i\n", __func__,
+-                      port);
+-              return false;
+-      }
+-
+-      return true;
+-}
+-
+-static bool
+-mt753x_phy_mode_supported(struct dsa_switch *ds, int port,
+-                        const struct phylink_link_state *state)
+-{
+-      struct mt7530_priv *priv = ds->priv;
+-
+-      return priv->info->phy_mode_supported(ds, port, state);
+-}
+-
+ static int
+ mt753x_pad_setup(struct dsa_switch *ds, const struct phylink_link_state *state)
+ {
+@@ -2770,9 +2701,6 @@ mt753x_phylink_mac_config(struct dsa_swi
+       struct mt7530_priv *priv = ds->priv;
+       u32 mcr_cur, mcr_new;
+-      if (!mt753x_phy_mode_supported(ds, port, state))
+-              goto unsupported;
+-
+       switch (port) {
+       case 0 ... 4: /* Internal phy */
+               if (state->interface != PHY_INTERFACE_MODE_GMII)
+@@ -2990,12 +2918,6 @@ mt753x_phylink_validate(struct dsa_switc
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+       struct mt7530_priv *priv = ds->priv;
+-      if (state->interface != PHY_INTERFACE_MODE_NA &&
+-          !mt753x_phy_mode_supported(ds, port, state)) {
+-              linkmode_zero(supported);
+-              return;
+-      }
+-
+       phylink_set_port_modes(mask);
+       if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
+@@ -3222,7 +3144,6 @@ static const struct mt753x_info mt753x_t
+               .phy_write = mt7530_phy_write,
+               .pad_setup = mt7530_pad_clk_setup,
+               .mac_port_get_caps = mt7530_mac_port_get_caps,
+-              .phy_mode_supported = mt7530_phy_mode_supported,
+               .mac_port_validate = mt7530_mac_port_validate,
+               .mac_port_get_state = mt7530_phylink_mac_link_state,
+               .mac_port_config = mt7530_mac_config,
+@@ -3234,7 +3155,6 @@ static const struct mt753x_info mt753x_t
+               .phy_write = mt7530_phy_write,
+               .pad_setup = mt7530_pad_clk_setup,
+               .mac_port_get_caps = mt7530_mac_port_get_caps,
+-              .phy_mode_supported = mt7530_phy_mode_supported,
+               .mac_port_validate = mt7530_mac_port_validate,
+               .mac_port_get_state = mt7530_phylink_mac_link_state,
+               .mac_port_config = mt7530_mac_config,
+@@ -3247,7 +3167,6 @@ static const struct mt753x_info mt753x_t
+               .pad_setup = mt7531_pad_setup,
+               .cpu_port_config = mt7531_cpu_port_config,
+               .mac_port_get_caps = mt7531_mac_port_get_caps,
+-              .phy_mode_supported = mt7531_phy_mode_supported,
+               .mac_port_validate = mt7531_mac_port_validate,
+               .mac_port_get_state = mt7531_phylink_mac_link_state,
+               .mac_port_config = mt7531_mac_config,
+@@ -3310,7 +3229,6 @@ mt7530_probe(struct mdio_device *mdiodev
+       if (!priv->info->sw_setup || !priv->info->pad_setup ||
+           !priv->info->phy_read || !priv->info->phy_write ||
+           !priv->info->mac_port_get_caps ||
+-          !priv->info->phy_mode_supported ||
+           !priv->info->mac_port_validate ||
+           !priv->info->mac_port_get_state || !priv->info->mac_port_config)
+               return -EINVAL;
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -771,8 +771,6 @@ struct mt753x_info {
+       int (*cpu_port_config)(struct dsa_switch *ds, int port);
+       void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
+                                 struct phylink_config *config);
+-      bool (*phy_mode_supported)(struct dsa_switch *ds, int port,
+-                                 const struct phylink_link_state *state);
+       void (*mac_port_validate)(struct dsa_switch *ds, int port,
+                                 unsigned long *supported);
+       int (*mac_port_get_state)(struct dsa_switch *ds, int port,
diff --git a/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch b/target/linux/generic/backport-5.15/705-04-v5.19-net-dsa-mt7530-drop-use-of-phylink_helper_basex_spee.patch
new file mode 100644 (file)
index 0000000..22bb206
--- /dev/null
@@ -0,0 +1,34 @@
+From 58344a3b85f1bd5ffddfc2c11f6f2bf688b5f990 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 11 Apr 2022 10:46:12 +0100
+Subject: [PATCH 04/13] net: dsa: mt7530: drop use of
+ phylink_helper_basex_speed()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Now that we have a better method to select SFP interface modes, we
+no longer need to use phylink_helper_basex_speed() in a driver's
+validation function.
+
+Tested-by: Marek BehĂºn <kabel@kernel.org>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 5 -----
+ 1 file changed, 5 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2942,11 +2942,6 @@ mt753x_phylink_validate(struct dsa_switc
+       linkmode_and(supported, supported, mask);
+       linkmode_and(state->advertising, state->advertising, mask);
+-
+-      /* We can only operate at 2500BaseX or 1000BaseX.  If requested
+-       * to advertise both, only report advertising at 2500BaseX.
+-       */
+-      phylink_helper_basex_speed(state);
+ }
+ static int
diff --git a/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch b/target/linux/generic/backport-5.15/705-05-v5.19-net-dsa-mt7530-only-indicate-linkmodes-that-can-be-s.patch
new file mode 100644 (file)
index 0000000..d5d7c54
--- /dev/null
@@ -0,0 +1,86 @@
+From 3c1d788a62dc648d1846049b66119ebb69dedd52 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 11 Apr 2022 10:46:17 +0100
+Subject: [PATCH 05/13] net: dsa: mt7530: only indicate linkmodes that can be
+ supported
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Now that mt7530 is not using the basex helper, it becomes unnecessary to
+indicate support for both 1000baseX and 2500baseX when one of the 803.3z
+PHY interface modes is being selected. Ensure that the driver indicates
+only those linkmodes that can actually be supported by the PHY interface
+mode.
+
+Tested-by: Marek BehĂºn <kabel@kernel.org>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 12 ++++++++----
+ drivers/net/dsa/mt7530.h |  1 +
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2518,12 +2518,13 @@ static int mt7531_rgmii_setup(struct mt7
+ }
+ static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port,
++                                phy_interface_t interface,
+                                 unsigned long *supported)
+ {
+       /* Port5 supports ethier RGMII or SGMII.
+        * Port6 supports SGMII only.
+        */
+-      if (port == 6) {
++      if (port == 6 && interface == PHY_INTERFACE_MODE_2500BASEX) {
+               phylink_set(supported, 2500baseX_Full);
+               phylink_set(supported, 2500baseT_Full);
+       }
+@@ -2898,16 +2899,18 @@ static void mt753x_phylink_get_caps(stru
+ static void
+ mt7530_mac_port_validate(struct dsa_switch *ds, int port,
++                       phy_interface_t interface,
+                        unsigned long *supported)
+ {
+ }
+ static void mt7531_mac_port_validate(struct dsa_switch *ds, int port,
++                                   phy_interface_t interface,
+                                    unsigned long *supported)
+ {
+       struct mt7530_priv *priv = ds->priv;
+-      mt7531_sgmii_validate(priv, port, supported);
++      mt7531_sgmii_validate(priv, port, interface, supported);
+ }
+ static void
+@@ -2930,12 +2933,13 @@ mt753x_phylink_validate(struct dsa_switc
+       }
+       /* This switch only supports 1G full-duplex. */
+-      if (state->interface != PHY_INTERFACE_MODE_MII) {
++      if (state->interface != PHY_INTERFACE_MODE_MII &&
++          state->interface != PHY_INTERFACE_MODE_2500BASEX) {
+               phylink_set(mask, 1000baseT_Full);
+               phylink_set(mask, 1000baseX_Full);
+       }
+-      priv->info->mac_port_validate(ds, port, mask);
++      priv->info->mac_port_validate(ds, port, state->interface, mask);
+       phylink_set(mask, Pause);
+       phylink_set(mask, Asym_Pause);
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -772,6 +772,7 @@ struct mt753x_info {
+       void (*mac_port_get_caps)(struct dsa_switch *ds, int port,
+                                 struct phylink_config *config);
+       void (*mac_port_validate)(struct dsa_switch *ds, int port,
++                                phy_interface_t interface,
+                                 unsigned long *supported);
+       int (*mac_port_get_state)(struct dsa_switch *ds, int port,
+                                 struct phylink_link_state *state);
diff --git a/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch b/target/linux/generic/backport-5.15/705-06-v5.19-net-dsa-mt7530-switch-to-use-phylink_get_linkmodes.patch
new file mode 100644 (file)
index 0000000..4a2c2f1
--- /dev/null
@@ -0,0 +1,131 @@
+From 1c2211cb15dd3957fb26c0e1615eceb5db851ad6 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 11 Apr 2022 10:46:22 +0100
+Subject: [PATCH 06/13] net: dsa: mt7530: switch to use phylink_get_linkmodes()
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Switch mt7530 to use phylink_get_linkmodes() to generate the ethtool
+linkmodes that can be supported. We are unable to use the generic
+helper for this as pause modes are dependent on the interface as
+the Autoneg bit depends on the interface mode.
+
+Tested-by: Marek BehĂºn <kabel@kernel.org>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 57 ++++------------------------------------
+ 1 file changed, 5 insertions(+), 52 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2517,19 +2517,6 @@ static int mt7531_rgmii_setup(struct mt7
+       return 0;
+ }
+-static void mt7531_sgmii_validate(struct mt7530_priv *priv, int port,
+-                                phy_interface_t interface,
+-                                unsigned long *supported)
+-{
+-      /* Port5 supports ethier RGMII or SGMII.
+-       * Port6 supports SGMII only.
+-       */
+-      if (port == 6 && interface == PHY_INTERFACE_MODE_2500BASEX) {
+-              phylink_set(supported, 2500baseX_Full);
+-              phylink_set(supported, 2500baseT_Full);
+-      }
+-}
+-
+ static void
+ mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port,
+                          unsigned int mode, phy_interface_t interface,
+@@ -2898,51 +2885,21 @@ static void mt753x_phylink_get_caps(stru
+ }
+ static void
+-mt7530_mac_port_validate(struct dsa_switch *ds, int port,
+-                       phy_interface_t interface,
+-                       unsigned long *supported)
+-{
+-}
+-
+-static void mt7531_mac_port_validate(struct dsa_switch *ds, int port,
+-                                   phy_interface_t interface,
+-                                   unsigned long *supported)
+-{
+-      struct mt7530_priv *priv = ds->priv;
+-
+-      mt7531_sgmii_validate(priv, port, interface, supported);
+-}
+-
+-static void
+ mt753x_phylink_validate(struct dsa_switch *ds, int port,
+                       unsigned long *supported,
+                       struct phylink_link_state *state)
+ {
+       __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+-      struct mt7530_priv *priv = ds->priv;
++      u32 caps;
++
++      caps = dsa_to_port(ds, port)->pl_config.mac_capabilities;
+       phylink_set_port_modes(mask);
++      phylink_get_linkmodes(mask, state->interface, caps);
+       if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
+-          !phy_interface_mode_is_8023z(state->interface)) {
+-              phylink_set(mask, 10baseT_Half);
+-              phylink_set(mask, 10baseT_Full);
+-              phylink_set(mask, 100baseT_Half);
+-              phylink_set(mask, 100baseT_Full);
++          !phy_interface_mode_is_8023z(state->interface))
+               phylink_set(mask, Autoneg);
+-      }
+-
+-      /* This switch only supports 1G full-duplex. */
+-      if (state->interface != PHY_INTERFACE_MODE_MII &&
+-          state->interface != PHY_INTERFACE_MODE_2500BASEX) {
+-              phylink_set(mask, 1000baseT_Full);
+-              phylink_set(mask, 1000baseX_Full);
+-      }
+-
+-      priv->info->mac_port_validate(ds, port, state->interface, mask);
+-
+-      phylink_set(mask, Pause);
+-      phylink_set(mask, Asym_Pause);
+       linkmode_and(supported, supported, mask);
+       linkmode_and(state->advertising, state->advertising, mask);
+@@ -3143,7 +3100,6 @@ static const struct mt753x_info mt753x_t
+               .phy_write = mt7530_phy_write,
+               .pad_setup = mt7530_pad_clk_setup,
+               .mac_port_get_caps = mt7530_mac_port_get_caps,
+-              .mac_port_validate = mt7530_mac_port_validate,
+               .mac_port_get_state = mt7530_phylink_mac_link_state,
+               .mac_port_config = mt7530_mac_config,
+       },
+@@ -3154,7 +3110,6 @@ static const struct mt753x_info mt753x_t
+               .phy_write = mt7530_phy_write,
+               .pad_setup = mt7530_pad_clk_setup,
+               .mac_port_get_caps = mt7530_mac_port_get_caps,
+-              .mac_port_validate = mt7530_mac_port_validate,
+               .mac_port_get_state = mt7530_phylink_mac_link_state,
+               .mac_port_config = mt7530_mac_config,
+       },
+@@ -3166,7 +3121,6 @@ static const struct mt753x_info mt753x_t
+               .pad_setup = mt7531_pad_setup,
+               .cpu_port_config = mt7531_cpu_port_config,
+               .mac_port_get_caps = mt7531_mac_port_get_caps,
+-              .mac_port_validate = mt7531_mac_port_validate,
+               .mac_port_get_state = mt7531_phylink_mac_link_state,
+               .mac_port_config = mt7531_mac_config,
+               .mac_pcs_an_restart = mt7531_sgmii_restart_an,
+@@ -3228,7 +3182,6 @@ mt7530_probe(struct mdio_device *mdiodev
+       if (!priv->info->sw_setup || !priv->info->pad_setup ||
+           !priv->info->phy_read || !priv->info->phy_write ||
+           !priv->info->mac_port_get_caps ||
+-          !priv->info->mac_port_validate ||
+           !priv->info->mac_port_get_state || !priv->info->mac_port_config)
+               return -EINVAL;
diff --git a/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch b/target/linux/generic/backport-5.15/705-07-v5.19-net-dsa-mt7530-partially-convert-to-phylink_pcs.patch
new file mode 100644 (file)
index 0000000..8a66b7f
--- /dev/null
@@ -0,0 +1,385 @@
+From fd993fd59d96d5e2d5972ec4ca1f9651025c987b Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 11 Apr 2022 10:46:27 +0100
+Subject: [PATCH 07/13] net: dsa: mt7530: partially convert to phylink_pcs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Partially convert the mt7530 driver to use phylink's PCS support. This
+is a partial implementation as we don't move anything into the
+pcs_config method yet - this driver supports SGMII or 1000BASE-X
+without in-band.
+
+Tested-by: Marek BehĂºn <kabel@kernel.org>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 144 +++++++++++++++++++++++----------------
+ drivers/net/dsa/mt7530.h |  21 +++---
+ 2 files changed, 95 insertions(+), 70 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -24,6 +24,11 @@
+ #include "mt7530.h"
++static struct mt753x_pcs *pcs_to_mt753x_pcs(struct phylink_pcs *pcs)
++{
++      return container_of(pcs, struct mt753x_pcs, pcs);
++}
++
+ /* String, offset, and register size in bytes if different from 4 bytes */
+ static const struct mt7530_mib_desc mt7530_mib[] = {
+       MIB_DESC(1, 0x00, "TxDrop"),
+@@ -2517,12 +2522,11 @@ static int mt7531_rgmii_setup(struct mt7
+       return 0;
+ }
+-static void
+-mt7531_sgmii_link_up_force(struct dsa_switch *ds, int port,
+-                         unsigned int mode, phy_interface_t interface,
+-                         int speed, int duplex)
++static void mt7531_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
++                             phy_interface_t interface, int speed, int duplex)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
++      int port = pcs_to_mt753x_pcs(pcs)->port;
+       unsigned int val;
+       /* For adjusting speed and duplex of SGMII force mode. */
+@@ -2548,6 +2552,9 @@ mt7531_sgmii_link_up_force(struct dsa_sw
+       /* MT7531 SGMII 1G force mode can only work in full duplex mode,
+        * no matter MT7531_SGMII_FORCE_HALF_DUPLEX is set or not.
++       *
++       * The speed check is unnecessary as the MAC capabilities apply
++       * this restriction. --rmk
+        */
+       if ((speed == SPEED_10 || speed == SPEED_100) &&
+           duplex != DUPLEX_FULL)
+@@ -2623,9 +2630,10 @@ static int mt7531_sgmii_setup_mode_an(st
+       return 0;
+ }
+-static void mt7531_sgmii_restart_an(struct dsa_switch *ds, int port)
++static void mt7531_pcs_an_restart(struct phylink_pcs *pcs)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
++      int port = pcs_to_mt753x_pcs(pcs)->port;
+       u32 val;
+       /* Only restart AN when AN is enabled */
+@@ -2682,6 +2690,24 @@ mt753x_mac_config(struct dsa_switch *ds,
+       return priv->info->mac_port_config(ds, port, mode, state->interface);
+ }
++static struct phylink_pcs *
++mt753x_phylink_mac_select_pcs(struct dsa_switch *ds, int port,
++                            phy_interface_t interface)
++{
++      struct mt7530_priv *priv = ds->priv;
++
++      switch (interface) {
++      case PHY_INTERFACE_MODE_TRGMII:
++      case PHY_INTERFACE_MODE_SGMII:
++      case PHY_INTERFACE_MODE_1000BASEX:
++      case PHY_INTERFACE_MODE_2500BASEX:
++              return &priv->pcs[port].pcs;
++
++      default:
++              return NULL;
++      }
++}
++
+ static void
+ mt753x_phylink_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
+                         const struct phylink_link_state *state)
+@@ -2743,17 +2769,6 @@ unsupported:
+               mt7530_write(priv, MT7530_PMCR_P(port), mcr_new);
+ }
+-static void
+-mt753x_phylink_mac_an_restart(struct dsa_switch *ds, int port)
+-{
+-      struct mt7530_priv *priv = ds->priv;
+-
+-      if (!priv->info->mac_pcs_an_restart)
+-              return;
+-
+-      priv->info->mac_pcs_an_restart(ds, port);
+-}
+-
+ static void mt753x_phylink_mac_link_down(struct dsa_switch *ds, int port,
+                                        unsigned int mode,
+                                        phy_interface_t interface)
+@@ -2763,16 +2778,13 @@ static void mt753x_phylink_mac_link_down
+       mt7530_clear(priv, MT7530_PMCR_P(port), PMCR_LINK_SETTINGS_MASK);
+ }
+-static void mt753x_mac_pcs_link_up(struct dsa_switch *ds, int port,
+-                                 unsigned int mode, phy_interface_t interface,
+-                                 int speed, int duplex)
++static void mt753x_phylink_pcs_link_up(struct phylink_pcs *pcs,
++                                     unsigned int mode,
++                                     phy_interface_t interface,
++                                     int speed, int duplex)
+ {
+-      struct mt7530_priv *priv = ds->priv;
+-
+-      if (!priv->info->mac_pcs_link_up)
+-              return;
+-
+-      priv->info->mac_pcs_link_up(ds, port, mode, interface, speed, duplex);
++      if (pcs->ops->pcs_link_up)
++              pcs->ops->pcs_link_up(pcs, mode, interface, speed, duplex);
+ }
+ static void mt753x_phylink_mac_link_up(struct dsa_switch *ds, int port,
+@@ -2785,8 +2797,6 @@ static void mt753x_phylink_mac_link_up(s
+       struct mt7530_priv *priv = ds->priv;
+       u32 mcr;
+-      mt753x_mac_pcs_link_up(ds, port, mode, interface, speed, duplex);
+-
+       mcr = PMCR_RX_EN | PMCR_TX_EN | PMCR_FORCE_LNK;
+       /* MT753x MAC works in 1G full duplex mode for all up-clocked
+@@ -2866,6 +2876,8 @@ mt7531_cpu_port_config(struct dsa_switch
+               return ret;
+       mt7530_write(priv, MT7530_PMCR_P(port),
+                    PMCR_CPU_PORT_SETTING(priv->id));
++      mt753x_phylink_pcs_link_up(&priv->pcs[port].pcs, MLO_AN_FIXED,
++                                 interface, speed, DUPLEX_FULL);
+       mt753x_phylink_mac_link_up(ds, port, MLO_AN_FIXED, interface, NULL,
+                                  speed, DUPLEX_FULL, true, true);
+@@ -2905,16 +2917,13 @@ mt753x_phylink_validate(struct dsa_switc
+       linkmode_and(state->advertising, state->advertising, mask);
+ }
+-static int
+-mt7530_phylink_mac_link_state(struct dsa_switch *ds, int port,
+-                            struct phylink_link_state *state)
++static void mt7530_pcs_get_state(struct phylink_pcs *pcs,
++                               struct phylink_link_state *state)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
++      int port = pcs_to_mt753x_pcs(pcs)->port;
+       u32 pmsr;
+-      if (port < 0 || port >= MT7530_NUM_PORTS)
+-              return -EINVAL;
+-
+       pmsr = mt7530_read(priv, MT7530_PMSR_P(port));
+       state->link = (pmsr & PMSR_LINK);
+@@ -2941,8 +2950,6 @@ mt7530_phylink_mac_link_state(struct dsa
+               state->pause |= MLO_PAUSE_RX;
+       if (pmsr & PMSR_TX_FC)
+               state->pause |= MLO_PAUSE_TX;
+-
+-      return 1;
+ }
+ static int
+@@ -2984,32 +2991,49 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
+       return 0;
+ }
+-static int
+-mt7531_phylink_mac_link_state(struct dsa_switch *ds, int port,
+-                            struct phylink_link_state *state)
++static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
++                               struct phylink_link_state *state)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
++      int port = pcs_to_mt753x_pcs(pcs)->port;
+       if (state->interface == PHY_INTERFACE_MODE_SGMII)
+-              return mt7531_sgmii_pcs_get_state_an(priv, port, state);
+-
+-      return -EOPNOTSUPP;
++              mt7531_sgmii_pcs_get_state_an(priv, port, state);
++      else
++              state->link = false;
+ }
+-static int
+-mt753x_phylink_mac_link_state(struct dsa_switch *ds, int port,
+-                            struct phylink_link_state *state)
++static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
++                           phy_interface_t interface,
++                           const unsigned long *advertising,
++                           bool permit_pause_to_mac)
+ {
+-      struct mt7530_priv *priv = ds->priv;
++      return 0;
++}
+-      return priv->info->mac_port_get_state(ds, port, state);
++static void mt7530_pcs_an_restart(struct phylink_pcs *pcs)
++{
+ }
++static const struct phylink_pcs_ops mt7530_pcs_ops = {
++      .pcs_get_state = mt7530_pcs_get_state,
++      .pcs_config = mt753x_pcs_config,
++      .pcs_an_restart = mt7530_pcs_an_restart,
++};
++
++static const struct phylink_pcs_ops mt7531_pcs_ops = {
++      .pcs_get_state = mt7531_pcs_get_state,
++      .pcs_config = mt753x_pcs_config,
++      .pcs_an_restart = mt7531_pcs_an_restart,
++      .pcs_link_up = mt7531_pcs_link_up,
++};
++
+ static int
+ mt753x_setup(struct dsa_switch *ds)
+ {
+       struct mt7530_priv *priv = ds->priv;
+       int ret = priv->info->sw_setup(ds);
++      int i;
+       if (ret)
+               return ret;
+@@ -3022,6 +3046,13 @@ mt753x_setup(struct dsa_switch *ds)
+       if (ret && priv->irq)
+               mt7530_free_irq_common(priv);
++      /* Initialise the PCS devices */
++      for (i = 0; i < priv->ds->num_ports; i++) {
++              priv->pcs[i].pcs.ops = priv->info->pcs_ops;
++              priv->pcs[i].priv = priv;
++              priv->pcs[i].port = i;
++      }
++
+       return ret;
+ }
+@@ -3083,9 +3114,8 @@ static const struct dsa_switch_ops mt753
+       .port_mirror_del        = mt753x_port_mirror_del,
+       .phylink_get_caps       = mt753x_phylink_get_caps,
+       .phylink_validate       = mt753x_phylink_validate,
+-      .phylink_mac_link_state = mt753x_phylink_mac_link_state,
++      .phylink_mac_select_pcs = mt753x_phylink_mac_select_pcs,
+       .phylink_mac_config     = mt753x_phylink_mac_config,
+-      .phylink_mac_an_restart = mt753x_phylink_mac_an_restart,
+       .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,
+@@ -3095,36 +3125,34 @@ static const struct dsa_switch_ops mt753
+ static const struct mt753x_info mt753x_table[] = {
+       [ID_MT7621] = {
+               .id = ID_MT7621,
++              .pcs_ops = &mt7530_pcs_ops,
+               .sw_setup = mt7530_setup,
+               .phy_read = mt7530_phy_read,
+               .phy_write = mt7530_phy_write,
+               .pad_setup = mt7530_pad_clk_setup,
+               .mac_port_get_caps = mt7530_mac_port_get_caps,
+-              .mac_port_get_state = mt7530_phylink_mac_link_state,
+               .mac_port_config = mt7530_mac_config,
+       },
+       [ID_MT7530] = {
+               .id = ID_MT7530,
++              .pcs_ops = &mt7530_pcs_ops,
+               .sw_setup = mt7530_setup,
+               .phy_read = mt7530_phy_read,
+               .phy_write = mt7530_phy_write,
+               .pad_setup = mt7530_pad_clk_setup,
+               .mac_port_get_caps = mt7530_mac_port_get_caps,
+-              .mac_port_get_state = mt7530_phylink_mac_link_state,
+               .mac_port_config = mt7530_mac_config,
+       },
+       [ID_MT7531] = {
+               .id = ID_MT7531,
++              .pcs_ops = &mt7531_pcs_ops,
+               .sw_setup = mt7531_setup,
+               .phy_read = mt7531_ind_phy_read,
+               .phy_write = mt7531_ind_phy_write,
+               .pad_setup = mt7531_pad_setup,
+               .cpu_port_config = mt7531_cpu_port_config,
+               .mac_port_get_caps = mt7531_mac_port_get_caps,
+-              .mac_port_get_state = mt7531_phylink_mac_link_state,
+               .mac_port_config = mt7531_mac_config,
+-              .mac_pcs_an_restart = mt7531_sgmii_restart_an,
+-              .mac_pcs_link_up = mt7531_sgmii_link_up_force,
+       },
+ };
+@@ -3182,7 +3210,7 @@ mt7530_probe(struct mdio_device *mdiodev
+       if (!priv->info->sw_setup || !priv->info->pad_setup ||
+           !priv->info->phy_read || !priv->info->phy_write ||
+           !priv->info->mac_port_get_caps ||
+-          !priv->info->mac_port_get_state || !priv->info->mac_port_config)
++          !priv->info->mac_port_config)
+               return -EINVAL;
+       priv->id = priv->info->id;
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -741,6 +741,12 @@ static const char *p5_intf_modes(unsigne
+ struct mt7530_priv;
++struct mt753x_pcs {
++      struct phylink_pcs pcs;
++      struct mt7530_priv *priv;
++      int port;
++};
++
+ /* struct mt753x_info -       This is the main data structure for holding the specific
+  *                    part for each supported device
+  * @sw_setup:         Holding the handler to a device initialization
+@@ -752,18 +758,14 @@ struct mt7530_priv;
+  *                    port
+  * @mac_port_validate:        Holding the way to set addition validate type for a
+  *                    certan MAC port
+- * @mac_port_get_state: Holding the way getting the MAC/PCS state for a certain
+- *                    MAC port
+  * @mac_port_config:  Holding the way setting up the PHY attribute to a
+  *                    certain MAC port
+- * @mac_pcs_an_restart        Holding the way restarting PCS autonegotiation for a
+- *                    certain MAC port
+- * @mac_pcs_link_up:  Holding the way setting up the PHY attribute to the pcs
+- *                    of the certain MAC port
+  */
+ struct mt753x_info {
+       enum mt753x_id id;
++      const struct phylink_pcs_ops *pcs_ops;
++
+       int (*sw_setup)(struct dsa_switch *ds);
+       int (*phy_read)(struct mt7530_priv *priv, int port, int regnum);
+       int (*phy_write)(struct mt7530_priv *priv, int port, int regnum, u16 val);
+@@ -774,15 +776,9 @@ struct mt753x_info {
+       void (*mac_port_validate)(struct dsa_switch *ds, int port,
+                                 phy_interface_t interface,
+                                 unsigned long *supported);
+-      int (*mac_port_get_state)(struct dsa_switch *ds, int port,
+-                                struct phylink_link_state *state);
+       int (*mac_port_config)(struct dsa_switch *ds, int port,
+                              unsigned int mode,
+                              phy_interface_t interface);
+-      void (*mac_pcs_an_restart)(struct dsa_switch *ds, int port);
+-      void (*mac_pcs_link_up)(struct dsa_switch *ds, int port,
+-                              unsigned int mode, phy_interface_t interface,
+-                              int speed, int duplex);
+ };
+ /* struct mt7530_priv -       This is the main data structure for holding the state
+@@ -824,6 +820,7 @@ struct mt7530_priv {
+       u8                      mirror_tx;
+       struct mt7530_port      ports[MT7530_NUM_PORTS];
++      struct mt753x_pcs       pcs[MT7530_NUM_PORTS];
+       /* protect among processes for registers access*/
+       struct mutex reg_mutex;
+       int irq;
diff --git a/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch b/target/linux/generic/backport-5.15/705-08-v5.19-net-dsa-mt7530-move-autoneg-handling-to-PCS-validati.patch
new file mode 100644 (file)
index 0000000..2d8b4d5
--- /dev/null
@@ -0,0 +1,80 @@
+From 2b0ee6768f3ac09072e5fd60b36580924e1cfa1c Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 11 Apr 2022 10:46:32 +0100
+Subject: [PATCH 08/13] net: dsa: mt7530: move autoneg handling to PCS
+ validation
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Move the autoneg bit handling to the PCS validation, which allows us to
+get rid of mt753x_phylink_validate() and rely on the default
+phylink_generic_validate() implementation for the MAC side.
+
+Tested-by: Marek BehĂºn <kabel@kernel.org>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 28 ++++++++++------------------
+ 1 file changed, 10 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2896,25 +2896,16 @@ static void mt753x_phylink_get_caps(stru
+       priv->info->mac_port_get_caps(ds, port, config);
+ }
+-static void
+-mt753x_phylink_validate(struct dsa_switch *ds, int port,
+-                      unsigned long *supported,
+-                      struct phylink_link_state *state)
+-{
+-      __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
+-      u32 caps;
+-
+-      caps = dsa_to_port(ds, port)->pl_config.mac_capabilities;
+-
+-      phylink_set_port_modes(mask);
+-      phylink_get_linkmodes(mask, state->interface, caps);
++static int mt753x_pcs_validate(struct phylink_pcs *pcs,
++                             unsigned long *supported,
++                             const struct phylink_link_state *state)
++{
++      /* Autonegotiation is not supported in TRGMII nor 802.3z modes */
++      if (state->interface == PHY_INTERFACE_MODE_TRGMII ||
++          phy_interface_mode_is_8023z(state->interface))
++              phylink_clear(supported, Autoneg);
+-      if (state->interface != PHY_INTERFACE_MODE_TRGMII &&
+-          !phy_interface_mode_is_8023z(state->interface))
+-              phylink_set(mask, Autoneg);
+-
+-      linkmode_and(supported, supported, mask);
+-      linkmode_and(state->advertising, state->advertising, mask);
++      return 0;
+ }
+ static void mt7530_pcs_get_state(struct phylink_pcs *pcs,
+@@ -3016,12 +3007,14 @@ static void mt7530_pcs_an_restart(struct
+ }
+ static const struct phylink_pcs_ops mt7530_pcs_ops = {
++      .pcs_validate = mt753x_pcs_validate,
+       .pcs_get_state = mt7530_pcs_get_state,
+       .pcs_config = mt753x_pcs_config,
+       .pcs_an_restart = mt7530_pcs_an_restart,
+ };
+ static const struct phylink_pcs_ops mt7531_pcs_ops = {
++      .pcs_validate = mt753x_pcs_validate,
+       .pcs_get_state = mt7531_pcs_get_state,
+       .pcs_config = mt753x_pcs_config,
+       .pcs_an_restart = mt7531_pcs_an_restart,
+@@ -3113,7 +3106,6 @@ static const struct dsa_switch_ops mt753
+       .port_mirror_add        = mt753x_port_mirror_add,
+       .port_mirror_del        = mt753x_port_mirror_del,
+       .phylink_get_caps       = mt753x_phylink_get_caps,
+-      .phylink_validate       = mt753x_phylink_validate,
+       .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,
diff --git a/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch b/target/linux/generic/backport-5.15/705-09-v5.19-net-dsa-mt7530-mark-as-non-legacy.patch
new file mode 100644 (file)
index 0000000..849a992
--- /dev/null
@@ -0,0 +1,34 @@
+From 5bc26de9bfaa6bb5539c09d4435dced98f429cfc Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 11 Apr 2022 10:46:37 +0100
+Subject: [PATCH 09/13] net: dsa: mt7530: mark as non-legacy
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The mt7530 driver does not make use of the speed, duplex, pause or
+advertisement in its phylink_mac_config() implementation, so it can be
+marked as a non-legacy driver.
+
+Tested-by: Marek BehĂºn <kabel@kernel.org>
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+---
+ drivers/net/dsa/mt7530.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2893,6 +2893,12 @@ static void mt753x_phylink_get_caps(stru
+       config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+                                  MAC_10 | MAC_100 | MAC_1000FD;
++      /* This driver does not make use of the speed, duplex, pause or the
++       * advertisement in its mac_config, so it is safe to mark this driver
++       * as non-legacy.
++       */
++      config->legacy_pre_march2020 = false;
++
+       priv->info->mac_port_get_caps(ds, port, config);
+ }
diff --git a/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch b/target/linux/generic/backport-5.15/705-10-v5.19-net-dsa-mt753x-fix-pcs-conversion-regression.patch
new file mode 100644 (file)
index 0000000..89f6e75
--- /dev/null
@@ -0,0 +1,116 @@
+From 1f15b5e8733115cee65342bcaafeaf0368809fae Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Mon, 25 Apr 2022 22:28:02 +0100
+Subject: [PATCH 10/13] net: dsa: mt753x: fix pcs conversion regression
+
+Daniel Golle reports that the conversion of mt753x to phylink PCS caused
+an oops as below.
+
+The problem is with the placement of the PCS initialisation, which
+occurs after mt7531_setup() has been called. However, burited in this
+function is a call to setup the CPU port, which requires the PCS
+structure to be already setup.
+
+Fix this by changing the initialisation order.
+
+Unable to handle kernel NULL pointer dereference at virtual address 0000000000000020
+Mem abort info:
+  ESR = 0x96000005
+  EC = 0x25: DABT (current EL), IL = 32 bits
+  SET = 0, FnV = 0
+  EA = 0, S1PTW = 0
+  FSC = 0x05: level 1 translation fault
+Data abort info:
+  ISV = 0, ISS = 0x00000005
+  CM = 0, WnR = 0
+user pgtable: 4k pages, 39-bit VAs, pgdp=0000000046057000
+[0000000000000020] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000
+Internal error: Oops: 96000005 [#1] SMP
+Modules linked in:
+CPU: 0 PID: 32 Comm: kworker/u4:1 Tainted: G S 5.18.0-rc3-next-20220422+ #0
+Hardware name: Bananapi BPI-R64 (DT)
+Workqueue: events_unbound deferred_probe_work_func
+pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+pc : mt7531_cpu_port_config+0xcc/0x1b0
+lr : mt7531_cpu_port_config+0xc0/0x1b0
+sp : ffffffc008d5b980
+x29: ffffffc008d5b990 x28: ffffff80060562c8 x27: 00000000f805633b
+x26: ffffff80001a8880 x25: 00000000000009c4 x24: 0000000000000016
+x23: ffffff8005eb6470 x22: 0000000000003600 x21: ffffff8006948080
+x20: 0000000000000000 x19: 0000000000000006 x18: 0000000000000000
+x17: 0000000000000001 x16: 0000000000000001 x15: 02963607fcee069e
+x14: 0000000000000000 x13: 0000000000000030 x12: 0101010101010101
+x11: ffffffc037302000 x10: 0000000000000870 x9 : ffffffc008d5b800
+x8 : ffffff800028f950 x7 : 0000000000000001 x6 : 00000000662b3000
+x5 : 00000000000002f0 x4 : 0000000000000000 x3 : ffffff800028f080
+x2 : 0000000000000000 x1 : ffffff800028f080 x0 : 0000000000000000
+Call trace:
+ mt7531_cpu_port_config+0xcc/0x1b0
+ mt753x_cpu_port_enable+0x24/0x1f0
+ mt7531_setup+0x49c/0x5c0
+ mt753x_setup+0x20/0x31c
+ dsa_register_switch+0x8bc/0x1020
+ mt7530_probe+0x118/0x200
+ mdio_probe+0x30/0x64
+ really_probe.part.0+0x98/0x280
+ __driver_probe_device+0x94/0x140
+ driver_probe_device+0x40/0x114
+ __device_attach_driver+0xb0/0x10c
+ bus_for_each_drv+0x64/0xa0
+ __device_attach+0xa8/0x16c
+ device_initial_probe+0x10/0x20
+ bus_probe_device+0x94/0x9c
+ deferred_probe_work_func+0x80/0xb4
+ process_one_work+0x200/0x3a0
+ worker_thread+0x260/0x4c0
+ kthread+0xd4/0xe0
+ ret_from_fork+0x10/0x20
+Code: 9409e911 937b7e60 8b0002a0 f9405800 (f9401005)
+---[ end trace 0000000000000000 ]---
+
+Reported-by: Daniel Golle <daniel@makrotopia.org>
+Tested-by: Daniel Golle <daniel@makrotopia.org>
+Fixes: cbd1f243bc41 ("net: dsa: mt7530: partially convert to phylink_pcs")
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Link: https://lore.kernel.org/r/E1nj6FW-007WZB-5Y@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/mt7530.c | 18 +++++++++---------
+ 1 file changed, 9 insertions(+), 9 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -3031,9 +3031,16 @@ static int
+ mt753x_setup(struct dsa_switch *ds)
+ {
+       struct mt7530_priv *priv = ds->priv;
+-      int ret = priv->info->sw_setup(ds);
+-      int i;
++      int i, ret;
++      /* Initialise the PCS devices */
++      for (i = 0; i < priv->ds->num_ports; i++) {
++              priv->pcs[i].pcs.ops = priv->info->pcs_ops;
++              priv->pcs[i].priv = priv;
++              priv->pcs[i].port = i;
++      }
++
++      ret = priv->info->sw_setup(ds);
+       if (ret)
+               return ret;
+@@ -3045,13 +3052,6 @@ mt753x_setup(struct dsa_switch *ds)
+       if (ret && priv->irq)
+               mt7530_free_irq_common(priv);
+-      /* Initialise the PCS devices */
+-      for (i = 0; i < priv->ds->num_ports; i++) {
+-              priv->pcs[i].pcs.ops = priv->info->pcs_ops;
+-              priv->pcs[i].priv = priv;
+-              priv->pcs[i].port = i;
+-      }
+-
+       return ret;
+ }
diff --git a/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch b/target/linux/generic/backport-5.15/705-11-v6.0-net-dsa-mt7530-rework-mt7530_hw_vlan_-add-del.patch
new file mode 100644 (file)
index 0000000..77b4fa1
--- /dev/null
@@ -0,0 +1,87 @@
+From e26be16262e1fc1e9f1798c12762663bd9c265c6 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 10 Jun 2022 19:05:37 +0200
+Subject: [PATCH 11/13] net: dsa: mt7530: rework mt7530_hw_vlan_{add,del}
+
+Rework vlan_add/vlan_del functions in preparation for dynamic cpu port.
+
+Currently BIT(MT7530_CPU_PORT) is added to new_members, even though
+mt7530_port_vlan_add() will be called on the CPU port too.
+
+Let DSA core decide when to call port_vlan_add for the CPU port, rather
+than doing it implicitly.
+
+We can do autonomous forwarding in a certain VLAN, but not add br0 to that
+VLAN and avoid flooding the CPU with those packets, if software knows it
+doesn't need to process them.
+
+Suggested-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/mt7530.c | 30 ++++++++++++------------------
+ 1 file changed, 12 insertions(+), 18 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -1522,11 +1522,11 @@ static void
+ mt7530_hw_vlan_add(struct mt7530_priv *priv,
+                  struct mt7530_hw_vlan_entry *entry)
+ {
++      struct dsa_port *dp = dsa_to_port(priv->ds, entry->port);
+       u8 new_members;
+       u32 val;
+-      new_members = entry->old_members | BIT(entry->port) |
+-                    BIT(MT7530_CPU_PORT);
++      new_members = entry->old_members | BIT(entry->port);
+       /* Validate the entry with independent learning, create egress tag per
+        * VLAN and joining the port as one of the port members.
+@@ -1537,22 +1537,20 @@ mt7530_hw_vlan_add(struct mt7530_priv *p
+       /* Decide whether adding tag or not for those outgoing packets from the
+        * port inside the VLAN.
+-       */
+-      val = entry->untagged ? MT7530_VLAN_EGRESS_UNTAG :
+-                              MT7530_VLAN_EGRESS_TAG;
+-      mt7530_rmw(priv, MT7530_VAWD2,
+-                 ETAG_CTRL_P_MASK(entry->port),
+-                 ETAG_CTRL_P(entry->port, val));
+-
+-      /* CPU port is always taken as a tagged port for serving more than one
++       * CPU port is always taken as a tagged port for serving more than one
+        * VLANs across and also being applied with egress type stack mode for
+        * that VLAN tags would be appended after hardware special tag used as
+        * DSA tag.
+        */
++      if (dsa_port_is_cpu(dp))
++              val = MT7530_VLAN_EGRESS_STACK;
++      else if (entry->untagged)
++              val = MT7530_VLAN_EGRESS_UNTAG;
++      else
++              val = MT7530_VLAN_EGRESS_TAG;
+       mt7530_rmw(priv, MT7530_VAWD2,
+-                 ETAG_CTRL_P_MASK(MT7530_CPU_PORT),
+-                 ETAG_CTRL_P(MT7530_CPU_PORT,
+-                             MT7530_VLAN_EGRESS_STACK));
++                 ETAG_CTRL_P_MASK(entry->port),
++                 ETAG_CTRL_P(entry->port, val));
+ }
+ static void
+@@ -1571,11 +1569,7 @@ mt7530_hw_vlan_del(struct mt7530_priv *p
+               return;
+       }
+-      /* If certain member apart from CPU port is still alive in the VLAN,
+-       * the entry would be kept valid. Otherwise, the entry is got to be
+-       * disabled.
+-       */
+-      if (new_members && new_members != BIT(MT7530_CPU_PORT)) {
++      if (new_members) {
+               val = IVL_MAC | VTAG_EN | PORT_MEM(new_members) |
+                     VLAN_VALID;
+               mt7530_write(priv, MT7530_VAWD1, val);
diff --git a/target/linux/generic/backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch b/target/linux/generic/backport-5.15/705-12-v6.0-net-dsa-mt7530-rework-mt753-01-_setup.patch
new file mode 100644 (file)
index 0000000..2324336
--- /dev/null
@@ -0,0 +1,75 @@
+From 1f0dfd443eea7fc3e818e96f7c8264913ba41859 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 10 Jun 2022 19:05:38 +0200
+Subject: [PATCH 12/13] net: dsa: mt7530: rework mt753[01]_setup
+
+Enumerate available cpu-ports instead of using hardcoded constant.
+
+Suggested-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/mt7530.c | 25 +++++++++++++++++++++----
+ 1 file changed, 21 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2087,11 +2087,12 @@ static int
+ mt7530_setup(struct dsa_switch *ds)
+ {
+       struct mt7530_priv *priv = ds->priv;
++      struct device_node *dn = NULL;
+       struct device_node *phy_node;
+       struct device_node *mac_np;
+       struct mt7530_dummy_poll p;
+       phy_interface_t interface;
+-      struct device_node *dn;
++      struct dsa_port *cpu_dp;
+       u32 id, val;
+       int ret, i;
+@@ -2099,7 +2100,19 @@ mt7530_setup(struct dsa_switch *ds)
+        * controller also is the container for two GMACs nodes representing
+        * as two netdev instances.
+        */
+-      dn = dsa_to_port(ds, MT7530_CPU_PORT)->master->dev.of_node->parent;
++      dsa_switch_for_each_cpu_port(cpu_dp, ds) {
++              dn = cpu_dp->master->dev.of_node->parent;
++              /* It doesn't matter which CPU port is found first,
++               * their masters should share the same parent OF node
++               */
++              break;
++      }
++
++      if (!dn) {
++              dev_err(ds->dev, "parent OF node of DSA master not found");
++              return -EINVAL;
++      }
++
+       ds->assisted_learning_on_cpu_port = true;
+       ds->mtu_enforcement_ingress = true;
+@@ -2261,6 +2274,7 @@ mt7531_setup(struct dsa_switch *ds)
+ {
+       struct mt7530_priv *priv = ds->priv;
+       struct mt7530_dummy_poll p;
++      struct dsa_port *cpu_dp;
+       u32 val, id;
+       int ret, i;
+@@ -2333,8 +2347,11 @@ mt7531_setup(struct dsa_switch *ds)
+                                CORE_PLL_GROUP4, val);
+       /* BPDU to CPU port */
+-      mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
+-                 BIT(MT7530_CPU_PORT));
++      dsa_switch_for_each_cpu_port(cpu_dp, ds) {
++              mt7530_rmw(priv, MT7531_CFC, MT7531_CPU_PMAP_MASK,
++                         BIT(cpu_dp->index));
++              break;
++      }
+       mt7530_rmw(priv, MT753X_BPC, MT753X_BPDU_PORT_FW_MASK,
+                  MT753X_BPDU_CPU_ONLY);
diff --git a/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch b/target/linux/generic/backport-5.15/705-13-v6.0-net-dsa-mt7530-get-cpu-port-via-dp-cpu_dp-instead-of.patch
new file mode 100644 (file)
index 0000000..3b5ce73
--- /dev/null
@@ -0,0 +1,117 @@
+From ad2606f6fafae3a7d41c4f2af5554c8f6adecbc7 Mon Sep 17 00:00:00 2001
+From: Frank Wunderlich <frank-w@public-files.de>
+Date: Fri, 10 Jun 2022 19:05:39 +0200
+Subject: [PATCH 13/13] net: dsa: mt7530: get cpu-port via dp->cpu_dp instead
+ of constant
+
+Replace last occurences of hardcoded cpu-port by cpu_dp member of
+dsa_port struct.
+
+Now the constant can be dropped.
+
+Suggested-by: Vladimir Oltean <olteanv@gmail.com>
+Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
+Reviewed-by: Vladimir Oltean <olteanv@gmail.com>
+Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/dsa/mt7530.c | 27 ++++++++++++++++++++-------
+ drivers/net/dsa/mt7530.h |  1 -
+ 2 files changed, 20 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -1038,6 +1038,7 @@ static int
+ mt7530_port_enable(struct dsa_switch *ds, int port,
+                  struct phy_device *phy)
+ {
++      struct dsa_port *dp = dsa_to_port(ds, port);
+       struct mt7530_priv *priv = ds->priv;
+       mutex_lock(&priv->reg_mutex);
+@@ -1046,7 +1047,11 @@ mt7530_port_enable(struct dsa_switch *ds
+        * restore the port matrix if the port is the member of a certain
+        * bridge.
+        */
+-      priv->ports[port].pm |= PCR_MATRIX(BIT(MT7530_CPU_PORT));
++      if (dsa_port_is_user(dp)) {
++              struct dsa_port *cpu_dp = dp->cpu_dp;
++
++              priv->ports[port].pm |= PCR_MATRIX(BIT(cpu_dp->index));
++      }
+       priv->ports[port].enable = true;
+       mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
+                  priv->ports[port].pm);
+@@ -1194,7 +1199,8 @@ mt7530_port_bridge_join(struct dsa_switc
+                       struct net_device *bridge)
+ {
+       struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
+-      u32 port_bitmap = BIT(MT7530_CPU_PORT);
++      struct dsa_port *cpu_dp = dp->cpu_dp;
++      u32 port_bitmap = BIT(cpu_dp->index);
+       struct mt7530_priv *priv = ds->priv;
+       mutex_lock(&priv->reg_mutex);
+@@ -1271,9 +1277,12 @@ mt7530_port_set_vlan_unaware(struct dsa_
+        * the CPU port get out of VLAN filtering mode.
+        */
+       if (all_user_ports_removed) {
+-              mt7530_write(priv, MT7530_PCR_P(MT7530_CPU_PORT),
++              struct dsa_port *dp = dsa_to_port(ds, port);
++              struct dsa_port *cpu_dp = dp->cpu_dp;
++
++              mt7530_write(priv, MT7530_PCR_P(cpu_dp->index),
+                            PCR_MATRIX(dsa_user_ports(priv->ds)));
+-              mt7530_write(priv, MT7530_PVC_P(MT7530_CPU_PORT), PORT_SPEC_TAG
++              mt7530_write(priv, MT7530_PVC_P(cpu_dp->index), PORT_SPEC_TAG
+                            | PVC_EG_TAG(MT7530_VLAN_EG_CONSISTENT));
+       }
+ }
+@@ -1311,6 +1320,7 @@ mt7530_port_bridge_leave(struct dsa_swit
+                        struct net_device *bridge)
+ {
+       struct dsa_port *dp = dsa_to_port(ds, port), *other_dp;
++      struct dsa_port *cpu_dp = dp->cpu_dp;
+       struct mt7530_priv *priv = ds->priv;
+       mutex_lock(&priv->reg_mutex);
+@@ -1339,8 +1349,8 @@ mt7530_port_bridge_leave(struct dsa_swit
+        */
+       if (priv->ports[port].enable)
+               mt7530_rmw(priv, MT7530_PCR_P(port), PCR_MATRIX_MASK,
+-                         PCR_MATRIX(BIT(MT7530_CPU_PORT)));
+-      priv->ports[port].pm = PCR_MATRIX(BIT(MT7530_CPU_PORT));
++                         PCR_MATRIX(BIT(cpu_dp->index)));
++      priv->ports[port].pm = PCR_MATRIX(BIT(cpu_dp->index));
+       /* When a port is removed from the bridge, the port would be set up
+        * back to the default as is at initial boot which is a VLAN-unaware
+@@ -1503,6 +1513,9 @@ static int
+ mt7530_port_vlan_filtering(struct dsa_switch *ds, int port, bool vlan_filtering,
+                          struct netlink_ext_ack *extack)
+ {
++      struct dsa_port *dp = dsa_to_port(ds, port);
++      struct dsa_port *cpu_dp = dp->cpu_dp;
++
+       if (vlan_filtering) {
+               /* The port is being kept as VLAN-unaware port when bridge is
+                * set up with vlan_filtering not being set, Otherwise, the
+@@ -1510,7 +1523,7 @@ mt7530_port_vlan_filtering(struct dsa_sw
+                * for becoming a VLAN-aware port.
+                */
+               mt7530_port_set_vlan_aware(ds, port);
+-              mt7530_port_set_vlan_aware(ds, MT7530_CPU_PORT);
++              mt7530_port_set_vlan_aware(ds, cpu_dp->index);
+       } else {
+               mt7530_port_set_vlan_unaware(ds, port);
+       }
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -8,7 +8,6 @@
+ #define MT7530_NUM_PORTS              7
+ #define MT7530_NUM_PHYS                       5
+-#define MT7530_CPU_PORT                       6
+ #define MT7530_NUM_FDB_RECORDS                2048
+ #define MT7530_ALL_MEMBERS            0xff
index 1786bf03452e56580435a5a15de5c82bac578800..77cf63b809be2006cfe848c11c8632048a1d0abe 100644 (file)
@@ -22,7 +22,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -1986,13 +1986,6 @@ int dsa_slave_create(struct dsa_port *po
+@@ -1977,13 +1977,6 @@ int dsa_slave_create(struct dsa_port *po
        port->slave = slave_dev;
        dsa_slave_setup_tagger(slave_dev);
  
@@ -36,7 +36,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        netif_carrier_off(slave_dev);
  
        ret = dsa_slave_phy_setup(slave_dev);
-@@ -2004,6 +1997,13 @@ int dsa_slave_create(struct dsa_port *po
+@@ -1995,6 +1988,13 @@ int dsa_slave_create(struct dsa_port *po
        }
  
        rtnl_lock();
index c2493a08fd91d1ef9497af45c0cb4465edea4d13..50aa5d8f0dd534a5691e0055ab0add5ce9bb7c9d 100644 (file)
@@ -16,7 +16,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
 
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -1997,14 +1997,12 @@ int dsa_slave_create(struct dsa_port *po
+@@ -1988,14 +1988,12 @@ int dsa_slave_create(struct dsa_port *po
        }
  
        rtnl_lock();
index d73b7455866cbbe8507fff1ae7453512c961b3d1..7c6a3a3f8d770d1fe513a356ffd5cd835ef2e239 100644 (file)
@@ -68,7 +68,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  static inline bool dsa_is_unused_port(struct dsa_switch *ds, int p)
  {
        return dsa_to_port(ds, p)->type == DSA_PORT_TYPE_UNUSED;
-@@ -916,6 +926,13 @@ struct dsa_switch_ops {
+@@ -949,6 +959,13 @@ struct dsa_switch_ops {
        int     (*tag_8021q_vlan_add)(struct dsa_switch *ds, int port, u16 vid,
                                      u16 flags);
        int     (*tag_8021q_vlan_del)(struct dsa_switch *ds, int port, u16 vid);
@@ -175,7 +175,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  
 --- a/net/dsa/slave.c
 +++ b/net/dsa/slave.c
-@@ -2320,6 +2320,36 @@ static int dsa_slave_netdevice_event(str
+@@ -2311,6 +2311,36 @@ static int dsa_slave_netdevice_event(str
                err = dsa_port_lag_change(dp, info->lower_state_info);
                return notifier_from_errno(err);
        }
@@ -212,7 +212,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
        case NETDEV_GOING_DOWN: {
                struct dsa_port *dp, *cpu_dp;
                struct dsa_switch_tree *dst;
-@@ -2331,6 +2361,8 @@ static int dsa_slave_netdevice_event(str
+@@ -2322,6 +2352,8 @@ static int dsa_slave_netdevice_event(str
                cpu_dp = dev->dsa_ptr;
                dst = cpu_dp->ds->dst;
  
index 4b5c47420438bd8c7d7660697dac83b2b08d0fb3..e3e338bd4ffc6555054ad2f1b5d6a23d6e89de1a 100644 (file)
@@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -2443,8 +2443,8 @@ static irqreturn_t mtk_handle_irq_rx(int
+@@ -2381,8 +2381,8 @@ static irqreturn_t mtk_handle_irq_rx(int
  
        eth->rx_events++;
        if (likely(napi_schedule_prep(&eth->rx_napi))) {
@@ -20,7 +20,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        }
  
        return IRQ_HANDLED;
-@@ -2456,8 +2456,8 @@ static irqreturn_t mtk_handle_irq_tx(int
+@@ -2394,8 +2394,8 @@ static irqreturn_t mtk_handle_irq_tx(int
  
        eth->tx_events++;
        if (likely(napi_schedule_prep(&eth->tx_napi))) {
@@ -30,12 +30,12 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        }
  
        return IRQ_HANDLED;
-@@ -3623,6 +3623,8 @@ static int mtk_probe(struct platform_dev
+@@ -3585,6 +3585,8 @@ static int mtk_probe(struct platform_dev
         * for NAPI to work
         */
        init_dummy_netdev(&eth->dummy_dev);
 +      eth->dummy_dev.threaded = 1;
 +      strcpy(eth->dummy_dev.name, "mtk_eth");
        netif_napi_add(&eth->dummy_dev, &eth->tx_napi, mtk_napi_tx,
-                      MTK_NAPI_WEIGHT);
+                      NAPI_POLL_WEIGHT);
        netif_napi_add(&eth->dummy_dev, &eth->rx_napi, mtk_napi_rx,
index 24b64c6ce6746b6364cdc81dc253c53dc80a1b97..d6e7f40f3b674162ee246076111b66ec8d4a3248 100644 (file)
@@ -23,7 +23,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
                        sysfs_remove_link(&dev->dev.kobj, "phydev");
 --- a/include/linux/phy.h
 +++ b/include/linux/phy.h
-@@ -789,6 +789,12 @@ struct phy_driver {
+@@ -823,6 +823,12 @@ struct phy_driver {
        /** @handle_interrupt: Override default interrupt handling */
        irqreturn_t (*handle_interrupt)(struct phy_device *phydev);
  
index deb25e652daec4f3c4ac155ece854b54a4ef12e9..4c0d1001e0fc3c0ebf43db56fa73915ed9f7d5a5 100644 (file)
@@ -14,7 +14,7 @@ Signed-off-by: Frank Wunderlich <frank-w@public-files.de>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3675,6 +3675,7 @@ static const struct mtk_soc_data mt2701_
+@@ -3637,6 +3637,7 @@ static const struct mtk_soc_data mt2701_
        .hw_features = MTK_HW_FEATURES,
        .required_clks = MT7623_CLKS_BITMAP,
        .required_pctl = true,
index 45c650b34a362f31ce88c2125cc951a6e3a5dfab..de1079ffae51651a5ebf028591a4b5fc329a4425 100644 (file)
@@ -103,7 +103,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
  
        ret = mtk_mdio_busy_wait(eth);
        if (ret < 0)
-@@ -683,6 +726,7 @@ static int mtk_mdio_init(struct mtk_eth
+@@ -621,6 +664,7 @@ static int mtk_mdio_init(struct mtk_eth
        eth->mii_bus->name = "mdio";
        eth->mii_bus->read = mtk_mdio_read;
        eth->mii_bus->write = mtk_mdio_write;
diff --git a/target/linux/mediatek/patches-5.15/704-net-ethernet-mtk_eth_soc-announce-2500baseT.patch b/target/linux/mediatek/patches-5.15/704-net-ethernet-mtk_eth_soc-announce-2500baseT.patch
deleted file mode 100644 (file)
index a7878ec..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -667,6 +667,7 @@ static void mtk_validate(struct phylink_
-               if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_SGMII)) {
-                       phylink_set(mask, 1000baseT_Full);
-                       phylink_set(mask, 1000baseX_Full);
-+                      phylink_set(mask, 2500baseT_Full);
-                       phylink_set(mask, 2500baseX_Full);
-               }
-               if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_RGMII)) {
index f6ac8360ee3506839ea072d4091de1570959c7d0..8a39c81e01774bef0e08daf487228eaf6da00afa 100644 (file)
@@ -14,7 +14,7 @@ Signed-off-by: RenĂ© van Dorst <opensource@vdorst.com>
 
 --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
 +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
-@@ -3290,6 +3290,7 @@ static const struct net_device_ops mtk_n
+@@ -3228,6 +3228,7 @@ static const struct net_device_ops mtk_n
  
  static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
  {
@@ -22,7 +22,7 @@ Signed-off-by: RenĂ© van Dorst <opensource@vdorst.com>
        const __be32 *_id = of_get_property(np, "reg", NULL);
        phy_interface_t phy_mode;
        struct phylink *phylink;
-@@ -3385,6 +3386,9 @@ static int mtk_add_mac(struct mtk_eth *e
+@@ -3347,6 +3348,9 @@ static int mtk_add_mac(struct mtk_eth *e
        else
                eth->netdev[id]->max_mtu = MTK_MAX_RX_LENGTH_2K - MTK_RX_ETH_HLEN;
  
index afdfc892d575cebb670978aaafa28a0a907b46c0..063b317fd5ce24e8b9685f076ec8818bcb30672b 100644 (file)
@@ -95,7 +95,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
                phydev->mii_ts->link_state(phydev->mii_ts, phydev);
 --- a/drivers/net/phy/phylink.c
 +++ b/drivers/net/phy/phylink.c
-@@ -946,7 +946,8 @@ void phylink_destroy(struct phylink *pl)
+@@ -1315,7 +1315,8 @@ void phylink_destroy(struct phylink *pl)
  }
  EXPORT_SYMBOL_GPL(phylink_destroy);
  
@@ -107,7 +107,7 @@ still required by target/linux/ramips/files/drivers/net/ethernet/ralink/mdio.c
        bool tx_pause, rx_pause;
 --- a/include/linux/phy.h
 +++ b/include/linux/phy.h
-@@ -669,7 +669,7 @@ struct phy_device {
+@@ -703,7 +703,7 @@ struct phy_device {
        u8 mdix;
        u8 mdix_ctrl;
  
index 97086fa95069a06d087c7fc6077da57e3688156c..365bdc688020a196f3505afe7e8eeb8875ef37fc 100644 (file)
@@ -37,7 +37,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
                break;
 --- a/include/linux/phy.h
 +++ b/include/linux/phy.h
-@@ -586,6 +586,7 @@ struct phy_device {
+@@ -620,6 +620,7 @@ struct phy_device {
        unsigned downshifted_rate:1;
        unsigned is_on_sfp_module:1;
        unsigned mac_managed_pm:1;