From: Christian Marangi Date: Fri, 21 Oct 2022 21:08:54 +0000 (+0200) Subject: generic: 5.15: move sfp HALNy patch from pending to backport X-Git-Tag: v23.05.0-rc1~1976 X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=d7a6e171c048d07644e3a39e8cefabeb0be06d8d;p=openwrt%2Fopenwrt.git generic: 5.15: move sfp HALNy patch from pending to backport 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 --- 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 index 0000000000..7bb6530266 --- /dev/null +++ b/target/linux/generic/backport-5.15/782-v6.1-net-dsa-mt7530-add-support-for-in-band-link-status.patch @@ -0,0 +1,130 @@ +From e19de30d20809af3221ef8a2648b8a8a52e02d90 Mon Sep 17 00:00:00 2001 +From: Daniel Golle +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 +Signed-off-by: David S. Miller +--- + 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 index 0000000000..6f69b7ddfe --- /dev/null +++ b/target/linux/generic/backport-5.15/783-v6.1-net-sfp-re-implement-soft-state-polling-setup.patch @@ -0,0 +1,98 @@ +From 8475c4b70b040f9d8cbc308100f2c4d865f810b3 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +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) +Signed-off-by: Jakub Kicinski +--- + 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 index 0000000000..e5f8031636 --- /dev/null +++ b/target/linux/generic/backport-5.15/784-v6.1-net-sfp-move-quirk-handling-into-sfp.c.patch @@ -0,0 +1,291 @@ +From 23571c7b96437483d28a990c906cc81f5f66374e Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +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) +Signed-off-by: Jakub Kicinski +--- + 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 index 0000000000..aa3112e585 --- /dev/null +++ b/target/linux/generic/backport-5.15/785-v6.1-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch @@ -0,0 +1,69 @@ +From 275416754e9a262c97a1ad6f806a4bc6e0464aa2 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +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) +Signed-off-by: Jakub Kicinski +--- + 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 index 0000000000..14b0f9b8c3 --- /dev/null +++ b/target/linux/generic/backport-5.15/786-v6.1-net-sfp-move-Huawei-MA5671A-fixup.patch @@ -0,0 +1,48 @@ +From 5029be761161374a3624aa7b4670174c35449bf5 Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +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) +Signed-off-by: Jakub Kicinski +--- + 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 index 0000000000..0c65de5ab8 --- /dev/null +++ b/target/linux/generic/backport-5.15/787-v6.1-net-sfp-add-support-for-HALNy-GPON-SFP.patch @@ -0,0 +1,79 @@ +From 73472c830eae5fce2107f7f086f1e6827d215caf Mon Sep 17 00:00:00 2001 +From: "Russell King (Oracle)" +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) +Signed-off-by: Jakub Kicinski +--- + 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; diff --git a/target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch b/target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch index d9835f8896..83b2c304e2 100644 --- a/target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch +++ b/target/linux/generic/hack-5.15/790-SFP-GE-T-ignore-TX_FAULT.patch @@ -26,7 +26,7 @@ Signed-off-by: Daniel Golle --- 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 // 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 } 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 index 8196f19540..0000000000 --- a/target/linux/generic/pending-5.15/731-net-dsa-mt7530-add-support-for-in-band-link-status.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 8e18c5fef75debfae3531fbd6901f3bf317d91ed Mon Sep 17 00:00:00 2001 -From: Daniel Golle -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 , - Sean Wang , - Landen Chao , - DENG Qingfang , - Andrew Lunn , - Vivien Didelot , - Florian Fainelli , - Vladimir Oltean , - David S. Miller , - Eric Dumazet , - Jakub Kicinski , - Paolo Abeni , - Matthias Brugger , - Philipp Zabel - -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 ---- - 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 index 8d43ccb3e9..0000000000 --- a/target/linux/generic/pending-5.15/770-net-sfp-move-quirk-handling-into-sfp.c.patch +++ /dev/null @@ -1,290 +0,0 @@ -From a4648a1957cd79bc389538aa0472db39a56e3df6 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -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) ---- - 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 index f285561ebb..0000000000 --- a/target/linux/generic/pending-5.15/771-net-sfp-move-Alcatel-Lucent-3FE46541AA-fixup.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 21fdd8281de3022aee35dd5bfccc892bd46529a3 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -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) ---- - 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 index dfd08af671..0000000000 --- a/target/linux/generic/pending-5.15/772-net-sfp-move-Huawei-MA5671A-fixup.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 4c9d8c654827ef42da702c5b6c3392e8ac0bc60a Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -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) ---- - 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 index 85c1d5b203..0000000000 --- a/target/linux/generic/pending-5.15/773-net-sfp-add-support-for-HALNy-GPON-SFP.patch +++ /dev/null @@ -1,86 +0,0 @@ -From 43ac680124bc57951a6d0356b41498c2324388bf Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -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) ---- - 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 index 3aa51deb3c..0000000000 --- a/target/linux/generic/pending-5.15/774--net-sfp-redo-soft-state-polling.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 9a84d699ddde0d4e272aa919ad8fd50271a3f932 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -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) ---- - 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 index 7aa29cd722..0000000000 --- a/target/linux/generic/pending-5.15/775-net-sfp-change-HALNy-to-ignore-hardware-pins.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 32a59a1c5dc8f6fa755bab9a5f9751fdb66bb234 Mon Sep 17 00:00:00 2001 -From: "Russell King (Oracle)" -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) ---- - 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,