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
This commit is contained in:
		@@ -25,6 +25,7 @@
 | 
				
			|||||||
#include <linux/switch.h>
 | 
					#include <linux/switch.h>
 | 
				
			||||||
#include <linux/of.h>
 | 
					#include <linux/of.h>
 | 
				
			||||||
#include <linux/version.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
 | 
					static int __init
 | 
				
			||||||
swconfig_init(void)
 | 
					swconfig_init(void)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -99,6 +99,9 @@ struct switch_dev_ops {
 | 
				
			|||||||
			     struct switch_port_link *link);
 | 
								     struct switch_port_link *link);
 | 
				
			||||||
	int (*get_port_stats)(struct switch_dev *dev, int port,
 | 
						int (*get_port_stats)(struct switch_dev *dev, int port,
 | 
				
			||||||
			      struct switch_port_stats *stats);
 | 
								      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 {
 | 
					struct switch_dev {
 | 
				
			||||||
@@ -170,4 +173,7 @@ struct switch_attr {
 | 
				
			|||||||
	int max;
 | 
						int max;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int switch_generic_set_link(struct switch_dev *dev, int port,
 | 
				
			||||||
 | 
								    struct switch_port_link *link);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _LINUX_SWITCH_H */
 | 
					#endif /* _LINUX_SWITCH_H */
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user