netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine
@ 2018-11-07 19:41 Heiner Kallweit
  2018-11-07 19:43 ` [PATCH net-next 1/5] net: phy: remove useless check in state machine case PHY_NOLINK Heiner Kallweit
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Heiner Kallweit @ 2018-11-07 19:41 UTC (permalink / raw)
  To: Florian Fainelli, Andrew Lunn, David Miller; +Cc: netdev

This patch series is based on two axioms:

- During autoneg a PHY always reports the link being down

- Info in clause 22/45 registers doesn't allow to differentiate between
  these two states:
  1. Link is physically down
  2. A link partner is connected and PHY is autonegotiating
  In both cases "link up" and "aneg finished" bits aren't set.
  One consequence is that having separate states PHY_NOLINK and PHY_AN
  isn't needed.

By using these two axioms the state machine can be significantly
simplified.

Heiner Kallweit (5):
  net: phy: remove useless check in state machine case PHY_NOLINK
  net: phy: remove useless check in state machine case PHY_RESUMING
  net: phy: add phy_check_link_status
  net: phy: remove state PHY_AN
  net: phy: use phy_check_link_status in more places in the state machine

 drivers/net/phy/phy.c | 172 +++++++++++-------------------------------
 include/linux/phy.h   |  19 +----
 2 files changed, 46 insertions(+), 145 deletions(-)

-- 
2.19.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH net-next 1/5] net: phy: remove useless check in state machine case PHY_NOLINK
  2018-11-07 19:41 [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine Heiner Kallweit
@ 2018-11-07 19:43 ` Heiner Kallweit
  2018-11-07 19:44 ` [PATCH net-next 2/5] net: phy: remove useless check in state machine case PHY_RESUMING Heiner Kallweit
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Heiner Kallweit @ 2018-11-07 19:43 UTC (permalink / raw)
  To: Florian Fainelli, Andrew Lunn, David Miller; +Cc: netdev

If aneg is enabled and the PHY reports the link as up then definitely
aneg finished successfully. Therefore this check is useless and
can be removed.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/net/phy/phy.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 476578746..87c6d304c 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -970,17 +970,6 @@ void phy_state_machine(struct work_struct *work)
 			break;
 
 		if (phydev->link) {
-			if (AUTONEG_ENABLE == phydev->autoneg) {
-				err = phy_aneg_done(phydev);
-				if (err < 0)
-					break;
-
-				if (!err) {
-					phydev->state = PHY_AN;
-					phydev->link_timeout = PHY_AN_TIMEOUT;
-					break;
-				}
-			}
 			phydev->state = PHY_RUNNING;
 			phy_link_up(phydev);
 		}
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next 2/5] net: phy: remove useless check in state machine case PHY_RESUMING
  2018-11-07 19:41 [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine Heiner Kallweit
  2018-11-07 19:43 ` [PATCH net-next 1/5] net: phy: remove useless check in state machine case PHY_NOLINK Heiner Kallweit
@ 2018-11-07 19:44 ` Heiner Kallweit
  2018-11-07 19:45 ` [PATCH net-next 3/5] net: phy: add phy_check_link_status Heiner Kallweit
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Heiner Kallweit @ 2018-11-07 19:44 UTC (permalink / raw)
  To: Florian Fainelli, Andrew Lunn, David Miller; +Cc: netdev

If aneg isn't finished yet then the PHY reports the link as down.
There's no benefit in setting the state to PHY_AN because the next
state machine run would set the status to PHY_NOLINK anyway (except
in the meantime aneg has been finished and link is up). Therefore
we can set the state to PHY_RUNNING or PHY_NOLINK directly.

In addition change the do_carrier parameter in phy_link_down() to true.
If carrier was marked as up before (what should never be the case because
PHY was in state PHY_HALTED before) then we should mark it as down now.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/net/phy/phy.c | 13 +------------
 1 file changed, 1 insertion(+), 12 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 87c6d304c..14dffa0da 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -1022,17 +1022,6 @@ void phy_state_machine(struct work_struct *work)
 		}
 		break;
 	case PHY_RESUMING:
-		if (AUTONEG_ENABLE == phydev->autoneg) {
-			err = phy_aneg_done(phydev);
-			if (err < 0) {
-				break;
-			} else if (!err) {
-				phydev->state = PHY_AN;
-				phydev->link_timeout = PHY_AN_TIMEOUT;
-				break;
-			}
-		}
-
 		err = phy_read_status(phydev);
 		if (err)
 			break;
