summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board/gdsys/a38x/ihs_phys.c237
-rw-r--r--common/board_r.c3
-rw-r--r--common/miiphyutil.c13
-rw-r--r--drivers/net/designware.c263
-rw-r--r--drivers/net/phy/miiphybb.c36
-rw-r--r--drivers/net/ravb.c159
-rw-r--r--drivers/net/sh_eth.c179
-rw-r--r--include/miiphy.h17
8 files changed, 438 insertions, 469 deletions
diff --git a/board/gdsys/a38x/ihs_phys.c b/board/gdsys/a38x/ihs_phys.c
index 690a29690b9..0c68087912a 100644
--- a/board/gdsys/a38x/ihs_phys.c
+++ b/board/gdsys/a38x/ihs_phys.c
@@ -102,102 +102,6 @@ uint calculate_octo_phy_mask(void)
return octo_phy_mask;
}
-int register_miiphy_bus(uint k, struct mii_dev **bus)
-{
- int retval;
- struct mii_dev *mdiodev = mdio_alloc();
- char *name = bb_miiphy_buses[k].name;
-
- if (!mdiodev)
- return -ENOMEM;
- strlcpy(mdiodev->name, name, MDIO_NAME_LEN);
- mdiodev->read = bb_miiphy_read;
- mdiodev->write = bb_miiphy_write;
-
- retval = mdio_register(mdiodev);
- if (retval < 0)
- return retval;
- *bus = miiphy_get_dev_by_name(name);
-
- return 0;
-}
-
-struct porttype *get_porttype(uint octo_phy_mask, uint k)
-{
- uint octo_index = k * 4;
-
- if (!k) {
- if (octo_phy_mask & 0x01)
- return &porttypes[PORTTYPE_MAIN_CAT];
- else if (!(octo_phy_mask & 0x03))
- return &porttypes[PORTTYPE_16C_16F];
- } else {
- if (octo_phy_mask & (1 << octo_index))
- return &porttypes[PORTTYPE_TOP_CAT];
- }
-
- return NULL;
-}
-
-int init_single_phy(struct porttype *porttype, struct mii_dev *bus,
- uint bus_idx, uint m, uint phy_idx)
-{
- struct phy_device *phydev;
-
- phydev = phy_find_by_mask(bus, BIT(m * 8 + phy_idx));
- printf(" %u", bus_idx * 32 + m * 8 + phy_idx);
-
- if (!phydev)
- puts("!");
- else
- ihs_phy_config(phydev, porttype->phy_invert_in_pol,
- porttype->phy_invert_out_pol);
-
- return 0;
-}
-
-int init_octo_phys(uint octo_phy_mask)
-{
- uint bus_idx;
-
- /* there are up to four octo-phys on each mdio bus */
- for (bus_idx = 0; bus_idx < bb_miiphy_buses_num; ++bus_idx) {
- uint m;
- uint octo_index = bus_idx * 4;
- struct mii_dev *bus = NULL;
- struct porttype *porttype = NULL;
- int ret;
-
- porttype = get_porttype(octo_phy_mask, bus_idx);
-
- if (!porttype)
- continue;
-
- for (m = 0; m < 4; ++m) {
- uint phy_idx;
-
- /**
- * Register a bus device if there is at least one phy
- * on the current bus
- */
- if (!m && octo_phy_mask & (0xf << octo_index)) {
- ret = register_miiphy_bus(bus_idx, &bus);
- if (ret)
- return ret;
- }
-
- if (!(octo_phy_mask & BIT(octo_index + m)))
- continue;
-
- for (phy_idx = 0; phy_idx < 8; ++phy_idx)
- init_single_phy(porttype, bus, bus_idx, m,
- phy_idx);
- }
- }
-
- return 0;
-}
-
/*
* MII GPIO bitbang implementation
* MDC MDIO bus
@@ -315,40 +219,109 @@ static int mii_delay(struct bb_miiphy_bus *bus)
return 0;
}
-struct bb_miiphy_bus bb_miiphy_buses[] = {
- {
- .name = "ihs0",
- .init = mii_mdio_init,
- .mdio_active = mii_mdio_active,
- .mdio_tristate = mii_mdio_tristate,
- .set_mdio = mii_set_mdio,
- .get_mdio = mii_get_mdio,
- .set_mdc = mii_set_mdc,
- .delay = mii_delay,
- .priv = &gpio_mii_set[0],
- },
- {
- .name = "ihs1",
- .init = mii_mdio_init,
- .mdio_active = mii_mdio_active,
- .mdio_tristate = mii_mdio_tristate,
- .set_mdio = mii_set_mdio,
- .get_mdio = mii_get_mdio,
- .set_mdc = mii_set_mdc,
- .delay = mii_delay,
- .priv = &gpio_mii_set[1],
- },
- {
- .name = "ihs2",
- .init = mii_mdio_init,
- .mdio_active = mii_mdio_active,
- .mdio_tristate = mii_mdio_tristate,
- .set_mdio = mii_set_mdio,
- .get_mdio = mii_get_mdio,
- .set_mdc = mii_set_mdc,
- .delay = mii_delay,
- .priv = &gpio_mii_set[2],
- },
-};
+int register_miiphy_bus(uint k, struct mii_dev **bus)
+{
+ struct bb_miiphy_bus *bb_miiphy = bb_miiphy_alloc();
+ struct mii_dev *mdiodev;
+ int retval;
+
+ if (!bb_miiphy)
+ return -ENOMEM;
+
+ mdiodev = &bb_miiphy->mii;
+ snprintf(mdiodev->name, MDIO_NAME_LEN, "ihs%d", k);
+ mdiodev->read = bb_miiphy_read;
+ mdiodev->write = bb_miiphy_write;
+
+ /* Copy the bus accessors and private data */
+ bb_miiphy->mdio_active = mii_mdio_active;
+ bb_miiphy->mdio_tristate = mii_mdio_tristate;
+ bb_miiphy->set_mdio = mii_set_mdio;
+ bb_miiphy->get_mdio = mii_get_mdio;
+ bb_miiphy->set_mdc = mii_set_mdc;
+ bb_miiphy->delay = mii_delay;
+ bb_miiphy->priv = &gpio_mii_set[k];
+
+ retval = mdio_register(mdiodev);
+ if (retval < 0)
+ return retval;
+ *bus = &bb_miiphy->mii;
+
+ return mii_mdio_init(bb_miiphy);
+}
+
+struct porttype *get_porttype(uint octo_phy_mask, uint k)
+{
+ uint octo_index = k * 4;
+
+ if (!k) {
+ if (octo_phy_mask & 0x01)
+ return &porttypes[PORTTYPE_MAIN_CAT];
+ else if (!(octo_phy_mask & 0x03))
+ return &porttypes[PORTTYPE_16C_16F];
+ } else {
+ if (octo_phy_mask & (1 << octo_index))
+ return &porttypes[PORTTYPE_TOP_CAT];
+ }
+
+ return NULL;
+}
+
+int init_single_phy(struct porttype *porttype, struct mii_dev *bus,
+ uint bus_idx, uint m, uint phy_idx)
+{
+ struct phy_device *phydev;
+
+ phydev = phy_find_by_mask(bus, BIT(m * 8 + phy_idx));
+ printf(" %u", bus_idx * 32 + m * 8 + phy_idx);
+
+ if (!phydev)
+ puts("!");
+ else
+ ihs_phy_config(phydev, porttype->phy_invert_in_pol,
+ porttype->phy_invert_out_pol);
+
+ return 0;
+}
+
+int init_octo_phys(uint octo_phy_mask)
+{
+ uint bus_idx;
-int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
+ /* there are up to four octo-phys on each mdio bus */
+ for (bus_idx = 0; bus_idx < ARRAY_SIZE(gpio_mii_set); ++bus_idx) {
+ uint m;
+ uint octo_index = bus_idx * 4;
+ struct mii_dev *bus = NULL;
+ struct porttype *porttype = NULL;
+ int ret;
+
+ porttype = get_porttype(octo_phy_mask, bus_idx);
+
+ if (!porttype)
+ continue;
+
+ for (m = 0; m < 4; ++m) {
+ uint phy_idx;
+
+ /**
+ * Register a bus device if there is at least one phy
+ * on the current bus
+ */
+ if (!m && octo_phy_mask & (0xf << octo_index)) {
+ ret = register_miiphy_bus(bus_idx, &bus);
+ if (ret)
+ return ret;
+ }
+
+ if (!(octo_phy_mask & BIT(octo_index + m)))
+ continue;
+
+ for (phy_idx = 0; phy_idx < 8; ++phy_idx)
+ init_single_phy(porttype, bus, bus_idx, m,
+ phy_idx);
+ }
+ }
+
+ return 0;
+}
diff --git a/common/board_r.c b/common/board_r.c
index 179259b00de..db0c5cb8032 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -749,9 +749,6 @@ static init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_BOARD_LATE_INIT
board_late_init,
#endif
-#ifdef CONFIG_BITBANGMII
- bb_miiphy_init,
-#endif
#ifdef CONFIG_PCI_ENDPOINT
pci_ep_init,
#endif
diff --git a/common/miiphyutil.c b/common/miiphyutil.c
index 9b8744e5d8b..2a034d3a77c 100644
--- a/common/miiphyutil.c
+++ b/common/miiphyutil.c
@@ -65,6 +65,14 @@ void miiphy_init(void)
current_mii = NULL;
}
+void mdio_init(struct mii_dev *bus)
+{
+ memset(bus, 0, sizeof(*bus));
+
+ /* initialize mii_dev struct fields */
+ INIT_LIST_HEAD(&bus->link);
+}
+
struct mii_dev *mdio_alloc(void)
{
struct mii_dev *bus;
@@ -73,10 +81,7 @@ struct mii_dev *mdio_alloc(void)
if (!bus)
return bus;
- memset(bus, 0, sizeof(*bus));
-
- /* initalize mii_dev struct fields */
- INIT_LIST_HEAD(&bus->link);
+ mdio_init(bus);
return bus;
}
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 2ab03015ffa..5a6e89c0575 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -226,6 +226,124 @@ static int dw_dm_mdio_init(const char *name, void *priv)
}
#endif
+#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
+static int dw_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
+{
+ struct dw_eth_dev *priv = bus->priv;
+ struct gpio_desc *desc = &priv->mdio_gpio;
+
+ desc->flags = 0;
+ dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+
+ return 0;
+}
+
+static int dw_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
+{
+ struct dw_eth_dev *priv = bus->priv;
+ struct gpio_desc *desc = &priv->mdio_gpio;
+
+ desc->flags = 0;
+ dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_IN);
+
+ return 0;
+}
+
+static int dw_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
+{
+ struct dw_eth_dev *priv = bus->priv;
+
+ if (v)
+ dm_gpio_set_value(&priv->mdio_gpio, 1);
+ else
+ dm_gpio_set_value(&priv->mdio_gpio, 0);
+
+ return 0;
+}
+
+static int dw_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
+{
+ struct dw_eth_dev *priv = bus->priv;
+
+ *v = dm_gpio_get_value(&priv->mdio_gpio);
+
+ return 0;
+}
+
+static int dw_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
+{
+ struct dw_eth_dev *priv = bus->priv;
+
+ if (v)
+ dm_gpio_set_value(&priv->mdc_gpio, 1);
+ else
+ dm_gpio_set_value(&priv->mdc_gpio, 0);
+
+ return 0;
+}
+
+static int dw_eth_bb_delay(struct bb_miiphy_bus *bus)
+{
+ struct dw_eth_dev *priv = bus->priv;
+
+ udelay(priv->bb_delay);
+ return 0;
+}
+
+static int dw_bb_mdio_init(const char *name, struct udevice *dev)
+{
+ struct dw_eth_dev *dwpriv = dev_get_priv(dev);
+ struct bb_miiphy_bus *bb_miiphy = bb_miiphy_alloc();
+ struct mii_dev *bus;
+ int ret;
+
+ if (!bb_miiphy) {
+ printf("Failed to allocate MDIO bus\n");
+ return -ENOMEM;
+ }
+
+ bus = &bb_miiphy->mii;
+
+ debug("\n%s: use bitbang mii..\n", dev->name);
+ ret = gpio_request_by_name(dev, "snps,mdc-gpio", 0,
+ &dwpriv->mdc_gpio,
+ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+ if (ret) {
+ debug("no mdc-gpio\n");
+ return ret;
+ }
+ ret = gpio_request_by_name(dev, "snps,mdio-gpio", 0,
+ &dwpriv->mdio_gpio,
+ GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+ if (ret) {
+ debug("no mdio-gpio\n");
+ return ret;
+ }
+ dwpriv->bb_delay = dev_read_u32_default(dev, "snps,bitbang-delay", 1);
+
+ dwpriv->bus = bus;
+ dwpriv->dev = dev;
+
+ snprintf(bus->name, sizeof(bus->name), "%s", name);
+ bus->read = bb_miiphy_read;
+ bus->write = bb_miiphy_write;
+#if CONFIG_IS_ENABLED(DM_GPIO)
+ bus->reset = dw_mdio_reset;
+#endif
+ bus->priv = dwpriv;
+
+ /* Copy the bus accessors and private data */
+ bb_miiphy->mdio_active = dw_eth_bb_mdio_active;
+ bb_miiphy->mdio_tristate = dw_eth_bb_mdio_tristate;
+ bb_miiphy->set_mdio = dw_eth_bb_set_mdio;
+ bb_miiphy->get_mdio = dw_eth_bb_get_mdio;
+ bb_miiphy->set_mdc = dw_eth_bb_set_mdc;
+ bb_miiphy->delay = dw_eth_bb_delay;
+
+ return mdio_register(bus);
+}
+#endif
+
static void tx_descs_init(struct dw_eth_dev *priv)
{
struct eth_dma_regs *dma_p = priv->dma_regs_p;
@@ -722,6 +840,7 @@ int designware_eth_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
struct dw_eth_dev *priv = dev_get_priv(dev);
+ bool __maybe_unused bbmiiphy = false;
phys_addr_t iobase = pdata->iobase;
void *ioaddr;
int ret, err;
@@ -812,51 +931,30 @@ int designware_eth_probe(struct udevice *dev)
priv->interface = pdata->phy_interface;
priv->max_speed = pdata->max_speed;
-#if IS_ENABLED(CONFIG_DM_MDIO)
- ret = dw_dm_mdio_init(dev->name, dev);
-#else
- ret = dw_mdio_init(dev->name, dev);
-#endif
- if (ret) {
- err = ret;
- goto mdio_err;
- }
- priv->bus = miiphy_get_dev_by_name(dev->name);
- priv->dev = dev;
-
#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
- if (dev_read_bool(dev, "snps,bitbang-mii")) {
- int bus_idx;
-
- debug("\n%s: use bitbang mii..\n", dev->name);
- ret = gpio_request_by_name(dev, "snps,mdc-gpio", 0,
- &priv->mdc_gpio, GPIOD_IS_OUT
- | GPIOD_IS_OUT_ACTIVE);
+ bbmiiphy = dev_read_bool(dev, "snps,bitbang-mii");
+ if (bbmiiphy) {
+ ret = dw_bb_mdio_init(dev->name, dev);
if (ret) {
- debug("no mdc-gpio\n");
- return ret;
+ err = ret;
+ goto mdio_err;
}
- ret = gpio_request_by_name(dev, "snps,mdio-gpio", 0,
- &priv->mdio_gpio, GPIOD_IS_OUT
- | GPIOD_IS_OUT_ACTIVE);
+ } else
+#endif
+ {
+#if IS_ENABLED(CONFIG_DM_MDIO)
+ ret = dw_dm_mdio_init(dev->name, dev);
+#else
+ ret = dw_mdio_init(dev->name, dev);
+#endif
if (ret) {
- debug("no mdio-gpio\n");
- return ret;
- }
- priv->bb_delay = dev_read_u32_default(dev, "snps,bitbang-delay", 1);
-
- for (bus_idx = 0; bus_idx < bb_miiphy_buses_num; bus_idx++) {
- if (!bb_miiphy_buses[bus_idx].priv) {
- bb_miiphy_buses[bus_idx].priv = priv;
- strlcpy(bb_miiphy_buses[bus_idx].name, priv->bus->name,
- MDIO_NAME_LEN);
- priv->bus->read = bb_miiphy_read;
- priv->bus->write = bb_miiphy_write;
- break;
- }
+ err = ret;
+ goto mdio_err;
}
+ priv->bus = miiphy_get_dev_by_name(dev->name);
+ priv->dev = dev;
}
-#endif
+
ret = dw_phy_init(priv, dev);
debug("%s, ret=%d\n", __func__, ret);
if (!ret)
@@ -865,7 +963,12 @@ int designware_eth_probe(struct udevice *dev)
/* continue here for cleanup if no PHY found */
err = ret;
mdio_unregister(priv->bus);
- mdio_free(priv->bus);
+#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
+ if (bbmiiphy)
+ bb_miiphy_free(container_of(priv->bus, struct bb_miiphy_bus, mii));
+ else
+#endif
+ mdio_free(priv->bus);
mdio_err:
#ifdef CONFIG_CLK
@@ -967,83 +1070,3 @@ static struct pci_device_id supported[] = {
};
U_BOOT_PCI_DEVICE(eth_designware, supported);
-
-#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
-static int dw_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
-{
- struct dw_eth_dev *priv = bus->priv;
- struct gpio_desc *desc = &priv->mdio_gpio;
-
- desc->flags = 0;
- dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
-
- return 0;
-}
-
-static int dw_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
-{
- struct dw_eth_dev *priv = bus->priv;
- struct gpio_desc *desc = &priv->mdio_gpio;
-
- desc->flags = 0;
- dm_gpio_set_dir_flags(&priv->mdio_gpio, GPIOD_IS_IN);
-
- return 0;
-}
-
-static int dw_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
-{
- struct dw_eth_dev *priv = bus->priv;
-
- if (v)
- dm_gpio_set_value(&priv->mdio_gpio, 1);
- else
- dm_gpio_set_value(&priv->mdio_gpio, 0);
-
- return 0;
-}
-
-static int dw_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
-{
- struct dw_eth_dev *priv = bus->priv;
-
- *v = dm_gpio_get_value(&priv->mdio_gpio);
-
- return 0;
-}
-
-static int dw_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
-{
- struct dw_eth_dev *priv = bus->priv;
-
- if (v)
- dm_gpio_set_value(&priv->mdc_gpio, 1);
- else
- dm_gpio_set_value(&priv->mdc_gpio, 0);
-
- return 0;
-}
-
-static int dw_eth_bb_delay(struct bb_miiphy_bus *bus)
-{
- struct dw_eth_dev *priv = bus->priv;
-
- udelay(priv->bb_delay);
- return 0;
-}
-
-struct bb_miiphy_bus bb_miiphy_buses[] = {
- {
- .name = BB_MII_DEVNAME,
- .mdio_active = dw_eth_bb_mdio_active,
- .mdio_tristate = dw_eth_bb_mdio_tristate,
- .set_mdio = dw_eth_bb_set_mdio,
- .get_mdio = dw_eth_bb_get_mdio,
- .set_mdc = dw_eth_bb_set_mdc,
- .delay = dw_eth_bb_delay,
- .priv = NULL,
- }
-};
-
-int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
-#endif
diff --git a/drivers/net/phy/miiphybb.c b/drivers/net/phy/miiphybb.c
index 9f5f9b12c9f..553af2c1032 100644
--- a/drivers/net/phy/miiphybb.c
+++ b/drivers/net/phy/miiphybb.c
@@ -14,31 +14,31 @@
#include <ioports.h>
#include <ppc_asm.tmpl>
+#include <malloc.h>
#include <miiphy.h>
#include <asm/global_data.h>
-int bb_miiphy_init(void)
+static inline struct bb_miiphy_bus *bb_miiphy_getbus(struct mii_dev *miidev)
{
- int i;
+ return container_of(miidev, struct bb_miiphy_bus, mii);
+}
- for (i = 0; i < bb_miiphy_buses_num; i++)
- if (bb_miiphy_buses[i].init != NULL)
- bb_miiphy_buses[i].init(&bb_miiphy_buses[i]);
+struct bb_miiphy_bus *bb_miiphy_alloc(void)
+{
+ struct bb_miiphy_bus *bus;
- return 0;
+ bus = malloc(sizeof(*bus));
+ if (!bus)
+ return bus;
+
+ mdio_init(&bus->mii);
+
+ return bus;
}
-static inline struct bb_miiphy_bus *bb_miiphy_getbus(const char *devname)
+void bb_miiphy_free(struct bb_miiphy_bus *bus)
{
- int i;
-
- /* Search the correct bus */
- for (i = 0; i < bb_miiphy_buses_num; i++) {
- if (!strcmp(bb_miiphy_buses[i].name, devname)) {
- return &bb_miiphy_buses[i];
- }
- }
- return NULL;
+ free(bus);
}
/*****************************************************************************
@@ -133,7 +133,7 @@ int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg)
int j; /* counter */
struct bb_miiphy_bus *bus;
- bus = bb_miiphy_getbus(miidev->name);
+ bus = bb_miiphy_getbus(miidev);
if (bus == NULL) {
return -1;
}
@@ -201,7 +201,7 @@ int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg,
struct bb_miiphy_bus *bus;
int j; /* counter */
- bus = bb_miiphy_getbus(miidev->name);
+ bus = bb_miiphy_getbus(miidev);
if (bus == NULL) {
/* Bus not found! */
return -1;
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index 7286ad19598..cb727ae9bc1 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -490,10 +490,70 @@ static void ravb_stop(struct udevice *dev)
ravb_reset(dev);
}
+/* Bitbang MDIO access */
+static int ravb_bb_mdio_active(struct bb_miiphy_bus *bus)
+{
+ struct ravb_priv *eth = bus->priv;
+
+ setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MMD);
+
+ return 0;
+}
+
+static int ravb_bb_mdio_tristate(struct bb_miiphy_bus *bus)
+{
+ struct ravb_priv *eth = bus->priv;
+
+ clrbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MMD);
+
+ return 0;
+}
+
+static int ravb_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
+{
+ struct ravb_priv *eth = bus->priv;
+
+ if (v)
+ setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDO);
+ else
+ clrbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDO);
+
+ return 0;
+}
+
+static int ravb_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
+{
+ struct ravb_priv *eth = bus->priv;
+
+ *v = (readl(eth->iobase + RAVB_REG_PIR) & PIR_MDI) >> 3;
+
+ return 0;
+}
+
+static int ravb_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
+{
+ struct ravb_priv *eth = bus->priv;
+
+ if (v)
+ setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDC);
+ else
+ clrbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDC);
+
+ return 0;
+}
+
+static int ravb_bb_delay(struct bb_miiphy_bus *bus)
+{
+ udelay(10);
+
+ return 0;
+}
+
static int ravb_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
struct ravb_priv *eth = dev_get_priv(dev);
+ struct bb_miiphy_bus *bb_miiphy;
struct mii_dev *mdiodev;
void __iomem *iobase;
int ret;
@@ -505,22 +565,32 @@ static int ravb_probe(struct udevice *dev)
if (ret < 0)
goto err_mdio_alloc;
- mdiodev = mdio_alloc();
- if (!mdiodev) {
+ bb_miiphy = bb_miiphy_alloc();
+ if (!bb_miiphy) {
ret = -ENOMEM;
goto err_mdio_alloc;
}
+ mdiodev = &bb_miiphy->mii;
+
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
- bb_miiphy_buses[0].priv = eth;
snprintf(mdiodev->name, sizeof(mdiodev->name), dev->name);
+ /* Copy the bus accessors and private data */
+ bb_miiphy->mdio_active = ravb_bb_mdio_active;
+ bb_miiphy->mdio_tristate = ravb_bb_mdio_tristate;
+ bb_miiphy->set_mdio = ravb_bb_set_mdio;
+ bb_miiphy->get_mdio = ravb_bb_get_mdio;
+ bb_miiphy->set_mdc = ravb_bb_set_mdc;
+ bb_miiphy->delay = ravb_bb_delay;
+ bb_miiphy->priv = eth;
+
ret = mdio_register(mdiodev);
if (ret < 0)
goto err_mdio_register;
- eth->bus = miiphy_get_dev_by_name(dev->name);
+ eth->bus = &bb_miiphy->mii;
/* Bring up PHY */
ret = clk_enable_bulk(&eth->clks);
@@ -540,7 +610,7 @@ static int ravb_probe(struct udevice *dev)
err_mdio_reset:
clk_release_bulk(&eth->clks);
err_mdio_register:
- mdio_free(mdiodev);
+ bb_miiphy_free(bb_miiphy);
err_mdio_alloc:
unmap_physmem(eth->iobase, MAP_NOCACHE);
return ret;
@@ -560,83 +630,6 @@ static int ravb_remove(struct udevice *dev)
return 0;
}
-static int ravb_bb_init(struct bb_miiphy_bus *bus)
-{
- return 0;
-}
-
-static int ravb_bb_mdio_active(struct bb_miiphy_bus *bus)
-{
- struct ravb_priv *eth = bus->priv;
-
- setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MMD);
-
- return 0;
-}
-
-static int ravb_bb_mdio_tristate(struct bb_miiphy_bus *bus)
-{
- struct ravb_priv *eth = bus->priv;
-
- clrbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MMD);
-
- return 0;
-}
-
-static int ravb_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
-{
- struct ravb_priv *eth = bus->priv;
-
- if (v)
- setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDO);
- else
- clrbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDO);
-
- return 0;
-}
-
-static int ravb_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
-{
- struct ravb_priv *eth = bus->priv;
-
- *v = (readl(eth->iobase + RAVB_REG_PIR) & PIR_MDI) >> 3;
-
- return 0;
-}
-
-static int ravb_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
-{
- struct ravb_priv *eth = bus->priv;
-
- if (v)
- setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDC);
- else
- clrbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDC);
-
- return 0;
-}
-
-static int ravb_bb_delay(struct bb_miiphy_bus *bus)
-{
- udelay(10);
-
- return 0;
-}
-
-struct bb_miiphy_bus bb_miiphy_buses[] = {
- {
- .name = "ravb",
- .init = ravb_bb_init,
- .mdio_active = ravb_bb_mdio_active,
- .mdio_tristate = ravb_bb_mdio_tristate,
- .set_mdio = ravb_bb_set_mdio,
- .get_mdio = ravb_bb_get_mdio,
- .set_mdc = ravb_bb_set_mdc,
- .delay = ravb_bb_delay,
- },
-};
-int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
-
static const struct eth_ops ravb_ops = {
.start = ravb_start,
.send = ravb_send,
@@ -658,8 +651,6 @@ int ravb_of_to_plat(struct udevice *dev)
pdata->max_speed = dev_read_u32_default(dev, "max-speed", 1000);
- sprintf(bb_miiphy_buses[0].name, dev->name);
-
return 0;
}
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index f1ce994cfd5..83e48609224 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -643,11 +643,80 @@ static void sh_ether_stop(struct udevice *dev)
sh_eth_stop(&priv->shdev);
}
+/******* for bb_miiphy *******/
+static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
+{
+ struct sh_eth_dev *eth = bus->priv;
+ struct sh_eth_info *port_info = &eth->port_info[eth->port];
+
+ sh_eth_write(port_info, sh_eth_read(port_info, PIR) | PIR_MMD, PIR);
+
+ return 0;
+}
+
+static int sh_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
+{
+ struct sh_eth_dev *eth = bus->priv;
+ struct sh_eth_info *port_info = &eth->port_info[eth->port];
+
+ sh_eth_write(port_info, sh_eth_read(port_info, PIR) & ~PIR_MMD, PIR);
+
+ return 0;
+}
+
+static int sh_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
+{
+ struct sh_eth_dev *eth = bus->priv;
+ struct sh_eth_info *port_info = &eth->port_info[eth->port];
+
+ if (v)
+ sh_eth_write(port_info,
+ sh_eth_read(port_info, PIR) | PIR_MDO, PIR);
+ else
+ sh_eth_write(port_info,
+ sh_eth_read(port_info, PIR) & ~PIR_MDO, PIR);
+
+ return 0;
+}
+
+static int sh_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
+{
+ struct sh_eth_dev *eth = bus->priv;
+ struct sh_eth_info *port_info = &eth->port_info[eth->port];
+
+ *v = (sh_eth_read(port_info, PIR) & PIR_MDI) >> 3;
+
+ return 0;
+}
+
+static int sh_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
+{
+ struct sh_eth_dev *eth = bus->priv;
+ struct sh_eth_info *port_info = &eth->port_info[eth->port];
+
+ if (v)
+ sh_eth_write(port_info,
+ sh_eth_read(port_info, PIR) | PIR_MDC, PIR);
+ else
+ sh_eth_write(port_info,
+ sh_eth_read(port_info, PIR) & ~PIR_MDC, PIR);
+
+ return 0;
+}
+
+static int sh_eth_bb_delay(struct bb_miiphy_bus *bus)
+{
+ udelay(10);
+
+ return 0;
+}
+
static int sh_ether_probe(struct udevice *udev)
{
struct eth_pdata *pdata = dev_get_plat(udev);
struct sh_ether_priv *priv = dev_get_priv(udev);
struct sh_eth_dev *eth = &priv->shdev;
+ struct bb_miiphy_bus *bb_miiphy;
struct mii_dev *mdiodev;
int ret;
@@ -658,22 +727,32 @@ static int sh_ether_probe(struct udevice *udev)
if (ret < 0)
return ret;
#endif
- mdiodev = mdio_alloc();
- if (!mdiodev) {
+ bb_miiphy = bb_miiphy_alloc();
+ if (!bb_miiphy) {
ret = -ENOMEM;
return ret;
}
+ mdiodev = &bb_miiphy->mii;
+
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
- bb_miiphy_buses[0].priv = eth;
snprintf(mdiodev->name, sizeof(mdiodev->name), udev->name);
+ /* Copy the bus accessors and private data */
+ bb_miiphy->mdio_active = sh_eth_bb_mdio_active;
+ bb_miiphy->mdio_tristate = sh_eth_bb_mdio_tristate;
+ bb_miiphy->set_mdio = sh_eth_bb_set_mdio;
+ bb_miiphy->get_mdio = sh_eth_bb_get_mdio;
+ bb_miiphy->set_mdc = sh_eth_bb_set_mdc;
+ bb_miiphy->delay = sh_eth_bb_delay;
+ bb_miiphy->priv = eth;
+
ret = mdio_register(mdiodev);
if (ret < 0)
goto err_mdio_register;
- priv->bus = miiphy_get_dev_by_name(udev->name);
+ priv->bus = &bb_miiphy->mii;
eth->port = CFG_SH_ETHER_USE_PORT;
eth->port_info[eth->port].phy_addr = CFG_SH_ETHER_PHY_ADDR;
@@ -703,7 +782,7 @@ err_phy_config:
clk_disable(&priv->clk);
#endif
err_mdio_register:
- mdio_free(mdiodev);
+ bb_miiphy_free(bb_miiphy);
return ret;
}
@@ -748,8 +827,6 @@ int sh_ether_of_to_plat(struct udevice *dev)
if (cell)
pdata->max_speed = fdt32_to_cpu(*cell);
- sprintf(bb_miiphy_buses[0].name, dev->name);
-
return 0;
}
@@ -775,91 +852,3 @@ U_BOOT_DRIVER(eth_sh_ether) = {
.plat_auto = sizeof(struct eth_pdata),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
-
-/******* for bb_miiphy *******/
-static int sh_eth_bb_init(struct bb_miiphy_bus *bus)
-{
- return 0;
-}
-
-static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
-{
- struct sh_eth_dev *eth = bus->priv;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
- sh_eth_write(port_info, sh_eth_read(port_info, PIR) | PIR_MMD, PIR);
-
- return 0;
-}
-
-static int sh_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
-{
- struct sh_eth_dev *eth = bus->priv;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
- sh_eth_write(port_info, sh_eth_read(port_info, PIR) & ~PIR_MMD, PIR);
-
- return 0;
-}
-
-static int sh_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
-{
- struct sh_eth_dev *eth = bus->priv;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
- if (v)
- sh_eth_write(port_info,
- sh_eth_read(port_info, PIR) | PIR_MDO, PIR);
- else
- sh_eth_write(port_info,
- sh_eth_read(port_info, PIR) & ~PIR_MDO, PIR);
-
- return 0;
-}
-
-static int sh_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
-{
- struct sh_eth_dev *eth = bus->priv;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
- *v = (sh_eth_read(port_info, PIR) & PIR_MDI) >> 3;
-
- return 0;
-}
-
-static int sh_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
-{
- struct sh_eth_dev *eth = bus->priv;
- struct sh_eth_info *port_info = &eth->port_info[eth->port];
-
- if (v)
- sh_eth_write(port_info,
- sh_eth_read(port_info, PIR) | PIR_MDC, PIR);
- else
- sh_eth_write(port_info,
- sh_eth_read(port_info, PIR) & ~PIR_MDC, PIR);
-
- return 0;
-}
-
-static int sh_eth_bb_delay(struct bb_miiphy_bus *bus)
-{
- udelay(10);
-
- return 0;
-}
-
-struct bb_miiphy_bus bb_miiphy_buses[] = {
- {
- .name = "sh_eth",
- .init = sh_eth_bb_init,
- .mdio_active = sh_eth_bb_mdio_active,
- .mdio_tristate = sh_eth_bb_mdio_tristate,
- .set_mdio = sh_eth_bb_set_mdio,
- .get_mdio = sh_eth_bb_get_mdio,
- .set_mdc = sh_eth_bb_set_mdc,
- .delay = sh_eth_bb_delay,
- }
-};
-
-int bb_miiphy_buses_num = ARRAY_SIZE(bb_miiphy_buses);
diff --git a/include/miiphy.h b/include/miiphy.h
index 1e6c7041fdc..b879fd16ae3 100644
--- a/include/miiphy.h
+++ b/include/miiphy.h
@@ -44,6 +44,7 @@ struct phy_device *mdio_phydev_for_ethname(const char *devname);
void miiphy_listdev(void);
+void mdio_init(struct mii_dev *bus);
struct mii_dev *mdio_alloc(void);
void mdio_free(struct mii_dev *bus);
int mdio_register(struct mii_dev *bus);
@@ -64,8 +65,6 @@ void mdio_list_devices(void);
#define BB_MII_DEVNAME "bb_miiphy"
struct bb_miiphy_bus {
- char name[MDIO_NAME_LEN];
- int (*init)(struct bb_miiphy_bus *bus);
int (*mdio_active)(struct bb_miiphy_bus *bus);
int (*mdio_tristate)(struct bb_miiphy_bus *bus);
int (*set_mdio)(struct bb_miiphy_bus *bus, int v);
@@ -73,19 +72,11 @@ struct bb_miiphy_bus {
int (*set_mdc)(struct bb_miiphy_bus *bus, int v);
int (*delay)(struct bb_miiphy_bus *bus);
void *priv;
+ struct mii_dev mii;
};
-extern struct bb_miiphy_bus bb_miiphy_buses[];
-extern int bb_miiphy_buses_num;
-
-/**
- * bb_miiphy_init() - Initialize bit-banged MII bus driver
- *
- * It is called during the generic post-relocation init sequence.
- *
- * Return: 0 if OK
- */
-int bb_miiphy_init(void);
+struct bb_miiphy_bus *bb_miiphy_alloc(void);
+void bb_miiphy_free(struct bb_miiphy_bus *bus);
int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg);
int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg,