From 3448a04097e3d57d0a22191be26649b7602cd15a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 24 Sep 2021 11:29:24 +0200 Subject: [PATCH] 5.4-stable patches added patches: phy-avoid-unnecessary-link-up-delay-in-polling-mode.patch --- ...essary-link-up-delay-in-polling-mode.patch | 84 +++++++++++++++++++ queue-5.4/series | 1 + 2 files changed, 85 insertions(+) create mode 100644 queue-5.4/phy-avoid-unnecessary-link-up-delay-in-polling-mode.patch diff --git a/queue-5.4/phy-avoid-unnecessary-link-up-delay-in-polling-mode.patch b/queue-5.4/phy-avoid-unnecessary-link-up-delay-in-polling-mode.patch new file mode 100644 index 00000000000..cc2a36b6f37 --- /dev/null +++ b/queue-5.4/phy-avoid-unnecessary-link-up-delay-in-polling-mode.patch @@ -0,0 +1,84 @@ +From e96bd2d3b1f83170d1d5c1a99e439b39a22a5b58 Mon Sep 17 00:00:00 2001 +From: Petr Oros +Date: Tue, 18 Feb 2020 10:35:55 +0100 +Subject: phy: avoid unnecessary link-up delay in polling mode + +From: Petr Oros + +commit e96bd2d3b1f83170d1d5c1a99e439b39a22a5b58 upstream. + +commit 93c0970493c71f ("net: phy: consider latched link-down status in +polling mode") removed double-read of latched link-state register for +polling mode from genphy_update_link(). This added extra ~1s delay into +sequence link down->up. +Following scenario: + - After boot link goes up + - phy_start() is called triggering an aneg restart, hence link goes + down and link-down info is latched. + - After aneg has finished link goes up. In phy_state_machine is checked + link state but it is latched "link is down". The state machine is + scheduled after one second and there is detected "link is up". This + extra delay can be avoided when we keep link-state register double read + in case when link was down previously. + +With this solution we don't miss a link-down event in polling mode and +link-up is faster. + +Details about this quirky behavior on Realtek phy: +Without patch: +T0: aneg is started, link goes down, link-down status is latched +T0+3s: state machine runs, up-to-date link-down is read +T0+4s: state machine runs, aneg is finished (BMSR_ANEGCOMPLETE==1), + here i read link-down (BMSR_LSTATUS==0), +T0+5s: state machine runs, aneg is finished (BMSR_ANEGCOMPLETE==1), + up-to-date link-up is read (BMSR_LSTATUS==1), + phydev->link goes up, state change PHY_NOLINK to PHY_RUNNING + +With patch: +T0: aneg is started, link goes down, link-down status is latched +T0+3s: state machine runs, up-to-date link-down is read +T0+4s: state machine runs, aneg is finished (BMSR_ANEGCOMPLETE==1), + first BMSR read: BMSR_ANEGCOMPLETE==1 and BMSR_LSTATUS==0, + second BMSR read: BMSR_ANEGCOMPLETE==1 and BMSR_LSTATUS==1, + phydev->link goes up, state change PHY_NOLINK to PHY_RUNNING + +Signed-off-by: Petr Oros +Reviewed-by: Heiner Kallweit +Signed-off-by: David S. Miller +Cc: Macpaul Lin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/phy-c45.c | 5 +++-- + drivers/net/phy/phy_device.c | 5 +++-- + 2 files changed, 6 insertions(+), 4 deletions(-) + +--- a/drivers/net/phy/phy-c45.c ++++ b/drivers/net/phy/phy-c45.c +@@ -239,9 +239,10 @@ int genphy_c45_read_link(struct phy_devi + + /* The link state is latched low so that momentary link + * drops can be detected. Do not double-read the status +- * in polling mode to detect such short link drops. ++ * in polling mode to detect such short link drops except ++ * the link was already down. + */ +- if (!phy_polling_mode(phydev)) { ++ if (!phy_polling_mode(phydev) || !phydev->link) { + val = phy_read_mmd(phydev, devad, MDIO_STAT1); + if (val < 0) + return val; +--- a/drivers/net/phy/phy_device.c ++++ b/drivers/net/phy/phy_device.c +@@ -1766,9 +1766,10 @@ int genphy_update_link(struct phy_device + + /* The link state is latched low so that momentary link + * drops can be detected. Do not double-read the status +- * in polling mode to detect such short link drops. ++ * in polling mode to detect such short link drops except ++ * the link was already down. + */ +- if (!phy_polling_mode(phydev)) { ++ if (!phy_polling_mode(phydev) || !phydev->link) { + status = phy_read(phydev, MII_BMSR); + if (status < 0) + return status; diff --git a/queue-5.4/series b/queue-5.4/series index 8546c879001..fa908171cfd 100644 --- a/queue-5.4/series +++ b/queue-5.4/series @@ -24,3 +24,4 @@ nilfs2-use-refcount_dec_and_lock-to-fix-potential-uaf.patch profiling-fix-shift-out-of-bounds-bugs.patch pwm-lpc32xx-don-t-modify-hw-state-in-.probe-after-the-pwm-chip-was-registered.patch pwm-mxs-don-t-modify-hw-state-in-.probe-after-the-pwm-chip-was-registered.patch +phy-avoid-unnecessary-link-up-delay-in-polling-mode.patch -- 2.47.3