@@ -1042,7 +1031,7 @@ void phy_state_machine(struct work_struct *work)
 			phy_link_up(phydev);
 		} else	{
 			phydev->state = PHY_NOLINK;
-			phy_link_down(phydev, false);
+			phy_link_down(phydev, true);
 		}
 		break;
 	}
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next 3/5] net: phy: add phy_check_link_status
  2018-11-07 19:41 [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine Heiner Kallweit
  2018-11-07 19:43 ` [PATCH net-next 1/5] net: phy: remove useless check in state machine case PHY_NOLINK Heiner Kallweit
  2018-11-07 19:44 ` [PATCH net-next 2/5] net: phy: remove useless check in state machine case PHY_RESUMING Heiner Kallweit
@ 2018-11-07 19:45 ` Heiner Kallweit
  2018-11-07 19:46 ` [PATCH net-next 4/5] net: phy: remove state PHY_AN Heiner Kallweit
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Heiner Kallweit @ 2018-11-07 19:45 UTC (permalink / raw)
  To: Florian Fainelli, Andrew Lunn, David Miller; +Cc: netdev

In few places in the state machine the state is set to PHY_RUNNING or
PHY_NOLINK after doing a phy_read_status(). So factor this out to
phy_check_link_status().

First use it in phy_start_aneg(): By setting the state to PHY_RUNNING
or PHY_NOLINK directly we can remove the code to handle the case that
we're using interrupts and aneg was finished already.

Definition of phy_link_up and phy_link_down needs to be moved because
they are called in the new function.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/net/phy/phy.c | 70 ++++++++++++++++++++++++-------------------
 1 file changed, 40 insertions(+), 30 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 14dffa0da..87ed00030 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -62,6 +62,17 @@ static const char *phy_state_to_str(enum phy_state st)
 	return NULL;
 }
 
+static void phy_link_up(struct phy_device *phydev)
+{
+	phydev->phy_link_change(phydev, true, true);
+	phy_led_trigger_change_speed(phydev);
+}
+
+static void phy_link_down(struct phy_device *phydev, bool do_carrier)
+{
+	phydev->phy_link_change(phydev, false, do_carrier);
+	phy_led_trigger_change_speed(phydev);
+}
 
 /**
  * phy_print_status - Convenience function to print out the current phy status
@@ -493,6 +504,34 @@ static int phy_config_aneg(struct phy_device *phydev)
 	return genphy_config_aneg(phydev);
 }
 
+/**
+ * phy_check_link_status - check link status and set state accordingly
+ * @phydev: the phy_device struct
+ *
+ * Description: Check for link and whether autoneg was triggered / is running
+ * and set state accordingly
+ */
+static int phy_check_link_status(struct phy_device *phydev)
+{
+	int err;
+
+	WARN_ON(!mutex_is_locked(&phydev->lock));
+
+	err = phy_read_status(phydev);
+	if (err)
+		return err;
+
+	if (phydev->link && phydev->state != PHY_RUNNING) {
+		phydev->state = PHY_RUNNING;
+		phy_link_up(phydev);
+	} else if (!phydev->link && phydev->state != PHY_NOLINK) {
+		phydev->state = PHY_NOLINK;
+		phy_link_down(phydev, true);
+	}
+
+	return 0;
+}
+
 /**
  * phy_start_aneg - start auto-negotiation for this PHY device
  * @phydev: the phy_device struct
@@ -504,7 +543,6 @@ static int phy_config_aneg(struct phy_device *phydev)
  */
 int phy_start_aneg(struct phy_device *phydev)
 {
-	bool trigger = 0;
 	int err;
 
 	if (!phydev->drv)
@@ -524,32 +562,16 @@ int phy_start_aneg(struct phy_device *phydev)
 
 	if (phydev->state != PHY_HALTED) {
 		if (AUTONEG_ENABLE == phydev->autoneg) {
-			phydev->state = PHY_AN;
-			phydev->link_timeout = PHY_AN_TIMEOUT;
+			err = phy_check_link_status(phydev);
 		} else {
 			phydev->state = PHY_FORCING;
 			phydev->link_timeout = PHY_FORCE_TIMEOUT;
 		}
 	}
 
-	/* Re-schedule a PHY state machine to check PHY status because
-	 * negotiation may already be done and aneg interrupt may not be
-	 * generated.
-	 */
-	if (!phy_polling_mode(phydev) && phydev->state == PHY_AN) {
-		err = phy_aneg_done(phydev);
-		if (err > 0) {
-			trigger = true;
-			err = 0;
-		}
-	}
-
 out_unlock:
 	mutex_unlock(&phydev->lock);
 
-	if (trigger)
-		phy_trigger_machine(phydev);
-
 	return err;
 }
 EXPORT_SYMBOL(phy_start_aneg);
