From b4ce62d3d23a2a910aefe803afc564c8b77ca205 Mon Sep 17 00:00:00 2001 From: Franck Jullien Date: Wed, 14 May 2014 18:59:29 +0200 Subject: drivers/net/ethoc: add mdio bus support Signed-off-by: Franck Jullien Signed-off-by: Sascha Hauer --- drivers/net/Kconfig | 1 + drivers/net/ethoc.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 057abd2bca..7a0d5e107b 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -80,6 +80,7 @@ config DRIVER_NET_EP93XX config DRIVER_NET_ETHOC bool "OpenCores ethernet MAC driver" + select PHYLIB help This option enables support for the OpenCores 10/100 Mbps Ethernet MAC core. diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c index ced84df7a0..679e1e552a 100644 --- a/drivers/net/ethoc.c +++ b/drivers/net/ethoc.c @@ -178,6 +178,8 @@ struct ethoc { u32 num_rx; u32 cur_rx; + + struct mii_bus miibus; }; /** @@ -481,6 +483,54 @@ static int ethoc_send_packet(struct eth_device *edev, void *packet, int length) return 0; } +static int ethoc_mdio_read(struct mii_bus *bus, int phy, int reg) +{ + struct ethoc *priv = bus->priv; + u64 start; + u32 data; + + ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg)); + ethoc_write(priv, MIICOMMAND, MIICOMMAND_READ); + + start = get_time_ns(); + while (ethoc_read(priv, MIISTATUS) & MIISTATUS_BUSY) { + if (is_timeout(start, 2 * MSECOND)) { + dev_err(bus->parent, "PHY command timeout\n"); + return -EBUSY; + } + } + + data = ethoc_read(priv, MIIRX_DATA); + + /* reset MII command register */ + ethoc_write(priv, MIICOMMAND, 0); + + return data; +} + +static int ethoc_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) +{ + struct ethoc *priv = bus->priv; + u64 start; + + ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(phy, reg)); + ethoc_write(priv, MIITX_DATA, val); + ethoc_write(priv, MIICOMMAND, MIICOMMAND_WRITE); + + start = get_time_ns(); + while (ethoc_read(priv, MIISTATUS) & MIISTATUS_BUSY) { + if (is_timeout(start, 2 * MSECOND)) { + dev_err(bus->parent, "PHY command timeout\n"); + return -EBUSY; + } + } + + /* reset MII command register */ + ethoc_write(priv, MIICOMMAND, 0); + + return 0; +} + static int ethoc_probe(struct device_d *dev) { struct eth_device *edev; @@ -493,6 +543,11 @@ static int ethoc_probe(struct device_d *dev) priv = edev->priv; priv->iobase = dev_request_mem_region(dev, 0); + priv->miibus.read = ethoc_mdio_read; + priv->miibus.write = ethoc_mdio_write; + priv->miibus.priv = priv; + priv->miibus.parent = dev; + edev->init = ethoc_init_dev; edev->open = ethoc_open; edev->send = ethoc_send_packet; @@ -503,6 +558,8 @@ static int ethoc_probe(struct device_d *dev) edev->set_ethaddr = ethoc_set_ethaddr; edev->parent = dev; + mdiobus_register(&priv->miibus); + eth_register(edev); return 0; -- cgit v1.2.3