[U-Boot] [RESEND Patch] net: mscc: refactor mscc_miim

Horatiu Vultur horatiu.vultur at microchip.com
Sun Jun 9 13:27:29 UTC 2019


Because all MSCC SoC use the same MDIO bus, put the implementation in
one common file(mscc_miim) and make all the other MSCC network drivers to
use these functions.

Signed-off-by: Horatiu Vultur <horatiu.vultur at microchip.com>
---
 drivers/net/mscc_eswitch/Makefile         |  10 +--
 drivers/net/mscc_eswitch/jr2_switch.c     | 119 ++----------------------------
 drivers/net/mscc_eswitch/luton_switch.c   | 101 +------------------------
 drivers/net/mscc_eswitch/mscc_miim.c      |  28 +++++++
 drivers/net/mscc_eswitch/mscc_miim.h      |  14 +++-
 drivers/net/mscc_eswitch/ocelot_switch.c  | 104 +-------------------------
 drivers/net/mscc_eswitch/serval_switch.c  | 101 +------------------------
 drivers/net/mscc_eswitch/servalt_switch.c | 102 +------------------------
 8 files changed, 63 insertions(+), 516 deletions(-)

diff --git a/drivers/net/mscc_eswitch/Makefile b/drivers/net/mscc_eswitch/Makefile
index 02f39a7..d583fe9 100644
--- a/drivers/net/mscc_eswitch/Makefile
+++ b/drivers/net/mscc_eswitch/Makefile
@@ -1,6 +1,6 @@
 
-obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_xfer.o mscc_mac_table.o
-obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_xfer.o mscc_mac_table.o
-obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o
-obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o
-obj-$(CONFIG_MSCC_SERVAL_SWITCH) += serval_switch.o mscc_xfer.o mscc_mac_table.o
+obj-$(CONFIG_MSCC_OCELOT_SWITCH) += ocelot_switch.o mscc_xfer.o mscc_mac_table.o mscc_miim.o
+obj-$(CONFIG_MSCC_LUTON_SWITCH) += luton_switch.o mscc_xfer.o mscc_mac_table.o mscc_miim.o
+obj-$(CONFIG_MSCC_JR2_SWITCH) += jr2_switch.o mscc_xfer.o mscc_miim.o
+obj-$(CONFIG_MSCC_SERVALT_SWITCH) += servalt_switch.o mscc_xfer.o mscc_miim.o
+obj-$(CONFIG_MSCC_SERVAL_SWITCH) += serval_switch.o mscc_xfer.o mscc_mac_table.o mscc_miim.o
diff --git a/drivers/net/mscc_eswitch/jr2_switch.c b/drivers/net/mscc_eswitch/jr2_switch.c
index 60d408f..6655177 100644
--- a/drivers/net/mscc_eswitch/jr2_switch.c
+++ b/drivers/net/mscc_eswitch/jr2_switch.c
@@ -17,20 +17,7 @@
 
 #include <dt-bindings/mscc/jr2_data.h>
 #include "mscc_xfer.h"
-
-#define GCB_MIIM_MII_STATUS		0x0
-#define		GCB_MIIM_STAT_BUSY		BIT(3)
-#define GCB_MIIM_MII_CMD		0x8
-#define		GCB_MIIM_MII_CMD_SCAN		BIT(0)
-#define		GCB_MIIM_MII_CMD_OPR_WRITE	BIT(1)
-#define		GCB_MIIM_MII_CMD_OPR_READ	BIT(2)
-#define		GCB_MIIM_MII_CMD_SINGLE_SCAN	BIT(3)
-#define		GCB_MIIM_MII_CMD_WRDATA(x)	((x) << 4)
-#define		GCB_MIIM_MII_CMD_REGAD(x)	((x) << 20)
-#define		GCB_MIIM_MII_CMD_PHYAD(x)	((x) << 25)
-#define		GCB_MIIM_MII_CMD_VLD		BIT(31)
-#define GCB_MIIM_DATA			0xC
-#define		GCB_MIIM_DATA_ERROR		(0x3 << 16)
+#include "mscc_miim.h"
 
 #define ANA_AC_RAM_CTRL_RAM_INIT		0x94358
 #define ANA_AC_STAT_GLOBAL_CFG_PORT_RESET	0x94370
