All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] smsc911x: power-up phydev before doing a software reset.
@ 2014-11-10 18:23 Enric Balletbo i Serra
  2014-11-11 11:20 ` Javier Martinez Canillas
  2014-11-11 23:30 ` David Miller
  0 siblings, 2 replies; 5+ messages in thread
From: Enric Balletbo i Serra @ 2014-11-10 18:23 UTC (permalink / raw)
  To: netdev, Steve Glendinning; +Cc: javier, ebutera, Enric Balletbo i Serra

With commit be9dad1f9f26604fb ("net: phy: suspend phydev when going
to HALTED"), the PHY device will be put in a low-power mode using
BMCR_PDOWN if the the interface is set down. The smsc911x driver does
a software_reset opening the device driver (ndo_open). In such case,
the PHY must be powered-up before access to any register and before
calling the software_reset function. Otherwise, as the PHY is powered
down the software reset fails and the interface can not be enabled
again.

This patch fixes this scenario that is easy to reproduce setting down
the network interface and setting up again.

    $ ifconfig eth0 down
    $ ifconfig eth0 up
    ifconfig: SIOCSIFFLAGS: Input/output error

Signed-off-by: Enric Balletbo i Serra <eballetbo@iseebcn.com>
---
 drivers/net/ethernet/smsc/smsc911x.c | 46 ++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index affb29d..d8bfe94 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -1342,6 +1342,42 @@ static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata)
 	spin_unlock(&pdata->mac_lock);
 }
 
