 0e5350db43
			
		
	
	0e5350db43
	
	
	
		
			
			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@nic.cz>
		
			
				
	
	
		
			109 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
		
			3.7 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 283b211aa01bdae94dffb3121655dbb20bf237f4 Mon Sep 17 00:00:00 2001
 | |
| From: Russell King <rmk+kernel@armlinux.org.uk>
 | |
| Date: Tue, 3 Dec 2019 15:22:05 +0000
 | |
| Subject: net: sfp: avoid tx-fault with Nokia GPON module
 | |
| 
 | |
| The Nokia GPON module can hold tx-fault active while it is initialising
 | |
| which can take up to 60s. Avoid this causing the module to be declared
 | |
| faulty after the SFP MSA defined non-cooled module timeout.
 | |
| 
 | |
| Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
 | |
| ---
 | |
|  drivers/net/phy/sfp.c | 42 ++++++++++++++++++++++++++++++------------
 | |
|  1 file changed, 30 insertions(+), 12 deletions(-)
 | |
| 
 | |
| --- a/drivers/net/phy/sfp.c
 | |
| +++ b/drivers/net/phy/sfp.c
 | |
| @@ -155,10 +155,20 @@ static const enum gpiod_flags gpio_flags
 | |
|  	GPIOD_ASIS,
 | |
|  };
 | |
|  
 | |
| -#define T_WAIT		msecs_to_jiffies(50)
 | |
| -#define T_INIT_JIFFIES	msecs_to_jiffies(300)
 | |
| -#define T_RESET_US	10
 | |
| -#define T_FAULT_RECOVER	msecs_to_jiffies(1000)
 | |
| +/* t_start_up (SFF-8431) or t_init (SFF-8472) is the time required for a
 | |
| + * non-cooled module to initialise its laser safety circuitry. We wait
 | |
| + * an initial T_WAIT period before we check the tx fault to give any PHY
 | |
| + * on board (for a copper SFP) time to initialise.
 | |
| + */
 | |
| +#define T_WAIT			msecs_to_jiffies(50)
 | |
| +#define T_START_UP		msecs_to_jiffies(300)
 | |
| +#define T_START_UP_BAD_GPON	msecs_to_jiffies(60000)
 | |
| +
 | |
| +/* t_reset is the time required to assert the TX_DISABLE signal to reset
 | |
| + * an indicated TX_FAULT.
 | |
| + */
 | |
| +#define T_RESET_US		10
 | |
| +#define T_FAULT_RECOVER		msecs_to_jiffies(1000)
 | |
|  
 | |
|  /* 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
 | |
| @@ -219,6 +229,7 @@ struct sfp {
 | |
|  
 | |
|  	struct sfp_eeprom_id id;
 | |
|  	unsigned int module_power_mW;
 | |
| +	unsigned int module_t_start_up;
 | |
|  
 | |
|  #if IS_ENABLED(CONFIG_HWMON)
 | |
|  	struct sfp_diag diag;
 | |
| @@ -1750,6 +1761,12 @@ 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;
 | |
| +
 | |
|  	return 0;
 | |
|  }
 | |
|  
 | |
| @@ -1955,11 +1972,12 @@ static void sfp_sm_main(struct sfp *sfp,
 | |
|  			break;
 | |
|  
 | |
|  		if (sfp->state & SFP_F_TX_FAULT) {
 | |
| -			/* Wait t_init before indicating that the link is up,
 | |
| -			 * provided the current state indicates no TX_FAULT. If
 | |
| -			 * TX_FAULT clears before this time, that's fine too.
 | |
| +			/* Wait up to t_init (SFF-8472) or t_start_up (SFF-8431)
 | |
| +			 * from the TX_DISABLE deassertion for the module to
 | |
| +			 * initialise, which is indicated by TX_FAULT
 | |
| +			 * deasserting.
 | |
|  			 */
 | |
| -			timeout = T_INIT_JIFFIES;
 | |
| +			timeout = sfp->module_t_start_up;
 | |
|  			if (timeout > T_WAIT)
 | |
|  				timeout -= T_WAIT;
 | |
|  			else
 | |
| @@ -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) {
 | |
| -			/* TX_FAULT is still asserted after t_init, so assume
 | |
| -			 * there is a fault.
 | |
| +			/* TX_FAULT is still asserted after t_init or
 | |
| +			 * or t_start_up, so assume there is a fault.
 | |
|  			 */
 | |
|  			sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
 | |
|  				     sfp->sm_retries == 5);
 | |
| @@ -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);
 | |
| -			sfp_sm_next(sfp, SFP_S_INIT, T_INIT_JIFFIES);
 | |
| +			sfp_sm_next(sfp, SFP_S_INIT, sfp->module_t_start_up);
 | |
|  		}
 | |
|  		break;
 | |
|  
 | |
| @@ -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);
 | |
| -			sfp_sm_next(sfp, SFP_S_REINIT, T_INIT_JIFFIES);
 | |
| +			sfp_sm_next(sfp, SFP_S_REINIT, sfp->module_t_start_up);
 | |
|  		}
 | |
|  		break;
 | |
|  
 |