@@ -279,13 +266,6 @@ struct jr2_private {
 	struct jr2_phy_port_t ports[MAX_PORT];
 };
 
-struct jr2_miim_dev {
-	void __iomem *regs;
-	phys_addr_t miim_base;
-	unsigned long miim_size;
-	struct mii_dev *bus;
-};
-
 static const unsigned long jr2_regs_qs[] = {
 	[MSCC_QS_XTR_RD] = 0x8,
 	[MSCC_QS_XTR_FLUSH] = 0x18,
@@ -294,99 +274,9 @@ static const unsigned long jr2_regs_qs[] = {
 	[MSCC_QS_INJ_CTRL] = 0x34,
 };
 
-static struct jr2_miim_dev miim[JR2_MIIM_BUS_COUNT];
+static struct mscc_miim_dev miim[JR2_MIIM_BUS_COUNT];
 static int miim_count = -1;
 
-static int mscc_miim_wait_ready(struct jr2_miim_dev *miim)
-{
-	unsigned long deadline;
-	u32 val;
-
-	deadline = timer_get_us() + 250000;
-
-	do {
-		val = readl(miim->regs + GCB_MIIM_MII_STATUS);
-	} while (timer_get_us() <= deadline && (val & GCB_MIIM_STAT_BUSY));
-
-	if (val & GCB_MIIM_STAT_BUSY)
-		return -ETIMEDOUT;
-
-	return 0;
-}
-
-static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
-{
-	struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
-	u32 val;
-	int ret;
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret)
-		goto out;
-
-	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
-	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
-	       miim->regs + GCB_MIIM_MII_CMD);
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret)
-		goto out;
-
-	val = readl(miim->regs + GCB_MIIM_DATA);
-	if (val & GCB_MIIM_DATA_ERROR) {
-		ret = -EIO;
-		goto out;
-	}
-
-	ret = val & 0xFFFF;
- out:
-	return ret;
-}
-
-static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
-			   u16 val)
-{
-	struct jr2_miim_dev *miim = (struct jr2_miim_dev *)bus->priv;
-	int ret;
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret < 0)
-		goto out;
-
-	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
-	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
-	       GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
-
- out:
-	return ret;
-}
-
-static struct mii_dev *jr2_mdiobus_init(phys_addr_t miim_base,
-					unsigned long miim_size)
-{
-	struct mii_dev *bus;
-
-	bus = mdio_alloc();
-	if (!bus)
-		return NULL;
-
-	++miim_count;
-	sprintf(bus->name, "miim-bus%d", miim_count);
-
-	miim[miim_count].regs = ioremap(miim_base, miim_size);
-	miim[miim_count].miim_base = miim_base;
-	miim[miim_count].miim_size = miim_size;
-	bus->priv = &miim[miim_count];
-	bus->read = mscc_miim_read;
-	bus->write = mscc_miim_write;
-
-	if (mdio_register(bus))
-		return NULL;
-
-	miim[miim_count].bus = bus;
-	return bus;
-}
-
 static void jr2_cpu_capture_setup(struct jr2_private *priv)
 {
 	/* ASM: No preamble and IFH prefix on CPU injected frames */
@@ -973,7 +863,7 @@ static int jr2_probe(struct udevice *dev)
 	}
 
 	/* Initialize miim buses */
-	memset(&miim, 0x0, sizeof(struct jr2_miim_dev) * JR2_MIIM_BUS_COUNT);
+	memset(&miim, 0x0, sizeof(struct mscc_miim_dev) * JR2_MIIM_BUS_COUNT);
 
 	/* iterate all the ports and find out on which bus they are */
 	i = 0;
@@ -1008,7 +898,8 @@ static int jr2_probe(struct udevice *dev)
 		/* If the bus is new then create a new bus */
 		if (!get_mdiobus(addr_base, addr_size))
 			priv->bus[miim_count] =
-				jr2_mdiobus_init(addr_base, addr_size);
+				mscc_mdiobus_init(miim, &miim_count, addr_base,
+						  addr_size);
 
 		/* Connect mdio bus with the port */
 		bus = get_mdiobus(addr_base, addr_size);
diff --git a/drivers/net/mscc_eswitch/luton_switch.c b/drivers/net/mscc_eswitch/luton_switch.c
index 94852b0..dffe81d 100644
--- a/drivers/net/mscc_eswitch/luton_switch.c
+++ b/drivers/net/mscc_eswitch/luton_switch.c
@@ -17,18 +17,7 @@
 
 #include "mscc_xfer.h"
 #include "mscc_mac_table.h"
-
-#define GCB_MIIM_MII_STATUS			0x0
-#define		GCB_MIIM_STAT_BUSY			BIT(3)
-#define GCB_MIIM_MII_CMD			0x8
-#define		GCB_MIIM_MII_CMD_OPR_WRITE		BIT(1)
-#define		GCB_MIIM_MII_CMD_OPR_READ		BIT(2)
-#define		GCB_MIIM_MII_CMD_WRDATA(x)		((x) << 4)
-#define		GCB_MIIM_MII_CMD_REGAD(x)		((x) << 20)
-#define		GCB_MIIM_MII_CMD_PHYAD(x)		((x) << 25)
-#define		GCB_MIIM_MII_CMD_VLD			BIT(31)
-#define GCB_MIIM_DATA				0xC
-#define		GCB_MIIM_DATA_ERROR			(0x2 << 16)
+#include "mscc_miim.h"
 
 #define ANA_PORT_VLAN_CFG(x)		(0x00 + 0x80 * (x))
 #define		ANA_PORT_VLAN_CFG_AWARE_ENA	BIT(20)
@@ -189,13 +178,6 @@ struct luton_private {
 	struct luton_phy_port_t ports[MAX_PORT];
 };
 
-struct mscc_miim_dev {
-	void __iomem *regs;
-	phys_addr_t miim_base;
-	unsigned long miim_size;
-	struct mii_dev *bus;
-};
-
 static const unsigned long luton_regs_qs[] = {
 	[MSCC_QS_XTR_RD] = 0x18,
 	[MSCC_QS_XTR_FLUSH] = 0x28,
@@ -213,84 +195,6 @@ static const unsigned long luton_regs_ana_table[] = {
 static struct mscc_miim_dev miim[LUTON_MIIM_BUS_COUNT];
 static int miim_count = -1;
 
-static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
-{
-	return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
-				 GCB_MIIM_STAT_BUSY, false, 250, false);
-}
-
-static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
-{
-	struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
-	u32 val;
-	int ret;
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret)
-		goto out;
-
-	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
-	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
-	       miim->regs + GCB_MIIM_MII_CMD);
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret)
-		goto out;
-
-	val = readl(miim->regs + GCB_MIIM_DATA);
-	if (val & GCB_MIIM_DATA_ERROR) {
-		ret = -EIO;
-		goto out;
-	}
-
-	ret = val & 0xFFFF;
- out:
-	return ret;
-}
-
-static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
-			   u16 val)
-{
-	struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
-	int ret;
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret < 0)
-		goto out;
-
-	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
-	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
-	       GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
- out:
-	return ret;
-}
-
-static struct mii_dev *serval_mdiobus_init(phys_addr_t miim_base,
-					   unsigned long miim_size)
-{
-	struct mii_dev *bus;
-
-	bus = mdio_alloc();
-	if (!bus)
-		return NULL;
-
-	++miim_count;
-	sprintf(bus->name, "miim-bus%d", miim_count);
-
-	miim[miim_count].regs = ioremap(miim_base, miim_size);
-	miim[miim_count].miim_base = miim_base;
-	miim[miim_count].miim_size = miim_size;
-	bus->priv = &miim[miim_count];
-	bus->read = mscc_miim_read;
-	bus->write = mscc_miim_write;
-
-	if (mdio_register(bus))
-		return NULL;
-
-	miim[miim_count].bus = bus;
-	return bus;
-}
-
 static void luton_stop(struct udevice *dev)
 {
 	struct luton_private *priv = dev_get_priv(dev);
@@ -760,7 +664,8 @@ static int luton_probe(struct udevice *dev)
 		/* If the bus is new then create a new bus */
 		if (!get_mdiobus(addr_base, addr_size))
 			priv->bus[miim_count] =
-				serval_mdiobus_init(addr_base, addr_size);
+				mscc_mdiobus_init(miim, &miim_count, addr_base,
+						  addr_size);
 
 		/* Connect mdio bus with the port */
 		bus = get_mdiobus(addr_base, addr_size);
diff --git a/drivers/net/mscc_eswitch/mscc_miim.c b/drivers/net/mscc_eswitch/mscc_miim.c
index 419dcc1..d8ee8df 100644
--- a/drivers/net/mscc_eswitch/mscc_miim.c
+++ b/drivers/net/mscc_eswitch/mscc_miim.c
@@ -72,3 +72,31 @@ int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
  out:
 	return ret;
 }
