mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 09:00:52 +07:00
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> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e70ac62828
commit
26c97a2d82
@ -155,8 +155,18 @@ static const enum gpiod_flags gpio_flags[] = {
|
|||||||
GPIOD_ASIS,
|
GPIOD_ASIS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 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_WAIT msecs_to_jiffies(50)
|
||||||
#define T_INIT_JIFFIES msecs_to_jiffies(300)
|
#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_RESET_US 10
|
||||||
#define T_FAULT_RECOVER msecs_to_jiffies(1000)
|
#define T_FAULT_RECOVER msecs_to_jiffies(1000)
|
||||||
|
|
||||||
@ -218,6 +228,7 @@ struct sfp {
|
|||||||
|
|
||||||
struct sfp_eeprom_id id;
|
struct sfp_eeprom_id id;
|
||||||
unsigned int module_power_mW;
|
unsigned int module_power_mW;
|
||||||
|
unsigned int module_t_start_up;
|
||||||
|
|
||||||
#if IS_ENABLED(CONFIG_HWMON)
|
#if IS_ENABLED(CONFIG_HWMON)
|
||||||
struct sfp_diag diag;
|
struct sfp_diag diag;
|
||||||
@ -1655,6 +1666,12 @@ static int sfp_sm_mod_probe(struct sfp *sfp, bool report)
|
|||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1855,11 +1872,12 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (sfp->state & SFP_F_TX_FAULT) {
|
if (sfp->state & SFP_F_TX_FAULT) {
|
||||||
/* Wait t_init before indicating that the link is up,
|
/* Wait up to t_init (SFF-8472) or t_start_up (SFF-8431)
|
||||||
* provided the current state indicates no TX_FAULT. If
|
* from the TX_DISABLE deassertion for the module to
|
||||||
* TX_FAULT clears before this time, that's fine too.
|
* initialise, which is indicated by TX_FAULT
|
||||||
|
* deasserting.
|
||||||
*/
|
*/
|
||||||
timeout = T_INIT_JIFFIES;
|
timeout = sfp->module_t_start_up;
|
||||||
if (timeout > T_WAIT)
|
if (timeout > T_WAIT)
|
||||||
timeout -= T_WAIT;
|
timeout -= T_WAIT;
|
||||||
else
|
else
|
||||||
@ -1876,8 +1894,8 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
|
|||||||
|
|
||||||
case SFP_S_INIT:
|
case SFP_S_INIT:
|
||||||
if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) {
|
if (event == SFP_E_TIMEOUT && sfp->state & SFP_F_TX_FAULT) {
|
||||||
/* TX_FAULT is still asserted after t_init, so assume
|
/* TX_FAULT is still asserted after t_init or
|
||||||
* there is a fault.
|
* or t_start_up, so assume there is a fault.
|
||||||
*/
|
*/
|
||||||
sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
|
sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
|
||||||
sfp->sm_retries == 5);
|
sfp->sm_retries == 5);
|
||||||
@ -1896,7 +1914,7 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
|
|||||||
case SFP_S_INIT_TX_FAULT:
|
case SFP_S_INIT_TX_FAULT:
|
||||||
if (event == SFP_E_TIMEOUT) {
|
if (event == SFP_E_TIMEOUT) {
|
||||||
sfp_module_tx_fault_reset(sfp);
|
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;
|
break;
|
||||||
|
|
||||||
@ -1920,7 +1938,7 @@ static void sfp_sm_main(struct sfp *sfp, unsigned int event)
|
|||||||
case SFP_S_TX_FAULT:
|
case SFP_S_TX_FAULT:
|
||||||
if (event == SFP_E_TIMEOUT) {
|
if (event == SFP_E_TIMEOUT) {
|
||||||
sfp_module_tx_fault_reset(sfp);
|
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;
|
break;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user