From: Rafał Miłecki <zajec5@gmail.com>
Date: Wed, 3 Feb 2016 09:33:38 +0000 (+0000)
Subject: swconfig: add (PHY) generic helper setting port link
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=19b9e14c47cf289758dc465fd44ee282c41c469a;p=openwrt%2Fstaging%2Frobimarko.git

swconfig: add (PHY) generic helper setting port link

It's quite common for switches to have PHY per port so adding a generic
helper setting link state will help many drivers. It just needs an API
to access PHYs which this patch also adds.

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>

SVN-Revision: 48621
---

diff --git a/target/linux/generic/files/drivers/net/phy/swconfig.c b/target/linux/generic/files/drivers/net/phy/swconfig.c
index 4bfe64fbd0..68ddd246ad 100644
--- a/target/linux/generic/files/drivers/net/phy/swconfig.c
+++ b/target/linux/generic/files/drivers/net/phy/swconfig.c
@@ -25,6 +25,7 @@
 #include <linux/switch.h>
 #include <linux/of.h>
 #include <linux/version.h>
+#include <uapi/linux/mii.h>
 
 #define SWCONFIG_DEVNAME	"switch%d"
 
@@ -1168,6 +1169,41 @@ unregister_switch(struct switch_dev *dev)
 }
 EXPORT_SYMBOL_GPL(unregister_switch);
 
+int
+switch_generic_set_link(struct switch_dev *dev, int port,
+			struct switch_port_link *link)
+{
+	if (WARN_ON(!dev->ops->phy_write16))
+		return -ENOTSUPP;
+
+	/* Generic implementation */
+	if (link->aneg) {
+		dev->ops->phy_write16(dev, port, MII_BMCR, 0x0000);
+		dev->ops->phy_write16(dev, port, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART);
+	} else {
+		u16 bmcr = 0;
+
+		if (link->duplex)
+			bmcr |= BMCR_FULLDPLX;
+
+		switch (link->speed) {
+		case SWITCH_PORT_SPEED_10:
+			break;
+		case SWITCH_PORT_SPEED_100:
+			bmcr |= BMCR_SPEED100;
+			break;
+		case SWITCH_PORT_SPEED_1000:
+			bmcr |= BMCR_SPEED1000;
+			break;
+		default:
+			return -ENOTSUPP;
+		}
+
+		dev->ops->phy_write16(dev, port, MII_BMCR, bmcr);
+	}
+
+	return 0;
+}
 
 static int __init
 swconfig_init(void)
diff --git a/target/linux/generic/files/include/linux/switch.h b/target/linux/generic/files/include/linux/switch.h
index 4ada0e5d33..0c4cce7fa5 100644
--- a/target/linux/generic/files/include/linux/switch.h
+++ b/target/linux/generic/files/include/linux/switch.h
@@ -99,6 +99,9 @@ struct switch_dev_ops {
 			     struct switch_port_link *link);
 	int (*get_port_stats)(struct switch_dev *dev, int port,
 			      struct switch_port_stats *stats);
+
+	int (*phy_read16)(struct switch_dev *dev, int addr, u8 reg, u16 *value);
+	int (*phy_write16)(struct switch_dev *dev, int addr, u8 reg, u16 value);
 };
 
 struct switch_dev {
@@ -170,4 +173,7 @@ struct switch_attr {
 	int max;
 };
 
+int switch_generic_set_link(struct switch_dev *dev, int port,
+			    struct switch_port_link *link);
+
 #endif /* _LINUX_SWITCH_H */