+
+struct mii_dev *mscc_mdiobus_init(struct mscc_miim_dev *miim, int *miim_count,
+				  phys_addr_t miim_base,
+				  unsigned long miim_size)
+{
+	struct mii_dev *bus;
+
+	bus = mdio_alloc();
+
+	if (!bus)
+		return NULL;
+
+	*miim_count += 1;
+	sprintf(bus->name, "miim-bus%d", *miim_count);
+
+	miim[*miim_count].regs = ioremap(miim_base, miim_size);
+	miim[*miim_count].miim_base = miim_base;
+	miim[*miim_count].miim_size = miim_size;
+	bus->priv = &miim[*miim_count];
+	bus->read = mscc_miim_read;
+	bus->write = mscc_miim_write;
+
+	if (mdio_register(bus))
+		return NULL;
+
+	miim[*miim_count].bus = bus;
+	return bus;
+}
diff --git a/drivers/net/mscc_eswitch/mscc_miim.h b/drivers/net/mscc_eswitch/mscc_miim.h
index 0e5d5e3..feb1f40 100644
--- a/drivers/net/mscc_eswitch/mscc_miim.h
+++ b/drivers/net/mscc_eswitch/mscc_miim.h
@@ -3,10 +3,22 @@
  * Copyright (c) 2018 Microsemi Corporation
  */
 
+#ifndef _MSCC_MIIM_H_
+#define _MSCC_MIIM_H_
+
 struct mscc_miim_dev {
 	void __iomem *regs;
-	void __iomem *phy_regs;
+	phys_addr_t miim_base;
+	unsigned long miim_size;
+	struct mii_dev *bus;
 };
 
 int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg);
 int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg, u16 val);
+
+struct mii_dev *mscc_mdiobus_init(struct mscc_miim_dev *miim, int *miim_count,
+				  phys_addr_t miim_base,
+				  unsigned long miim_size);
+
+
+#endif /* _MSCC_MIIM_H_ */
diff --git a/drivers/net/mscc_eswitch/ocelot_switch.c b/drivers/net/mscc_eswitch/ocelot_switch.c
index 5c7e696..0ba84ab 100644
--- a/drivers/net/mscc_eswitch/ocelot_switch.c
+++ b/drivers/net/mscc_eswitch/ocelot_switch.c
@@ -17,6 +17,7 @@
 
 #include "mscc_xfer.h"
 #include "mscc_mac_table.h"
+#include "mscc_miim.h"
 
 #define PHY_CFG				0x0
 #define PHY_CFG_ENA				0xF
@@ -25,20 +26,6 @@
 #define PHY_STAT			0x4
 #define PHY_STAT_SUPERVISOR_COMPLETE		BIT(0)
 
-#define GCB_MIIM_MII_STATUS		0x0
-#define		GCB_MIIM_STAT_BUSY		BIT(3)
-#define GCB_MIIM_MII_CMD		0x8
-#define		GCB_MIIM_MII_CMD_SCAN		BIT(0)
-#define		GCB_MIIM_MII_CMD_OPR_WRITE	BIT(1)
-#define		GCB_MIIM_MII_CMD_OPR_READ	BIT(2)
-#define		GCB_MIIM_MII_CMD_SINGLE_SCAN	BIT(3)
-#define		GCB_MIIM_MII_CMD_WRDATA(x)	((x) << 4)
-#define		GCB_MIIM_MII_CMD_REGAD(x)	((x) << 20)
-#define		GCB_MIIM_MII_CMD_PHYAD(x)	((x) << 25)
-#define		GCB_MIIM_MII_CMD_VLD		BIT(31)
-#define GCB_MIIM_DATA			0xC
-#define		GCB_MIIM_DATA_ERROR		(0x3 << 16)
-
 #define ANA_PORT_VLAN_CFG(x)		(0x7000 + 0x100 * (x))
 #define		ANA_PORT_VLAN_CFG_AWARE_ENA	BIT(20)
 #define		ANA_PORT_VLAN_CFG_POP_CNT(x)	((x) << 18)
@@ -173,13 +160,6 @@ struct ocelot_private {
 	struct ocelot_phy_port_t ports[MAX_PORT];
 };
 
-struct mscc_miim_dev {
-	void __iomem *regs;
-	phys_addr_t miim_base;
-	unsigned long miim_size;
-	struct mii_dev *bus;
-};
-
 static struct mscc_miim_dev miim[OCELOT_MIIM_BUS_COUNT];
 static int miim_count = -1;
 
@@ -209,85 +189,6 @@ static void mscc_phy_reset(void)
 	}
 }
 
-static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
-{
-	return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
-				 GCB_MIIM_STAT_BUSY, false, 250, false);
-}
-
-static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
-{
-	struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
-	u32 val;
-	int ret;
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret)
-		goto out;
-
-	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
-	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
-	       miim->regs + GCB_MIIM_MII_CMD);
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret)
-		goto out;
-
-	val = readl(miim->regs + GCB_MIIM_DATA);
-	if (val & GCB_MIIM_DATA_ERROR) {
-		ret = -EIO;
-		goto out;
-	}
-
-	ret = val & 0xFFFF;
- out:
-	return ret;
-}
-
-static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
-			   u16 val)
-{
-	struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
-	int ret;
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret < 0)
-		goto out;
-
-	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
-	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
-	       GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
- out:
-	return ret;
-}
-
-static struct mii_dev *ocelot_mdiobus_init(phys_addr_t miim_base,
-					   unsigned long miim_size)
-{
-	struct mii_dev *bus;
-
-	bus = mdio_alloc();
-
-	if (!bus)
-		return NULL;
-
-	++miim_count;
-	sprintf(bus->name, "miim-bus%d", miim_count);
-
-	miim[miim_count].regs = ioremap(miim_base, miim_size);
-	miim[miim_count].miim_base = miim_base;
-	miim[miim_count].miim_size = miim_size;
-	bus->priv = &miim[miim_count];
-	bus->read = mscc_miim_read;
-	bus->write = mscc_miim_write;
-
-	if (mdio_register(bus))
-		return NULL;
-
-	miim[miim_count].bus = bus;
-	return bus;
-}
-
 __weak void mscc_switch_reset(void)
 {
 }
@@ -682,7 +583,8 @@ static int ocelot_probe(struct udevice *dev)
 		/* If the bus is new then create a new bus */
 		if (!get_mdiobus(addr_base, addr_size))
 			priv->bus[miim_count] =
-				ocelot_mdiobus_init(addr_base, addr_size);
+				mscc_mdiobus_init(miim, &miim_count, addr_base,
+						  addr_size);
 
 		/* Connect mdio bus with the port */
 		bus = get_mdiobus(addr_base, addr_size);
diff --git a/drivers/net/mscc_eswitch/serval_switch.c b/drivers/net/mscc_eswitch/serval_switch.c
index 2559f5d..269ed30 100644
--- a/drivers/net/mscc_eswitch/serval_switch.c
+++ b/drivers/net/mscc_eswitch/serval_switch.c
@@ -17,18 +17,7 @@
 
 #include "mscc_xfer.h"
 #include "mscc_mac_table.h"
-
-#define GCB_MIIM_MII_STATUS			0x0
-#define		GCB_MIIM_STAT_BUSY			BIT(3)
-#define GCB_MIIM_MII_CMD			0x8
-#define		GCB_MIIM_MII_CMD_OPR_WRITE		BIT(1)
-#define		GCB_MIIM_MII_CMD_OPR_READ		BIT(2)
-#define		GCB_MIIM_MII_CMD_WRDATA(x)		((x) << 4)
-#define		GCB_MIIM_MII_CMD_REGAD(x)		((x) << 20)
-#define		GCB_MIIM_MII_CMD_PHYAD(x)		((x) << 25)
-#define		GCB_MIIM_MII_CMD_VLD			BIT(31)
-#define GCB_MIIM_DATA				0xC
-#define		GCB_MIIM_DATA_ERROR			(0x2 << 16)
+#include "mscc_miim.h"
 
 #define ANA_PORT_VLAN_CFG(x)			(0xc000 + 0x100 * (x))
 #define		ANA_PORT_VLAN_CFG_AWARE_ENA		BIT(20)
