netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 1/2] net: phy: smsc: Move SMSC PHY constants to <linux/smscphy.h>
@ 2012-01-03 23:36 Javier Martinez Canillas
  2012-01-03 23:36 ` [PATCH v2 2/2] net/smsc911x: Check if PHY is in operational mode before software reset Javier Martinez Canillas
  2012-01-04  1:24 ` [PATCH v2 1/2] net: phy: smsc: Move SMSC PHY constants to <linux/smscphy.h> David Miller
  0 siblings, 2 replies; 4+ messages in thread
From: Javier Martinez Canillas @ 2012-01-03 23:36 UTC (permalink / raw)
  To: David Miller
  Cc: steve.glendinning, eballetbo, ben, netdev,
	Javier Martinez Canillas

SMSC generation 4 LAN chips integrate an IEEE 802.3 ethernet physical layer.
The ethernet driver for this family of devices needs to access the SMSC PHY
registers and bit-fields.

So, this patch moves these constants to a place where it can be used for both
the PHY and LAN drivers.

Signed-off-by: Javier Martinez Canillas <javier@dowhile0.org>
---
v2: Remove the GPL license from the file since are only trivial defines.
	
 drivers/net/ethernet/smsc/smsc911x.h |    4 ++++
 drivers/net/phy/smsc.c               |   21 +--------------------
 include/linux/smscphy.h              |   25 +++++++++++++++++++++++++
 3 files changed, 30 insertions(+), 20 deletions(-)
 create mode 100644 include/linux/smscphy.h

diff --git a/drivers/net/ethernet/smsc/smsc911x.h b/drivers/net/ethernet/smsc/smsc911x.h
index 8d67aac..938ecf2 100644
--- a/drivers/net/ethernet/smsc/smsc911x.h
+++ b/drivers/net/ethernet/smsc/smsc911x.h
@@ -401,4 +401,8 @@
 #include <asm/smsc911x.h>
 #endif
 
+#ifdef CONFIG_SMSC_PHY
+#include <linux/smscphy.h>
+#endif
+
 #endif				/* __SMSC911X_H__ */
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 342505c..fc3e7e9 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -22,26 +22,7 @@
 #include <linux/ethtool.h>
 #include <linux/phy.h>
 #include <linux/netdevice.h>
