lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:	Wed, 29 Apr 2015 18:57:44 -0700
From:	Florian Fainelli <f.fainelli@...il.com>
To:	netdev@...r.kernel.org
Cc:	dave@...emloft.net, Florian Fainelli <f.fainelli@...il.com>,
	vivien.didelot@...oirfairelinux.com,
	jerome.oufella@...oirfairelinux.com, linux@...ck-us.net,
	andrew@...n.ch, cphealy@...il.com, mathieu@...eaurora.org,
	jonasj76@...il.com, andrey.volkov@...vision.fr,
	Chris.Packham@...iedtelesis.co.nz
Subject: [RFC PATCH net-next 8/8] net: dsa: mv88e6xxx: Allow them to be proper PHY drivers

Register a PHY fixup for the different MV88E6xxx switches supported by
the 88e6xxxx driver, basically replacing the legacy probe function.

Since these are all now a PHY driver, the Ethernet MAC controller attached
to it needs to be signaled proper link parameters (speed, duplex, link)

Signed-off-by: Florian Fainelli <f.fainelli@...il.com>
---
 drivers/net/dsa/mv88e6123_61_65.c | 116 ++++++++++++++++++++++++++++++++++++++
 drivers/net/dsa/mv88e6131.c       | 107 +++++++++++++++++++++++++++++++++++
 drivers/net/dsa/mv88e6171.c       |  95 +++++++++++++++++++++++++++++++
 drivers/net/dsa/mv88e6352.c       | 102 +++++++++++++++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx.c       |  40 ++++++++++++-
 drivers/net/dsa/mv88e6xxx.h       |  12 ++++
 6 files changed, 470 insertions(+), 2 deletions(-)

diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
index b4af6d5aff7c..acd0e08d6b21 100644
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -296,6 +296,122 @@ struct dsa_switch_driver mv88e6123_61_65_switch_driver = {
 	.get_regs		= mv88e6xxx_get_regs,
 };
 
+/* PHY library read status callback, must reflect the CPU port link parameters
+ * towards the attached Ethernet MAC driver
+ */
+static int mv88e6123_61_65_read_status(struct phy_device *phydev)
+{
+	phydev->link = 1;
+	phydev->speed = SPEED_1000;
+	phydev->duplex = DUPLEX_FULL;
+	phydev->state = PHY_RUNNING;
+
+	netif_carrier_on(phydev->attached_dev);
+	phydev->adjust_link(phydev->attached_dev);
+
+	return 0;
+}
+
+static int mv88e6123_61_65_phy_probe(struct phy_device *phydev)
+{
+	struct dsa_switch *ds;
+
+	ds = dsa_alloc_switch(sizeof(struct mv88e6xxx_priv_state));
+	if (!ds)
+		return -ENOMEM;
+
+	phydev->priv = ds;
+	phydev->is_switch = true;
+	ds->drv = &mv88e6123_61_65_switch_driver;
+	ds->tag_protocol = DSA_TAG_PROTO_EDSA;
+	ds->master_dev = &phydev->dev;
+
+	return 0;
+}
+
+static void mv88e6123_61_65_remove(struct phy_device *phydev)
+{
+	struct dsa_switch *ds = phydev->priv;
+
+	dsa_switch_unregister(ds);
+	kfree(ds);
+	phydev->priv = NULL;
+}
+
+static int mv88e6123_61_65_phy_fixup(struct phy_device *phydev)
+{
+	int ret;
+
+	if (phydev->addr != 16)
+		return 0;
+
+	ret = __mv88e6xxx_reg_read(phydev->bus, phydev->addr, REG_PORT(0), 0x03);
+	if (ret < 0)
+		return 0;
+
+	switch (ret) {
+	case PORT_SWITCH_ID_6123_A1:
+	case PORT_SWITCH_ID_6123_A2:
+	case PORT_SWITCH_ID_6161_A1:
+	case PORT_SWITCH_ID_6161_A2:
+	case PORT_SWITCH_ID_6165_A1:
+	case PORT_SWITCH_ID_6165_A2:
+		phydev->phy_id = ret;
+		break;
+	default:
+		ret &= 0xfff0;
+		switch (ret) {
+		case PORT_SWITCH_ID_6123:
+		case PORT_SWITCH_ID_6161:
+		case PORT_SWITCH_ID_6165:
+			phydev->phy_id = ret;
+			break;
+		}
+	}
+
+	return 0;
+}
+
+#define MV88E61XX_DRV(_magic, _name)			\
+{							\
+	.phy_id		= (_magic),			\
+	.phy_id_mask	= 0xffffffff,			\
+	.name		= (_name),			\
+	.features	= PHY_GBIT_FEATURES,		\
+	.config_init	= mv88e6xxx_config_init,	\
+	.config_aneg	= mv88e6xxx_config_aneg,	\
+	.read_status	= mv88e6123_61_65_read_status,	\
+	.probe		= mv88e6123_61_65_phy_probe,	\
+	.remove		= mv88e6123_61_65_remove,	\
+	.driver		= { .owner = THIS_MODULE },	\
+}
+
+static struct phy_driver mv88e6123_61_65_phy_drivers[] = {
+	MV88E61XX_DRV(PORT_SWITCH_ID_6123_A1, "Marvell 88E6123 (A1)"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6123_A2, "Marvell 88E6123 (A2)"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6123, "Marvell 88E6123"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6161_A1, "Marvell 88E6161 (A1)"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6161_A2, "Marvell 88E6161 (A2)"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6161, "Marvell 88E6161"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6165_A1, "Marvell 88E6165 (A1)"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6165_A2, "Marvell 88E6165 (A2)"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6165, "Marvell 88E6165"),
+};
+
+int __init mv88e6123_61_65_phy_drivers_register(void)
+{
+	phy_register_fixup_for_id(PHY_ANY_ID, mv88e6123_61_65_phy_fixup);
+
+	return phy_drivers_register(mv88e6123_61_65_phy_drivers,
+				    ARRAY_SIZE(mv88e6123_61_65_phy_drivers));
+}
+
+void __exit mv88e6123_61_65_phy_drivers_unregister(void)
+{
+	phy_drivers_unregister(mv88e6123_61_65_phy_drivers,
+			       ARRAY_SIZE(mv88e6123_61_65_phy_drivers));
+}
+
 MODULE_ALIAS("platform:mv88e6123");
 MODULE_ALIAS("platform:mv88e6161");
 MODULE_ALIAS("platform:mv88e6165");
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index e54824fa0d95..e60e3e3a2e65 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -313,6 +313,113 @@ struct dsa_switch_driver mv88e6131_switch_driver = {
 	.get_sset_count		= mv88e6xxx_get_sset_count,
 };
 