@@ -156,13 +145,6 @@ struct serval_private {
 	struct serval_phy_port_t ports[MAX_PORT];
 };
 
-struct mscc_miim_dev {
-	void __iomem *regs;
-	phys_addr_t miim_base;
-	unsigned long miim_size;
-	struct mii_dev *bus;
-};
-
 static const unsigned long serval_regs_qs[] = {
 	[MSCC_QS_XTR_RD] = 0x8,
 	[MSCC_QS_XTR_FLUSH] = 0x18,
@@ -180,84 +162,6 @@ static const unsigned long serval_regs_ana_table[] = {
 static struct mscc_miim_dev miim[SERVAL_MIIM_BUS_COUNT];
 static int miim_count = -1;
 
-static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
-{
-	return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
-				 GCB_MIIM_STAT_BUSY, false, 250, false);
-}
-
-static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
-{
-	struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
-	u32 val;
-	int ret;
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret)
-		goto out;
-
-	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
-	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
-	       miim->regs + GCB_MIIM_MII_CMD);
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret)
-		goto out;
-
-	val = readl(miim->regs + GCB_MIIM_DATA);
-	if (val & GCB_MIIM_DATA_ERROR) {
-		ret = -EIO;
-		goto out;
-	}
-
-	ret = val & 0xFFFF;
- out:
-	return ret;
-}
-
-static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
-			   u16 val)
-{
-	struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
-	int ret;
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret < 0)
-		goto out;
-
-	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
-	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
-	       GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
- out:
-	return ret;
-}
-
-static struct mii_dev *serval_mdiobus_init(phys_addr_t miim_base,
-					   unsigned long miim_size)
-{
-	struct mii_dev *bus;
-
-	bus = mdio_alloc();
-	if (!bus)
-		return NULL;
-
-	++miim_count;
-	sprintf(bus->name, "miim-bus%d", miim_count);
-
-	miim[miim_count].regs = ioremap(miim_base, miim_size);
-	miim[miim_count].miim_base = miim_base;
-	miim[miim_count].miim_size = miim_size;
-	bus->priv = &miim[miim_count];
-	bus->read = mscc_miim_read;
-	bus->write = mscc_miim_write;
-
-	if (mdio_register(bus))
-		return NULL;
-
-	miim[miim_count].bus = bus;
-	return bus;
-}
-
 static void serval_cpu_capture_setup(struct serval_private *priv)
 {
 	int i;
@@ -636,7 +540,8 @@ static int serval_probe(struct udevice *dev)
 		/* If the bus is new then create a new bus */
 		if (!get_mdiobus(addr_base, addr_size))
 			priv->bus[miim_count] =
-				serval_mdiobus_init(addr_base, addr_size);
+				mscc_mdiobus_init(miim, &miim_count, addr_base,
+						  addr_size);
 
 		/* Connect mdio bus with the port */
 		bus = get_mdiobus(addr_base, addr_size);
diff --git a/drivers/net/mscc_eswitch/servalt_switch.c b/drivers/net/mscc_eswitch/servalt_switch.c
index 995c623..d20ec49 100644
--- a/drivers/net/mscc_eswitch/servalt_switch.c
+++ b/drivers/net/mscc_eswitch/servalt_switch.c
@@ -16,18 +16,7 @@
 #include <wait_bit.h>
 
 #include "mscc_xfer.h"
-
-#define GCB_MIIM_MII_STATUS		0x0
-#define		GCB_MIIM_STAT_BUSY		BIT(3)
-#define GCB_MIIM_MII_CMD		0x8
-#define		GCB_MIIM_MII_CMD_OPR_WRITE	BIT(1)
-#define		GCB_MIIM_MII_CMD_OPR_READ	BIT(2)
-#define		GCB_MIIM_MII_CMD_WRDATA(x)	((x) << 4)
-#define		GCB_MIIM_MII_CMD_REGAD(x)	((x) << 20)
-#define		GCB_MIIM_MII_CMD_PHYAD(x)	((x) << 25)
-#define		GCB_MIIM_MII_CMD_VLD		BIT(31)
-#define GCB_MIIM_DATA			0xC
-#define		GCB_MIIM_DATA_ERROR		(0x3 << 16)
+#include "mscc_miim.h"
 
 #define PHY_CFG				0x0
 #define PHY_CFG_ENA				0x3
@@ -134,13 +123,6 @@ struct servalt_private {
 	struct servalt_phy_port_t ports[MAX_PORT];
 };
 
-struct mscc_miim_dev {
-	void __iomem *regs;
-	phys_addr_t miim_base;
-	unsigned long miim_size;
-	struct mii_dev *bus;
-};
-
 static const unsigned long servalt_regs_qs[] = {
 	[MSCC_QS_XTR_RD] = 0x8,
 	[MSCC_QS_XTR_FLUSH] = 0x18,
@@ -152,85 +134,6 @@ static const unsigned long servalt_regs_qs[] = {
 static struct mscc_miim_dev miim[SERVALT_MIIM_BUS_COUNT];
 static int miim_count = -1;
 
-static int mscc_miim_wait_ready(struct mscc_miim_dev *miim)
-{
-	return wait_for_bit_le32(miim->regs + GCB_MIIM_MII_STATUS,
-				 GCB_MIIM_STAT_BUSY, false, 250, false);
-}
-
-static int mscc_miim_read(struct mii_dev *bus, int addr, int devad, int reg)
-{
-	struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
-	u32 val;
-	int ret;
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret)
-		goto out;
-
-	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
-	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_OPR_READ,
-	       miim->regs + GCB_MIIM_MII_CMD);
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret)
-		goto out;
-
-	val = readl(miim->regs + GCB_MIIM_DATA);
-	if (val & GCB_MIIM_DATA_ERROR) {
-		ret = -EIO;
-		goto out;
-	}
-
-	ret = val & 0xFFFF;
-out:
-	return ret;
-}
-
-static int mscc_miim_write(struct mii_dev *bus, int addr, int devad, int reg,
-			   u16 val)
-{
-	struct mscc_miim_dev *miim = (struct mscc_miim_dev *)bus->priv;
-	int ret;
-
-	ret = mscc_miim_wait_ready(miim);
-	if (ret < 0)
-		goto out;
-
-	writel(GCB_MIIM_MII_CMD_VLD | GCB_MIIM_MII_CMD_PHYAD(addr) |
-	       GCB_MIIM_MII_CMD_REGAD(reg) | GCB_MIIM_MII_CMD_WRDATA(val) |
-	       GCB_MIIM_MII_CMD_OPR_WRITE, miim->regs + GCB_MIIM_MII_CMD);
-
-out:
-	return ret;
-}
-
-static struct mii_dev *servalt_mdiobus_init(phys_addr_t miim_base,
-					    unsigned long miim_size)
-{
-	struct mii_dev *bus;
-
-	bus = mdio_alloc();
-	if (!bus)
-		return NULL;
-
-	++miim_count;
-	sprintf(bus->name, "miim-bus%d", miim_count);
-
-	miim[miim_count].regs = ioremap(miim_base, miim_size);
-	miim[miim_count].miim_base = miim_base;
-	miim[miim_count].miim_size = miim_size;
-	bus->priv = &miim[miim_count];
-	bus->read = mscc_miim_read;
-	bus->write = mscc_miim_write;
-
-	if (mdio_register(bus))
-		return NULL;
-
-	miim[miim_count].bus = bus;
-	return bus;
-}
-
 static void mscc_phy_reset(void)
 {
 	writel(0, BASE_DEVCPU_GCB + GCB_PHY_CFG + PHY_CFG);
@@ -564,7 +467,8 @@ static int servalt_probe(struct udevice *dev)
 		/* If the bus is new then create a new bus */
 		if (!get_mdiobus(addr_base, addr_size))
 			priv->bus[miim_count] =
-				servalt_mdiobus_init(addr_base, addr_size);
+				mscc_mdiobus_init(miim, &miim_count, addr_base,
+						  addr_size);
 
 		/* Connect mdio bus with the port */
 		bus = get_mdiobus(addr_base, addr_size);
-- 
2.7.4



More information about the U-Boot mailing list