[openwrt/openwrt] mvebu: SFP backports for GPON modules

LEDE Commits lede-commits at lists.infradead.org
Sat Mar 26 13:26:37 PDT 2022


chunkeey pushed a commit to openwrt/openwrt.git, branch openwrt-21.02:
https://git.openwrt.org/0e5350db439259347db2ab689325915864c75e06

commit 0e5350db439259347db2ab689325915864c75e06
Author: Marek Behún <marek.behun at nic.cz>
AuthorDate: Sat Jan 8 19:56:02 2022 +0100

    mvebu: SFP backports for GPON modules
    
    This backports the following upstream Linux patches
      net: sfp: add mode quirk for GPON module Ubiquiti U-Fiber Instant
      net: sfp: relax bitrate-derived mode check
      net: sfp: cope with SFPs that set both LOS normal and LOS inverted
    for 5.4 for mvebu platform.
    
    This fixes GPON modules:
      Ubiquiti U-Fiber Instant SFP GPON
      VSOL V2801F
      CarlitoxxPro CPGOS03-0490 v2.0
    
    Signed-off-by: Marek Behún <marek.behun at nic.cz>
---
 ...e-with-SFPs-that-set-both-LOS-normal-and-.patch | 94 ++++++++++++++++++++++
 ...L-V2801F-CarlitoxxPro-CPGOS03-0490-v2.0-w.patch |  6 +-
 ...-workaround-for-Realtek-RTL8672-and-RTL96.patch |  8 +-
 ...net-avoid-tx-fault-with-Nokia-GPON-module.patch | 10 +--
 ...ove-incomplete-100BASE-FX-and-100BASE-LX-.patch |  2 +-
 ...-module-start-stop-upstream-notifications.patch |  4 +-
 ...53-net-sfp-add-support-for-Clause-45-PHYs.patch |  4 +-
 .../pending-5.4/754-net-sfp-fix-unbind.patch       |  2 +-
 .../pending-5.4/755-net-sfp-fix-hwmon.patch        |  4 +-
 ...-a-definition-for-the-fault-recovery-atte.patch |  6 +-
 .../757-net-sfp-rename-sm_retries.patch            |  8 +-
 .../758-net-sfp-error-handling-for-phy-probe.patch |  4 +-
 .../759-net-sfp-re-attempt-probing-for-phy.patch   |  4 +-
 ...fp-add-mode-quirk-Ubiquiti-UFiber-Instant.patch | 93 +++++++++++++++++++++
 .../772-net-sfp-relax-bitrate-devided-check.patch  | 44 ++++++++++
 15 files changed, 262 insertions(+), 31 deletions(-)

