9be752b
From e95d5ac146d9da8a703a726fe70a9f4ac02ab8b2 Mon Sep 17 00:00:00 2001
9be752b
From: Patrick Uiterwijk <patrick@puiterwijk.org>
9be752b
Date: Fri, 25 Mar 2016 00:38:45 +0000
9be752b
Subject: [PATCH 2/2] net: dsa: mv88e6xxx: Clear the PDOWN bit on setup
9be752b
9be752b
Some of the vendor-specific bootloaders set up this part
9be752b
of the initialization for us, so this was never added.
9be752b
However, since upstream bootloaders don't initialize the
9be752b
chip specifically, they leave the fiber MII's PDOWN flag
9be752b
set, which means that the CPU port doesn't connect.
9be752b
9be752b
This patch checks whether this flag has been clear prior
9be752b
by something else, and if not make us clear it.
9be752b
9be752b
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
9be752b
Signed-off-by: Patrick Uiterwijk <patrick@puiterwijk.org>
9be752b
---
9be752b
 drivers/net/dsa/mv88e6xxx.c | 36 ++++++++++++++++++++++++++++++++++++
9be752b
 drivers/net/dsa/mv88e6xxx.h |  8 ++++++++
9be752b
 2 files changed, 44 insertions(+)
9be752b
9be752b
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
9be752b
index 86a2029..50454be 100644
9be752b
--- a/drivers/net/dsa/mv88e6xxx.c
9be752b
+++ b/drivers/net/dsa/mv88e6xxx.c
9be752b
@@ -2296,6 +2296,25 @@ restore_page_0:
9be752b
 	return ret;
9be752b
 }
9be752b
 
9be752b
+static int mv88e6xxx_power_on_serdes(struct dsa_switch *ds)
9be752b
+{
9be752b
+	int ret;
9be752b
+
9be752b
+	ret = _mv88e6xxx_phy_page_read(ds, REG_FIBER_SERDES, PAGE_FIBER_SERDES,
9be752b
+				       MII_BMCR);
9be752b
+	if (ret < 0)
9be752b
+		return ret;
9be752b
+
9be752b
+	if (ret & BMCR_PDOWN) {
9be752b
+		ret &= ~BMCR_PDOWN;
9be752b
+		ret = _mv88e6xxx_phy_page_write(ds, REG_FIBER_SERDES,
9be752b
+						PAGE_FIBER_SERDES, MII_BMCR,
9be752b
+						ret);
9be752b
+	}
9be752b
+
9be752b
+	return ret;
9be752b
+}
9be752b
+
9be752b
 static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
9be752b
 {
9be752b
 	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
9be752b
@@ -2399,6 +2418,23 @@ static int mv88e6xxx_setup_port(struct dsa_switch *ds, int port)
9be752b
 			goto abort;
9be752b
 	}
9be752b
 
9be752b
+	/* If this port is connected to a SerDes, make sure the SerDes is not
9be752b
+	 * powered down.
9be752b
+	 */
9be752b
+	if (mv88e6xxx_6352_family(ds)) {
9be752b
+		ret = _mv88e6xxx_reg_read(ds, REG_PORT(port), PORT_STATUS);
9be752b
+		if (ret < 0)
9be752b
+			goto abort;
9be752b
+		ret &= PORT_STATUS_CMODE_MASK;
9be752b
+		if ((ret == PORT_STATUS_CMODE_100BASE_X) ||
9be752b
+		    (ret == PORT_STATUS_CMODE_1000BASE_X) ||
9be752b
+		    (ret == PORT_STATUS_CMODE_SGMII)) {
9be752b
+			ret = mv88e6xxx_power_on_serdes(ds);
9be752b
+			if (ret < 0)
9be752b
+				goto abort;
9be752b
+		}
9be752b
+	}
9be752b
+
9be752b
 	/* Port Control 2: don't force a good FCS, set the maximum frame size to
9be752b
 	 * 10240 bytes, disable 802.1q tags checking, don't discard tagged or
9be752b
 	 * untagged frames on this port, do a destination address lookup on all
9be752b
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
9be752b
index 9a038ab..26a424a 100644
9be752b
--- a/drivers/net/dsa/mv88e6xxx.h
9be752b
+++ b/drivers/net/dsa/mv88e6xxx.h
9be752b
@@ -28,6 +28,10 @@
9be752b
 #define SMI_CMD_OP_45_READ_DATA_INC	((3 << 10) | SMI_CMD_BUSY)
9be752b
 #define SMI_DATA		0x01
9be752b
 
9be752b
+/* Fiber/SERDES Registers are located at SMI address F, page 1 */
9be752b
+#define REG_FIBER_SERDES	0x0f
9be752b
+#define PAGE_FIBER_SERDES	0x01
9be752b
+
9be752b
 #define REG_PORT(p)		(0x10 + (p))
9be752b
 #define PORT_STATUS		0x00
9be752b
 #define PORT_STATUS_PAUSE_EN	BIT(15)
9be752b
@@ -45,6 +49,10 @@
9be752b
 #define PORT_STATUS_MGMII	BIT(6) /* 6185 */
9be752b
 #define PORT_STATUS_TX_PAUSED	BIT(5)
9be752b
 #define PORT_STATUS_FLOW_CTRL	BIT(4)
9be752b
+#define PORT_STATUS_CMODE_MASK	0x0f
9be752b
+#define PORT_STATUS_CMODE_100BASE_X	0x8
9be752b
+#define PORT_STATUS_CMODE_1000BASE_X	0x9
9be752b
+#define PORT_STATUS_CMODE_SGMII		0xa
9be752b
 #define PORT_PCS_CTRL		0x01
9be752b
 #define PORT_PCS_CTRL_RGMII_DELAY_RXCLK	BIT(15)
9be752b
 #define PORT_PCS_CTRL_RGMII_DELAY_TXCLK	BIT(14)
9be752b
-- 
9be752b
2.5.0
9be752b