swconfig: add (PHY) generic helper setting port link
[openwrt/openwrt.git] / target / linux / generic / files / drivers / net / phy / swconfig.c
index 4bfe64fbd0dc62a3007802eaeb1b4fef8e6cc956..68ddd246addab8897dde186484c08be138db9a00 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/switch.h>
 #include <linux/of.h>
 #include <linux/version.h>
 #include <linux/switch.h>
 #include <linux/of.h>
 #include <linux/version.h>
+#include <uapi/linux/mii.h>
 
 #define SWCONFIG_DEVNAME       "switch%d"
 
 
 #define SWCONFIG_DEVNAME       "switch%d"
 
@@ -1168,6 +1169,41 @@ unregister_switch(struct switch_dev *dev)
 }
 EXPORT_SYMBOL_GPL(unregister_switch);
 
 }
 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)
 
 static int __init
 swconfig_init(void)