From 92a190aaab3536d695c51e0739f925910eb49889 Mon Sep 17 00:00:00 2001 From: Alexey Brodkin Date: Wed, 22 Jan 2014 20:54:06 +0400 Subject: [PATCH] net/designware - switch driver to phylib usage With this change driver will benefit from existing phylib and thus custom phy functionality implemented in the driver will go away: * Instantiation of the driver is now much shorter - 2 parameters instead of 4. * Simplified phy management/functoinality in driver is replaced with rich functionality of phylib. * Support of custom phy initialization is now done with existing "board_phy_config". Note that after this change some previously used config options (driver-specific PHY configuration) will be obsolete and they are simply substituted with similar options of phylib. For example: * CONFIG_DW_AUTONEG - no need in this one. Autonegotiation is enabled by default. * CONFIG_DW_SEARCH_PHY - if one wants to specify attached phy explicitly CONFIG_PHY_ADDR board config option has to be used, otherwise automatically the first discovered on MDIO bus phy will be used I believe there's no need now in "doc/README.designware_eth" because user only needs to instantiate the driver with "designware_initialize" whose prototype exists in "include/netdev.h". Cc: Joe Hershberger Cc: Vipin Kumar Cc: Stefan Roese Cc: Mischa Jonker Cc: Shiraz Hashim Cc: Albert ARIBAUD Cc: Amit Virdi Cc: Sonic Zhang Signed-off-by: Alexey Brodkin --- board/bf609-ezkit/bf609-ezkit.c | 4 +- board/spear/spear300/spear300.c | 3 +- board/spear/spear310/spear310.c | 3 +- board/spear/spear320/spear320.c | 3 +- board/spear/spear600/spear600.c | 3 +- board/spear/x600/x600.c | 25 +-- doc/README.designware_eth | 25 --- drivers/net/designware.c | 460 +++++++++++++--------------------------- drivers/net/designware.h | 18 +- include/configs/bf609-ezkit.h | 3 +- include/configs/spear-common.h | 4 +- include/configs/spear6xx_evb.h | 3 + include/netdev.h | 2 +- 13 files changed, 177 insertions(+), 379 deletions(-) delete mode 100644 doc/README.designware_eth diff --git a/board/bf609-ezkit/bf609-ezkit.c b/board/bf609-ezkit/bf609-ezkit.c index cfc64fe..43a4330 100644 --- a/board/bf609-ezkit/bf609-ezkit.c +++ b/board/bf609-ezkit/bf609-ezkit.c @@ -41,12 +41,12 @@ int board_eth_init(bd_t *bis) if (CONFIG_DW_PORTS & 1) { static const unsigned short pins[] = P_RMII0; if (!peripheral_request_list(pins, "emac0")) - ret += designware_initialize(0, EMAC0_MACCFG, 1, 0); + ret += designware_initialize(EMAC0_MACCFG, 0); } if (CONFIG_DW_PORTS & 2) { static const unsigned short pins[] = P_RMII1; if (!peripheral_request_list(pins, "emac1")) - ret += designware_initialize(1, EMAC1_MACCFG, 1, 0); + ret += designware_initialize(EMAC1_MACCFG, 0); } return ret; diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c index e25aba2..6b6bd9f 100644 --- a/board/spear/spear300/spear300.c +++ b/board/spear/spear300/spear300.c @@ -53,8 +53,7 @@ int board_eth_init(bd_t *bis) #if defined(CONFIG_DESIGNWARE_ETH) u32 interface = PHY_INTERFACE_MODE_MII; - if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY, - interface) >= 0) + if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0) ret++; #endif return ret; diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c index 70f9aa1..a4c6a8e 100644 --- a/board/spear/spear310/spear310.c +++ b/board/spear/spear310/spear310.c @@ -54,8 +54,7 @@ int board_eth_init(bd_t *bis) #if defined(CONFIG_DESIGNWARE_ETH) u32 interface = PHY_INTERFACE_MODE_MII; - if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY, - interface) >= 0) + if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0) ret++; #endif #if defined(CONFIG_MACB) diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c index f6b1fdd..ab732a7 100644 --- a/board/spear/spear320/spear320.c +++ b/board/spear/spear320/spear320.c @@ -65,8 +65,7 @@ int board_eth_init(bd_t *bis) #if defined(CONFIG_DESIGNWARE_ETH) u32 interface = PHY_INTERFACE_MODE_MII; - if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY, - interface) >= 0) + if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0) ret++; #endif #if defined(CONFIG_MACB) diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c index e996a0e..8472002 100644 --- a/board/spear/spear600/spear600.c +++ b/board/spear/spear600/spear600.c @@ -51,8 +51,7 @@ int board_eth_init(bd_t *bis) #if defined(CONFIG_DW_AUTONEG) interface = PHY_INTERFACE_MODE_GMII; #endif - if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_DW0_PHY, - interface) >= 0) + if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0) ret++; #endif return ret; diff --git a/board/spear/x600/x600.c b/board/spear/x600/x600.c index 044d204..b8edfcd 100644 --- a/board/spear/x600/x600.c +++ b/board/spear/x600/x600.c @@ -67,31 +67,32 @@ void board_nand_init(void) fsmc_nand_init(nand); } -int designware_board_phy_init(struct eth_device *dev, int phy_addr, - int (*mii_write)(struct eth_device *, u8, u8, u16), - int dw_reset_phy(struct eth_device *)) +int board_phy_config(struct phy_device *phydev) { /* Extended PHY control 1, select GMII */ - mii_write(dev, phy_addr, 23, 0x0020); + phy_write(phydev, MDIO_DEVAD_NONE, 23, 0x0020); /* Software reset necessary after GMII mode selction */ - dw_reset_phy(dev); + phy_reset(phydev); /* Enable extended page register access */ - mii_write(dev, phy_addr, 31, 0x0001); + phy_write(phydev, MDIO_DEVAD_NONE, 31, 0x0001); /* 17e: Enhanced LED behavior, needs to be written twice */ - mii_write(dev, phy_addr, 17, 0x09ff); - mii_write(dev, phy_addr, 17, 0x09ff); + phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x09ff); + phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x09ff); /* 16e: Enhanced LED method select */ - mii_write(dev, phy_addr, 16, 0xe0ea); + phy_write(phydev, MDIO_DEVAD_NONE, 16, 0xe0ea); /* Disable extended page register access */ - mii_write(dev, phy_addr, 31, 0x0000); + phy_write(phydev, MDIO_DEVAD_NONE, 31, 0x0000); /* Enable clock output pin */ - mii_write(dev, phy_addr, 18, 0x0049); + phy_write(phydev, MDIO_DEVAD_NONE, 18, 0x0049); + + if (phydev->drv->config) + phydev->drv->config(phydev); return 0; } @@ -100,7 +101,7 @@ int board_eth_init(bd_t *bis) { int ret = 0; - if (designware_initialize(0, CONFIG_SPEAR_ETHBASE, CONFIG_PHY_ADDR, + if (designware_initialize(CONFIG_SPEAR_ETHBASE, PHY_INTERFACE_MODE_GMII) >= 0) ret++; diff --git a/doc/README.designware_eth b/doc/README.designware_eth deleted file mode 100644 index 25ec6bd..0000000 --- a/doc/README.designware_eth +++ /dev/null @@ -1,25 +0,0 @@ -This driver supports Designware Ethernet Controller provided by Synopsis. - -The driver is enabled by CONFIG_DESIGNWARE_ETH. - -The driver has been developed and tested on SPEAr platforms. By default, the -MDIO interface works at 100/Full. #defining the below options in board -configuration file changes this behavior. - -Call an subroutine from respective board/.../board.c -designware_initialize(u32 id, ulong base_addr, u32 phy_addr); - -The various options suported by the driver are -1. CONFIG_DW_ALTDESCRIPTOR - Define this to use the Alternate/Enhanced Descriptor configurations. -1. CONFIG_DW_AUTONEG - Define this to autonegotiate with the host before proceeding with mac - level configuration. This obviates the definitions of CONFIG_DW_SPEED10M - and CONFIG_DW_DUPLEXHALF. -2. CONFIG_DW_SPEED10M - Define this to change the default behavior from 100Mbps to 10Mbps. -3. CONFIG_DW_DUPLEXHALF - Define this to change the default behavior from Full Duplex to Half. -4. CONFIG_DW_SEARCH_PHY - Define this to search the phy address. This would overwrite the value - passed as 3rd arg from designware_initialize routine. diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 1868089..44c1e35 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -17,7 +17,75 @@ #include #include "designware.h" -static int configure_phy(struct eth_device *dev); +#if !defined(CONFIG_PHYLIB) +# error "DesignWare Ether MAC requires PHYLIB - missing CONFIG_PHYLIB" +#endif + +static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) +{ + struct eth_mac_regs *mac_p = bus->priv; + ulong start; + u16 miiaddr; + int timeout = CONFIG_MDIO_TIMEOUT; + + miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | + ((reg << MIIREGSHIFT) & MII_REGMSK); + + writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr); + + start = get_timer(0); + while (get_timer(start) < timeout) { + if (!(readl(&mac_p->miiaddr) & MII_BUSY)) + return readl(&mac_p->miidata); + udelay(10); + }; + + return -1; +} + +static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, + u16 val) +{ + struct eth_mac_regs *mac_p = bus->priv; + ulong start; + u16 miiaddr; + int ret = -1, timeout = CONFIG_MDIO_TIMEOUT; + + writel(val, &mac_p->miidata); + miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | + ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE; + + writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr); + + start = get_timer(0); + while (get_timer(start) < timeout) { + if (!(readl(&mac_p->miiaddr) & MII_BUSY)) { + ret = 0; + break; + } + udelay(10); + }; + + return ret; +} + +static int dw_mdio_init(char *name, struct eth_mac_regs *mac_regs_p) +{ + struct mii_dev *bus = mdio_alloc(); + + if (!bus) { + printf("Failed to allocate MDIO bus\n"); + return -1; + } + + bus->read = dw_mdio_read; + bus->write = dw_mdio_write; + sprintf(bus->name, name); + + bus->priv = (void *)mac_regs_p; + + return mdio_register(bus); +} static void tx_descs_init(struct eth_device *dev) { @@ -83,53 +151,59 @@ static void rx_descs_init(struct eth_device *dev) priv->rx_currdescnum = 0; } -static void descs_init(struct eth_device *dev) +static int dw_write_hwaddr(struct eth_device *dev) { - tx_descs_init(dev); - rx_descs_init(dev); + struct dw_eth_dev *priv = dev->priv; + struct eth_mac_regs *mac_p = priv->mac_regs_p; + u32 macid_lo, macid_hi; + u8 *mac_id = &dev->enetaddr[0]; + + macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) + + (mac_id[3] << 24); + macid_hi = mac_id[4] + (mac_id[5] << 8); + + writel(macid_hi, &mac_p->macaddr0hi); + writel(macid_lo, &mac_p->macaddr0lo); + + return 0; } -static int mac_reset(struct eth_device *dev) +static void dw_adjust_link(struct eth_mac_regs *mac_p, + struct phy_device *phydev) { - struct dw_eth_dev *priv = dev->priv; - struct eth_mac_regs *mac_p = priv->mac_regs_p; - struct eth_dma_regs *dma_p = priv->dma_regs_p; + u32 conf = readl(&mac_p->conf) | FRAMEBURSTENABLE | DISABLERXOWN; - ulong start; - int timeout = CONFIG_MACRESET_TIMEOUT; + if (!phydev->link) { + printf("%s: No link.\n", phydev->dev->name); + return; + } - writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode); + if (phydev->speed != 1000) + conf |= MII_PORTSELECT; - if (priv->interface != PHY_INTERFACE_MODE_RGMII) - writel(MII_PORTSELECT, &mac_p->conf); + if (phydev->speed == 100) + conf |= FES_100; - start = get_timer(0); - while (get_timer(start) < timeout) { - if (!(readl(&dma_p->busmode) & DMAMAC_SRST)) - return 0; + if (phydev->duplex) + conf |= FULLDPLXMODE; - /* Try again after 10usec */ - udelay(10); - }; + writel(conf, &mac_p->conf); - return -1; + printf("Speed: %d, %s duplex%s\n", phydev->speed, + (phydev->duplex) ? "full" : "half", + (phydev->port == PORT_FIBRE) ? ", fiber mode" : ""); } -static int dw_write_hwaddr(struct eth_device *dev) +static void dw_eth_halt(struct eth_device *dev) { struct dw_eth_dev *priv = dev->priv; struct eth_mac_regs *mac_p = priv->mac_regs_p; - u32 macid_lo, macid_hi; - u8 *mac_id = &dev->enetaddr[0]; + struct eth_dma_regs *dma_p = priv->dma_regs_p; - macid_lo = mac_id[0] + (mac_id[1] << 8) + \ - (mac_id[2] << 16) + (mac_id[3] << 24); - macid_hi = mac_id[4] + (mac_id[5] << 8); + writel(readl(&mac_p->conf) & ~(RXENABLE | TXENABLE), &mac_p->conf); + writel(readl(&dma_p->opmode) & ~(RXSTART | TXSTART), &dma_p->opmode); - writel(macid_hi, &mac_p->macaddr0hi); - writel(macid_lo, &mac_p->macaddr0lo); - - return 0; + phy_shutdown(priv->phydev); } static int dw_eth_init(struct eth_device *dev, bd_t *bis) @@ -137,55 +211,43 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis) struct dw_eth_dev *priv = dev->priv; struct eth_mac_regs *mac_p = priv->mac_regs_p; struct eth_dma_regs *dma_p = priv->dma_regs_p; - u32 conf; + unsigned int start; - if (priv->phy_configured != 1) - configure_phy(dev); + writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode); - /* Print link status only once */ - if (!priv->link_printed) { - printf("ENET Speed is %d Mbps - %s duplex connection\n", - priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL"); - priv->link_printed = 1; - } + start = get_timer(0); + while (readl(&dma_p->busmode) & DMAMAC_SRST) { + if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) + return -1; - /* Reset ethernet hardware */ - if (mac_reset(dev) < 0) - return -1; + mdelay(100); + }; - /* Resore the HW MAC address as it has been lost during MAC reset */ + /* Soft reset above clears HW address registers. + * So we have to set it here once again */ dw_write_hwaddr(dev); - writel(FIXEDBURST | PRIORXTX_41 | BURST_16, - &dma_p->busmode); - - writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD | - TXSECONDFRAME, &dma_p->opmode); + rx_descs_init(dev); + tx_descs_init(dev); - conf = FRAMEBURSTENABLE | DISABLERXOWN; + writel(FIXEDBURST | PRIORXTX_41 | BURST_16, &dma_p->busmode); - if (priv->speed != 1000) - conf |= MII_PORTSELECT; + writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD, + &dma_p->opmode); - if ((priv->interface != PHY_INTERFACE_MODE_MII) && - (priv->interface != PHY_INTERFACE_MODE_GMII)) { + writel(readl(&dma_p->opmode) | RXSTART | TXSTART, &dma_p->opmode); - if (priv->speed == 100) - conf |= FES_100; + /* Start up the PHY */ + if (phy_startup(priv->phydev)) { + printf("Could not initialize PHY %s\n", + priv->phydev->dev->name); + return -1; } - if (priv->duplex == FULL) - conf |= FULLDPLXMODE; - - writel(conf, &mac_p->conf); + dw_adjust_link(mac_p, priv->phydev); - descs_init(dev); - - /* - * Start/Enable xfer at dma as well as mac level - */ - writel(readl(&dma_p->opmode) | RXSTART, &dma_p->opmode); - writel(readl(&dma_p->opmode) | TXSTART, &dma_p->opmode); + if (!priv->phydev->link) + return -1; writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf); @@ -267,251 +329,30 @@ static int dw_eth_recv(struct eth_device *dev) return length; } -static void dw_eth_halt(struct eth_device *dev) -{ - struct dw_eth_dev *priv = dev->priv; - - mac_reset(dev); - priv->tx_currdescnum = priv->rx_currdescnum = 0; -} - -static int eth_mdio_read(struct eth_device *dev, u8 addr, u8 reg, u16 *val) +static int dw_phy_init(struct eth_device *dev) { struct dw_eth_dev *priv = dev->priv; - struct eth_mac_regs *mac_p = priv->mac_regs_p; - ulong start; - u32 miiaddr; - int timeout = CONFIG_MDIO_TIMEOUT; - - miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \ - ((reg << MIIREGSHIFT) & MII_REGMSK); - - writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr); - - start = get_timer(0); - while (get_timer(start) < timeout) { - if (!(readl(&mac_p->miiaddr) & MII_BUSY)) { - *val = readl(&mac_p->miidata); - return 0; - } + struct phy_device *phydev; + int mask = 0xffffffff; - /* Try again after 10usec */ - udelay(10); - }; - - return -1; -} - -static int eth_mdio_write(struct eth_device *dev, u8 addr, u8 reg, u16 val) -{ - struct dw_eth_dev *priv = dev->priv; - struct eth_mac_regs *mac_p = priv->mac_regs_p; - ulong start; - u32 miiaddr; - int ret = -1, timeout = CONFIG_MDIO_TIMEOUT; - u16 value; - - writel(val, &mac_p->miidata); - miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) | \ - ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE; - - writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr); - - start = get_timer(0); - while (get_timer(start) < timeout) { - if (!(readl(&mac_p->miiaddr) & MII_BUSY)) { - ret = 0; - break; - } - - /* Try again after 10usec */ - udelay(10); - }; - - /* Needed as a fix for ST-Phy */ - eth_mdio_read(dev, addr, reg, &value); - - return ret; -} - -#if defined(CONFIG_DW_SEARCH_PHY) -static int find_phy(struct eth_device *dev) -{ - int phy_addr = 0; - u16 ctrl, oldctrl; - - do { - eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl); - oldctrl = ctrl & BMCR_ANENABLE; - - ctrl ^= BMCR_ANENABLE; - eth_mdio_write(dev, phy_addr, MII_BMCR, ctrl); - eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl); - ctrl &= BMCR_ANENABLE; - - if (ctrl == oldctrl) { - phy_addr++; - } else { - ctrl ^= BMCR_ANENABLE; - eth_mdio_write(dev, phy_addr, MII_BMCR, ctrl); - - return phy_addr; - } - } while (phy_addr < 32); - - return -1; -} +#ifdef CONFIG_PHY_ADDR + mask = 1 << CONFIG_PHY_ADDR; #endif -static int dw_reset_phy(struct eth_device *dev) -{ - struct dw_eth_dev *priv = dev->priv; - u16 ctrl; - ulong start; - int timeout = CONFIG_PHYRESET_TIMEOUT; - u32 phy_addr = priv->address; - - eth_mdio_write(dev, phy_addr, MII_BMCR, BMCR_RESET); - - start = get_timer(0); - while (get_timer(start) < timeout) { - eth_mdio_read(dev, phy_addr, MII_BMCR, &ctrl); - if (!(ctrl & BMCR_RESET)) - break; - - /* Try again after 10usec */ - udelay(10); - }; - - if (get_timer(start) >= CONFIG_PHYRESET_TIMEOUT) + phydev = phy_find_by_mask(priv->bus, mask, priv->interface); + if (!phydev) return -1; -#ifdef CONFIG_PHY_RESET_DELAY - udelay(CONFIG_PHY_RESET_DELAY); -#endif - return 0; -} + phydev->supported &= PHY_GBIT_FEATURES; + phydev->advertising = phydev->supported; -/* - * Add weak default function for board specific PHY configuration - */ -int __weak designware_board_phy_init(struct eth_device *dev, int phy_addr, - int (*mii_write)(struct eth_device *, u8, u8, u16), - int dw_reset_phy(struct eth_device *)) -{ - return 0; -} + priv->phydev = phydev; + phy_config(phydev); -static int configure_phy(struct eth_device *dev) -{ - struct dw_eth_dev *priv = dev->priv; - int phy_addr; - u16 bmcr; -#if defined(CONFIG_DW_AUTONEG) - u16 bmsr; - u32 timeout; - ulong start; -#endif - -#if defined(CONFIG_DW_SEARCH_PHY) - phy_addr = find_phy(dev); - if (phy_addr >= 0) - priv->address = phy_addr; - else - return -1; -#else - phy_addr = priv->address; -#endif - - /* - * Some boards need board specific PHY initialization. This is - * after the main driver init code but before the auto negotiation - * is run. - */ - if (designware_board_phy_init(dev, phy_addr, - eth_mdio_write, dw_reset_phy) < 0) - return -1; - - if (dw_reset_phy(dev) < 0) - return -1; - -#if defined(CONFIG_DW_AUTONEG) - /* Set Auto-Neg Advertisement capabilities to 10/100 half/full */ - eth_mdio_write(dev, phy_addr, MII_ADVERTISE, 0x1E1); - - bmcr = BMCR_ANENABLE | BMCR_ANRESTART; -#else - bmcr = BMCR_SPEED100 | BMCR_FULLDPLX; - -#if defined(CONFIG_DW_SPEED10M) - bmcr &= ~BMCR_SPEED100; -#endif -#if defined(CONFIG_DW_DUPLEXHALF) - bmcr &= ~BMCR_FULLDPLX; -#endif -#endif - if (eth_mdio_write(dev, phy_addr, MII_BMCR, bmcr) < 0) - return -1; - - /* Read the phy status register and populate priv structure */ -#if defined(CONFIG_DW_AUTONEG) - timeout = CONFIG_AUTONEG_TIMEOUT; - start = get_timer(0); - puts("Waiting for PHY auto negotiation to complete"); - while (get_timer(start) < timeout) { - eth_mdio_read(dev, phy_addr, MII_BMSR, &bmsr); - if (bmsr & BMSR_ANEGCOMPLETE) { - priv->phy_configured = 1; - break; - } - - /* Print dot all 1s to show progress */ - if ((get_timer(start) % 1000) == 0) - putc('.'); - - /* Try again after 1msec */ - udelay(1000); - }; - - if (!(bmsr & BMSR_ANEGCOMPLETE)) - puts(" TIMEOUT!\n"); - else - puts(" done\n"); -#else - priv->phy_configured = 1; -#endif - - priv->speed = miiphy_speed(dev->name, phy_addr); - priv->duplex = miiphy_duplex(dev->name, phy_addr); - - return 0; -} - -#if defined(CONFIG_MII) -static int dw_mii_read(const char *devname, u8 addr, u8 reg, u16 *val) -{ - struct eth_device *dev; - - dev = eth_get_dev_by_name(devname); - if (dev) - eth_mdio_read(dev, addr, reg, val); - - return 0; -} - -static int dw_mii_write(const char *devname, u8 addr, u8 reg, u16 val) -{ - struct eth_device *dev; - - dev = eth_get_dev_by_name(devname); - if (dev) - eth_mdio_write(dev, addr, reg, val); - - return 0; + return 1; } -#endif -int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface) +int designware_initialize(ulong base_addr, u32 interface) { struct eth_device *dev; struct dw_eth_dev *priv; @@ -533,19 +374,14 @@ int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface) memset(dev, 0, sizeof(struct eth_device)); memset(priv, 0, sizeof(struct dw_eth_dev)); - sprintf(dev->name, "mii%d", id); + sprintf(dev->name, "dwmac.%lx", base_addr); dev->iobase = (int)base_addr; dev->priv = priv; - eth_getenv_enetaddr_by_index("eth", id, &dev->enetaddr[0]); - priv->dev = dev; priv->mac_regs_p = (struct eth_mac_regs *)base_addr; priv->dma_regs_p = (struct eth_dma_regs *)(base_addr + DW_DMA_BASE_OFFSET); - priv->address = phy_addr; - priv->phy_configured = 0; - priv->interface = interface; dev->init = dw_eth_init; dev->send = dw_eth_send; @@ -555,8 +391,10 @@ int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface) eth_register(dev); -#if defined(CONFIG_MII) - miiphy_register(dev->name, dw_mii_read, dw_mii_write); -#endif - return 1; + priv->interface = interface; + + dw_mdio_init(dev->name, priv->mac_regs_p); + priv->bus = miiphy_get_dev_by_name(dev->name); + + return dw_phy_init(dev); } diff --git a/drivers/net/designware.h b/drivers/net/designware.h index 5440c92..afeacce 100644 --- a/drivers/net/designware.h +++ b/drivers/net/designware.h @@ -16,8 +16,6 @@ #define CONFIG_MACRESET_TIMEOUT (3 * CONFIG_SYS_HZ) #define CONFIG_MDIO_TIMEOUT (3 * CONFIG_SYS_HZ) -#define CONFIG_PHYRESET_TIMEOUT (3 * CONFIG_SYS_HZ) -#define CONFIG_AUTONEG_TIMEOUT (5 * CONFIG_SYS_HZ) struct eth_mac_regs { u32 conf; /* 0x00 */ @@ -217,14 +215,9 @@ struct dmamacdescr { #endif struct dw_eth_dev { - u32 address; u32 interface; - u32 speed; - u32 duplex; u32 tx_currdescnum; u32 rx_currdescnum; - u32 phy_configured; - u32 link_printed; struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM]; struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM]; @@ -236,15 +229,8 @@ struct dw_eth_dev { struct eth_dma_regs *dma_regs_p; struct eth_device *dev; + struct phy_device *phydev; + struct mii_dev *bus; }; -/* Speed specific definitions */ -#define SPEED_10M 1 -#define SPEED_100M 2 -#define SPEED_1000M 3 - -/* Duplex mode specific definitions */ -#define HALF_DUPLEX 1 -#define FULL_DUPLEX 2 - #endif diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h index 1a43e1b..12192ff 100644 --- a/include/configs/bf609-ezkit.h +++ b/include/configs/bf609-ezkit.h @@ -72,12 +72,13 @@ #define CONFIG_NET_MULTI #define CONFIG_HOSTNAME "bf609-ezkit" #define CONFIG_DESIGNWARE_ETH +#define CONFIG_PHY_ADDR 1 #define CONFIG_DW_PORTS 1 -#define CONFIG_DW_AUTONEG #define CONFIG_DW_ALTDESCRIPTOR #define CONFIG_CMD_NET #define CONFIG_CMD_MII #define CONFIG_MII +#define CONFIG_PHYLIB /* i2c Settings */ #define CONFIG_BFIN_TWI_I2C diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h index 23f7ad7..e090a37 100644 --- a/include/configs/spear-common.h +++ b/include/configs/spear-common.h @@ -17,11 +17,9 @@ /* Ethernet driver configuration */ #define CONFIG_MII #define CONFIG_DESIGNWARE_ETH -#define CONFIG_DW_SEARCH_PHY -#define CONFIG_DW0_PHY 1 #define CONFIG_NET_MULTI +#define CONFIG_PHYLIB #define CONFIG_PHY_RESET_DELAY 10000 /* in usec */ -#define CONFIG_DW_AUTONEG #define CONFIG_PHY_GIGE /* Include GbE speed/duplex detection */ /* USBD driver configuration */ diff --git a/include/configs/spear6xx_evb.h b/include/configs/spear6xx_evb.h index 7f4dc58..28dddcc 100644 --- a/include/configs/spear6xx_evb.h +++ b/include/configs/spear6xx_evb.h @@ -37,6 +37,9 @@ #define CONFIG_SYS_FSMC_NAND_8BIT #define CONFIG_SYS_NAND_BASE 0xD2000000 +/* Ethernet PHY configuration */ +#define CONFIG_PHY_NATSEMI + /* Environment Settings */ #define CONFIG_EXTRA_ENV_SETTINGS CONFIG_EXTRA_ENV_USBTTY diff --git a/include/netdev.h b/include/netdev.h index 47fa80d..3705629 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -36,7 +36,7 @@ int calxedaxgmac_initialize(u32 id, ulong base_addr); int cs8900_initialize(u8 dev_num, int base_addr); int davinci_emac_initialize(void); int dc21x4x_initialize(bd_t *bis); -int designware_initialize(u32 id, ulong base_addr, u32 phy_addr, u32 interface); +int designware_initialize(ulong base_addr, u32 interface); int dm9000_initialize(bd_t *bis); int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr); int e1000_initialize(bd_t *bis);