+static int mv88e6131_read_status(struct phy_device *phydev)
+{
+	struct dsa_switch *ds = phydev->priv;
+	struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+
+	phydev->link = 1;
+	phydev->duplex = DUPLEX_FULL;
+	if (ps->id == PORT_SWITCH_ID_6085)
+		phydev->speed = SPEED_100;
+	else
+		phydev->speed = SPEED_1000;
+	phydev->state = PHY_RUNNING;
+
+	netif_carrier_on(phydev->attached_dev);
+	phydev->adjust_link(phydev->attached_dev);
+
+	return 0;
+}
+
+static int mv88e6131_phy_probe(struct phy_device *phydev)
+{
+	struct dsa_switch *ds;
+
+	ds = dsa_alloc_switch(sizeof(struct mv88e6xxx_priv_state));
+	if (!ds)
+		return -ENOMEM;
+
+	phydev->priv = ds;
+	phydev->is_switch = true;
+	ds->master_dev = &phydev->dev;
+	ds->drv = &mv88e6131_switch_driver;
+	ds->tag_protocol = DSA_TAG_PROTO_DSA;
+
+	return 0;
+}
+
+static void mv88e6131_remove(struct phy_device *phydev)
+{
+	struct dsa_switch *ds = phydev->priv;
+
+	dsa_switch_unregister(ds);
+	kfree(ds);
+	phydev->priv = NULL;
+}
+
+static int mv88e6131_phy_fixup(struct phy_device *phydev)
+{
+	int ret;
+
+	if (phydev->addr != 16)
+		return 0;
+
+	ret = __mv88e6xxx_reg_read(phydev->bus, phydev->addr, REG_PORT(0), 0x03);
+	if (ret < 0)
+		return 0;
+
+	if (ret == PORT_SWITCH_ID_6131_B2) {
+		phydev->phy_id = ret;
+		return 0;
+	}
+
+	ret &= 0xfff0;
+	switch (ret) {
+	case PORT_SWITCH_ID_6085:
+	case PORT_SWITCH_ID_6095:
+	case PORT_SWITCH_ID_6131:
+		phydev->phy_id = ret;
+		break;
+	}
+
+	return 0;
+}
+
+#define MV88E61XX_DRV(_magic, _feat, _name)		\
+{							\
+	.phy_id		= (_magic),			\
+	.phy_id_mask	= 0xffffffff,			\
+	.name		= _name,			\
+	.features	= (_feat),			\
+	.config_init	= mv88e6xxx_config_init,	\
+	.config_aneg	= mv88e6xxx_config_aneg,	\
+	.read_status	= mv88e6131_read_status,	\
+	.probe		= mv88e6131_phy_probe,		\
+	.remove		= mv88e6131_remove,		\
+	.driver		= { .owner = THIS_MODULE },	\
+}
+static struct phy_driver mv88e6131_phy_drivers[] = {
+	MV88E61XX_DRV(PORT_SWITCH_ID_6085, PHY_BASIC_FEATURES, "Marvell 88E6085"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6095, PHY_GBIT_FEATURES, "Marvell 88E6095/88E6095F"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6131_B2, PHY_GBIT_FEATURES, "Marvell 88E6131 (B2)"),
+	MV88E61XX_DRV(PORT_SWITCH_ID_6131, PHY_GBIT_FEATURES, "Marvell 88E6131"),
+};
+
+int __init mv88e6131_phy_drivers_register(void)
+{
+	phy_register_fixup_for_id(PHY_ANY_ID, mv88e6131_phy_fixup);
+
+	return phy_drivers_register(mv88e6131_phy_drivers,
+				    ARRAY_SIZE(mv88e6131_phy_drivers));
+}
+
+void __exit mv88e6131_phy_drivers_unregister(void)
+{
+	phy_drivers_unregister(mv88e6131_phy_drivers,
+			       ARRAY_SIZE(mv88e6131_phy_drivers));
+}
+
 MODULE_ALIAS("platform:mv88e6085");
 MODULE_ALIAS("platform:mv88e6095");
 MODULE_ALIAS("platform:mv88e6095f");
