kernel: backport workaround for Realtek RTL8672 and RTL9601C chips

Adds support for GPON SFP modules based on the Realtek RTL8672 and
RTL9601C chips, including but not limited to:
* V-SOL V2801F
* C-Data FD511GX-RM0
* OPTON GP801R
* BAUDCOM BD-1234-SFM
* CPGOS03-0490 v2.0
* Ubiquiti U-Fiber Instant
* EXOT EGS1

Signed-off-by: Vladimir Markovets <abam_a@yahoo.com>
(cherry picked from commit f032601ed7)
This commit is contained in:
Vladimir Markovets
2021-07-22 00:09:22 +02:00
committed by Hauke Mehrtens
parent 77ee281a3e
commit 6ced8cad8e
14 changed files with 392 additions and 37 deletions

View File

@@ -39,7 +39,7 @@ Signed-off-by: Russell King <rmk+kernel@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
@@ -218,6 +228,7 @@ struct sfp {
@@ -219,6 +229,7 @@ struct sfp {
struct sfp_eeprom_id id;
unsigned int module_power_mW;
@@ -47,7 +47,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
#if IS_ENABLED(CONFIG_HWMON)
struct sfp_diag diag;
@@ -1655,6 +1666,12 @@ static int sfp_sm_mod_probe(struct sfp *
@@ -1742,6 +1753,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@armlinux.org.uk>
return 0;
}
@@ -1860,11 +1877,12 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1947,11 +1964,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@armlinux.org.uk>
if (timeout > T_WAIT)
timeout -= T_WAIT;
else
@@ -1881,8 +1899,8 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1968,8 +1986,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@armlinux.org.uk>
*/
sfp_sm_fault(sfp, SFP_S_INIT_TX_FAULT,
sfp->sm_retries == 5);
@@ -1901,7 +1919,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1988,7 +2006,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@armlinux.org.uk>
}
break;
@@ -1925,7 +1943,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -2012,7 +2030,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);

View File

@@ -30,7 +30,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
if (phylink_test(link_modes, 1000baseX_Full))
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1489,18 +1489,7 @@ static void sfp_sm_fault(struct sfp *sfp
@@ -1505,18 +1505,7 @@ static void sfp_sm_fault(struct sfp *sfp
static void sfp_sm_probe_for_phy(struct sfp *sfp)
{

View File

@@ -132,7 +132,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
if (phylink_test(link_modes, 2500baseX_Full))
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -242,7 +242,7 @@ struct sfp {
@@ -243,7 +243,7 @@ struct sfp {
static bool sff_module_supported(const struct sfp_eeprom_id *id)
{
@@ -141,7 +141,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
id->base.phys_ext_id == SFP_PHYS_EXT_ID_SFP;
}
@@ -253,7 +253,7 @@ static const struct sff_data sff_data =
@@ -254,7 +254,7 @@ static const struct sff_data sff_data =
static bool sfp_module_supported(const struct sfp_eeprom_id *id)
{

View File

@@ -78,7 +78,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
[SFP_S_WAIT] = "wait",
[SFP_S_INIT] = "init",
[SFP_S_INIT_TX_FAULT] = "init_tx_fault",
@@ -1831,6 +1833,8 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1918,6 +1920,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@armlinux.org.uk>
if (sfp->mod_phy)
sfp_sm_phy_detach(sfp);
sfp_module_tx_disable(sfp);
@@ -1898,6 +1902,10 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1985,6 +1989,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);

View File

@@ -54,7 +54,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
.connect_phy = phylink_sfp_connect_phy,
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1396,7 +1396,6 @@ static void sfp_sm_mod_next(struct sfp *
@@ -1412,7 +1412,6 @@ static void sfp_sm_mod_next(struct sfp *
static void sfp_sm_phy_detach(struct sfp *sfp)
{
@@ -62,7 +62,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
sfp_remove_phy(sfp->sfp_bus);
phy_device_remove(sfp->mod_phy);
phy_device_free(sfp->mod_phy);
@@ -1427,7 +1426,6 @@ static void sfp_sm_probe_phy(struct sfp
@@ -1443,7 +1442,6 @@ static void sfp_sm_probe_phy(struct sfp
}
sfp->mod_phy = phy;

View File

@@ -14,7 +14,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1402,12 +1402,12 @@ static void sfp_sm_phy_detach(struct sfp
@@ -1418,12 +1418,12 @@ static void sfp_sm_phy_detach(struct sfp
sfp->mod_phy = NULL;
}
@@ -29,7 +29,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
if (phy == ERR_PTR(-ENODEV)) {
dev_info(sfp->dev, "no PHY detected\n");
return;
@@ -1417,6 +1417,13 @@ static void sfp_sm_probe_phy(struct sfp
@@ -1433,6 +1433,13 @@ static void sfp_sm_probe_phy(struct sfp
return;
}
@@ -43,7 +43,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
err = sfp_add_phy(sfp->sfp_bus, phy);
if (err) {
phy_device_remove(phy);
@@ -1487,10 +1494,32 @@ static void sfp_sm_fault(struct sfp *sfp
@@ -1503,10 +1510,32 @@ static void sfp_sm_fault(struct sfp *sfp
}
}
@@ -78,7 +78,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
static int sfp_module_parse_power(struct sfp *sfp)
@@ -1550,6 +1579,13 @@ static int sfp_sm_mod_hpower(struct sfp
@@ -1566,6 +1595,13 @@ static int sfp_sm_mod_hpower(struct sfp
return -EAGAIN;
}

View File

@@ -15,7 +15,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -2344,6 +2344,10 @@ static int sfp_remove(struct platform_de
@@ -2431,6 +2431,10 @@ static int sfp_remove(struct platform_de
sfp_unregister_socket(sfp->sfp_bus);

View File

@@ -15,7 +15,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1796,6 +1796,10 @@ static void sfp_sm_module(struct sfp *sf
@@ -1883,6 +1883,10 @@ static void sfp_sm_module(struct sfp *sf
break;
}
@@ -26,7 +26,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0);
/* fall through */
case SFP_MOD_WAITDEV:
@@ -1845,15 +1849,6 @@ static void sfp_sm_module(struct sfp *sf
@@ -1932,15 +1936,6 @@ static void sfp_sm_module(struct sfp *sf
case SFP_MOD_ERROR:
break;
}

View File

@@ -26,7 +26,7 @@ Signed-off-by: Russell King <rmk+kernel@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.
@@ -1885,7 +1893,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1972,7 +1980,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@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
@@ -1925,7 +1933,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -2012,7 +2020,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@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.
@@ -1938,7 +1946,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -2025,7 +2033,7 @@ static void sfp_sm_main(struct sfp *sfp,
sfp_sm_link_check_los(sfp);
/* Reset the fault retry count */

View File

@@ -13,7 +13,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -234,7 +234,7 @@ struct sfp {
@@ -235,7 +235,7 @@ struct sfp {
unsigned char sm_mod_tries;
unsigned char sm_dev_state;
unsigned short sm_state;
@@ -22,7 +22,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
struct sfp_eeprom_id id;
unsigned int module_power_mW;
@@ -1490,7 +1490,7 @@ static bool sfp_los_event_inactive(struc
@@ -1506,7 +1506,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@armlinux.org.uk>
dev_err(sfp->dev,
"module persistently indicates fault, disabling\n");
sfp_sm_next(sfp, SFP_S_TX_DISABLE, 0);
@@ -1893,7 +1893,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -1980,7 +1980,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@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
@@ -1933,7 +1933,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -2020,7 +2020,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@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.
@@ -1946,7 +1946,7 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -2033,7 +2033,7 @@ static void sfp_sm_main(struct sfp *sfp,
sfp_sm_link_check_los(sfp);
/* Reset the fault retry count */

View File

@@ -10,7 +10,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
--- a/drivers/net/phy/sfp.c
+++ b/drivers/net/phy/sfp.c
@@ -1410,7 +1410,7 @@ static void sfp_sm_phy_detach(struct sfp
@@ -1426,7 +1426,7 @@ static void sfp_sm_phy_detach(struct sfp
sfp->mod_phy = NULL;
}
@@ -19,7 +19,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
{
struct phy_device *phy;
int err;
@@ -1418,18 +1418,18 @@ static void sfp_sm_probe_phy(struct sfp
@@ -1434,18 +1434,18 @@ static void sfp_sm_probe_phy(struct sfp
phy = get_phy_device(sfp->i2c_mii, SFP_PHY_ADDR, is_c45);
if (phy == ERR_PTR(-ENODEV)) {
dev_info(sfp->dev, "no PHY detected\n");
@@ -41,7 +41,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
err = sfp_add_phy(sfp->sfp_bus, phy);
@@ -1437,10 +1437,12 @@ static void sfp_sm_probe_phy(struct sfp
@@ -1453,10 +1453,12 @@ static void sfp_sm_probe_phy(struct sfp
phy_device_remove(phy);
phy_device_free(phy);
dev_err(sfp->dev, "sfp_add_phy failed: %d\n", err);
@@ -55,7 +55,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
}
static void sfp_sm_link_up(struct sfp *sfp)
@@ -1513,21 +1515,24 @@ static void sfp_sm_fault(struct sfp *sfp
@@ -1529,21 +1531,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@armlinux.org.uk>
}
static int sfp_module_parse_power(struct sfp *sfp)
@@ -1938,7 +1943,10 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -2025,7 +2030,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.
*/

View File

@@ -48,7 +48,7 @@ Signed-off-by: Russell King <rmk+kernel@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.
@@ -235,6 +243,7 @@ struct sfp {
@@ -236,6 +244,7 @@ struct sfp {
unsigned char sm_dev_state;
unsigned short sm_state;
unsigned char sm_fault_retries;
@@ -56,7 +56,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
struct sfp_eeprom_id id;
unsigned int module_power_mW;
@@ -1416,10 +1425,8 @@ static int sfp_sm_probe_phy(struct sfp *
@@ -1432,10 +1441,8 @@ static int sfp_sm_probe_phy(struct sfp *
int err;
phy = get_phy_device(sfp->i2c_mii, SFP_PHY_ADDR, is_c45);
@@ -69,7 +69,7 @@ Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
if (IS_ERR(phy)) {
dev_err(sfp->dev, "mdiobus scan returned %ld\n", PTR_ERR(phy));
return PTR_ERR(phy);
@@ -1867,6 +1874,7 @@ static void sfp_sm_module(struct sfp *sf
@@ -1954,6 +1961,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@armlinux.org.uk>
/* Some events are global */
if (sfp->sm_state != SFP_S_DOWN &&
@@ -1940,22 +1948,39 @@ static void sfp_sm_main(struct sfp *sfp,
@@ -2027,22 +2035,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) {