From 1c16b574c4f77a30a0268acee30be96ae0dc5948 Mon Sep 17 00:00:00 2001 From: Russell King Date: Wed, 27 Nov 2019 11:45:25 +0000 Subject: kernel: add backported phy/phylink/sfp patches Backport the phy/phylink/sfp patches currently queued in netdev or in mainline necessary to support GPON popular modules, specifically to support Huawei and Nokia GPON modules. Signed-off-by: Russell King [jonas.gorski: include kernel version in file names, refresh patches] Signed-off-by: Jonas Gorski --- ...move-module-insert-reporting-out-of-probe.patch | 159 +++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 target/linux/generic/backport-4.19/734-v5.5-net-sfp-move-module-insert-reporting-out-of-probe.patch (limited to 'target/linux/generic/backport-4.19/734-v5.5-net-sfp-move-module-insert-reporting-out-of-probe.patch') diff --git a/target/linux/generic/backport-4.19/734-v5.5-net-sfp-move-module-insert-reporting-out-of-probe.patch b/target/linux/generic/backport-4.19/734-v5.5-net-sfp-move-module-insert-reporting-out-of-probe.patch new file mode 100644 index 0000000000..26b6a6b0e4 --- /dev/null +++ b/target/linux/generic/backport-4.19/734-v5.5-net-sfp-move-module-insert-reporting-out-of-probe.patch @@ -0,0 +1,159 @@ +From 57cbf7453551db1df619b79410d79fc418d862d5 Mon Sep 17 00:00:00 2001 +From: Russell King +Date: Tue, 5 Nov 2019 13:00:45 +0000 +Subject: [PATCH 632/660] net: sfp: move module insert reporting out of probe + +Move the module insertion reporting out of the probe handling, but +after we have detected that the upstream has attached (since that is +whom we are reporting insertion to.) + +Only report module removal if we had previously reported a module +insertion. + +This gives cleaner semantics, and means we can probe the module before +we have an upstream attached. + +Signed-off-by: Russell King +--- + drivers/net/phy/sfp.c | 58 +++++++++++++++++++++++++++++-------------- + 1 file changed, 40 insertions(+), 18 deletions(-) + +--- a/drivers/net/phy/sfp.c ++++ b/drivers/net/phy/sfp.c +@@ -45,11 +45,12 @@ enum { + SFP_E_TIMEOUT, + + SFP_MOD_EMPTY = 0, ++ SFP_MOD_ERROR, + SFP_MOD_PROBE, ++ SFP_MOD_WAITDEV, + SFP_MOD_HPOWER, + SFP_MOD_WAITPWR, + SFP_MOD_PRESENT, +- SFP_MOD_ERROR, + + SFP_DEV_DETACHED = 0, + SFP_DEV_DOWN, +@@ -68,11 +69,12 @@ enum { + + static const char * const mod_state_strings[] = { + [SFP_MOD_EMPTY] = "empty", ++ [SFP_MOD_ERROR] = "error", + [SFP_MOD_PROBE] = "probe", ++ [SFP_MOD_WAITDEV] = "waitdev", + [SFP_MOD_HPOWER] = "hpower", + [SFP_MOD_WAITPWR] = "waitpwr", + [SFP_MOD_PRESENT] = "present", +- [SFP_MOD_ERROR] = "error", + }; + + static const char *mod_state_to_str(unsigned short mod_state) +@@ -1479,16 +1481,13 @@ static int sfp_sm_mod_probe(struct sfp * + if (ret < 0) + return ret; + +- ret = sfp_module_insert(sfp->sfp_bus, &sfp->id); +- if (ret < 0) +- return ret; +- + return 0; + } + + static void sfp_sm_mod_remove(struct sfp *sfp) + { +- sfp_module_remove(sfp->sfp_bus); ++ if (sfp->sm_mod_state > SFP_MOD_WAITDEV) ++ sfp_module_remove(sfp->sfp_bus); + + sfp_hwmon_remove(sfp); + +@@ -1539,12 +1538,12 @@ static void sfp_sm_module(struct sfp *sf + } + + /* Handle device detach globally */ +- if (sfp->sm_dev_state < SFP_DEV_DOWN) { ++ if (sfp->sm_dev_state < SFP_DEV_DOWN && ++ sfp->sm_mod_state > SFP_MOD_WAITDEV) { + if (sfp->module_power_mW > 1000 && + sfp->sm_mod_state > SFP_MOD_HPOWER) + sfp_sm_mod_hpower(sfp, false); +- if (sfp->sm_mod_state > SFP_MOD_EMPTY) +- sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); ++ sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0); + return; + } + +@@ -1555,6 +1554,7 @@ static void sfp_sm_module(struct sfp *sf + break; + + case SFP_MOD_PROBE: ++ /* Wait for T_PROBE_INIT to time out */ + if (event != SFP_E_TIMEOUT) + break; + +@@ -1568,6 +1568,20 @@ static void sfp_sm_module(struct sfp *sf + break; + } + ++ sfp_sm_mod_next(sfp, SFP_MOD_WAITDEV, 0); ++ /* fall through */ ++ case SFP_MOD_WAITDEV: ++ /* Ensure that the device is attached before proceeding */ ++ if (sfp->sm_dev_state < SFP_DEV_DOWN) ++ break; ++ ++ /* Report the module insertion to the upstream device */ ++ err = sfp_module_insert(sfp->sfp_bus, &sfp->id); ++ if (err < 0) { ++ sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); ++ break; ++ } ++ + /* If this is a power level 1 module, we are done */ + if (sfp->module_power_mW <= 1000) + goto insert; +@@ -1577,12 +1591,17 @@ static void sfp_sm_module(struct sfp *sf + case SFP_MOD_HPOWER: + /* Enable high power mode */ + err = sfp_sm_mod_hpower(sfp, true); +- if (err == 0) +- sfp_sm_mod_next(sfp, SFP_MOD_WAITPWR, T_HPOWER_LEVEL); +- else if (err != -EAGAIN) +- sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); +- else +- sfp_sm_set_timer(sfp, T_PROBE_RETRY); ++ if (err < 0) { ++ if (err != -EAGAIN) { ++ sfp_module_remove(sfp->sfp_bus); ++ sfp_sm_mod_next(sfp, SFP_MOD_ERROR, 0); ++ } else { ++ sfp_sm_set_timer(sfp, T_PROBE_RETRY); ++ } ++ break; ++ } ++ ++ sfp_sm_mod_next(sfp, SFP_MOD_WAITPWR, T_HPOWER_LEVEL); + break; + + case SFP_MOD_WAITPWR: +@@ -1750,8 +1769,6 @@ static void sfp_sm_event(struct sfp *sfp + static void sfp_attach(struct sfp *sfp) + { + sfp_sm_event(sfp, SFP_E_DEV_ATTACH); +- if (sfp->state & SFP_F_PRESENT) +- sfp_sm_event(sfp, SFP_E_INSERT); + } + + static void sfp_detach(struct sfp *sfp) +@@ -2001,6 +2018,11 @@ static int sfp_probe(struct platform_dev + sfp->state |= SFP_F_RATE_SELECT; + sfp_set_state(sfp, sfp->state); + sfp_module_tx_disable(sfp); ++ if (sfp->state & SFP_F_PRESENT) { ++ rtnl_lock(); ++ sfp_sm_event(sfp, SFP_E_INSERT); ++ rtnl_unlock(); ++ } + + for (i = 0; i < GPIO_MAX; i++) { + if (gpio_flags[i] != GPIOD_IN || !sfp->gpio[i]) -- cgit v1.2.3