diff --git a/drivers/net/dsa/mv88e6171.c b/drivers/net/dsa/mv88e6171.c
index 9104efea0e3e..120a0f46e321 100644
--- a/drivers/net/dsa/mv88e6171.c
+++ b/drivers/net/dsa/mv88e6171.c
@@ -307,5 +307,100 @@ struct dsa_switch_driver mv88e6171_switch_driver = {
 	.fdb_getnext		= mv88e6xxx_port_fdb_getnext,
 };
 
+static int mv88e6171_read_status(struct phy_device *phydev)
+{
+	phydev->link = 1;
+	phydev->duplex = DUPLEX_FULL;
+	phydev->state = PHY_RUNNING;
+
+	netif_carrier_on(phydev->attached_dev);
+	phydev->adjust_link(phydev->attached_dev);
+
+	return 0;
+}
+
+static int mv88e6171_phy_probe(struct phy_device *phydev)
+{
+	struct dsa_switch *ds;
+
+	ds = dsa_alloc_switch(sizeof(struct mv88e6xxx_priv_state));
+	if (!ds)
+		return -ENOMEM;
+
+	/* We cannot register the switch yet, since we do not have an attached
+	 * network device
+	 */
+	phydev->is_switch = true;
+	phydev->priv = ds;
+	ds->master_dev = &phydev->dev;
+	ds->drv = &mv88e6171_switch_driver;
+	ds->tag_protocol = DSA_TAG_PROTO_EDSA;
+
+	return 0;
+}
+
+static void mv88e6171_remove(struct phy_device *phydev)
+{
+	struct dsa_switch *ds = phydev->priv;
+
+	dsa_switch_unregister(ds);
+	kfree(ds);
+	phydev->priv = NULL;
+}
+
+static int mv88e6171_phy_fixup(struct phy_device *phydev)
+{
+	int ret;
+
+	if (phydev->addr != 16)
+		return 0;
+
+	ret = __mv88e6xxx_reg_read(phydev->bus, phydev->addr, REG_PORT(0), 0x03);
+	if (ret < 0)
+		return 0;
+
+	ret &= 0xfff0;
+	switch (ret) {
+	case PORT_SWITCH_ID_6171:
+	case PORT_SWITCH_ID_6172:
+		phydev->phy_id = ret;
+		break;
+	}
+
+	return 0;
+}
+
+#define MV88E6171_DRV(_magic, _name)			\
+{							\
+	.phy_id		= (_magic),			\
+	.phy_id_mask	= 0xfffffff0,			\
+	.name		= _name,			\
+	.features	= PHY_GBIT_FEATURES,		\
+	.config_init	= mv88e6xxx_config_init,	\
+	.config_aneg	= mv88e6xxx_config_aneg,	\
+	.read_status	= mv88e6171_read_status,	\
+	.probe		= mv88e6171_phy_probe,		\
+	.remove		= mv88e6171_remove,		\
+	.driver		= { .owner = THIS_MODULE },	\
+}
+static struct phy_driver mv88e6171_phy_drivers[] = {
+	MV88E6171_DRV(PORT_SWITCH_ID_6171, "Marvell 88E6171"),
+	MV88E6171_DRV(PORT_SWITCH_ID_6172, "Marvell 88E6172"),
+};
+
+int __init mv88e6171_phy_drivers_register(void)
+{
+	phy_register_fixup_for_id(PHY_ANY_ID, mv88e6171_phy_fixup);
+
+	return phy_drivers_register(mv88e6171_phy_drivers,
+				    ARRAY_SIZE(mv88e6171_phy_drivers));
+}
+
+void __exit mv88e6171_phy_drivers_unregister(void)
+{
+	phy_drivers_unregister(mv88e6171_phy_drivers,
+			       ARRAY_SIZE(mv88e6171_phy_drivers));
+}
+
 MODULE_ALIAS("platform:mv88e6171");
 MODULE_ALIAS("platform:mv88e6172");