@@ -893,18 +915,6 @@ void phy_start(struct phy_device *phydev)
 }
 EXPORT_SYMBOL(phy_start);
 
-static void phy_link_up(struct phy_device *phydev)
-{
-	phydev->phy_link_change(phydev, true, true);
-	phy_led_trigger_change_speed(phydev);
-}
-
-static void phy_link_down(struct phy_device *phydev, bool do_carrier)
-{
-	phydev->phy_link_change(phydev, false, do_carrier);
-	phy_led_trigger_change_speed(phydev);
-}
-
 /**
  * phy_state_machine - Handle the state machine
  * @work: work_struct that describes the work to be done
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next 4/5] net: phy: remove state PHY_AN
  2018-11-07 19:41 [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine Heiner Kallweit
                   ` (2 preceding siblings ...)
  2018-11-07 19:45 ` [PATCH net-next 3/5] net: phy: add phy_check_link_status Heiner Kallweit
@ 2018-11-07 19:46 ` Heiner Kallweit
  2018-11-07 19:47 ` [PATCH net-next 5/5] net: phy: use phy_check_link_status in more places in the state machine Heiner Kallweit
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Heiner Kallweit @ 2018-11-07 19:46 UTC (permalink / raw)
  To: Florian Fainelli, Andrew Lunn, David Miller; +Cc: netdev

After the recent changes in the state machine state PHY_AN isn't used
any longer and can be removed.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/net/phy/phy.c | 27 ---------------------------
 include/linux/phy.h   | 19 +------------------
 2 files changed, 1 insertion(+), 45 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 87ed00030..226824804 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -50,7 +50,6 @@ static const char *phy_state_to_str(enum phy_state st)
 	PHY_STATE_STR(READY)
 	PHY_STATE_STR(PENDING)
 	PHY_STATE_STR(UP)
-	PHY_STATE_STR(AN)
 	PHY_STATE_STR(RUNNING)
 	PHY_STATE_STR(NOLINK)
 	PHY_STATE_STR(FORCING)
@@ -944,32 +943,6 @@ void phy_state_machine(struct work_struct *work)
 	case PHY_UP:
 		needs_aneg = true;
 
-		phydev->link_timeout = PHY_AN_TIMEOUT;
-
-		break;
-	case PHY_AN:
-		err = phy_read_status(phydev);
-		if (err < 0)
-			break;
-
-		/* If the link is down, give up on negotiation for now */
-		if (!phydev->link) {
-			phydev->state = PHY_NOLINK;
-			phy_link_down(phydev, true);
-			break;
-		}
-
-		/* Check if negotiation is done.  Break if there's an error */
-		err = phy_aneg_done(phydev);
-		if (err < 0)
-			break;
-
-		/* If AN is done, we're running */
-		if (err > 0) {
-			phydev->state = PHY_RUNNING;
-			phy_link_up(phydev);
-		} else if (0 == phydev->link_timeout--)
-			needs_aneg = true;
 		break;
 	case PHY_NOLINK:
 		if (!phy_polling_mode(phydev))
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 9e4d49ef4..2090277ea 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -178,7 +178,6 @@ static inline const char *phy_modes(phy_interface_t interface)
 #define PHY_INIT_TIMEOUT	100000
 #define PHY_STATE_TIME		1
 #define PHY_FORCE_TIMEOUT	10
-#define PHY_AN_TIMEOUT		10
 
 #define PHY_MAX_ADDR	32
 
@@ -297,24 +296,10 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
  *
  * UP: The PHY and attached device are ready to do work.
  * Interrupts should be started here.
- * - timer moves to AN
- *
- * AN: The PHY is currently negotiating the link state.  Link is
- * therefore down for now.  phy_timer will set this state when it
- * detects the state is UP.  config_aneg will set this state
- * whenever called with phydev->autoneg set to AUTONEG_ENABLE.
- * - If autonegotiation finishes, but there's no link, it sets
- *   the state to NOLINK.
- * - If aneg finishes with link, it sets the state to RUNNING,
- *   and calls adjust_link
- * - If autonegotiation did not finish after an arbitrary amount
- *   of time, autonegotiation should be tried again if the PHY
- *   supports "magic" autonegotiation (back to AN)
- * - If it didn't finish, and no magic_aneg, move to FORCING.
+ * - timer moves to NOLINK or RUNNING
  *
  * NOLINK: PHY is up, but not currently plugged in.
  * - If the timer notes that the link comes back, we move to RUNNING
- * - config_aneg moves to AN
  * - phy_stop moves to HALTED
  *
  * FORCING: PHY is being configured with forced settings
@@ -329,7 +314,6 @@ struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr);
  *   link state is polled every other cycle of this state machine,
  *   which makes it every other second)
  * - irq will set CHANGELINK
- * - config_aneg will set AN
  * - phy_stop moves to HALTED
  *
  * CHANGELINK: PHY experienced a change in link state