diff --git a/target/linux/generic/backport-5.4/768-net-sfp-cope-with-SFPs-that-set-both-LOS-normal-and-.patch b/target/linux/generic/backport-5.4/768-net-sfp-cope-with-SFPs-that-set-both-LOS-normal-and-.patch
new file mode 100644
index 0000000000..fbbaae1d2b
--- /dev/null
+++ b/target/linux/generic/backport-5.4/768-net-sfp-cope-with-SFPs-that-set-both-LOS-normal-and-.patch
@@ -0,0 +1,94 @@
+From da5bc1832b325b15e4cca3b63861ecf48be870ef Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel at armlinux.org.uk>
+Date: Sun, 10 Jan 2021 10:58:32 +0000
+Subject: [PATCH] net: sfp: cope with SFPs that set both LOS normal and LOS
+ inverted
+
+The SFP MSA defines two option bits in byte 65 to indicate how the
+Rx_LOS signal on SFP pin 8 behaves:
+
+bit 2 - Loss of Signal implemented, signal inverted from standard
+        definition in SFP MSA (often called "Signal Detect").
+bit 1 - Loss of Signal implemented, signal as defined in SFP MSA
+        (often called "Rx_LOS").
+
+Clearly, setting both bits results in a meaningless situation: it would
+mean that LOS is implemented in both the normal sense (1 = signal loss)
+and inverted sense (0 = signal loss).
+
+Unfortunately, there are modules out there which set both bits, which
+will be initially interpret as "inverted" sense, and then, if the LOS
+signal changes state, we will toggle between LINK_UP and WAIT_LOS
+states.
+
+Change our LOS handling to give well defined behaviour: only interpret
+these bits as meaningful if exactly one is set, otherwise treat it as
+if LOS is not implemented.
+
+Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Link: https://lore.kernel.org/r/E1kyYQa-0004iR-CU@rmk-PC.armlinux.org.uk
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/sfp.c | 36 ++++++++++++++++++++++--------------
+ 1 file changed, 22 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -1430,15 +1430,19 @@ static void sfp_sm_link_down(struct sfp
+ 
+ static void sfp_sm_link_check_los(struct sfp *sfp)
+ {
+-	unsigned int los = sfp->state & SFP_F_LOS;
++	const __be16 los_inverted = cpu_to_be16(SFP_OPTIONS_LOS_INVERTED);
++	const __be16 los_normal = cpu_to_be16(SFP_OPTIONS_LOS_NORMAL);
++	__be16 los_options = sfp->id.ext.options & (los_inverted | los_normal);
++	bool los = false;
+ 
+ 	/* If neither SFP_OPTIONS_LOS_INVERTED nor SFP_OPTIONS_LOS_NORMAL
+-	 * are set, we assume that no LOS signal is available.
++	 * are set, we assume that no LOS signal is available. If both are
++	 * set, we assume LOS is not implemented (and is meaningless.)
+ 	 */
+-	if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_INVERTED))
+-		los ^= SFP_F_LOS;
+-	else if (!(sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_NORMAL)))
+-		los = 0;
++	if (los_options == los_inverted)
++		los = !(sfp->state & SFP_F_LOS);
++	else if (los_options == los_normal)
++		los = !!(sfp->state & SFP_F_LOS);
+ 
+ 	if (los)
+ 		sfp_sm_next(sfp, SFP_S_WAIT_LOS, 0);
+@@ -1448,18 +1452,22 @@ static void sfp_sm_link_check_los(struct
+ 
+ static bool sfp_los_event_active(struct sfp *sfp, unsigned int event)
+ {
+-	return (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_INVERTED) &&
+-		event == SFP_E_LOS_LOW) ||
+-	       (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_NORMAL) &&
+-		event == SFP_E_LOS_HIGH);
++	const __be16 los_inverted = cpu_to_be16(SFP_OPTIONS_LOS_INVERTED);
++	const __be16 los_normal = cpu_to_be16(SFP_OPTIONS_LOS_NORMAL);
++	__be16 los_options = sfp->id.ext.options & (los_inverted | los_normal);
++
++	return (los_options == los_inverted && event == SFP_E_LOS_LOW) ||
++	       (los_options == los_normal && event == SFP_E_LOS_HIGH);
+ }
+ 
+ static bool sfp_los_event_inactive(struct sfp *sfp, unsigned int event)
+ {
+-	return (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_INVERTED) &&
+-		event == SFP_E_LOS_HIGH) ||
+-	       (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_LOS_NORMAL) &&
+-		event == SFP_E_LOS_LOW);
++	const __be16 los_inverted = cpu_to_be16(SFP_OPTIONS_LOS_INVERTED);
++	const __be16 los_normal = cpu_to_be16(SFP_OPTIONS_LOS_NORMAL);
++	__be16 los_options = sfp->id.ext.options & (los_inverted | los_normal);
++
++	return (los_options == los_inverted && event == SFP_E_LOS_HIGH) ||
++	       (los_options == los_normal && event == SFP_E_LOS_LOW);
+ }
+ 
+ static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
diff --git a/target/linux/generic/backport-5.4/852-v5.10-0001-net-sfp-VSOL-V2801F-CarlitoxxPro-CPGOS03-0490-v2.0-w.patch b/target/linux/generic/backport-5.4/852-v5.10-0001-net-sfp-VSOL-V2801F-CarlitoxxPro-CPGOS03-0490-v2.0-w.patch
index 1901054a10..39f4b273ae 100644
--- a/target/linux/generic/backport-5.4/852-v5.10-0001-net-sfp-VSOL-V2801F-CarlitoxxPro-CPGOS03-0490-v2.0-w.patch
+++ b/target/linux/generic/backport-5.4/852-v5.10-0001-net-sfp-VSOL-V2801F-CarlitoxxPro-CPGOS03-0490-v2.0-w.patch
@@ -68,7 +68,7 @@ Signed-off-by: David S. Miller <davem at davemloft.net>
  
  		msgs[1].len = this_len;
  