diff --git a/drivers/net/dsa/mv88e6352.c b/drivers/net/dsa/mv88e6352.c
index 126c11b81e75..e7198edddd13 100644
--- a/drivers/net/dsa/mv88e6352.c
+++ b/drivers/net/dsa/mv88e6352.c
@@ -551,4 +551,106 @@ struct dsa_switch_driver mv88e6352_switch_driver = {
 	.fdb_getnext		= mv88e6xxx_port_fdb_getnext,
 };
 
+static int mv88e6352_read_status(struct phy_device *phydev)
+{
+	phydev->link = 1;
+	phydev->duplex = DUPLEX_FULL;
+	phydev->speed = SPEED_1000;
+	phydev->state = PHY_RUNNING;
+
+	netif_carrier_on(phydev->attached_dev);
+	phydev->adjust_link(phydev->attached_dev);
+
+	return 0;
+}
+
+static int mv88e6352_phy_probe(struct phy_device *phydev)
+{
+	struct dsa_switch *ds;
+
+	ds = dsa_alloc_switch(sizeof(struct mv88e6xxx_priv_state));
+	if (!ds)
+		return -ENOMEM;
+
+	phydev->priv = ds;
+	phydev->is_switch = true;
+	ds->master_dev = &phydev->dev;
+	ds->drv = &mv88e6352_switch_driver;
+	ds->tag_protocol = DSA_TAG_PROTO_EDSA;
+
+	return 0;
+}
+
+static void mv88e6352_remove(struct phy_device *phydev)
+{
+	struct dsa_switch *ds = phydev->priv;
+
+	dsa_switch_unregister(ds);
+	kfree(ds);
+	phydev->priv = NULL;
+}
+
+static int mv88e6352_phy_fixup(struct phy_device *phydev)
+{
+	int ret;
+
+	if (phydev->addr != 16)
+		return 0;
+
+	ret = __mv88e6xxx_reg_read(phydev->bus, phydev->addr, REG_PORT(0), 0x03);
+	if (ret < 0)
+		return 0;
+
+	switch (ret) {
+	case PORT_SWITCH_ID_6352_A0:
+	case PORT_SWITCH_ID_6352_A1:
+		phydev->phy_id = ret;
+		return 0;
+	}
+
+	ret &= 0xfff0;
+	switch (ret) {
+	case PORT_SWITCH_ID_6176:
+	case PORT_SWITCH_ID_6352:
+		phydev->phy_id = ret;
+		break;
+	}
+
+	return 0;
+}
+#define MV88E6352_DRV(_magic, _name)			\
+{							\
+	.phy_id		= (_magic),			\
+	.phy_id_mask	= 0xffffffff,			\
+	.name		= _name,			\
+	.features	= PHY_GBIT_FEATURES,		\
+	.config_init	= mv88e6xxx_config_init,	\
+	.config_aneg	= mv88e6xxx_config_aneg,	\
+	.read_status	= mv88e6352_read_status,	\
+	.probe		= mv88e6352_phy_probe,		\
+	.remove		= mv88e6352_remove,		\
+	.driver		= { .owner = THIS_MODULE },	\
+}
+
+static struct phy_driver mv88e6352_phy_drivers[] = {
+	MV88E6352_DRV(PORT_SWITCH_ID_6176, "Marvell 88E6176"),
+	MV88E6352_DRV(PORT_SWITCH_ID_6352_A0, "Marvell 88E6352 (A0)"),
+	MV88E6352_DRV(PORT_SWITCH_ID_6352_A1, "Marvell 88E6352 (A1)"),
+	MV88E6352_DRV(PORT_SWITCH_ID_6352, "Marvell 88E6352"),
+};
+
+int __init mv88e6352_phy_drivers_register(void)
+{
+	phy_register_fixup_for_id(PHY_ANY_ID, mv88e6352_phy_fixup);
+
+	return phy_drivers_register(mv88e6352_phy_drivers,
+				    ARRAY_SIZE(mv88e6352_phy_drivers));
+}
+
+void __exit mv88e6352_phy_drivers_unregister(void)
+{
+	phy_drivers_unregister(mv88e6352_phy_drivers,
+			       ARRAY_SIZE(mv88e6352_phy_drivers));
+}
+
 MODULE_ALIAS("platform:mv88e6352");
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index af639ab4c55b..c51c6f179682 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -75,10 +75,22 @@ int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg)
 	return ret & 0xffff;
 }
 
