--- /dev/null
+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);
--- /dev/null
+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 {
--- /dev/null
+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)
--- /dev/null
+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);
+
+ bitmap_or(support, support, modes, __ETHTOOL_LINK_MODE_MASK_NBITS);
+--- 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;
--- /dev/null
+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;
--- /dev/null
+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,