@@ -353,7 +337,6 @@ enum phy_state {
 	PHY_READY,
 	PHY_PENDING,
 	PHY_UP,
-	PHY_AN,
 	PHY_RUNNING,
 	PHY_NOLINK,
 	PHY_FORCING,
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH net-next 5/5] net: phy: use phy_check_link_status in more places in the state machine
  2018-11-07 19:41 [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine Heiner Kallweit
                   ` (3 preceding siblings ...)
  2018-11-07 19:46 ` [PATCH net-next 4/5] net: phy: remove state PHY_AN Heiner Kallweit
@ 2018-11-07 19:47 ` Heiner Kallweit
  2018-11-07 19:48 ` [PATCH net-next 0/5] net: phy: improve and simplify phylib " Andrew Lunn
  2018-11-08 22:58 ` David Miller
  6 siblings, 0 replies; 15+ messages in thread
From: Heiner Kallweit @ 2018-11-07 19:47 UTC (permalink / raw)
  To: Florian Fainelli, Andrew Lunn, David Miller; +Cc: netdev

Use phy_check_link_status in more places in the state machine.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
---
 drivers/net/phy/phy.c | 53 ++++---------------------------------------
 1 file changed, 5 insertions(+), 48 deletions(-)

diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index 226824804..dd5bff955 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -945,17 +945,13 @@ void phy_state_machine(struct work_struct *work)
 
 		break;
 	case PHY_NOLINK:
+	case PHY_RUNNING:
 		if (!phy_polling_mode(phydev))
 			break;
-
-		err = phy_read_status(phydev);
-		if (err)
-			break;
-
-		if (phydev->link) {
-			phydev->state = PHY_RUNNING;
-			phy_link_up(phydev);
-		}
+		/* fall through */
+	case PHY_CHANGELINK:
+	case PHY_RESUMING:
+		err = phy_check_link_status(phydev);
 		break;
 	case PHY_FORCING:
 		err = genphy_update_link(phydev);
@@ -971,32 +967,6 @@ void phy_state_machine(struct work_struct *work)
 			phy_link_down(phydev, false);
 		}
 		break;
-	case PHY_RUNNING:
-		if (!phy_polling_mode(phydev))
-			break;
-
-		err = phy_read_status(phydev);
-		if (err)
-			break;
-
-		if (!phydev->link) {
-			phydev->state = PHY_NOLINK;
-			phy_link_down(phydev, true);
-		}
-		break;
-	case PHY_CHANGELINK:
-		err = phy_read_status(phydev);
-		if (err)
-			break;
-
-		if (phydev->link) {
-			phydev->state = PHY_RUNNING;
-			phy_link_up(phydev);
-		} else {
-			phydev->state = PHY_NOLINK;
-			phy_link_down(phydev, true);
-		}
-		break;
 	case PHY_HALTED:
 		if (phydev->link) {
 			phydev->link = 0;
@@ -1004,19 +974,6 @@ void phy_state_machine(struct work_struct *work)
 			do_suspend = true;
 		}
 		break;
-	case PHY_RESUMING:
-		err = phy_read_status(phydev);
-		if (err)
-			break;
-
-		if (phydev->link) {
-			phydev->state = PHY_RUNNING;
-			phy_link_up(phydev);
-		} else	{
-			phydev->state = PHY_NOLINK;
-			phy_link_down(phydev, true);
-		}
-		break;
 	}
 
 	mutex_unlock(&phydev->lock);
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine
  2018-11-07 19:41 [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine Heiner Kallweit
                   ` (4 preceding siblings ...)
  2018-11-07 19:47 ` [PATCH net-next 5/5] net: phy: use phy_check_link_status in more places in the state machine Heiner Kallweit
@ 2018-11-07 19:48 ` Andrew Lunn
  2018-11-07 20:05   ` Heiner Kallweit
  2018-11-08 22:58 ` David Miller
  6 siblings, 1 reply; 15+ messages in thread
From: Andrew Lunn @ 2018-11-07 19:48 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Florian Fainelli, David Miller, netdev

On Wed, Nov 07, 2018 at 08:41:52PM +0100, Heiner Kallweit wrote:
> This patch series is based on two axioms:
> 
> - During autoneg a PHY always reports the link being down

Hi Heiner

I think that is a risky assumption to make.

What happens if this assumption is incorrect?

     Andrew

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine
  2018-11-07 19:48 ` [PATCH net-next 0/5] net: phy: improve and simplify phylib " Andrew Lunn
@ 2018-11-07 20:05   ` Heiner Kallweit
  2018-11-07 20:21     ` Andrew Lunn
  0 siblings, 1 reply; 15+ messages in thread
From: Heiner Kallweit @ 2018-11-07 20:05 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Florian Fainelli, David Miller, netdev

On 07.11.2018 20:48, Andrew Lunn wrote:
> On Wed, Nov 07, 2018 at 08:41:52PM +0100, Heiner Kallweit wrote:
>> This patch series is based on two axioms:
>>
>> - During autoneg a PHY always reports the link being down
> 
> Hi Heiner
> 
> I think that is a risky assumption to make.
> 
I wasn't sure initially too (found no clear rule in 802.3 clause 22)
and therefore asked around. Florian agrees to the assumption,
see here: https://www.spinics.net/lists/netdev/msg519242.html

If a PHY reports the link as up then every user would assume that
data can be transferred. But that's not the case during aneg.
Therefore reporting the link as up during aneg wouldn't make sense.

> What happens if this assumption is incorrect?
> 
Then we have to flush this patch series down the drain ;)
At least I would have to check in detail which parts need to be
changed. I clearly mention the assumptions so that every
reviewer can check whether he agrees.

>      Andrew
> 
Heiner

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine
  2018-11-07 20:05   ` Heiner Kallweit
@ 2018-11-07 20:21     ` Andrew Lunn
  2018-11-07 20:45       ` Heiner Kallweit
  0 siblings, 1 reply; 15+ messages in thread
From: Andrew Lunn @ 2018-11-07 20:21 UTC (permalink / raw)
  To: Heiner Kallweit; +Cc: Florian Fainelli, David Miller, netdev

On Wed, Nov 07, 2018 at 09:05:49PM +0100, Heiner Kallweit wrote:
> On 07.11.2018 20:48, Andrew Lunn wrote:
> > On Wed, Nov 07, 2018 at 08:41:52PM +0100, Heiner Kallweit wrote:
> >> This patch series is based on two axioms:
> >>
> >> - During autoneg a PHY always reports the link being down
> > 
> > Hi Heiner
> > 
> > I think that is a risky assumption to make.
> > 
> I wasn't sure initially too (found no clear rule in 802.3 clause 22)
> and therefore asked around. Florian agrees to the assumption,
> see here: https://www.spinics.net/lists/netdev/msg519242.html
> 
> If a PHY reports the link as up then every user would assume that
> data can be transferred. But that's not the case during aneg.
> Therefore reporting the link as up during aneg wouldn't make sense.

Hi Heiner

If auto-neg has already been completed once before, i can see a lazy
hardware designed not reporting link down, or at least, not until
auto-neg actually fails.

And what about if link is down for too short a time for us to notice?
I've seen some code fail because the kernel went off and did something
else for too long, and a state change was missed. 

> > What happens if this assumption is incorrect?
> > 
> Then we have to flush this patch series down the drain ;)
> At least I would have to check in detail which parts need to be
> changed. I clearly mention the assumptions so that every
> reviewer can check whether he agrees.

Thanks for doing that. I want to be happy this is safe, and not going
to introduce regressions.

   Andrew

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine
  2018-11-07 20:21     ` Andrew Lunn
@ 2018-11-07 20:45       ` Heiner Kallweit
  2018-11-08  7:20         ` Heiner Kallweit
  0 siblings, 1 reply; 15+ messages in thread
From: Heiner Kallweit @ 2018-11-07 20:45 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Florian Fainelli, David Miller, netdev

On 07.11.2018 21:21, Andrew Lunn wrote:
> On Wed, Nov 07, 2018 at 09:05:49PM +0100, Heiner Kallweit wrote:
>> On 07.11.2018 20:48, Andrew Lunn wrote:
>>> On Wed, Nov 07, 2018 at 08:41:52PM +0100, Heiner Kallweit wrote:
>>>> This patch series is based on two axioms:
>>>>
>>>> - During autoneg a PHY always reports the link being down
>>>
>>> Hi Heiner
>>>
>>> I think that is a risky assumption to make.
>>>
>> I wasn't sure initially too (found no clear rule in 802.3 clause 22)
>> and therefore asked around. Florian agrees to the assumption,
>> see here: https://www.spinics.net/lists/netdev/msg519242.html
>>
>> If a PHY reports the link as up then every user would assume that
>> data can be transferred. But that's not the case during aneg.
>> Therefore reporting the link as up during aneg wouldn't make sense.
> 
> Hi Heiner
> 
> If auto-neg has already been completed once before, i can see a lazy
> hardware designed not reporting link down, or at least, not until
> auto-neg actually fails.
> 
"aneg finished" flag means that the aneg parameters in the register set
are valid. Once the link goes down that's not necessarily the case any
longer. E.g. some PHYs have an "auto speed down" feature and reduce
the speed to save power once they detect the link is down.
Of course I can not rule out that there are broken designs (or as you
stated more politely: lazy designs) out there. But in this case I assume
we would see issues already. And we would have to think about whether we
want to support such broken / lazy designs in phylib.

> And what about if link is down for too short a time for us to notice?
> I've seen some code fail because the kernel went off and did something
> else for too long, and a state change was missed. 
> 
This is a case we have already, independent of my change.
genphy_update_link() reads BMSR twice, thus ignoring potential latched
info about a temporary link failure. When polling phylib ignores
everything that happens between two poll intervals.

>>> What happens if this assumption is incorrect?
>>>
>> Then we have to flush this patch series down the drain ;)
>> At least I would have to check in detail which parts need to be
>> changed. I clearly mention the assumptions so that every
>> reviewer can check whether he agrees.
> 
> Thanks for doing that. I want to be happy this is safe, and not going
> to introduce regressions.
> 
>    Andrew
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine
  2018-11-07 20:45       ` Heiner Kallweit
@ 2018-11-08  7:20         ` Heiner Kallweit
  0 siblings, 0 replies; 15+ messages in thread
From: Heiner Kallweit @ 2018-11-08  7:20 UTC (permalink / raw)
  To: Andrew Lunn; +Cc: Florian Fainelli, David Miller, netdev

On 07.11.2018 21:45, Heiner Kallweit wrote:
> On 07.11.2018 21:21, Andrew Lunn wrote:
>> On Wed, Nov 07, 2018 at 09:05:49PM +0100, Heiner Kallweit wrote:
>>> On 07.11.2018 20:48, Andrew Lunn wrote:
>>>> On Wed, Nov 07, 2018 at 08:41:52PM +0100, Heiner Kallweit wrote:
>>>>> This patch series is based on two axioms:
>>>>>
>>>>> - During autoneg a PHY always reports the link being down
>>>>
>>>> Hi Heiner
>>>>
>>>> I think that is a risky assumption to make.
>>>>
>>> I wasn't sure initially too (found no clear rule in 802.3 clause 22)
>>> and therefore asked around. Florian agrees to the assumption,
>>> see here: https://www.spinics.net/lists/netdev/msg519242.html
>>>
>>> If a PHY reports the link as up then every user would assume that
>>> data can be transferred. But that's not the case during aneg.
>>> Therefore reporting the link as up during aneg wouldn't make sense.
>>
>> Hi Heiner
>>
>> If auto-neg has already been completed once before, i can see a lazy
>> hardware designed not reporting link down, or at least, not until
>> auto-neg actually fails.
>>
> "aneg finished" flag means that the aneg parameters in the register set
> are valid. Once the link goes down that's not necessarily the case any
> longer. E.g. some PHYs have an "auto speed down" feature and reduce
> the speed to save power once they detect the link is down.
> Of course I can not rule out that there are broken designs (or as you
> stated more politely: lazy designs) out there. But in this case I assume
> we would see issues already. And we would have to think about whether we
> want to support such broken / lazy designs in phylib.
> 
Had one more look at the changes to check what happens if "link up" and
"aneg done" are not in sync.

When link goes down the changes don't change current behavior. We just
check the "link up" bit.

When link goes up and aneg isn't finished yet, then we would report
"link is up" earlier to userspace than we do now. If userspace starts
some network activity based on the "link up" event then they may fail.
But it really would be a major flaw if a PHY signals "link up" whilst
it's not actually ready yet to transfer data.

In case of such a broken design we would have issues with the current
code already, at least if interrupts are used. The "link up" interrupt
would cause the state machine to go to PHY_CHANGELINK which doesn't
check for aneg status.

>> And what about if link is down for too short a time for us to notice?
>> I've seen some code fail because the kernel went off and did something
>> else for too long, and a state change was missed. 
>>
> This is a case we have already, independent of my change.
> genphy_update_link() reads BMSR twice, thus ignoring potential latched
> info about a temporary link failure. When polling phylib ignores
> everything that happens between two poll intervals.
> 
>>>> What happens if this assumption is incorrect?
>>>>
>>> Then we have to flush this patch series down the drain ;)
>>> At least I would have to check in detail which parts need to be
>>> changed. I clearly mention the assumptions so that every
>>> reviewer can check whether he agrees.
>>
>> Thanks for doing that. I want to be happy this is safe, and not going
>> to introduce regressions.
>>
>>    Andrew
>>
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine
  2018-11-07 19:41 [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine Heiner Kallweit
                   ` (5 preceding siblings ...)
  2018-11-07 19:48 ` [PATCH net-next 0/5] net: phy: improve and simplify phylib " Andrew Lunn
@ 2018-11-08 22:58 ` David Miller
  2018-11-08 23:00   ` Florian Fainelli
  6 siblings, 1 reply; 15+ messages in thread
From: David Miller @ 2018-11-08 22:58 UTC (permalink / raw)
  To: hkallweit1; +Cc: f.fainelli, andrew, netdev

From: Heiner Kallweit <hkallweit1@gmail.com>
Date: Wed, 7 Nov 2018 20:41:52 +0100

> This patch series is based on two axioms:
> 
> - During autoneg a PHY always reports the link being down
> 
> - Info in clause 22/45 registers doesn't allow to differentiate between
>   these two states:
>   1. Link is physically down
>   2. A link partner is connected and PHY is autonegotiating
>   In both cases "link up" and "aneg finished" bits aren't set.
>   One consequence is that having separate states PHY_NOLINK and PHY_AN
>   isn't needed.
> 
> By using these two axioms the state machine can be significantly
> simplified.

So how are we going to move forward on this?

Maybe we can apply this series and just watch carefully for any
problems that get reported or are found?

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine
  2018-11-08 22:58 ` David Miller
@ 2018-11-08 23:00   ` Florian Fainelli
  2018-11-08 23:01     ` Andrew Lunn
  2018-11-08 23:04     ` David Miller
  0 siblings, 2 replies; 15+ messages in thread
From: Florian Fainelli @ 2018-11-08 23:00 UTC (permalink / raw)
  To: David Miller, hkallweit1; +Cc: andrew, netdev

On 11/8/18 2:58 PM, David Miller wrote:
> From: Heiner Kallweit <hkallweit1@gmail.com>
> Date: Wed, 7 Nov 2018 20:41:52 +0100
> 
>> This patch series is based on two axioms:
>>
>> - During autoneg a PHY always reports the link being down
>>
>> - Info in clause 22/45 registers doesn't allow to differentiate between
>>   these two states:
>>   1. Link is physically down
>>   2. A link partner is connected and PHY is autonegotiating
>>   In both cases "link up" and "aneg finished" bits aren't set.
>>   One consequence is that having separate states PHY_NOLINK and PHY_AN
>>   isn't needed.
>>
>> By using these two axioms the state machine can be significantly
>> simplified.
> 
> So how are we going to move forward on this?
> 
> Maybe we can apply this series and just watch carefully for any
> problems that get reported or are found?

Given Heiner is always responsive and taking care of fixing what might
be/have broken, no objections with me on that.
-- 
Florian

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine
  2018-11-08 23:00   ` Florian Fainelli
@ 2018-11-08 23:01     ` Andrew Lunn
  2018-11-08 23:04     ` David Miller
  1 sibling, 0 replies; 15+ messages in thread
From: Andrew Lunn @ 2018-11-08 23:01 UTC (permalink / raw)
  To: Florian Fainelli; +Cc: David Miller, hkallweit1, netdev

On Thu, Nov 08, 2018 at 03:00:01PM -0800, Florian Fainelli wrote:
> On 11/8/18 2:58 PM, David Miller wrote:
> > From: Heiner Kallweit <hkallweit1@gmail.com>
> > Date: Wed, 7 Nov 2018 20:41:52 +0100
> > 
> >> This patch series is based on two axioms:
> >>
> >> - During autoneg a PHY always reports the link being down
> >>
> >> - Info in clause 22/45 registers doesn't allow to differentiate between
> >>   these two states:
> >>   1. Link is physically down
> >>   2. A link partner is connected and PHY is autonegotiating
> >>   In both cases "link up" and "aneg finished" bits aren't set.
> >>   One consequence is that having separate states PHY_NOLINK and PHY_AN
> >>   isn't needed.
> >>
> >> By using these two axioms the state machine can be significantly
> >> simplified.
> > 
> > So how are we going to move forward on this?
> > 
> > Maybe we can apply this series and just watch carefully for any
> > problems that get reported or are found?
> 
> Given Heiner is always responsive and taking care of fixing what might
> be/have broken, no objections with me on that.

Yes, lets try it.

     Andrew

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine
  2018-11-08 23:00   ` Florian Fainelli
  2018-11-08 23:01     ` Andrew Lunn
@ 2018-11-08 23:04     ` David Miller
  1 sibling, 0 replies; 15+ messages in thread
From: David Miller @ 2018-11-08 23:04 UTC (permalink / raw)
  To: f.fainelli; +Cc: hkallweit1, andrew, netdev

From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 8 Nov 2018 15:00:01 -0800

> On 11/8/18 2:58 PM, David Miller wrote:
>> From: Heiner Kallweit <hkallweit1@gmail.com>
>> Date: Wed, 7 Nov 2018 20:41:52 +0100
>> 
>>> This patch series is based on two axioms:
>>>
>>> - During autoneg a PHY always reports the link being down
>>>
>>> - Info in clause 22/45 registers doesn't allow to differentiate between
>>>   these two states:
>>>   1. Link is physically down
>>>   2. A link partner is connected and PHY is autonegotiating
>>>   In both cases "link up" and "aneg finished" bits aren't set.
>>>   One consequence is that having separate states PHY_NOLINK and PHY_AN
>>>   isn't needed.
>>>
>>> By using these two axioms the state machine can be significantly
>>> simplified.
>> 
>> So how are we going to move forward on this?
>> 
>> Maybe we can apply this series and just watch carefully for any
>> problems that get reported or are found?
> 
> Given Heiner is always responsive and taking care of fixing what might
> be/have broken, no objections with me on that.

Great, I've applied this series to net-next then.

Thanks.

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2018-11-09  8:42 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-07 19:41 [PATCH net-next 0/5] net: phy: improve and simplify phylib state machine Heiner Kallweit
2018-11-07 19:43 ` [PATCH net-next 1/5] net: phy: remove useless check in state machine case PHY_NOLINK Heiner Kallweit
2018-11-07 19:44 ` [PATCH net-next 2/5] net: phy: remove useless check in state machine case PHY_RESUMING Heiner Kallweit
2018-11-07 19:45 ` [PATCH net-next 3/5] net: phy: add phy_check_link_status Heiner Kallweit
2018-11-07 19:46 ` [PATCH net-next 4/5] net: phy: remove state PHY_AN Heiner Kallweit
2018-11-07 19:47 ` [PATCH net-next 5/5] net: phy: use phy_check_link_status in more places in the state machine Heiner Kallweit
2018-11-07 19:48 ` [PATCH net-next 0/5] net: phy: improve and simplify phylib " Andrew Lunn
2018-11-07 20:05   ` Heiner Kallweit
2018-11-07 20:21     ` Andrew Lunn
2018-11-07 20:45       ` Heiner Kallweit
2018-11-08  7:20         ` Heiner Kallweit
2018-11-08 22:58 ` David Miller
2018-11-08 23:00   ` Florian Fainelli
2018-11-08 23:01     ` Andrew Lunn
2018-11-08 23:04     ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).