+static inline struct mii_bus *mv88e6xxx_mii_bus(struct dsa_switch *ds)
+{
+	struct phy_device *phydev;
+	if (ds->from_pd)
+		return dsa_host_dev_to_mii_bus(ds->master_dev);
+
+	phydev = to_phy_device(ds->master_dev);
+
+	return phydev->bus;
+}
+
+
 /* Must be called with SMI mutex held */
 static int _mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
 {
-	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+	struct mii_bus *bus = mv88e6xxx_mii_bus(ds);
 	int ret;
 
 	if (bus == NULL)
@@ -142,7 +154,7 @@ int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
 static int _mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg,
 				u16 val)
 {
-	struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev);
+	struct mii_bus *bus = mv88e6xxx_mii_bus(ds);
 
 	if (bus == NULL)
 		return -EINVAL;
@@ -1446,19 +1458,36 @@ mv88e6xxx_phy_write_indirect(struct dsa_switch *ds, int port, int regnum,
 	return ret;
 }
 
+int mv88e6xxx_config_init(struct phy_device *phydev)
+{
+	struct dsa_switch *ds = phydev->priv;
+
+	/* We now have an attached network device, register this device */
+	return dsa_switch_register_phydev(ds, phydev);
+}
+
+int mv88e6xxx_config_aneg(struct phy_device *phydev)
+{
+	return 0;
+}
+
 static int __init mv88e6xxx_init(void)
 {
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
 	register_switch_driver(&mv88e6131_switch_driver);
+	mv88e6131_phy_drivers_register();
 #endif
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
 	register_switch_driver(&mv88e6123_61_65_switch_driver);
+	mv88e6123_61_65_phy_drivers_register();
 #endif
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
 	register_switch_driver(&mv88e6352_switch_driver);
+	mv88e6352_phy_drivers_register();
 #endif
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
 	register_switch_driver(&mv88e6171_switch_driver);
+	mv88e6171_phy_drivers_register();
 #endif
 	return 0;
 }
@@ -1468,12 +1497,19 @@ static void __exit mv88e6xxx_cleanup(void)
 {
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6171)
 	unregister_switch_driver(&mv88e6171_switch_driver);
+	mv88e6171_phy_drivers_unregister();
+#endif
+#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352)
+	unregister_switch_driver(&mv88e6352_switch_driver);
+	mv88e6352_phy_drivers_unregister();
 #endif
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65)
 	unregister_switch_driver(&mv88e6123_61_65_switch_driver);
+	mv88e6123_61_65_phy_drivers_unregister();
 #endif
 #if IS_ENABLED(CONFIG_NET_DSA_MV88E6131)
 	unregister_switch_driver(&mv88e6131_switch_driver);
+	mv88e6131_phy_drivers_unregister();
 #endif
 }
 module_exit(mv88e6xxx_cleanup);
diff --git a/drivers/net/dsa/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx.h
index e045154f3364..449f948ca27f 100644
--- a/drivers/net/dsa/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx.h
@@ -315,6 +315,18 @@ extern struct dsa_switch_driver mv88e6123_61_65_switch_driver;
 extern struct dsa_switch_driver mv88e6352_switch_driver;
 extern struct dsa_switch_driver mv88e6171_switch_driver;
 
+int mv88e6xxx_config_init(struct phy_device *phydev);
+int mv88e6xxx_config_aneg(struct phy_device *phydev);
+
+int mv88e6123_61_65_phy_drivers_register(void);
+void mv88e6123_61_65_phy_drivers_unregister(void);
+int mv88e6131_phy_drivers_register(void);
+void mv88e6131_phy_drivers_unregister(void);
+int mv88e6352_phy_drivers_register(void);
+void mv88e6352_phy_drivers_unregister(void);
+int mv88e6171_phy_drivers_register(void);
+void mv88e6171_phy_drivers_unregister(void);
+
 #define REG_READ(addr, reg)						\
 	({								\
 		int __ret;						\
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists