diff options
| author | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
|---|---|---|
| committer | Dmitry Torokhov <[email protected]> | 2023-08-30 16:06:38 -0700 | 
| commit | 1ac731c529cd4d6adbce134754b51ff7d822b145 (patch) | |
| tree | 143ab3f35ca5f3b69f583c84e6964b17139c2ec1 /drivers/net/phy/phy.c | |
| parent | 07b4c950f27bef0362dc6ad7ee713aab61d58149 (diff) | |
| parent | 54116d442e001e1b6bd482122043b1870998a1f3 (diff) | |
Merge branch 'next' into for-linus
Prepare input updates for 6.6 merge window.
Diffstat (limited to 'drivers/net/phy/phy.c')
| -rw-r--r-- | drivers/net/phy/phy.c | 56 | 
1 files changed, 40 insertions, 16 deletions
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index b33e55a7364e..0c0df38cd1ab 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -57,6 +57,18 @@ static const char *phy_state_to_str(enum phy_state st)  	return NULL;  } +static void phy_process_state_change(struct phy_device *phydev, +				     enum phy_state old_state) +{ +	if (old_state != phydev->state) { +		phydev_dbg(phydev, "PHY state change %s -> %s\n", +			   phy_state_to_str(old_state), +			   phy_state_to_str(phydev->state)); +		if (phydev->drv && phydev->drv->link_change_notify) +			phydev->drv->link_change_notify(phydev); +	} +} +  static void phy_link_up(struct phy_device *phydev)  {  	phydev->phy_link_change(phydev, true); @@ -1169,6 +1181,22 @@ void phy_stop_machine(struct phy_device *phydev)  	mutex_unlock(&phydev->lock);  } +static void phy_process_error(struct phy_device *phydev) +{ +	mutex_lock(&phydev->lock); +	phydev->state = PHY_HALTED; +	mutex_unlock(&phydev->lock); + +	phy_trigger_machine(phydev); +} + +static void phy_error_precise(struct phy_device *phydev, +			      const void *func, int err) +{ +	WARN(1, "%pS: returned: %d\n", func, err); +	phy_process_error(phydev); +} +  /**   * phy_error - enter HALTED state for this PHY device   * @phydev: target phy_device struct @@ -1181,12 +1209,7 @@ void phy_stop_machine(struct phy_device *phydev)  void phy_error(struct phy_device *phydev)  {  	WARN_ON(1); - -	mutex_lock(&phydev->lock); -	phydev->state = PHY_HALTED; -	mutex_unlock(&phydev->lock); - -	phy_trigger_machine(phydev); +	phy_process_error(phydev);  }  EXPORT_SYMBOL(phy_error); @@ -1301,6 +1324,7 @@ EXPORT_SYMBOL(phy_free_interrupt);  void phy_stop(struct phy_device *phydev)  {  	struct net_device *dev = phydev->attached_dev; +	enum phy_state old_state;  	if (!phy_is_started(phydev) && phydev->state != PHY_DOWN) {  		WARN(1, "called from state %s\n", @@ -1309,6 +1333,7 @@ void phy_stop(struct phy_device *phydev)  	}  	mutex_lock(&phydev->lock); +	old_state = phydev->state;  	if (phydev->state == PHY_CABLETEST) {  		phy_abort_cable_test(phydev); @@ -1319,6 +1344,7 @@ void phy_stop(struct phy_device *phydev)  		sfp_upstream_stop(phydev->sfp_bus);  	phydev->state = PHY_HALTED; +	phy_process_state_change(phydev, old_state);  	mutex_unlock(&phydev->lock); @@ -1378,6 +1404,7 @@ void phy_state_machine(struct work_struct *work)  	struct net_device *dev = phydev->attached_dev;  	bool needs_aneg = false, do_suspend = false;  	enum phy_state old_state; +	const void *func = NULL;  	bool finished = false;  	int err = 0; @@ -1396,6 +1423,7 @@ void phy_state_machine(struct work_struct *work)  	case PHY_NOLINK:  	case PHY_RUNNING:  		err = phy_check_link_status(phydev); +		func = &phy_check_link_status;  		break;  	case PHY_CABLETEST:  		err = phydev->drv->cable_test_get_status(phydev, &finished); @@ -1425,24 +1453,20 @@ void phy_state_machine(struct work_struct *work)  	mutex_unlock(&phydev->lock); -	if (needs_aneg) +	if (needs_aneg) {  		err = phy_start_aneg(phydev); -	else if (do_suspend) +		func = &phy_start_aneg; +	} else if (do_suspend) {  		phy_suspend(phydev); +	}  	if (err == -ENODEV)  		return;  	if (err < 0) -		phy_error(phydev); +		phy_error_precise(phydev, func, err); -	if (old_state != phydev->state) { -		phydev_dbg(phydev, "PHY state change %s -> %s\n", -			   phy_state_to_str(old_state), -			   phy_state_to_str(phydev->state)); -		if (phydev->drv && phydev->drv->link_change_notify) -			phydev->drv->link_change_notify(phydev); -	} +	phy_process_state_change(phydev, old_state);  	/* Only re-schedule a PHY state machine change if we are polling the  	 * PHY, if PHY_MAC_INTERRUPT is set, then we will be moving  |