diff options
author | Russell King <linux@armlinux.org.uk> | 2019-11-27 11:45:25 +0000 |
---|---|---|
committer | Jonas Gorski <jonas.gorski@gmail.com> | 2020-01-21 22:32:48 +0100 |
commit | 1c16b574c4f77a30a0268acee30be96ae0dc5948 (patch) | |
tree | 716fd94ee81e332ba19e1af7bf98371120ea1856 /target/linux/generic/backport-4.19/732-v5.5-net-sfp-track-upstream-s-attachment-state-in-state-m.patch | |
parent | a07638eb24b8310a35ea6c3b09f6db59bb31cd68 (diff) | |
download | upstream-1c16b574c4f77a30a0268acee30be96ae0dc5948.tar.gz upstream-1c16b574c4f77a30a0268acee30be96ae0dc5948.tar.bz2 upstream-1c16b574c4f77a30a0268acee30be96ae0dc5948.zip |
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 <linux@armlinux.org.uk>
[jonas.gorski: include kernel version in file names, refresh patches]
Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
Diffstat (limited to 'target/linux/generic/backport-4.19/732-v5.5-net-sfp-track-upstream-s-attachment-state-in-state-m.patch')
-rw-r--r-- | target/linux/generic/backport-4.19/732-v5.5-net-sfp-track-upstream-s-attachment-state-in-state-m.patch | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/target/linux/generic/backport-4.19/732-v5.5-net-sfp-track-upstream-s-attachment-state-in-state-m.patch b/target/linux/generic/backport-4.19/732-v5.5-net-sfp-track-upstream-s-attachment-state-in-state-m.patch new file mode 100644 index 0000000000..5ee44dbf0c --- /dev/null +++ b/target/linux/generic/backport-4.19/732-v5.5-net-sfp-track-upstream-s-attachment-state-in-state-m.patch @@ -0,0 +1,153 @@ +From ec6036a58f979c66bbd5cd9d0d1c783a98c2c644 Mon Sep 17 00:00:00 2001 +From: Russell King <rmk+kernel@armlinux.org.uk> +Date: Tue, 5 Nov 2019 12:57:40 +0000 +Subject: [PATCH 630/660] net: sfp: track upstream's attachment state in state + machine + +Track the upstream's attachment state in the state machine rather than +maintaining a boolean, which ensures that we have a strict order of +ATTACH followed by an UP event - we can never believe that a newly +attached upstream will be anything but down. + +Rearrange the order of state machines so we run the module state +machine after the upstream device's state machine, so the module state +machine can check the current state of the device and take action to +e.g. reset back to empty state when the upstream is detached. + +This is to allow the module detection to run independently of the +network device becoming available. + +Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> +--- + drivers/net/phy/sfp.c | 42 +++++++++++++++++++++++++++++------------- + 1 file changed, 29 insertions(+), 13 deletions(-) + +--- a/drivers/net/phy/sfp.c ++++ b/drivers/net/phy/sfp.c +@@ -34,6 +34,8 @@ enum { + + SFP_E_INSERT = 0, + SFP_E_REMOVE, ++ SFP_E_DEV_ATTACH, ++ SFP_E_DEV_DETACH, + SFP_E_DEV_DOWN, + SFP_E_DEV_UP, + SFP_E_TX_FAULT, +@@ -48,7 +50,8 @@ enum { + SFP_MOD_PRESENT, + SFP_MOD_ERROR, + +- SFP_DEV_DOWN = 0, ++ SFP_DEV_DETACHED = 0, ++ SFP_DEV_DOWN, + SFP_DEV_UP, + + SFP_S_DOWN = 0, +@@ -78,6 +81,7 @@ static const char *mod_state_to_str(unsi + } + + static const char * const dev_state_strings[] = { ++ [SFP_DEV_DETACHED] = "detached", + [SFP_DEV_DOWN] = "down", + [SFP_DEV_UP] = "up", + }; +@@ -92,6 +96,8 @@ static const char *dev_state_to_str(unsi + static const char * const event_strings[] = { + [SFP_E_INSERT] = "insert", + [SFP_E_REMOVE] = "remove", ++ [SFP_E_DEV_ATTACH] = "dev_attach", ++ [SFP_E_DEV_DETACH] = "dev_detach", + [SFP_E_DEV_DOWN] = "dev_down", + [SFP_E_DEV_UP] = "dev_up", + [SFP_E_TX_FAULT] = "tx_fault", +@@ -186,7 +192,6 @@ struct sfp { + struct gpio_desc *gpio[GPIO_MAX]; + int gpio_irq[GPIO_MAX]; + +- bool attached; + struct mutex st_mutex; /* Protects state */ + unsigned int state; + struct delayed_work poll; +@@ -1494,17 +1499,26 @@ static void sfp_sm_mod_remove(struct sfp + dev_info(sfp->dev, "module removed\n"); + } + +-/* This state machine tracks the netdev up/down state */ ++/* This state machine tracks the upstream's state */ + static void sfp_sm_device(struct sfp *sfp, unsigned int event) + { + switch (sfp->sm_dev_state) { + default: +- if (event == SFP_E_DEV_UP) ++ if (event == SFP_E_DEV_ATTACH) ++ sfp->sm_dev_state = SFP_DEV_DOWN; ++ break; ++ ++ case SFP_DEV_DOWN: ++ if (event == SFP_E_DEV_DETACH) ++ sfp->sm_dev_state = SFP_DEV_DETACHED; ++ else if (event == SFP_E_DEV_UP) + sfp->sm_dev_state = SFP_DEV_UP; + break; + + case SFP_DEV_UP: +- if (event == SFP_E_DEV_DOWN) ++ if (event == SFP_E_DEV_DETACH) ++ sfp->sm_dev_state = SFP_DEV_DETACHED; ++ else if (event == SFP_E_DEV_DOWN) + sfp->sm_dev_state = SFP_DEV_DOWN; + break; + } +@@ -1515,17 +1529,20 @@ static void sfp_sm_device(struct sfp *sf + */ + static void sfp_sm_module(struct sfp *sfp, unsigned int event) + { +- /* Handle remove event globally, it resets this state machine */ +- if (event == SFP_E_REMOVE) { ++ /* Handle remove event globally, it resets this state machine. ++ * Also deal with upstream detachment. ++ */ ++ if (event == SFP_E_REMOVE || sfp->sm_dev_state < SFP_DEV_DOWN) { + if (sfp->sm_mod_state > SFP_MOD_PROBE) + sfp_sm_mod_remove(sfp); +- sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); ++ if (sfp->sm_mod_state != SFP_MOD_EMPTY) ++ sfp_sm_mod_next(sfp, SFP_MOD_EMPTY, 0); + return; + } + + switch (sfp->sm_mod_state) { + default: +- if (event == SFP_E_INSERT && sfp->attached) ++ if (event == SFP_E_INSERT) + sfp_sm_mod_next(sfp, SFP_MOD_PROBE, T_SERIAL); + break; + +@@ -1691,8 +1708,8 @@ static void sfp_sm_event(struct sfp *sfp + sm_state_to_str(sfp->sm_state), + event_to_str(event)); + +- sfp_sm_module(sfp, event); + sfp_sm_device(sfp, event); ++ sfp_sm_module(sfp, event); + sfp_sm_main(sfp, event); + + dev_dbg(sfp->dev, "SM: exit %s:%s:%s\n", +@@ -1705,15 +1722,14 @@ static void sfp_sm_event(struct sfp *sfp + + static void sfp_attach(struct sfp *sfp) + { +- sfp->attached = true; ++ 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) + { +- sfp->attached = false; +- sfp_sm_event(sfp, SFP_E_REMOVE); ++ sfp_sm_event(sfp, SFP_E_DEV_DETACH); + } + + static void sfp_start(struct sfp *sfp) |