+static int smsc911x_phy_general_power_up(struct smsc911x_data *pdata)
+{
+	int rc = 0;
+
+	if (!pdata->phy_dev)
+		return rc;
+
+	/* If the internal PHY is in General Power-Down mode, all, except the
+	 * management interface, is powered-down and stays in that condition as
+	 * long as Phy register bit 0.11 is HIGH.
+	 *
+	 * In that case, clear the bit 0.11, so the PHY powers up and we can
+	 * access to the phy registers.
+	 */
+	rc = phy_read(pdata->phy_dev, MII_BMCR);
+	if (rc < 0) {
+		SMSC_WARN(pdata, drv, "Failed reading PHY control reg");
+		return rc;
+	}
+
+	/* If the PHY general power-down bit is not set is not necessary to
+	 * disable the general power down-mode.
+	 */
+	if (rc & BMCR_PDOWN) {
+		rc = phy_write(pdata->phy_dev, MII_BMCR, rc & ~BMCR_PDOWN);
+		if (rc < 0) {
+			SMSC_WARN(pdata, drv, "Failed writing PHY control reg");
+			return rc;
+		}
+
+		mdelay(1);
+	}
+
+	return 0;
+}
+
 static int smsc911x_phy_disable_energy_detect(struct smsc911x_data *pdata)
 {
 	int rc = 0;
@@ -1415,6 +1451,16 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata)
 	int ret;
 
 	/*
+	 * Make sure to power-up the PHY chip before doing a reset, otherwise
+	 * the reset fails.
+	 */
+	ret = smsc911x_phy_general_power_up(pdata);
+	if (ret) {
+		SMSC_WARN(pdata, drv, "Failed to power-up the PHY chip");
+		return ret;
+	}
+
+	/*
 	 * LAN9210/LAN9211/LAN9220/LAN9221 chips have an internal PHY that
 	 * are initialized in a Energy Detect Power-Down mode that prevents
 	 * the MAC chip to be software reseted. So we have to wakeup the PHY
-- 
1.9.1

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

* Re: [PATCH] smsc911x: power-up phydev before doing a software reset.
  2014-11-10 18:23 [PATCH] smsc911x: power-up phydev before doing a software reset Enric Balletbo i Serra
@ 2014-11-11 11:20 ` Javier Martinez Canillas
  2014-11-11 23:30 ` David Miller
  1 sibling, 0 replies; 5+ messages in thread
From: Javier Martinez Canillas @ 2014-11-11 11:20 UTC (permalink / raw)
  To: Enric Balletbo i Serra; +Cc: netdev, Steve Glendinning, Enrico Butera

Hello Enric,

On Mon, Nov 10, 2014 at 7:23 PM, Enric Balletbo i Serra
<eballetbo@iseebcn.com> wrote:
> With commit be9dad1f9f26604fb ("net: phy: suspend phydev when going
> to HALTED"), the PHY device will be put in a low-power mode using
> BMCR_PDOWN if the the interface is set down. The smsc911x driver does
> a software_reset opening the device driver (ndo_open). In such case,
> the PHY must be powered-up before access to any register and before
> calling the software_reset function. Otherwise, as the PHY is powered
> down the software reset fails and the interface can not be enabled
> again.
>

The patch looks good to me, I just have a small comment.

> +
> +       /* If the PHY general power-down bit is not set is not necessary to
> +        * disable the general power down-mode.
> +        */
> +       if (rc & BMCR_PDOWN) {
> +               rc = phy_write(pdata->phy_dev, MII_BMCR, rc & ~BMCR_PDOWN);
> +               if (rc < 0) {
> +                       SMSC_WARN(pdata, drv, "Failed writing PHY control reg");
> +                       return rc;
> +               }
> +
> +               mdelay(1);

According to Documentation/timers/timers-howto.txt, the *delay()
family of functions should only be used in atomic context since those
are implemented as a busy-wait loop to achieve the desired delay.

AFAICT smsc911x_soft_reset() is only called from process context so
usleep_range() should be used instead.

Best regards,
Javier

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

* Re: [PATCH] smsc911x: power-up phydev before doing a software reset.
  2014-11-10 18:23 [PATCH] smsc911x: power-up phydev before doing a software reset Enric Balletbo i Serra
  2014-11-11 11:20 ` Javier Martinez Canillas
@ 2014-11-11 23:30 ` David Miller
  2014-11-13  7:57   ` Enric Balletbo Serra
  1 sibling, 1 reply; 5+ messages in thread
From: David Miller @ 2014-11-11 23:30 UTC (permalink / raw)
  To: eballetbo; +Cc: netdev, steve.glendinning, javier, ebutera

From: Enric Balletbo i Serra <eballetbo@iseebcn.com>
Date: Mon, 10 Nov 2014 19:23:09 +0100

> With commit be9dad1f9f26604fb ("net: phy: suspend phydev when going
> to HALTED"), the PHY device will be put in a low-power mode using
> BMCR_PDOWN if the the interface is set down. The smsc911x driver does
> a software_reset opening the device driver (ndo_open). In such case,
> the PHY must be powered-up before access to any register and before
> calling the software_reset function. Otherwise, as the PHY is powered
> down the software reset fails and the interface can not be enabled
> again.
> 
> This patch fixes this scenario that is easy to reproduce setting down
> the network interface and setting up again.
> 
>     $ ifconfig eth0 down
>     $ ifconfig eth0 up
>     ifconfig: SIOCSIFFLAGS: Input/output error
> 
> Signed-off-by: Enric Balletbo i Serra <eballetbo@iseebcn.com>
 ...
> +		mdelay(1);

As per Javier's feedback, please convert this to usleep_range()
if you agree that this can only be invoked from process context.

Thanks.

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

* Re: [PATCH] smsc911x: power-up phydev before doing a software reset.
  2014-11-11 23:30 ` David Miller
@ 2014-11-13  7:57   ` Enric Balletbo Serra
  2014-11-13  8:27     ` Javier Martinez Canillas
  0 siblings, 1 reply; 5+ messages in thread
From: Enric Balletbo Serra @ 2014-11-13  7:57 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, Steve Glendinning, Javier Martinez Canillas, Enrico Butera

Hi,

2014-11-12 0:30 GMT+01:00 David Miller <davem@davemloft.net>:
> From: Enric Balletbo i Serra <eballetbo@iseebcn.com>
> Date: Mon, 10 Nov 2014 19:23:09 +0100
>
>> With commit be9dad1f9f26604fb ("net: phy: suspend phydev when going
>> to HALTED"), the PHY device will be put in a low-power mode using
>> BMCR_PDOWN if the the interface is set down. The smsc911x driver does
>> a software_reset opening the device driver (ndo_open). In such case,
>> the PHY must be powered-up before access to any register and before
>> calling the software_reset function. Otherwise, as the PHY is powered
>> down the software reset fails and the interface can not be enabled
>> again.
>>
>> This patch fixes this scenario that is easy to reproduce setting down
>> the network interface and setting up again.
>>
>>     $ ifconfig eth0 down
>>     $ ifconfig eth0 up
>>     ifconfig: SIOCSIFFLAGS: Input/output error
>>
>> Signed-off-by: Enric Balletbo i Serra <eballetbo@iseebcn.com>
>  ...
>> +             mdelay(1);
>
> As per Javier's feedback, please convert this to usleep_range()
> if you agree that this can only be invoked from process context.
>

Yes, I'm agree. I'll send version 2 of the patch changing this. Also
there are other places that use the mdelay family intead of
usleep_range() and can only be invoked from process context. Maybe
would be interesting send another patch changing this.

Cheers,
   Enric

> Thanks.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH] smsc911x: power-up phydev before doing a software reset.
  2014-11-13  7:57   ` Enric Balletbo Serra
@ 2014-11-13  8:27     ` Javier Martinez Canillas
  0 siblings, 0 replies; 5+ messages in thread
From: Javier Martinez Canillas @ 2014-11-13  8:27 UTC (permalink / raw)
  To: Enric Balletbo Serra
  Cc: David Miller, netdev, Steve Glendinning, Enrico Butera

Hello Enric,

On Thu, Nov 13, 2014 at 8:57 AM, Enric Balletbo Serra
<eballetbo@gmail.com> wrote:
>
> Yes, I'm agree. I'll send version 2 of the patch changing this. Also
> there are other places that use the mdelay family intead of
> usleep_range() and can only be invoked from process context. Maybe
> would be interesting send another patch changing this.
>

Agreed, that could be a separate patch though.

Also there is a mdelay(100) before enabling energy detect mode in
smsc911x_phy_enable_energy_detect() which I believe can be removed.

Best regards,
Javier

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

end of thread, other threads:[~2014-11-13  8:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-11-10 18:23 [PATCH] smsc911x: power-up phydev before doing a software reset Enric Balletbo i Serra
2014-11-11 11:20 ` Javier Martinez Canillas
2014-11-11 23:30 ` David Miller
2014-11-13  7:57   ` Enric Balletbo Serra
2014-11-13  8:27     ` Javier Martinez Canillas

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.