-
-#define MII_LAN83C185_ISF 29 /* Interrupt Source Flags */
-#define MII_LAN83C185_IM  30 /* Interrupt Mask */
-#define MII_LAN83C185_CTRL_STATUS 17 /* Mode/Status Register */
-
-#define MII_LAN83C185_ISF_INT1 (1<<1) /* Auto-Negotiation Page Received */
-#define MII_LAN83C185_ISF_INT2 (1<<2) /* Parallel Detection Fault */
-#define MII_LAN83C185_ISF_INT3 (1<<3) /* Auto-Negotiation LP Ack */
-#define MII_LAN83C185_ISF_INT4 (1<<4) /* Link Down */
-#define MII_LAN83C185_ISF_INT5 (1<<5) /* Remote Fault Detected */
-#define MII_LAN83C185_ISF_INT6 (1<<6) /* Auto-Negotiation complete */
-#define MII_LAN83C185_ISF_INT7 (1<<7) /* ENERGYON */
-
-#define MII_LAN83C185_ISF_INT_ALL (0x0e)
-
-#define MII_LAN83C185_ISF_INT_PHYLIB_EVENTS \
-	(MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4 | \
-	 MII_LAN83C185_ISF_INT7)
-
-#define MII_LAN83C185_EDPWRDOWN	(1 << 13) /* EDPWRDOWN */
+#include <linux/smscphy.h>
 
 static int smsc_phy_config_intr(struct phy_device *phydev)
 {
diff --git a/include/linux/smscphy.h b/include/linux/smscphy.h
new file mode 100644
index 0000000..ce718cb
--- /dev/null
+++ b/include/linux/smscphy.h
@@ -0,0 +1,25 @@
+#ifndef __LINUX_SMSCPHY_H__
+#define __LINUX_SMSCPHY_H__
+
+#define MII_LAN83C185_ISF 29 /* Interrupt Source Flags */
+#define MII_LAN83C185_IM  30 /* Interrupt Mask */
+#define MII_LAN83C185_CTRL_STATUS 17 /* Mode/Status Register */
+
+#define MII_LAN83C185_ISF_INT1 (1<<1) /* Auto-Negotiation Page Received */
+#define MII_LAN83C185_ISF_INT2 (1<<2) /* Parallel Detection Fault */
+#define MII_LAN83C185_ISF_INT3 (1<<3) /* Auto-Negotiation LP Ack */
+#define MII_LAN83C185_ISF_INT4 (1<<4) /* Link Down */
+#define MII_LAN83C185_ISF_INT5 (1<<5) /* Remote Fault Detected */
+#define MII_LAN83C185_ISF_INT6 (1<<6) /* Auto-Negotiation complete */
+#define MII_LAN83C185_ISF_INT7 (1<<7) /* ENERGYON */
+
+#define MII_LAN83C185_ISF_INT_ALL (0x0e)
+
+#define MII_LAN83C185_ISF_INT_PHYLIB_EVENTS \
+	(MII_LAN83C185_ISF_INT6 | MII_LAN83C185_ISF_INT4 | \
+	 MII_LAN83C185_ISF_INT7)
+
+#define MII_LAN83C185_EDPWRDOWN (1 << 13) /* EDPWRDOWN */
+#define MII_LAN83C185_ENERGYON  (1 << 1)  /* ENERGYON */
+
+#endif /* __LINUX_SMSCPHY_H__ */
-- 
1.7.4.1

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

* [PATCH v2 2/2] net/smsc911x: Check if PHY is in operational mode before software reset
  2012-01-03 23:36 [PATCH v2 1/2] net: phy: smsc: Move SMSC PHY constants to <linux/smscphy.h> Javier Martinez Canillas
@ 2012-01-03 23:36 ` Javier Martinez Canillas
  2012-01-04  1:24   ` David Miller
  2012-01-04  1:24 ` [PATCH v2 1/2] net: phy: smsc: Move SMSC PHY constants to <linux/smscphy.h> David Miller
  1 sibling, 1 reply; 4+ messages in thread
From: Javier Martinez Canillas @ 2012-01-03 23:36 UTC (permalink / raw)
  To: David Miller
  Cc: steve.glendinning, eballetbo, ben, netdev,
	Javier Martinez Canillas

SMSC LAN generation 4 chips integrate an IEEE 802.3 ethernet physical layer.
The PHY driver for this integrated chip enable an energy detect power-down mode.
When the PHY is in a power-down mode, it prevents the MAC portion chip to be
software reseted.

That means that if we compile the kernel with the configuration option SMSC_PHY
enabled and try to bring the network interface up without an cable plug-ed the
PHY will be in a low power mode and the software reset will fail returning -EIO
to user-space:

root@igep00x0:~# ifconfig eth0 up
ifconfig: SIOCSIFFLAGS: Input/output error

This patch disable the energy detect power-down mode before trying to software
reset the LAN chip and re-enables after it was reseted successfully.

Signed-off-by: Javier Martinez Canillas <javier@dowhile0.org>
---
v2: Use correct style for multi-line comments.

 drivers/net/ethernet/smsc/smsc911x.c |   92 ++++++++++++++++++++++++++++++++++
 1 files changed, 92 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/smsc/smsc911x.c b/drivers/net/ethernet/smsc/smsc911x.c
index 8843071..8485c3c 100644
--- a/drivers/net/ethernet/smsc/smsc911x.c
+++ b/drivers/net/ethernet/smsc/smsc911x.c
@@ -1243,10 +1243,92 @@ static void smsc911x_rx_multicast_update_workaround(struct smsc911x_data *pdata)
 	spin_unlock(&pdata->mac_lock);
 }
 
+static int smsc911x_phy_disable_energy_detect(struct smsc911x_data *pdata)
+{
+	int rc = 0;
+
+	if (!pdata->phy_dev)
+		return rc;
+
+	rc = phy_read(pdata->phy_dev, MII_LAN83C185_CTRL_STATUS);
+
+	if (rc < 0) {
+		SMSC_WARN(pdata, drv, "Failed reading PHY control reg");
+		return rc;
+	}
+
+	/*
+	 * If energy is detected the PHY is already awake so is not necessary
+	 * to disable the energy detect power-down mode.
+	 */
+	if ((rc & MII_LAN83C185_EDPWRDOWN) &&
+	    !(rc & MII_LAN83C185_ENERGYON)) {
+		/* Disable energy detect mode for this SMSC Transceivers */
+		rc = phy_write(pdata->phy_dev, MII_LAN83C185_CTRL_STATUS,
+			       rc & (~MII_LAN83C185_EDPWRDOWN));
+
+		if (rc < 0) {
+			SMSC_WARN(pdata, drv, "Failed writing PHY control reg");
+			return rc;
+		}
+
+		mdelay(1);
+	}
+
+	return 0;
+}
+
+static int smsc911x_phy_enable_energy_detect(struct smsc911x_data *pdata)
+{
+	int rc = 0;
+
+	if (!pdata->phy_dev)
+		return rc;
+
+	rc = phy_read(pdata->phy_dev, MII_LAN83C185_CTRL_STATUS);
+
+	if (rc < 0) {
+		SMSC_WARN(pdata, drv, "Failed reading PHY control reg");
+		return rc;
+	}
+
+	/* Only enable if energy detect mode is already disabled */
+	if (!(rc & MII_LAN83C185_EDPWRDOWN)) {
+		mdelay(100);
+		/* Enable energy detect mode for this SMSC Transceivers */
+		rc = phy_write(pdata->phy_dev, MII_LAN83C185_CTRL_STATUS,
+			       rc | MII_LAN83C185_EDPWRDOWN);
+
+		if (rc < 0) {
+			SMSC_WARN(pdata, drv, "Failed writing PHY control reg");
+			return rc;
+		}
+
+		mdelay(1);
+	}
+	return 0;
+}
+
 static int smsc911x_soft_reset(struct smsc911x_data *pdata)
 {
 	unsigned int timeout;
 	unsigned int temp;
+	int 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
+	 * before.
+	 */
+	if (pdata->generation == 4) {
+		ret = smsc911x_phy_disable_energy_detect(pdata);
+
+		if (ret) {
+			SMSC_WARN(pdata, drv, "Failed to wakeup the PHY chip");
+			return ret;
+		}
+	}
 
 	/* Reset the LAN911x */
 	smsc911x_reg_write(pdata, HW_CFG, HW_CFG_SRST_);
@@ -1260,6 +1342,16 @@ static int smsc911x_soft_reset(struct smsc911x_data *pdata)
 		SMSC_WARN(pdata, drv, "Failed to complete reset");
 		return -EIO;
 	}
+
+	if (pdata->generation == 4) {
+		ret = smsc911x_phy_enable_energy_detect(pdata);
+
+		if (ret) {
+			SMSC_WARN(pdata, drv, "Failed to wakeup the PHY chip");
+			return ret;
+		}
+	}
+
 	return 0;
 }
 
-- 
1.7.4.1

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

* Re: [PATCH v2 1/2] net: phy: smsc: Move SMSC PHY constants to <linux/smscphy.h>
  2012-01-03 23:36 [PATCH v2 1/2] net: phy: smsc: Move SMSC PHY constants to <linux/smscphy.h> Javier Martinez Canillas
  2012-01-03 23:36 ` [PATCH v2 2/2] net/smsc911x: Check if PHY is in operational mode before software reset Javier Martinez Canillas
@ 2012-01-04  1:24 ` David Miller
  1 sibling, 0 replies; 4+ messages in thread
From: David Miller @ 2012-01-04  1:24 UTC (permalink / raw)
  To: javier; +Cc: steve.glendinning, eballetbo, ben, netdev

From: Javier Martinez Canillas <javier@dowhile0.org>
Date: Wed,  4 Jan 2012 00:36:18 +0100

> SMSC generation 4 LAN chips integrate an IEEE 802.3 ethernet physical layer.
> The ethernet driver for this family of devices needs to access the SMSC PHY
> registers and bit-fields.
> 
> So, this patch moves these constants to a place where it can be used for both
> the PHY and LAN drivers.
> 
> Signed-off-by: Javier Martinez Canillas <javier@dowhile0.org>

Applied.

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

* Re: [PATCH v2 2/2] net/smsc911x: Check if PHY is in operational mode before software reset
  2012-01-03 23:36 ` [PATCH v2 2/2] net/smsc911x: Check if PHY is in operational mode before software reset Javier Martinez Canillas
@ 2012-01-04  1:24   ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2012-01-04  1:24 UTC (permalink / raw)
  To: javier; +Cc: steve.glendinning, eballetbo, ben, netdev

From: Javier Martinez Canillas <javier@dowhile0.org>
Date: Wed,  4 Jan 2012 00:36:19 +0100

> SMSC LAN generation 4 chips integrate an IEEE 802.3 ethernet physical layer.
> The PHY driver for this integrated chip enable an energy detect power-down mode.
> When the PHY is in a power-down mode, it prevents the MAC portion chip to be
> software reseted.
> 
> That means that if we compile the kernel with the configuration option SMSC_PHY
> enabled and try to bring the network interface up without an cable plug-ed the
> PHY will be in a low power mode and the software reset will fail returning -EIO
> to user-space:
> 
> root@igep00x0:~# ifconfig eth0 up
> ifconfig: SIOCSIFFLAGS: Input/output error
> 
> This patch disable the energy detect power-down mode before trying to software
> reset the LAN chip and re-enables after it was reseted successfully.
> 
> Signed-off-by: Javier Martinez Canillas <javier@dowhile0.org>

Applied.

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

end of thread, other threads:[~2012-01-04  1:24 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-03 23:36 [PATCH v2 1/2] net: phy: smsc: Move SMSC PHY constants to <linux/smscphy.h> Javier Martinez Canillas
2012-01-03 23:36 ` [PATCH v2 2/2] net/smsc911x: Check if PHY is in operational mode before software reset Javier Martinez Canillas
2012-01-04  1:24   ` David Miller
2012-01-04  1:24 ` [PATCH v2 1/2] net: phy: smsc: Move SMSC PHY constants to <linux/smscphy.h> 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).