-@@ -1569,6 +1579,28 @@ static int sfp_sm_mod_hpower(struct sfp
+@@ -1577,6 +1587,28 @@ static int sfp_sm_mod_hpower(struct sfp
  	return 0;
  }
  
@@ -97,7 +97,7 @@ Signed-off-by: David S. Miller <davem at davemloft.net>
  static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
  {
  	/* SFP module inserted - read I2C data */
-@@ -1577,14 +1609,20 @@ static int sfp_sm_mod_probe(struct sfp *
+@@ -1585,14 +1617,20 @@ static int sfp_sm_mod_probe(struct sfp *
  	u8 check;
  	int ret;
  
@@ -120,7 +120,7 @@ Signed-off-by: David S. Miller <davem at davemloft.net>
  		dev_err(sfp->dev, "EEPROM short read: %d\n", ret);
  		return -EAGAIN;
  	}
-@@ -1612,6 +1650,21 @@ static int sfp_sm_mod_probe(struct sfp *
+@@ -1620,6 +1658,21 @@ static int sfp_sm_mod_probe(struct sfp *
  		}
  	}
  
diff --git a/target/linux/generic/backport-5.4/852-v5.10-0002-net-sfp-add-workaround-for-Realtek-RTL8672-and-RTL96.patch b/target/linux/generic/backport-5.4/852-v5.10-0002-net-sfp-add-workaround-for-Realtek-RTL8672-and-RTL96.patch
index 27ae97cee7..8c95284280 100644
--- a/target/linux/generic/backport-5.4/852-v5.10-0002-net-sfp-add-workaround-for-Realtek-RTL8672-and-RTL96.patch
+++ b/target/linux/generic/backport-5.4/852-v5.10-0002-net-sfp-add-workaround-for-Realtek-RTL8672-and-RTL96.patch
@@ -102,7 +102,7 @@ Signed-off-by: Jakub Kicinski <kuba at kernel.org>
  	err = sfp_read(sfp, true, 0, &sfp->diag, sizeof(sfp->diag));
  	if (err < 0) {
  		if (sfp->hwmon_tries--) {
-@@ -1579,26 +1585,30 @@ static int sfp_sm_mod_hpower(struct sfp
+@@ -1587,26 +1593,30 @@ static int sfp_sm_mod_hpower(struct sfp
  	return 0;
  }
  
@@ -149,7 +149,7 @@ Signed-off-by: Jakub Kicinski <kuba at kernel.org>
  }
  
  static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
-@@ -1609,11 +1619,11 @@ static int sfp_sm_mod_probe(struct sfp *
+@@ -1617,11 +1627,11 @@ static int sfp_sm_mod_probe(struct sfp *
  	u8 check;
  	int ret;
  
@@ -165,7 +165,7 @@ Signed-off-by: Jakub Kicinski <kuba at kernel.org>
  
  	ret = sfp_read(sfp, false, 0, &id.base, sizeof(id.base));
  	if (ret < 0) {
-@@ -1627,6 +1637,33 @@ static int sfp_sm_mod_probe(struct sfp *
+@@ -1635,6 +1645,33 @@ static int sfp_sm_mod_probe(struct sfp *
  		return -EAGAIN;
  	}
  
@@ -199,7 +199,7 @@ Signed-off-by: Jakub Kicinski <kuba at kernel.org>
  	/* Cotsworks do not seem to update the checksums when they
  	 * do the final programming with the final module part number,
  	 * serial number and date code.
-@@ -1650,9 +1687,6 @@ static int sfp_sm_mod_probe(struct sfp *
+@@ -1658,9 +1695,6 @@ static int sfp_sm_mod_probe(struct sfp *
  		}
  	}
  
diff --git a/target/linux/generic/pending-5.4/739-net-avoid-tx-fault-with-Nokia-GPON-module.patch b/target/linux/generic/pending-5.4/739-net-avoid-tx-fault-with-Nokia-GPON-module.patch
index 6648d10c81..4c5f99acc5 100644
--- a/target/linux/generic/pending-5.4/739-net-avoid-tx-fault-with-Nokia-GPON-module.patch
+++ b/target/linux/generic/pending-5.4/739-net-avoid-tx-fault-with-Nokia-GPON-module.patch
@@ -47,7 +47,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  
  #if IS_ENABLED(CONFIG_HWMON)
  	struct sfp_diag diag;
-@@ -1742,6 +1753,12 @@ static int sfp_sm_mod_probe(struct sfp *
+@@ -1750,6 +1761,12 @@ static int sfp_sm_mod_probe(struct sfp *
  	if (ret < 0)
  		return ret;
  
@@ -60,7 +60,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  	return 0;
  }
  
-@@ -1947,11 +1964,12 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -1955,11 +1972,12 @@ static void sfp_sm_main(struct sfp *sfp,
  			break;
  
  		if (sfp->state & SFP_F_TX_FAULT) {
@@ -77,7 +77,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  			if (timeout > T_WAIT)
  				timeout -= T_WAIT;
  			else
-@@ -1968,8 +1986,8 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -1976,8 +1994,8 @@ static void sfp_sm_main(struct sfp *sfp,
  
  	case SFP_S_INIT:
  		if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) {
@@ -88,7 +88,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  			 */
  			sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
  				     sfp->sm_retries == 5);
-@@ -1988,7 +2006,7 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -1996,7 +2014,7 @@ static void sfp_sm_main(struct sfp *sfp,
  	case SFP_S_INIT_TX_FAULT:
  		if (event == SFP_E_TIMEOUT) {
  			sfp_module_tx_fault_reset(sfp);
@@ -97,7 +97,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  		}
  		break;
  
-@@ -2012,7 +2030,7 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2020,7 +2038,7 @@ static void sfp_sm_main(struct sfp *sfp,
  	case SFP_S_TX_FAULT:
  		if (event == SFP_E_TIMEOUT) {
  			sfp_module_tx_fault_reset(sfp);
diff --git a/target/linux/generic/pending-5.4/740-net-sfp-remove-incomplete-100BASE-FX-and-100BASE-LX-.patch b/target/linux/generic/pending-5.4/740-net-sfp-remove-incomplete-100BASE-FX-and-100BASE-LX-.patch
index 1abc34e94b..e439d19517 100644
--- a/target/linux/generic/pending-5.4/740-net-sfp-remove-incomplete-100BASE-FX-and-100BASE-LX-.patch
+++ b/target/linux/generic/pending-5.4/740-net-sfp-remove-incomplete-100BASE-FX-and-100BASE-LX-.patch
@@ -30,7 +30,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  	if (phylink_test(link_modes, 1000baseX_Full))
 --- a/drivers/net/phy/sfp.c
 +++ b/drivers/net/phy/sfp.c
-@@ -1505,18 +1505,7 @@ static void sfp_sm_fault(struct sfp *sfp
+@@ -1513,18 +1513,7 @@ static void sfp_sm_fault(struct sfp *sfp
  
  static void sfp_sm_probe_for_phy(struct sfp *sfp)
  {
diff --git a/target/linux/generic/pending-5.4/743-net-sfp-add-module-start-stop-upstream-notifications.patch b/target/linux/generic/pending-5.4/743-net-sfp-add-module-start-stop-upstream-notifications.patch
index ba1b5b5822..50200135dd 100644
--- a/target/linux/generic/pending-5.4/743-net-sfp-add-module-start-stop-upstream-notifications.patch
+++ b/target/linux/generic/pending-5.4/743-net-sfp-add-module-start-stop-upstream-notifications.patch
@@ -78,7 +78,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  	[SFP_S_WAIT] = "wait",
  	[SFP_S_INIT] = "init",
  	[SFP_S_INIT_TX_FAULT] = "init_tx_fault",
-@@ -1918,6 +1920,8 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -1926,6 +1928,8 @@ static void sfp_sm_main(struct sfp *sfp,
  		if (sfp->sm_state == SFP_S_LINK_UP &&
  		    sfp->sm_dev_state == SFP_DEV_UP)
  			sfp_sm_link_down(sfp);
@@ -87,7 +87,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  		if (sfp->mod_phy)
  			sfp_sm_phy_detach(sfp);
  		sfp_module_tx_disable(sfp);
-@@ -1985,6 +1989,10 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -1993,6 +1997,10 @@ static void sfp_sm_main(struct sfp *sfp,
  			 * clear.  Probe for the PHY and check the LOS state.
  			 */
  			sfp_sm_probe_for_phy(sfp);
diff --git a/target/linux/generic/pending-5.4/753-net-sfp-add-support-for-Clause-45-PHYs.patch b/target/linux/generic/pending-5.4/753-net-sfp-add-support-for-Clause-45-PHYs.patch
index dcd1ba7ef3..f7c4bc1105 100644
--- a/target/linux/generic/pending-5.4/753-net-sfp-add-support-for-Clause-45-PHYs.patch
+++ b/target/linux/generic/pending-5.4/753-net-sfp-add-support-for-Clause-45-PHYs.patch
@@ -43,7 +43,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  	err = sfp_add_phy(sfp->sfp_bus, phy);
  	if (err) {
  		phy_device_remove(phy);
-@@ -1503,10 +1510,32 @@ static void sfp_sm_fault(struct sfp *sfp
+@@ -1511,10 +1518,32 @@ static void sfp_sm_fault(struct sfp *sfp
  	}
  }
  
@@ -78,7 +78,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  }
  
  static int sfp_module_parse_power(struct sfp *sfp)
-@@ -1566,6 +1595,13 @@ static int sfp_sm_mod_hpower(struct sfp
+@@ -1574,6 +1603,13 @@ static int sfp_sm_mod_hpower(struct sfp
  		return -EAGAIN;
  	}
  
diff --git a/target/linux/generic/pending-5.4/754-net-sfp-fix-unbind.patch b/target/linux/generic/pending-5.4/754-net-sfp-fix-unbind.patch
index c31922e021..6872973385 100644
--- a/target/linux/generic/pending-5.4/754-net-sfp-fix-unbind.patch
+++ b/target/linux/generic/pending-5.4/754-net-sfp-fix-unbind.patch
@@ -15,7 +15,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
 
 --- a/drivers/net/phy/sfp.c
 +++ b/drivers/net/phy/sfp.c
-@@ -2431,6 +2431,10 @@ static int sfp_remove(struct platform_de
+@@ -2439,6 +2439,10 @@ static int sfp_remove(struct platform_de
  
  	sfp_unregister_socket(sfp->sfp_bus);
  
diff --git a/target/linux/generic/pending-5.4/755-net-sfp-fix-hwmon.patch b/target/linux/generic/pending-5.4/755-net-sfp-fix-hwmon.patch
index a18e4801a2..be3b19b0ec 100644
--- a/target/linux/generic/pending-5.4/755-net-sfp-fix-hwmon.patch
+++ b/target/linux/generic/pending-5.4/755-net-sfp-fix-hwmon.patch
@@ -15,7 +15,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
 
 --- a/drivers/net/phy/sfp.c
 +++ b/drivers/net/phy/sfp.c
-@@ -1883,6 +1883,10 @@ static void sfp_sm_module(struct sfp *sf
+@@ -1891,6 +1891,10 @@ static void sfp_sm_module(struct sfp *sf
  			break;
  		}
  
@@ -26,7 +26,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  		sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0);
  		/* fall through */
  	case SFP_MOD_WAITDEV:
-@@ -1932,15 +1936,6 @@ static void sfp_sm_module(struct sfp *sf
+@@ -1940,15 +1944,6 @@ static void sfp_sm_module(struct sfp *sf
  	case SFP_MOD_ERROR:
  		break;
  	}
diff --git a/target/linux/generic/pending-5.4/756-net-sfp-use-a-definition-for-the-fault-recovery-atte.patch b/target/linux/generic/pending-5.4/756-net-sfp-use-a-definition-for-the-fault-recovery-atte.patch
index ba4f8c40c4..c8e3cf5e4f 100644
--- a/target/linux/generic/pending-5.4/756-net-sfp-use-a-definition-for-the-fault-recovery-atte.patch
+++ b/target/linux/generic/pending-5.4/756-net-sfp-use-a-definition-for-the-fault-recovery-atte.patch
@@ -26,7 +26,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  /* SFP module presence detection is poor: the three MOD DEF signals are
   * the same length on the PCB, which means it's possible for MOD DEF 0 to
   * connect before the I2C bus on MOD DEF 1/2.
-@@ -1972,7 +1980,7 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -1980,7 +1988,7 @@ static void sfp_sm_main(struct sfp *sfp,
  		sfp_module_tx_enable(sfp);
  
  		/* Initialise the fault clearance retries */
@@ -35,7 +35,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  
  		/* We need to check the TX_FAULT state, which is not defined
  		 * while TX_DISABLE is asserted. The earliest we want to do
-@@ -2012,7 +2020,7 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2020,7 +2028,7 @@ 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,
@@ -44,7 +44,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  		} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
  	init_done:	/* TX_FAULT deasserted or we timed out with TX_FAULT
  			 * clear.  Probe for the PHY and check the LOS state.
-@@ -2025,7 +2033,7 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2033,7 +2041,7 @@ static void sfp_sm_main(struct sfp *sfp,
  			sfp_sm_link_check_los(sfp);
  
  			/* Reset the fault retry count */
diff --git a/target/linux/generic/pending-5.4/757-net-sfp-rename-sm_retries.patch b/target/linux/generic/pending-5.4/757-net-sfp-rename-sm_retries.patch
index 13f3b6ccff..a8d3f32443 100644
--- a/target/linux/generic/pending-5.4/757-net-sfp-rename-sm_retries.patch
+++ b/target/linux/generic/pending-5.4/757-net-sfp-rename-sm_retries.patch
@@ -22,7 +22,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  
  	struct sfp_eeprom_id id;
  	unsigned int module_power_mW;
-@@ -1506,7 +1506,7 @@ static bool sfp_los_event_inactive(struc
+@@ -1514,7 +1514,7 @@ static bool sfp_los_event_inactive(struc
  
  static void sfp_sm_fault(struct sfp *sfp, unsigned int next_state, bool warn)
  {
@@ -31,7 +31,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  		dev_err(sfp->dev,
  			"module persistently indicates fault, disabling\n");
  		sfp_sm_next(sfp, SFP_S_TX_DISABLE, 0);
-@@ -1980,7 +1980,7 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -1988,7 +1988,7 @@ static void sfp_sm_main(struct sfp *sfp,
  		sfp_module_tx_enable(sfp);
  
  		/* Initialise the fault clearance retries */
@@ -40,7 +40,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  
  		/* We need to check the TX_FAULT state, which is not defined
  		 * while TX_DISABLE is asserted. The earliest we want to do
-@@ -2020,7 +2020,7 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2028,7 +2028,7 @@ 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,
@@ -49,7 +49,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  		} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
  	init_done:	/* TX_FAULT deasserted or we timed out with TX_FAULT
  			 * clear.  Probe for the PHY and check the LOS state.
-@@ -2033,7 +2033,7 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2041,7 +2041,7 @@ static void sfp_sm_main(struct sfp *sfp,
  			sfp_sm_link_check_los(sfp);
  
  			/* Reset the fault retry count */
diff --git a/target/linux/generic/pending-5.4/758-net-sfp-error-handling-for-phy-probe.patch b/target/linux/generic/pending-5.4/758-net-sfp-error-handling-for-phy-probe.patch
index dfa772dc72..5964ed5c5f 100644
--- a/target/linux/generic/pending-5.4/758-net-sfp-error-handling-for-phy-probe.patch
+++ b/target/linux/generic/pending-5.4/758-net-sfp-error-handling-for-phy-probe.patch
@@ -55,7 +55,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  }
  
  static void sfp_sm_link_up(struct sfp *sfp)
-@@ -1529,21 +1531,24 @@ static void sfp_sm_fault(struct sfp *sfp
+@@ -1537,21 +1539,24 @@ static void sfp_sm_fault(struct sfp *sfp
   * Clause 45 copper SFP+ modules (10G) appear to switch their interface
   * mode according to the negotiated line speed.
   */
@@ -83,7 +83,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  }
  
  static int sfp_module_parse_power(struct sfp *sfp)
-@@ -2025,7 +2030,10 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2033,7 +2038,10 @@ static void sfp_sm_main(struct sfp *sfp,
  	init_done:	/* TX_FAULT deasserted or we timed out with TX_FAULT
  			 * clear.  Probe for the PHY and check the LOS state.
  			 */
diff --git a/target/linux/generic/pending-5.4/759-net-sfp-re-attempt-probing-for-phy.patch b/target/linux/generic/pending-5.4/759-net-sfp-re-attempt-probing-for-phy.patch
index aebb6b0398..27e2187398 100644
--- a/target/linux/generic/pending-5.4/759-net-sfp-re-attempt-probing-for-phy.patch
+++ b/target/linux/generic/pending-5.4/759-net-sfp-re-attempt-probing-for-phy.patch
@@ -69,7 +69,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  	if (IS_ERR(phy)) {
  		dev_err(sfp->dev, "mdiobus scan returned %ld\n", PTR_ERR(phy));
  		return PTR_ERR(phy);
-@@ -1954,6 +1961,7 @@ static void sfp_sm_module(struct sfp *sf
+@@ -1962,6 +1969,7 @@ static void sfp_sm_module(struct sfp *sf
  static void sfp_sm_main(struct sfp *sfp, unsigned int event)
  {
  	unsigned long timeout;
@@ -77,7 +77,7 @@ Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
  
  	/* Some events are global */
  	if (sfp->sm_state != SFP_S_DOWN &&
-@@ -2027,22 +2035,39 @@ static void sfp_sm_main(struct sfp *sfp,
+@@ -2035,22 +2043,39 @@ static void sfp_sm_main(struct sfp *sfp,
  			sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
  				     sfp->sm_fault_retries == N_FAULT_INIT);
  		} else if (event == SFP_E_TIMEOUT || event == SFP_E_TX_CLEAR) {
diff --git a/target/linux/generic/pending-5.4/771-net-sfp-add-mode-quirk-Ubiquiti-UFiber-Instant.patch b/target/linux/generic/pending-5.4/771-net-sfp-add-mode-quirk-Ubiquiti-UFiber-Instant.patch
new file mode 100644
index 0000000000..e48b474472
--- /dev/null
+++ b/target/linux/generic/pending-5.4/771-net-sfp-add-mode-quirk-Ubiquiti-UFiber-Instant.patch
@@ -0,0 +1,93 @@
+From f0b4f847673299577c29b71d3f3acd3c313d81b7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Pali=20Roh=C3=A1r?= <pali at kernel.org>
+Date: Mon, 25 Jan 2021 16:02:28 +0100
+Subject: net: sfp: add mode quirk for GPON module Ubiquiti U-Fiber Instant
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The Ubiquiti U-Fiber Instant SFP GPON module has nonsensical information
+stored in its EEPROM. It claims to support all transceiver types including
+10G Ethernet. Clear all claimed modes and set only 1000baseX_Full, which is
+the only one supported.
+
+This module has also phys_id set to SFF, and the SFP subsystem currently
+does not allow to use SFP modules detected as SFFs. Add exception for this
+module so it can be detected as supported.
+
+This change finally allows to detect and use SFP GPON module Ubiquiti
+U-Fiber Instant on Linux system.
+
+EEPROM content of this SFP module is (where XX is serial number):
+
+00: 02 04 0b ff ff ff ff ff ff ff ff 03 0c 00 14 c8    ???........??.??
+10: 00 00 00 00 55 42 4e 54 20 20 20 20 20 20 20 20    ....UBNT
+20: 20 20 20 20 00 18 e8 29 55 46 2d 49 4e 53 54 41        .??)UF-INSTA
+30: 4e 54 20 20 20 20 20 20 34 20 20 20 05 1e 00 36    NT      4   ??.6
+40: 00 06 00 00 55 42 4e 54 XX XX XX XX XX XX XX XX    .?..UBNTXXXXXXXX
+50: 20 20 20 20 31 34 30 31 32 33 20 20 60 80 02 41        140123  `??A
+
+Signed-off-by: Pali Rohár <pali at kernel.org>
+Signed-off-by: Jakub Kicinski <kuba at kernel.org>
+---
+ drivers/net/phy/sfp-bus.c | 15 +++++++++++++++
+ drivers/net/phy/sfp.c     | 17 +++++++++++++++--
+ 2 files changed, 30 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/phy/sfp-bus.c
++++ b/drivers/net/phy/sfp-bus.c
+@@ -44,6 +44,17 @@ static void sfp_quirk_2500basex(const st
+ 	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
+@@ -63,6 +74,10 @@ static const struct sfp_quirk sfp_quirks
+ 		.vendor = "HUAWEI",
+ 		.part = "MA5671A",
+ 		.modes = sfp_quirk_2500basex,
++	}, {
++		.vendor = "UBNT",
++		.part = "UF-INSTANT",
++		.modes = sfp_quirk_ubnt_uf_instant,
+ 	},
+ };
+ 
+--- a/drivers/net/phy/sfp.c
++++ b/drivers/net/phy/sfp.c
+@@ -273,8 +273,21 @@ static const struct sff_data sff_data =
+ 
+ static bool sfp_module_supported(const struct sfp_eeprom_id *id)
+ {
+-	return id->base.phys_id == SFF8024_ID_SFP &&
+-	       id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP;
++	if (id->base.phys_id == SFF8024_ID_SFP &&
++	    id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP)
++		return true;
++
++	/* SFP GPON module Ubiquiti U-Fiber Instant has in its EEPROM stored
++	 * phys id SFF instead of SFP. Therefore mark this module explicitly
++	 * as supported based on vendor name and pn match.
++	 */
++	if (id->base.phys_id == SFF8024_ID_SFF_8472 &&
++	    id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP &&
++	    !memcmp(id->base.vendor_name, "UBNT            ", 16) &&
++	    !memcmp(id->base.vendor_pn, "UF-INSTANT      ", 16))
++		return true;
++
++	return false;
+ }
+ 
+ static const struct sff_data sfp_data = {
diff --git a/target/linux/generic/pending-5.4/772-net-sfp-relax-bitrate-devided-check.patch b/target/linux/generic/pending-5.4/772-net-sfp-relax-bitrate-devided-check.patch
new file mode 100644
index 0000000000..672d2d0b23
--- /dev/null
+++ b/target/linux/generic/pending-5.4/772-net-sfp-relax-bitrate-devided-check.patch
@@ -0,0 +1,44 @@
+From 7a77233ec6d114322e2c4f71b4e26dbecd9ea8a7 Mon Sep 17 00:00:00 2001
+From: Russell King <rmk+kernel at armlinux.org.uk>
+Date: Wed, 9 Dec 2020 11:22:54 +0000
+Subject: net: sfp: relax bitrate-derived mode check
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Do not check the encoding when deriving 1000BASE-X from the bitrate
+when no other modes are discovered. Some GPON modules (VSOL V2801F
+and CarlitoxxPro CPGOS03-0490 v2.0) indicate NRZ encoding with a
+1200Mbaud bitrate, but should be driven with 1000BASE-X on the host
+side.
+
+Tested-by: Pali Rohár <pali at kernel.org>
+Reviewed-by: Andrew Lunn <andrew at lunn.ch>
+Signed-off-by: Russell King <rmk+kernel at armlinux.org.uk>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/phy/sfp-bus.c | 11 +++++------
+ 1 file changed, 5 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/phy/sfp-bus.c
++++ b/drivers/net/phy/sfp-bus.c
+@@ -349,14 +349,13 @@ void sfp_parse_support(struct sfp_bus *b
+ 	}
+ 
+ 	/* If we haven't discovered any modes that this module supports, try
+-	 * the encoding and bitrate to determine supported modes. Some BiDi
+-	 * modules (eg, 1310nm/1550nm) are not 1000BASE-BX compliant due to
+-	 * the differing wavelengths, so do not set any transceiver bits.
++	 * the bitrate to determine supported modes. Some BiDi modules (eg,
++	 * 1310nm/1550nm) are not 1000BASE-BX compliant due to the differing
++	 * wavelengths, so do not set any transceiver bits.
+ 	 */
+ 	if (bitmap_empty(modes, __ETHTOOL_LINK_MODE_MASK_NBITS)) {
+-		/* If the encoding and bit rate allows 1000baseX */
+-		if (id->base.encoding == SFF8024_ENCODING_8B10B && br_nom &&
+-		    br_min <= 1300 && br_max >= 1200)
++		/* If the bit rate allows 1000baseX */
++		if (br_nom && br_min <= 1300 && br_max >= 1200)
+ 			phylink_set(modes, 1000baseX_Full);
+ 	}
+ 




More information about the lede-commits mailing list