diff options
author | Horatiu Vultur <horatiu.vultur@microchip.com> | 2019-06-09 15:27:29 +0200 |
---|---|---|
committer | Joe Hershberger <joe.hershberger@ni.com> | 2019-07-15 13:32:25 -0500 |
commit | 61243678c2ffe39b23ac73adb9b42c3d317817ce (patch) | |
tree | 6735dbc87002d34134bc880d332131a30195827c /drivers/net | |
parent | ec9594a50f02944944dcc76a6cffce9861e8614d (diff) |
net: mscc: refactor mscc_miim
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@microchip.com>
Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/mscc_eswitch/Makefile | 10 | ||||
-rw-r--r-- | drivers/net/mscc_eswitch/jr2_switch.c | 119 | ||||
-rw-r--r-- | drivers/net/mscc_eswitch/luton_switch.c | 101 | ||||
-rw-r--r-- | drivers/net/mscc_eswitch/mscc_miim.c | 28 | ||||
-rw-r--r-- | drivers/net/mscc_eswitch/mscc_miim.h | 14 | ||||
-rw-r--r-- | drivers/net/mscc_eswitch/ocelot_switch.c | 104 | ||||
-rw-r--r-- | drivers/net/mscc_eswitch/serval_switch.c | 101 | ||||
-rw-r--r-- | 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 02f39a76bb..d583fe9fc4 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 60d408f1c7..665517775e 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 94852b06e7..dffe81d873 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 419dcc1dd6..d8ee8df47b 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 0e5d5e3c81..feb1f40ae5 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 5c7e6961be..0ba84ab78a 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 2c30941253..1a21360a96 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; @@ -634,7 +538,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 995c62309d..d20ec49d56 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); |