generic: 5.15: move sfp HALNy patch from pending to backport
authorChristian Marangi <ansuelsmth@gmail.com>
Fri, 21 Oct 2022 21:08:54 +0000 (23:08 +0200)
committerChristian Marangi <ansuelsmth@gmail.com>
Mon, 24 Oct 2022 19:10:46 +0000 (21:10 +0200)
Move sfp HALNy patch from pending to backport as they got merged
upstream. The patch was reordered and one was squashed in the upstream
variant.

Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
14 files changed:
target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch [new file with mode: 0644]
target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch [new file with mode: 0644]
target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch
target/linux/generic/pending-5.15/731-net-dsa-mt7530-add-support-for-in-band-link-status.patch [deleted file]
target/linux/generic/pending-5.15/770-net-sfp-move-quirk-handling-into-sfp.c.patch [deleted file]
target/linux/generic/pending-5.15/771-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch [deleted file]
target/linux/generic/pending-5.15/772-net-sfp-move-Huawei-MA5671A-fixup.patch [deleted file]
target/linux/generic/pending-5.15/773-net-sfp-add-support-for-HALNy-GPON-SFP.patch [deleted file]
target/linux/generic/pending-5.15/774--net-sfp-redo-soft-state-polling.patch [deleted file]
target/linux/generic/pending-5.15/775-net-sfp-change-HALNy-to-ignore-hardware-pins.patch [deleted file]

diff --git a/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch b/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch
new file mode 100644 (file)
index 0000000..7bb6530
--- /dev/null
@@ -0,0 +1,130 @@
+From e19de30d20809af3221ef8a2648b8a8a52e02d90 Mon Sep 17 00:00:00 2001
+From: Daniel Golle <daniel@makrotopia.org>
+Date: Wed, 21 Sep 2022 01:23:14 +0100
+Subject: [PATCH 1/1] net: dsa: mt7530: add support for in-band link status
+
+Read link status from SGMII PCS for in-band managed 2500Base-X and
+1000Base-X connection on a MAC port of the MT7531. This is needed to
+get the SFP cage working which is connected to SGMII interface of
+port 5 of the MT7531 switch IC on the Bananapi BPi-R3 board.
+While at it also handle an_complete for both the autoneg and the
+non-autoneg codepath.
+
+Signed-off-by: Daniel Golle <daniel@makrotopia.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/mt7530.c | 50 +++++++++++++++++++++++++++++-----------
+ drivers/net/dsa/mt7530.h |  1 +
+ 2 files changed, 38 insertions(+), 13 deletions(-)
+
+--- a/drivers/net/dsa/mt7530.c
++++ b/drivers/net/dsa/mt7530.c
+@@ -2699,9 +2699,6 @@ mt7531_mac_config(struct dsa_switch *ds,
+       case PHY_INTERFACE_MODE_NA:
+       case PHY_INTERFACE_MODE_1000BASEX:
+       case PHY_INTERFACE_MODE_2500BASEX:
+-              if (phylink_autoneg_inband(mode))
+-                      return -EINVAL;
+-
+               return mt7531_sgmii_setup_mode_force(priv, port, interface);
+       default:
+               return -EINVAL;
+@@ -2777,13 +2774,6 @@ unsupported:
+               return;
+       }
+-      if (phylink_autoneg_inband(mode) &&
+-          state->interface != PHY_INTERFACE_MODE_SGMII) {
+-              dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
+-                      __func__);
+-              return;
+-      }
+-
+       mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
+       mcr_new = mcr_cur;
+       mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
+@@ -2920,6 +2910,9 @@ static void mt753x_phylink_get_caps(stru
+       config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
+                                  MAC_10 | MAC_100 | MAC_1000FD;
++      if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port))
++              config->mac_capabilities |= MAC_2500FD;
++
+       /* 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.
+@@ -2985,6 +2978,7 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
+       status = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
+       state->link = !!(status & MT7531_SGMII_LINK_STATUS);
++      state->an_complete = !!(status & MT7531_SGMII_AN_COMPLETE);
+       if (state->interface == PHY_INTERFACE_MODE_SGMII &&
+           (status & MT7531_SGMII_AN_ENABLE)) {
+               val = mt7530_read(priv, MT7531_PCS_SPEED_ABILITY(port));
+@@ -3015,16 +3009,44 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
+       return 0;
+ }
++static void
++mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
++                                struct phylink_link_state *state)
++{
++      unsigned int val;
++
++      val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
++      state->link = !!(val & MT7531_SGMII_LINK_STATUS);
++      if (!state->link)
++              return;
++
++      state->an_complete = state->link;
++
++      if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
++              state->speed = SPEED_2500;
++      else
++              state->speed = SPEED_1000;
++
++      state->duplex = DUPLEX_FULL;
++      state->pause = MLO_PAUSE_NONE;
++}
++
+ static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
+                                struct phylink_link_state *state)
+ {
+       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)
++      if (state->interface == PHY_INTERFACE_MODE_SGMII) {
+               mt7531_sgmii_pcs_get_state_an(priv, port, state);
+-      else
+-              state->link = false;
++              return;
++      } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
++                 (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
++              mt7531_sgmii_pcs_get_state_inband(priv, port, state);
++              return;
++      }
++
++      state->link = false;
+ }
+ static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
+@@ -3065,6 +3087,8 @@ mt753x_setup(struct dsa_switch *ds)
+               priv->pcs[i].pcs.ops = priv->info->pcs_ops;
+               priv->pcs[i].priv = priv;
+               priv->pcs[i].port = i;
++              if (mt753x_is_mac_port(i))
++                      priv->pcs[i].pcs.poll = 1;
+       }
+       ret = priv->info->sw_setup(ds);
+--- a/drivers/net/dsa/mt7530.h
++++ b/drivers/net/dsa/mt7530.h
+@@ -373,6 +373,7 @@ enum mt7530_vlan_port_acc_frm {
+ #define  MT7531_SGMII_LINK_STATUS     BIT(18)
+ #define  MT7531_SGMII_AN_ENABLE               BIT(12)
+ #define  MT7531_SGMII_AN_RESTART      BIT(9)
++#define  MT7531_SGMII_AN_COMPLETE     BIT(21)
+ /* Register for SGMII PCS_SPPED_ABILITY */
+ #define MT7531_PCS_SPEED_ABILITY(p)   MT7531_SGMII_REG(p, 0x08)
diff --git a/target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch b/target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch
new file mode 100644 (file)
index 0000000..6f69b7d
--- /dev/null
@@ -0,0 +1,98 @@
+From 8475c4b70b040f9d8cbc308100f2c4d865f810b3 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 13 Sep 2022 20:06:27 +0100
+Subject: [PATCH 1/1] net: sfp: re-implement soft state polling setup
+
+Re-implement the decision making for soft state polling. Instead of
+generating the soft state mask in sfp_soft_start_poll() by looking at
+which GPIOs are available, record their availability in
+sfp_sm_mod_probe() in sfp->state_hw_mask.
+
+This will then allow us to clear bits in sfp->state_hw_mask in module
+specific quirks when the hardware signals should not be used, thereby
+allowing us to switch to using the software state polling.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/sfp.c | 38 ++++++++++++++++++++++++++------------
+ 1 file changed, 26 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -234,6 +234,7 @@ struct sfp {
+       bool need_poll;
+       struct mutex st_mutex;                  /* Protects state */
++      unsigned int state_hw_mask;
+       unsigned int state_soft_mask;
+       unsigned int state;
+       struct delayed_work poll;
+@@ -499,17 +500,18 @@ static void sfp_soft_set_state(struct sf
+ static void sfp_soft_start_poll(struct sfp *sfp)
+ {
+       const struct sfp_eeprom_id *id = &sfp->id;
++      unsigned int mask = 0;
+       sfp->state_soft_mask = 0;
+-      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE &&
+-          !sfp->gpio[GPIO_TX_DISABLE])
+-              sfp->state_soft_mask |= SFP_F_TX_DISABLE;
+-      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT &&
+-          !sfp->gpio[GPIO_TX_FAULT])
+-              sfp->state_soft_mask |= SFP_F_TX_FAULT;
+-      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS &&
+-          !sfp->gpio[GPIO_LOS])
+-              sfp->state_soft_mask |= SFP_F_LOS;
++      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE)
++              mask |= SFP_F_TX_DISABLE;
++      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT)
++              mask |= SFP_F_TX_FAULT;
++      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS)
++              mask |= SFP_F_LOS;
++
++      // Poll the soft state for hardware pins we want to ignore
++      sfp->state_soft_mask = ~sfp->state_hw_mask & mask;
+       if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) &&
+           !sfp->need_poll)
+@@ -523,10 +525,11 @@ static void sfp_soft_stop_poll(struct sf
+ static unsigned int sfp_get_state(struct sfp *sfp)
+ {
+-      unsigned int state = sfp->get_state(sfp);
++      unsigned int soft = sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT);
++      unsigned int state;
+-      if (state & SFP_F_PRESENT &&
+-          sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT))
++      state = sfp->get_state(sfp) & sfp->state_hw_mask;
++      if (state & SFP_F_PRESENT && soft)
+               state |= sfp_soft_get_state(sfp);
+       return state;
+@@ -1940,6 +1943,15 @@ static int sfp_sm_mod_probe(struct sfp *
+       if (ret < 0)
+               return ret;
++      /* Initialise state bits to use from hardware */
++      sfp->state_hw_mask = SFP_F_PRESENT;
++      if (sfp->gpio[GPIO_TX_DISABLE])
++              sfp->state_hw_mask |= SFP_F_TX_DISABLE;
++      if (sfp->gpio[GPIO_TX_FAULT])
++              sfp->state_hw_mask |= SFP_F_TX_FAULT;
++      if (sfp->gpio[GPIO_LOS])
++              sfp->state_hw_mask |= SFP_F_LOS;
++
+       if (!memcmp(id.base.vendor_name, "ALCATELLUCENT   ", 16) &&
+           !memcmp(id.base.vendor_pn, "3FE46541AA      ", 16))
+               sfp->module_t_start_up = T_START_UP_BAD_GPON;
+@@ -2565,6 +2577,8 @@ static int sfp_probe(struct platform_dev
+                               return PTR_ERR(sfp->gpio[i]);
+               }
++      sfp->state_hw_mask = SFP_F_PRESENT;
++
+       sfp->get_state = sfp_gpio_get_state;
+       sfp->set_state = sfp_gpio_set_state;
diff --git a/target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch b/target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch
new file mode 100644 (file)
index 0000000..e5f8031
--- /dev/null
@@ -0,0 +1,291 @@
+From 23571c7b96437483d28a990c906cc81f5f66374e Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 13 Sep 2022 20:06:32 +0100
+Subject: [PATCH 1/1] net: sfp: move quirk handling into sfp.c
+
+We need to handle more quirks than just those which affect the link
+modes of the module. Move the quirk lookup into sfp.c, and pass the
+quirk to sfp-bus.c
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/sfp-bus.c | 98 ++-------------------------------------
+ drivers/net/phy/sfp.c     | 94 ++++++++++++++++++++++++++++++++++++-
+ drivers/net/phy/sfp.h     |  9 +++-
+ 3 files changed, 104 insertions(+), 97 deletions(-)
+
+--- a/drivers/net/phy/sfp-bus.c
++++ b/drivers/net/phy/sfp-bus.c
+@@ -10,12 +10,6 @@
+ #include "sfp.h"
+-struct sfp_quirk {
+-      const char *vendor;
+-      const char *part;
+-      void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
+-};
+-
+ /**
+  * struct sfp_bus - internal representation of a sfp bus
+  */
+@@ -38,93 +32,6 @@ struct sfp_bus {
+       bool started;
+ };
+-static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
+-                              unsigned long *modes)
+-{
+-      phylink_set(modes, 2500baseX_Full);
+-}
+-
+-static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
+-                                    unsigned long *modes)
+-{
+-      /* Ubiquiti U-Fiber Instant module claims that support all transceiver
+-       * types including 10G Ethernet which is not truth. So clear all claimed
+-       * modes and set only one mode which module supports: 1000baseX_Full.
+-       */
+-      phylink_zero(modes);
+-      phylink_set(modes, 1000baseX_Full);
+-}
+-
+-static const struct sfp_quirk sfp_quirks[] = {
+-      {
+-              // Alcatel Lucent G-010S-P can operate at 2500base-X, but
+-              // incorrectly report 2500MBd NRZ in their EEPROM
+-              .vendor = "ALCATELLUCENT",
+-              .part = "G010SP",
+-              .modes = sfp_quirk_2500basex,
+-      }, {
+-              // Alcatel Lucent G-010S-A can operate at 2500base-X, but
+-              // report 3.2GBd NRZ in their EEPROM
+-              .vendor = "ALCATELLUCENT",
+-              .part = "3FE46541AA",
+-              .modes = sfp_quirk_2500basex,
+-      }, {
+-              // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
+-              // NRZ in their EEPROM
+-              .vendor = "HUAWEI",
+-              .part = "MA5671A",
+-              .modes = sfp_quirk_2500basex,
+-      }, {
+-              // Lantech 8330-262D-E can operate at 2500base-X, but
+-              // incorrectly report 2500MBd NRZ in their EEPROM
+-              .vendor = "Lantech",
+-              .part = "8330-262D-E",
+-              .modes = sfp_quirk_2500basex,
+-      }, {
+-              .vendor = "UBNT",
+-              .part = "UF-INSTANT",
+-              .modes = sfp_quirk_ubnt_uf_instant,
+-      },
+-};
+-
+-static size_t sfp_strlen(const char *str, size_t maxlen)
+-{
+-      size_t size, i;
+-
+-      /* Trailing characters should be filled with space chars */
+-      for (i = 0, size = 0; i < maxlen; i++)
+-              if (str[i] != ' ')
+-                      size = i + 1;
+-
+-      return size;
+-}
+-
+-static bool sfp_match(const char *qs, const char *str, size_t len)
+-{
+-      if (!qs)
+-              return true;
+-      if (strlen(qs) != len)
+-              return false;
+-      return !strncmp(qs, str, len);
+-}
+-
+-static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
+-{
+-      const struct sfp_quirk *q;
+-      unsigned int i;
+-      size_t vs, ps;
+-
+-      vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
+-      ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
+-
+-      for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
+-              if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
+-                  sfp_match(q->part, id->base.vendor_pn, ps))
+-                      return q;
+-
+-      return NULL;
+-}
+-
+ /**
+  * sfp_parse_port() - Parse the EEPROM base ID, setting the port type
+  * @bus: a pointer to the &struct sfp_bus structure for the sfp module
+@@ -786,12 +693,13 @@ void sfp_link_down(struct sfp_bus *bus)
+ }
+ EXPORT_SYMBOL_GPL(sfp_link_down);
+-int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id)
++int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
++                    const struct sfp_quirk *quirk)
+ {
+       const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
+       int ret = 0;
+-      bus->sfp_quirk = sfp_lookup_quirk(id);
++      bus->sfp_quirk = quirk;
+       if (ops && ops->module_insert)
+               ret = ops->module_insert(bus->upstream, id);
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -253,6 +253,8 @@ struct sfp {
+       unsigned int module_t_start_up;
+       bool tx_fault_ignore;
++      const struct sfp_quirk *quirk;
++
+ #if IS_ENABLED(CONFIG_HWMON)
+       struct sfp_diag diag;
+       struct delayed_work hwmon_probe;
+@@ -309,6 +311,93 @@ static const struct of_device_id sfp_of_
+ };
+ MODULE_DEVICE_TABLE(of, sfp_of_match);
++static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
++                              unsigned long *modes)
++{
++      linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, modes);
++}
++
++static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
++                                    unsigned long *modes)
++{
++      /* Ubiquiti U-Fiber Instant module claims that support all transceiver
++       * types including 10G Ethernet which is not truth. So clear all claimed
++       * modes and set only one mode which module supports: 1000baseX_Full.
++       */
++      linkmode_zero(modes);
++      linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes);
++}
++
++static const struct sfp_quirk sfp_quirks[] = {
++      {
++              // Alcatel Lucent G-010S-P can operate at 2500base-X, but
++              // incorrectly report 2500MBd NRZ in their EEPROM
++              .vendor = "ALCATELLUCENT",
++              .part = "G010SP",
++              .modes = sfp_quirk_2500basex,
++      }, {
++              // Alcatel Lucent G-010S-A can operate at 2500base-X, but
++              // report 3.2GBd NRZ in their EEPROM
++              .vendor = "ALCATELLUCENT",
++              .part = "3FE46541AA",
++              .modes = sfp_quirk_2500basex,
++      }, {
++              // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
++              // NRZ in their EEPROM
++              .vendor = "HUAWEI",
++              .part = "MA5671A",
++              .modes = sfp_quirk_2500basex,
++      }, {
++              // Lantech 8330-262D-E can operate at 2500base-X, but
++              // incorrectly report 2500MBd NRZ in their EEPROM
++              .vendor = "Lantech",
++              .part = "8330-262D-E",
++              .modes = sfp_quirk_2500basex,
++      }, {
++              .vendor = "UBNT",
++              .part = "UF-INSTANT",
++              .modes = sfp_quirk_ubnt_uf_instant,
++      },
++};
++
++static size_t sfp_strlen(const char *str, size_t maxlen)
++{
++      size_t size, i;
++
++      /* Trailing characters should be filled with space chars */
++      for (i = 0, size = 0; i < maxlen; i++)
++              if (str[i] != ' ')
++                      size = i + 1;
++
++      return size;
++}
++
++static bool sfp_match(const char *qs, const char *str, size_t len)
++{
++      if (!qs)
++              return true;
++      if (strlen(qs) != len)
++              return false;
++      return !strncmp(qs, str, len);
++}
++
++static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
++{
++      const struct sfp_quirk *q;
++      unsigned int i;
++      size_t vs, ps;
++
++      vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
++      ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
++
++      for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
++              if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
++                  sfp_match(q->part, id->base.vendor_pn, ps))
++                      return q;
++
++      return NULL;
++}
++
+ static unsigned long poll_jiffies;
+ static unsigned int sfp_gpio_get_state(struct sfp *sfp)
+@@ -1964,6 +2053,8 @@ static int sfp_sm_mod_probe(struct sfp *
+       else
+               sfp->tx_fault_ignore = false;
++      sfp->quirk = sfp_lookup_quirk(&id);
++
+       return 0;
+ }
+@@ -2075,7 +2166,8 @@ static void sfp_sm_module(struct sfp *sf
+                       break;
+               /* Report the module insertion to the upstream device */
+-              err = sfp_module_insert(sfp->sfp_bus, &sfp->id);
++              err = sfp_module_insert(sfp->sfp_bus, &sfp->id,
++                                      sfp->quirk);
+               if (err < 0) {
+                       sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
+                       break;
+--- a/drivers/net/phy/sfp.h
++++ b/drivers/net/phy/sfp.h
+@@ -6,6 +6,12 @@
+ struct sfp;
++struct sfp_quirk {
++      const char *vendor;
++      const char *part;
++      void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
++};
++
+ struct sfp_socket_ops {
+       void (*attach)(struct sfp *sfp);
+       void (*detach)(struct sfp *sfp);
+@@ -23,7 +29,8 @@ int sfp_add_phy(struct sfp_bus *bus, str
+ void sfp_remove_phy(struct sfp_bus *bus);
+ void sfp_link_up(struct sfp_bus *bus);
+ void sfp_link_down(struct sfp_bus *bus);
+-int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
++int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
++                    const struct sfp_quirk *quirk);
+ void sfp_module_remove(struct sfp_bus *bus);
+ int sfp_module_start(struct sfp_bus *bus);
+ void sfp_module_stop(struct sfp_bus *bus);
diff --git a/target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch b/target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch
new file mode 100644 (file)
index 0000000..aa3112e
--- /dev/null
@@ -0,0 +1,69 @@
+From 275416754e9a262c97a1ad6f806a4bc6e0464aa2 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 13 Sep 2022 20:06:37 +0100
+Subject: [PATCH 1/1] net: sfp: move Alcatel Lucent 3FE46541AA fixup
+
+Add a new fixup mechanism to the SFP quirks, and use it for this
+module.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/sfp.c | 14 +++++++++-----
+ drivers/net/phy/sfp.h |  1 +
+ 2 files changed, 10 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -311,6 +311,11 @@ static const struct of_device_id sfp_of_
+ };
+ MODULE_DEVICE_TABLE(of, sfp_of_match);
++static void sfp_fixup_long_startup(struct sfp *sfp)
++{
++      sfp->module_t_start_up = T_START_UP_BAD_GPON;
++}
++
+ static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
+                               unsigned long *modes)
+ {
+@@ -341,6 +346,7 @@ static const struct sfp_quirk sfp_quirks
+               .vendor = "ALCATELLUCENT",
+               .part = "3FE46541AA",
+               .modes = sfp_quirk_2500basex,
++              .fixup = sfp_fixup_long_startup,
+       }, {
+               // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
+               // NRZ in their EEPROM
+@@ -2041,11 +2047,7 @@ static int sfp_sm_mod_probe(struct sfp *
+       if (sfp->gpio[GPIO_LOS])
+               sfp->state_hw_mask |= SFP_F_LOS;
+-      if (!memcmp(id.base.vendor_name, "ALCATELLUCENT   ", 16) &&
+-          !memcmp(id.base.vendor_pn, "3FE46541AA      ", 16))
+-              sfp->module_t_start_up = T_START_UP_BAD_GPON;
+-      else
+-              sfp->module_t_start_up = T_START_UP;
++      sfp->module_t_start_up = T_START_UP;
+       if (!memcmp(id.base.vendor_name, "HUAWEI          ", 16) &&
+           !memcmp(id.base.vendor_pn, "MA5671A         ", 16))
+@@ -2054,6 +2056,8 @@ static int sfp_sm_mod_probe(struct sfp *
+               sfp->tx_fault_ignore = false;
+       sfp->quirk = sfp_lookup_quirk(&id);
++      if (sfp->quirk && sfp->quirk->fixup)
++              sfp->quirk->fixup(sfp);
+       return 0;
+ }
+--- a/drivers/net/phy/sfp.h
++++ b/drivers/net/phy/sfp.h
+@@ -10,6 +10,7 @@ struct sfp_quirk {
+       const char *vendor;
+       const char *part;
+       void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
++      void (*fixup)(struct sfp *sfp);
+ };
+ struct sfp_socket_ops {
diff --git a/target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch b/target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch
new file mode 100644 (file)
index 0000000..14b0f9b
--- /dev/null
@@ -0,0 +1,48 @@
+From 5029be761161374a3624aa7b4670174c35449bf5 Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 13 Sep 2022 20:06:42 +0100
+Subject: [PATCH 1/1] net: sfp: move Huawei MA5671A fixup
+
+Move this module over to the new fixup mechanism.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/sfp.c | 12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -316,6 +316,11 @@ static void sfp_fixup_long_startup(struc
+       sfp->module_t_start_up = T_START_UP_BAD_GPON;
+ }
++static void sfp_fixup_ignore_tx_fault(struct sfp *sfp)
++{
++      sfp->tx_fault_ignore = true;
++}
++
+ static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
+                               unsigned long *modes)
+ {
+@@ -353,6 +358,7 @@ static const struct sfp_quirk sfp_quirks
+               .vendor = "HUAWEI",
+               .part = "MA5671A",
+               .modes = sfp_quirk_2500basex,
++              .fixup = sfp_fixup_ignore_tx_fault,
+       }, {
+               // Lantech 8330-262D-E can operate at 2500base-X, but
+               // incorrectly report 2500MBd NRZ in their EEPROM
+@@ -2049,11 +2055,7 @@ static int sfp_sm_mod_probe(struct sfp *
+       sfp->module_t_start_up = T_START_UP;
+-      if (!memcmp(id.base.vendor_name, "HUAWEI          ", 16) &&
+-          !memcmp(id.base.vendor_pn, "MA5671A         ", 16))
+-              sfp->tx_fault_ignore = true;
+-      else
+-              sfp->tx_fault_ignore = false;
++      sfp->tx_fault_ignore = false;
+       sfp->quirk = sfp_lookup_quirk(&id);
+       if (sfp->quirk && sfp->quirk->fixup)
diff --git a/target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch b/target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch
new file mode 100644 (file)
index 0000000..0c65de5
--- /dev/null
@@ -0,0 +1,79 @@
+From 73472c830eae5fce2107f7f086f1e6827d215caf Mon Sep 17 00:00:00 2001
+From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
+Date: Tue, 13 Sep 2022 20:06:48 +0100
+Subject: [PATCH 1/1] net: sfp: add support for HALNy GPON SFP
+
+Add a quirk for the HALNy HL-GSFP module, which appears to have an
+inverted RX_LOS signal, and maybe uses TX_FAULT as a serial port
+transmit pin. Rather than use these hardware signals, switch to
+using software polling for these status signals.
+
+Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+---
+ drivers/net/phy/sfp-bus.c |  2 +-
+ drivers/net/phy/sfp.c     | 21 ++++++++++++++++++---
+ 2 files changed, 19 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/phy/sfp-bus.c
++++ b/drivers/net/phy/sfp-bus.c
+@@ -283,7 +283,7 @@ void sfp_parse_support(struct sfp_bus *b
+                       phylink_set(modes, 2500baseX_Full);
+       }
+-      if (bus->sfp_quirk)
++      if (bus->sfp_quirk && bus->sfp_quirk->modes)
+               bus->sfp_quirk->modes(id, modes);
+       linkmode_or(support, support, modes);
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -321,6 +321,15 @@ static void sfp_fixup_ignore_tx_fault(st
+       sfp->tx_fault_ignore = true;
+ }
++static void sfp_fixup_halny_gsfp(struct sfp *sfp)
++{
++      /* Ignore the TX_FAULT and LOS signals on this module.
++       * these are possibly used for other purposes on this
++       * module, e.g. a serial port.
++       */
++      sfp->state_hw_mask &= ~(SFP_F_TX_FAULT | SFP_F_LOS);
++}
++
+ static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
+                               unsigned long *modes)
+ {
+@@ -353,6 +362,10 @@ static const struct sfp_quirk sfp_quirks
+               .modes = sfp_quirk_2500basex,
+               .fixup = sfp_fixup_long_startup,
+       }, {
++              .vendor = "HALNy",
++              .part = "HL-GSFP",
++              .fixup = sfp_fixup_halny_gsfp,
++      }, {
+               // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
+               // NRZ in their EEPROM
+               .vendor = "HUAWEI",
+@@ -369,16 +382,18 @@ static const struct sfp_quirk sfp_quirks
+               .vendor = "UBNT",
+               .part = "UF-INSTANT",
+               .modes = sfp_quirk_ubnt_uf_instant,
+-      },
++      }
+ };
+ static size_t sfp_strlen(const char *str, size_t maxlen)
+ {
+       size_t size, i;
+-      /* Trailing characters should be filled with space chars */
++      /* Trailing characters should be filled with space chars, but
++       * some manufacturers can't read SFF-8472 and use NUL.
++       */
+       for (i = 0, size = 0; i < maxlen; i++)
+-              if (str[i] != ' ')
++              if (str[i] != ' ' && str[i] != '\0')
+                       size = i + 1;
+       return size;
index d9835f889610360b56d0ea8429708bfceb2eb322..83b2c304e2d10e3e1feb90377df629b3da771ff6 100644 (file)
@@ -26,7 +26,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
 
 --- a/drivers/net/phy/sfp.c
 +++ b/drivers/net/phy/sfp.c
-@@ -369,6 +369,11 @@ static const struct sfp_quirk sfp_quirks
+@@ -373,6 +373,11 @@ static const struct sfp_quirk sfp_quirks
                .modes = sfp_quirk_2500basex,
                .fixup = sfp_fixup_ignore_tx_fault,
        }, {
@@ -38,7 +38,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                // Lantech 8330-262D-E can operate at 2500base-X, but
                // incorrectly report 2500MBd NRZ in their EEPROM
                .vendor = "Lantech",
-@@ -2303,7 +2308,8 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2306,7 +2311,8 @@ static void sfp_sm_main(struct sfp *sfp,
                         * or t_start_up, so assume there is a fault.
                         */
                        sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
@@ -48,7 +48,7 @@ Signed-off-by: Daniel Golle <daniel@makrotopia.org>
                } else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
        init_done:
                        sfp->sm_phy_retries = R_PHY_RETRY;
-@@ -2526,10 +2532,12 @@ static void sfp_check_state(struct sfp *
+@@ -2529,10 +2535,12 @@ static void sfp_check_state(struct sfp *
        mutex_lock(&sfp->st_mutex);
        state = sfp_get_state(sfp);
        changed = state ^ sfp->state;
diff --git a/target/linux/generic/pending-5.15/731-net-dsa-mt7530-add-support-for-in-band-link-status.patch b/target/linux/generic/pending-5.15/731-net-dsa-mt7530-add-support-for-in-band-link-status.patch
deleted file mode 100644 (file)
index 8196f19..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-From 8e18c5fef75debfae3531fbd6901f3bf317d91ed Mon Sep 17 00:00:00 2001
-From: Daniel Golle <daniel@makrotopia.org>
-Date: Fri, 9 Sep 2022 04:28:43 +0100
-Subject: [PATCH] net: dsa: mt7530: add support for in-band link status
-To: linux-mediatek@lists.infradead.org,
-    netdev@vger.kernel.org
-Cc: Russell King <linux@armlinux.org.uk>,
-    Sean Wang <sean.wang@mediatek.com>,
-    Landen Chao <Landen.Chao@mediatek.com>,
-    DENG Qingfang <dqfext@gmail.com>,
-    Andrew Lunn <andrew@lunn.ch>,
-    Vivien Didelot <vivien.didelot@gmail.com>,
-    Florian Fainelli <f.fainelli@gmail.com>,
-    Vladimir Oltean <olteanv@gmail.com>,
-    David S. Miller <davem@davemloft.net>,
-    Eric Dumazet <edumazet@google.com>,
-    Jakub Kicinski <kuba@kernel.org>,
-    Paolo Abeni <pabeni@redhat.com>,
-    Matthias Brugger <matthias.bgg@gmail.com>,
-    Philipp Zabel <p.zabel@pengutronix.de>
-
-Read link status from SGMII PCS for in-band managed 2500Base-X and
-1000Base-X connection on a MAC port of the MT7531. This is needed to
-get the SFP cage working which is connected to SGMII interface of
-port 5 of the MT7531 switch IC on the Bananapi BPi-R3 board.
-
-Signed-off-by: Daniel Golle <daniel@makrotopia.org>
----
- drivers/net/dsa/mt7530.c | 48 +++++++++++++++++++++++++++++-----------
- 1 file changed, 35 insertions(+), 13 deletions(-)
-
---- a/drivers/net/dsa/mt7530.c
-+++ b/drivers/net/dsa/mt7530.c
-@@ -2703,9 +2703,6 @@ mt7531_mac_config(struct dsa_switch *ds,
-       case PHY_INTERFACE_MODE_NA:
-       case PHY_INTERFACE_MODE_1000BASEX:
-       case PHY_INTERFACE_MODE_2500BASEX:
--              if (phylink_autoneg_inband(mode))
--                      return -EINVAL;
--
-               return mt7531_sgmii_setup_mode_force(priv, port, interface);
-       default:
-               return -EINVAL;
-@@ -2781,13 +2778,6 @@ unsupported:
-               return;
-       }
--      if (phylink_autoneg_inband(mode) &&
--          state->interface != PHY_INTERFACE_MODE_SGMII) {
--              dev_err(ds->dev, "%s: in-band negotiation unsupported\n",
--                      __func__);
--              return;
--      }
--
-       mcr_cur = mt7530_read(priv, MT7530_PMCR_P(port));
-       mcr_new = mcr_cur;
-       mcr_new &= ~PMCR_LINK_SETTINGS_MASK;
-@@ -2924,6 +2914,9 @@ static void mt753x_phylink_get_caps(stru
-       config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
-                                  MAC_10 | MAC_100 | MAC_1000FD;
-+      if ((priv->id == ID_MT7531) && mt753x_is_mac_port(port))
-+              config->mac_capabilities |= MAC_2500FD;
-+
-       /* 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.
-@@ -3019,16 +3012,43 @@ mt7531_sgmii_pcs_get_state_an(struct mt7
-       return 0;
- }
-+static void
-+mt7531_sgmii_pcs_get_state_inband(struct mt7530_priv *priv, int port,
-+                                struct phylink_link_state *state)
-+{
-+      unsigned int val;
-+
-+      val = mt7530_read(priv, MT7531_PCS_CONTROL_1(port));
-+      state->link = !!(val & MT7531_SGMII_LINK_STATUS);
-+      if (!state->link)
-+              return;
-+
-+      if (state->interface == PHY_INTERFACE_MODE_2500BASEX)
-+              state->speed = SPEED_2500;
-+      else
-+              state->speed = SPEED_1000;
-+
-+      state->duplex = DUPLEX_FULL;
-+      state->pause = 0;
-+}
-+
- static void mt7531_pcs_get_state(struct phylink_pcs *pcs,
-                                struct phylink_link_state *state)
- {
-       struct mt7530_priv *priv = pcs_to_mt753x_pcs(pcs)->priv;
-       int port = pcs_to_mt753x_pcs(pcs)->port;
-+      unsigned int val;
--      if (state->interface == PHY_INTERFACE_MODE_SGMII)
-+      if (state->interface == PHY_INTERFACE_MODE_SGMII) {
-               mt7531_sgmii_pcs_get_state_an(priv, port, state);
--      else
--              state->link = false;
-+              return;
-+      } else if ((state->interface == PHY_INTERFACE_MODE_1000BASEX) ||
-+                 (state->interface == PHY_INTERFACE_MODE_2500BASEX)) {
-+              mt7531_sgmii_pcs_get_state_inband(priv, port, state);
-+              return;
-+      }
-+
-+      state->link = false;
- }
- static int mt753x_pcs_config(struct phylink_pcs *pcs, unsigned int mode,
-@@ -3069,6 +3089,8 @@ mt753x_setup(struct dsa_switch *ds)
-               priv->pcs[i].pcs.ops = priv->info->pcs_ops;
-               priv->pcs[i].priv = priv;
-               priv->pcs[i].port = i;
-+              if (mt753x_is_mac_port(i))
-+                      priv->pcs[i].pcs.poll = 1;
-       }
-       ret = priv->info->sw_setup(ds);
diff --git a/target/linux/generic/pending-5.15/770-net-sfp-move-quirk-handling-into-sfp.c.patch b/target/linux/generic/pending-5.15/770-net-sfp-move-quirk-handling-into-sfp.c.patch
deleted file mode 100644 (file)
index 8d43ccb..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-From a4648a1957cd79bc389538aa0472db39a56e3df6 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 26 Aug 2022 08:43:30 +0100
-Subject: [PATCH 1/6] net: sfp: move quirk handling into sfp.c
-
-We need to handle more quirks than just those which affect the link
-modes of the module. Move the quirk lookup into sfp.c, and pass the
-quirk to sfp-bus.c
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/phy/sfp-bus.c | 98 ++-------------------------------------
- drivers/net/phy/sfp.c     | 94 ++++++++++++++++++++++++++++++++++++-
- drivers/net/phy/sfp.h     |  9 +++-
- 3 files changed, 104 insertions(+), 97 deletions(-)
-
---- a/drivers/net/phy/sfp-bus.c
-+++ b/drivers/net/phy/sfp-bus.c
-@@ -10,12 +10,6 @@
- #include "sfp.h"
--struct sfp_quirk {
--      const char *vendor;
--      const char *part;
--      void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
--};
--
- /**
-  * struct sfp_bus - internal representation of a sfp bus
-  */
-@@ -38,93 +32,6 @@ struct sfp_bus {
-       bool started;
- };
--static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
--                              unsigned long *modes)
--{
--      phylink_set(modes, 2500baseX_Full);
--}
--
--static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
--                                    unsigned long *modes)
--{
--      /* Ubiquiti U-Fiber Instant module claims that support all transceiver
--       * types including 10G Ethernet which is not truth. So clear all claimed
--       * modes and set only one mode which module supports: 1000baseX_Full.
--       */
--      phylink_zero(modes);
--      phylink_set(modes, 1000baseX_Full);
--}
--
--static const struct sfp_quirk sfp_quirks[] = {
--      {
--              // Alcatel Lucent G-010S-P can operate at 2500base-X, but
--              // incorrectly report 2500MBd NRZ in their EEPROM
--              .vendor = "ALCATELLUCENT",
--              .part = "G010SP",
--              .modes = sfp_quirk_2500basex,
--      }, {
--              // Alcatel Lucent G-010S-A can operate at 2500base-X, but
--              // report 3.2GBd NRZ in their EEPROM
--              .vendor = "ALCATELLUCENT",
--              .part = "3FE46541AA",
--              .modes = sfp_quirk_2500basex,
--      }, {
--              // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
--              // NRZ in their EEPROM
--              .vendor = "HUAWEI",
--              .part = "MA5671A",
--              .modes = sfp_quirk_2500basex,
--      }, {
--              // Lantech 8330-262D-E can operate at 2500base-X, but
--              // incorrectly report 2500MBd NRZ in their EEPROM
--              .vendor = "Lantech",
--              .part = "8330-262D-E",
--              .modes = sfp_quirk_2500basex,
--      }, {
--              .vendor = "UBNT",
--              .part = "UF-INSTANT",
--              .modes = sfp_quirk_ubnt_uf_instant,
--      },
--};
--
--static size_t sfp_strlen(const char *str, size_t maxlen)
--{
--      size_t size, i;
--
--      /* Trailing characters should be filled with space chars */
--      for (i = 0, size = 0; i < maxlen; i++)
--              if (str[i] != ' ')
--                      size = i + 1;
--
--      return size;
--}
--
--static bool sfp_match(const char *qs, const char *str, size_t len)
--{
--      if (!qs)
--              return true;
--      if (strlen(qs) != len)
--              return false;
--      return !strncmp(qs, str, len);
--}
--
--static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
--{
--      const struct sfp_quirk *q;
--      unsigned int i;
--      size_t vs, ps;
--
--      vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
--      ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
--
--      for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
--              if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
--                  sfp_match(q->part, id->base.vendor_pn, ps))
--                      return q;
--
--      return NULL;
--}
--
- /**
-  * sfp_parse_port() - Parse the EEPROM base ID, setting the port type
-  * @bus: a pointer to the &struct sfp_bus structure for the sfp module
-@@ -786,12 +693,13 @@ void sfp_link_down(struct sfp_bus *bus)
- }
- EXPORT_SYMBOL_GPL(sfp_link_down);
--int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id)
-+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
-+                    const struct sfp_quirk *quirk)
- {
-       const struct sfp_upstream_ops *ops = sfp_get_upstream_ops(bus);
-       int ret = 0;
--      bus->sfp_quirk = sfp_lookup_quirk(id);
-+      bus->sfp_quirk = quirk;
-       if (ops && ops->module_insert)
-               ret = ops->module_insert(bus->upstream, id);
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -252,6 +252,8 @@ struct sfp {
-       unsigned int module_t_start_up;
-       bool tx_fault_ignore;
-+      const struct sfp_quirk *quirk;
-+
- #if IS_ENABLED(CONFIG_HWMON)
-       struct sfp_diag diag;
-       struct delayed_work hwmon_probe;
-@@ -308,6 +310,93 @@ static const struct of_device_id sfp_of_
- };
- MODULE_DEVICE_TABLE(of, sfp_of_match);
-+static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
-+                              unsigned long *modes)
-+{
-+      linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseX_Full_BIT, modes);
-+}
-+
-+static void sfp_quirk_ubnt_uf_instant(const struct sfp_eeprom_id *id,
-+                                    unsigned long *modes)
-+{
-+      /* Ubiquiti U-Fiber Instant module claims that support all transceiver
-+       * types including 10G Ethernet which is not truth. So clear all claimed
-+       * modes and set only one mode which module supports: 1000baseX_Full.
-+       */
-+      linkmode_zero(modes);
-+      linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, modes);
-+}
-+
-+static const struct sfp_quirk sfp_quirks[] = {
-+      {
-+              // Alcatel Lucent G-010S-P can operate at 2500base-X, but
-+              // incorrectly report 2500MBd NRZ in their EEPROM
-+              .vendor = "ALCATELLUCENT",
-+              .part = "G010SP",
-+              .modes = sfp_quirk_2500basex,
-+      }, {
-+              // Alcatel Lucent G-010S-A can operate at 2500base-X, but
-+              // report 3.2GBd NRZ in their EEPROM
-+              .vendor = "ALCATELLUCENT",
-+              .part = "3FE46541AA",
-+              .modes = sfp_quirk_2500basex,
-+      }, {
-+              // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
-+              // NRZ in their EEPROM
-+              .vendor = "HUAWEI",
-+              .part = "MA5671A",
-+              .modes = sfp_quirk_2500basex,
-+      }, {
-+              // Lantech 8330-262D-E can operate at 2500base-X, but
-+              // incorrectly report 2500MBd NRZ in their EEPROM
-+              .vendor = "Lantech",
-+              .part = "8330-262D-E",
-+              .modes = sfp_quirk_2500basex,
-+      }, {
-+              .vendor = "UBNT",
-+              .part = "UF-INSTANT",
-+              .modes = sfp_quirk_ubnt_uf_instant,
-+      },
-+};
-+
-+static size_t sfp_strlen(const char *str, size_t maxlen)
-+{
-+      size_t size, i;
-+
-+      /* Trailing characters should be filled with space chars */
-+      for (i = 0, size = 0; i < maxlen; i++)
-+              if (str[i] != ' ')
-+                      size = i + 1;
-+
-+      return size;
-+}
-+
-+static bool sfp_match(const char *qs, const char *str, size_t len)
-+{
-+      if (!qs)
-+              return true;
-+      if (strlen(qs) != len)
-+              return false;
-+      return !strncmp(qs, str, len);
-+}
-+
-+static const struct sfp_quirk *sfp_lookup_quirk(const struct sfp_eeprom_id *id)
-+{
-+      const struct sfp_quirk *q;
-+      unsigned int i;
-+      size_t vs, ps;
-+
-+      vs = sfp_strlen(id->base.vendor_name, ARRAY_SIZE(id->base.vendor_name));
-+      ps = sfp_strlen(id->base.vendor_pn, ARRAY_SIZE(id->base.vendor_pn));
-+
-+      for (i = 0, q = sfp_quirks; i < ARRAY_SIZE(sfp_quirks); i++, q++)
-+              if (sfp_match(q->vendor, id->base.vendor_name, vs) &&
-+                  sfp_match(q->part, id->base.vendor_pn, ps))
-+                      return q;
-+
-+      return NULL;
-+}
-+
- static unsigned long poll_jiffies;
- static unsigned int sfp_gpio_get_state(struct sfp *sfp)
-@@ -1952,6 +2041,8 @@ static int sfp_sm_mod_probe(struct sfp *
-       else
-               sfp->tx_fault_ignore = false;
-+      sfp->quirk = sfp_lookup_quirk(&id);
-+
-       return 0;
- }
-@@ -2063,7 +2154,8 @@ static void sfp_sm_module(struct sfp *sf
-                       break;
-               /* Report the module insertion to the upstream device */
--              err = sfp_module_insert(sfp->sfp_bus, &sfp->id);
-+              err = sfp_module_insert(sfp->sfp_bus, &sfp->id,
-+                                      sfp->quirk);
-               if (err < 0) {
-                       sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0);
-                       break;
---- a/drivers/net/phy/sfp.h
-+++ b/drivers/net/phy/sfp.h
-@@ -6,6 +6,12 @@
- struct sfp;
-+struct sfp_quirk {
-+      const char *vendor;
-+      const char *part;
-+      void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
-+};
-+
- struct sfp_socket_ops {
-       void (*attach)(struct sfp *sfp);
-       void (*detach)(struct sfp *sfp);
-@@ -23,7 +29,8 @@ int sfp_add_phy(struct sfp_bus *bus, str
- void sfp_remove_phy(struct sfp_bus *bus);
- void sfp_link_up(struct sfp_bus *bus);
- void sfp_link_down(struct sfp_bus *bus);
--int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id);
-+int sfp_module_insert(struct sfp_bus *bus, const struct sfp_eeprom_id *id,
-+                    const struct sfp_quirk *quirk);
- void sfp_module_remove(struct sfp_bus *bus);
- int sfp_module_start(struct sfp_bus *bus);
- void sfp_module_stop(struct sfp_bus *bus);
diff --git a/target/linux/generic/pending-5.15/771-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch b/target/linux/generic/pending-5.15/771-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch
deleted file mode 100644 (file)
index f285561..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-From 21fdd8281de3022aee35dd5bfccc892bd46529a3 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 26 Aug 2022 08:43:35 +0100
-Subject: [PATCH 2/6] net: sfp: move Alcatel Lucent 3FE46541AA fixup
-
-Add a new fixup mechanism to the SFP quirks, and use it for this
-module.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/phy/sfp.c | 14 +++++++++-----
- drivers/net/phy/sfp.h |  1 +
- 2 files changed, 10 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -310,6 +310,11 @@ static const struct of_device_id sfp_of_
- };
- MODULE_DEVICE_TABLE(of, sfp_of_match);
-+static void sfp_fixup_long_startup(struct sfp *sfp)
-+{
-+      sfp->module_t_start_up = T_START_UP_BAD_GPON;
-+}
-+
- static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
-                               unsigned long *modes)
- {
-@@ -340,6 +345,7 @@ static const struct sfp_quirk sfp_quirks
-               .vendor = "ALCATELLUCENT",
-               .part = "3FE46541AA",
-               .modes = sfp_quirk_2500basex,
-+              .fixup = sfp_fixup_long_startup,
-       }, {
-               // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
-               // NRZ in their EEPROM
-@@ -2029,11 +2035,7 @@ static int sfp_sm_mod_probe(struct sfp *
-       if (ret < 0)
-               return ret;
--      if (!memcmp(id.base.vendor_name, "ALCATELLUCENT   ", 16) &&
--          !memcmp(id.base.vendor_pn, "3FE46541AA      ", 16))
--              sfp->module_t_start_up = T_START_UP_BAD_GPON;
--      else
--              sfp->module_t_start_up = T_START_UP;
-+      sfp->module_t_start_up = T_START_UP;
-       if (!memcmp(id.base.vendor_name, "HUAWEI          ", 16) &&
-           !memcmp(id.base.vendor_pn, "MA5671A         ", 16))
-@@ -2042,6 +2044,8 @@ static int sfp_sm_mod_probe(struct sfp *
-               sfp->tx_fault_ignore = false;
-       sfp->quirk = sfp_lookup_quirk(&id);
-+      if (sfp->quirk && sfp->quirk->fixup)
-+              sfp->quirk->fixup(sfp);
-       return 0;
- }
---- a/drivers/net/phy/sfp.h
-+++ b/drivers/net/phy/sfp.h
-@@ -10,6 +10,7 @@ struct sfp_quirk {
-       const char *vendor;
-       const char *part;
-       void (*modes)(const struct sfp_eeprom_id *id, unsigned long *modes);
-+      void (*fixup)(struct sfp *sfp);
- };
- struct sfp_socket_ops {
diff --git a/target/linux/generic/pending-5.15/772-net-sfp-move-Huawei-MA5671A-fixup.patch b/target/linux/generic/pending-5.15/772-net-sfp-move-Huawei-MA5671A-fixup.patch
deleted file mode 100644 (file)
index dfd08af..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-From 4c9d8c654827ef42da702c5b6c3392e8ac0bc60a Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 26 Aug 2022 08:43:40 +0100
-Subject: [PATCH 3/6] net: sfp: move Huawei MA5671A fixup
-
-Move this module over to the new fixup mechanism.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/phy/sfp.c | 12 +++++++-----
- 1 file changed, 7 insertions(+), 5 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -315,6 +315,11 @@ static void sfp_fixup_long_startup(struc
-       sfp->module_t_start_up = T_START_UP_BAD_GPON;
- }
-+static void sfp_fixup_ignore_tx_fault(struct sfp *sfp)
-+{
-+      sfp->tx_fault_ignore = true;
-+}
-+
- static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
-                               unsigned long *modes)
- {
-@@ -352,6 +357,7 @@ static const struct sfp_quirk sfp_quirks
-               .vendor = "HUAWEI",
-               .part = "MA5671A",
-               .modes = sfp_quirk_2500basex,
-+              .fixup = sfp_fixup_ignore_tx_fault,
-       }, {
-               // Lantech 8330-262D-E can operate at 2500base-X, but
-               // incorrectly report 2500MBd NRZ in their EEPROM
-@@ -2037,11 +2043,7 @@ static int sfp_sm_mod_probe(struct sfp *
-       sfp->module_t_start_up = T_START_UP;
--      if (!memcmp(id.base.vendor_name, "HUAWEI          ", 16) &&
--          !memcmp(id.base.vendor_pn, "MA5671A         ", 16))
--              sfp->tx_fault_ignore = true;
--      else
--              sfp->tx_fault_ignore = false;
-+      sfp->tx_fault_ignore = false;
-       sfp->quirk = sfp_lookup_quirk(&id);
-       if (sfp->quirk && sfp->quirk->fixup)
diff --git a/target/linux/generic/pending-5.15/773-net-sfp-add-support-for-HALNy-GPON-SFP.patch b/target/linux/generic/pending-5.15/773-net-sfp-add-support-for-HALNy-GPON-SFP.patch
deleted file mode 100644 (file)
index 85c1d5b..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-From 43ac680124bc57951a6d0356b41498c2324388bf Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 26 Aug 2022 08:43:45 +0100
-Subject: [PATCH 4/6] net: sfp: add support for HALNy GPON SFP
-
-Add a quirk for the HALNy HL-GSFP module, which appears to have an
-inverted RX_LOS signal, and possibly uses TX_FAULT as an inverted
-host-link status signal. As we can't be certain about the modules
-use of TX_FAULT, we ignore it.
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/phy/sfp-bus.c |  2 +-
- drivers/net/phy/sfp.c     | 29 ++++++++++++++++++++++++++---
- 2 files changed, 27 insertions(+), 4 deletions(-)
-
---- a/drivers/net/phy/sfp-bus.c
-+++ b/drivers/net/phy/sfp-bus.c
-@@ -283,7 +283,7 @@ void sfp_parse_support(struct sfp_bus *b
-                       phylink_set(modes, 2500baseX_Full);
-       }
--      if (bus->sfp_quirk)
-+      if (bus->sfp_quirk && bus->sfp_quirk->modes)
-               bus->sfp_quirk->modes(id, modes);
-       linkmode_or(support, support, modes);
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -320,6 +320,23 @@ static void sfp_fixup_ignore_tx_fault(st
-       sfp->tx_fault_ignore = true;
- }
-+static void sfp_fixup_inverted_los(struct sfp *sfp)
-+{
-+      const __be16 los_inverted = cpu_to_be16(SFP_OPTIONS_LOS_INVERTED);
-+      const __be16 los_normal = cpu_to_be16(SFP_OPTIONS_LOS_NORMAL);
-+
-+      sfp->id.ext.options &= ~los_normal;
-+      sfp->id.ext.options |= los_inverted;
-+}
-+
-+static void sfp_fixup_halny_gsfp(struct sfp *sfp)
-+{
-+      /* LOS is inverted */
-+      sfp_fixup_inverted_los(sfp);
-+      /* TX fault might be inverted, but we don't know for certain. */
-+      sfp_fixup_ignore_tx_fault(sfp);
-+}
-+
- static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,
-                               unsigned long *modes)
- {
-@@ -352,6 +369,10 @@ static const struct sfp_quirk sfp_quirks
-               .modes = sfp_quirk_2500basex,
-               .fixup = sfp_fixup_long_startup,
-       }, {
-+              .vendor = "HALNy",
-+              .part = "HL-GSFP",
-+              .fixup = sfp_fixup_halny_gsfp,
-+      }, {
-               // Huawei MA5671A can operate at 2500base-X, but report 1.2GBd
-               // NRZ in their EEPROM
-               .vendor = "HUAWEI",
-@@ -368,16 +389,18 @@ static const struct sfp_quirk sfp_quirks
-               .vendor = "UBNT",
-               .part = "UF-INSTANT",
-               .modes = sfp_quirk_ubnt_uf_instant,
--      },
-+      }
- };
- static size_t sfp_strlen(const char *str, size_t maxlen)
- {
-       size_t size, i;
--      /* Trailing characters should be filled with space chars */
-+      /* Trailing characters should be filled with space chars, but
-+       * some manufacturers can't read SFF-8472 and use NUL.
-+       */
-       for (i = 0, size = 0; i < maxlen; i++)
--              if (str[i] != ' ')
-+              if (str[i] != ' ' && str[i] != '\0')
-                       size = i + 1;
-       return size;
diff --git a/target/linux/generic/pending-5.15/774--net-sfp-redo-soft-state-polling.patch b/target/linux/generic/pending-5.15/774--net-sfp-redo-soft-state-polling.patch
deleted file mode 100644 (file)
index 3aa51de..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From 9a84d699ddde0d4e272aa919ad8fd50271a3f932 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 26 Aug 2022 08:48:20 +0100
-Subject: [PATCH 5/6] net: sfp: redo soft state polling
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/phy/sfp.c | 35 ++++++++++++++++++++++++-----------
- 1 file changed, 24 insertions(+), 11 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -234,6 +234,7 @@ struct sfp {
-       bool need_poll;
-       struct mutex st_mutex;                  /* Protects state */
-+      unsigned int state_ignore_hw_mask;
-       unsigned int state_soft_mask;
-       unsigned int state;
-       struct delayed_work poll;
-@@ -623,17 +624,18 @@ static void sfp_soft_set_state(struct sf
- static void sfp_soft_start_poll(struct sfp *sfp)
- {
-       const struct sfp_eeprom_id *id = &sfp->id;
-+      unsigned int mask = 0;
-       sfp->state_soft_mask = 0;
--      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE &&
--          !sfp->gpio[GPIO_TX_DISABLE])
--              sfp->state_soft_mask |= SFP_F_TX_DISABLE;
--      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT &&
--          !sfp->gpio[GPIO_TX_FAULT])
--              sfp->state_soft_mask |= SFP_F_TX_FAULT;
--      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS &&
--          !sfp->gpio[GPIO_LOS])
--              sfp->state_soft_mask |= SFP_F_LOS;
-+      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_DISABLE)
-+              mask |= SFP_F_TX_DISABLE;
-+      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_TX_FAULT)
-+              mask |= SFP_F_TX_FAULT;
-+      if (id->ext.enhopts & SFP_ENHOPTS_SOFT_RX_LOS)
-+              mask |= SFP_F_LOS;
-+
-+      // Poll the soft state for hardware pins we want to ignore
-+      sfp->state_soft_mask = sfp->state_ignore_hw_mask & mask;
-       if (sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT) &&
-           !sfp->need_poll)
-@@ -647,10 +649,12 @@ static void sfp_soft_stop_poll(struct sf
- static unsigned int sfp_get_state(struct sfp *sfp)
- {
-+      unsigned int soft = sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT);
-       unsigned int state = sfp->get_state(sfp);
--      if (state & SFP_F_PRESENT &&
--          sfp->state_soft_mask & (SFP_F_LOS | SFP_F_TX_FAULT))
-+      state &= ~sfp->state_ignore_hw_mask;
-+
-+      if (state & SFP_F_PRESENT && soft)
-               state |= sfp_soft_get_state(sfp);
-       return state;
-@@ -2064,6 +2068,15 @@ static int sfp_sm_mod_probe(struct sfp *
-       if (ret < 0)
-               return ret;
-+      /* Initialise state bits to ignore from hardware */
-+      sfp->state_ignore_hw_mask = 0;
-+      if (!sfp->gpio[GPIO_TX_DISABLE])
-+              sfp->state_ignore_hw_mask |= SFP_F_TX_DISABLE;
-+      if (!sfp->gpio[GPIO_TX_FAULT])
-+              sfp->state_ignore_hw_mask |= SFP_F_TX_FAULT;
-+      if (!sfp->gpio[GPIO_LOS])
-+              sfp->state_ignore_hw_mask |= SFP_F_LOS;
-+
-       sfp->module_t_start_up = T_START_UP;
-       sfp->tx_fault_ignore = false;
diff --git a/target/linux/generic/pending-5.15/775-net-sfp-change-HALNy-to-ignore-hardware-pins.patch b/target/linux/generic/pending-5.15/775-net-sfp-change-HALNy-to-ignore-hardware-pins.patch
deleted file mode 100644 (file)
index 7aa29cd..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-From 32a59a1c5dc8f6fa755bab9a5f9751fdb66bb234 Mon Sep 17 00:00:00 2001
-From: "Russell King (Oracle)" <rmk+kernel@armlinux.org.uk>
-Date: Fri, 26 Aug 2022 08:48:25 +0100
-Subject: [PATCH 6/6] net: sfp: change HALNy to ignore hardware pins
-
-Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
----
- drivers/net/phy/sfp.c | 14 +-------------
- 1 file changed, 1 insertion(+), 13 deletions(-)
-
---- a/drivers/net/phy/sfp.c
-+++ b/drivers/net/phy/sfp.c
-@@ -321,21 +321,9 @@ static void sfp_fixup_ignore_tx_fault(st
-       sfp->tx_fault_ignore = true;
- }
--static void sfp_fixup_inverted_los(struct sfp *sfp)
--{
--      const __be16 los_inverted = cpu_to_be16(SFP_OPTIONS_LOS_INVERTED);
--      const __be16 los_normal = cpu_to_be16(SFP_OPTIONS_LOS_NORMAL);
--
--      sfp->id.ext.options &= ~los_normal;
--      sfp->id.ext.options |= los_inverted;
--}
--
- static void sfp_fixup_halny_gsfp(struct sfp *sfp)
- {
--      /* LOS is inverted */
--      sfp_fixup_inverted_los(sfp);
--      /* TX fault might be inverted, but we don't know for certain. */
--      sfp_fixup_ignore_tx_fault(sfp);
-+      sfp->state_ignore_hw_mask |= SFP_F_TX_FAULT | SFP_F_LOS;
- }
- static void sfp_quirk_2500basex(const struct sfp_eeprom_id *id,