diff options
Diffstat (limited to 'drivers/net/fec_imx.c')
-rw-r--r-- | drivers/net/fec_imx.c | 89 |
1 files changed, 52 insertions, 37 deletions
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c index 599a9b4099..453185a9f6 100644 --- a/drivers/net/fec_imx.c +++ b/drivers/net/fec_imx.c @@ -23,11 +23,11 @@ #include <net.h> #include <init.h> #include <driver.h> -#include <miidev.h> #include <fec.h> #include <io.h> #include <clock.h> #include <xfuncs.h> +#include <linux/phy.h> #include <asm/mmu.h> @@ -50,10 +50,9 @@ struct fec_frame { /* * MII-interface related functions */ -static int fec_miidev_read(struct mii_device *mdev, int phyAddr, int regAddr) +static int fec_miibus_read(struct mii_bus *bus, int phyAddr, int regAddr) { - struct eth_device *edev = mdev->edev; - struct fec_priv *fec = (struct fec_priv *)edev->priv; + struct fec_priv *fec = (struct fec_priv *)bus->priv; uint32_t reg; /* convenient holder for the PHY register */ uint32_t phy; /* convenient holder for the PHY */ @@ -93,11 +92,10 @@ static int fec_miidev_read(struct mii_device *mdev, int phyAddr, int regAddr) return readl(fec->regs + FEC_MII_DATA); } -static int fec_miidev_write(struct mii_device *mdev, int phyAddr, - int regAddr, int data) +static int fec_miibus_write(struct mii_bus *bus, int phyAddr, + int regAddr, u16 data) { - struct eth_device *edev = mdev->edev; - struct fec_priv *fec = (struct fec_priv *)edev->priv; + struct fec_priv *fec = (struct fec_priv *)bus->priv; uint32_t reg; /* convenient holder for the PHY register */ uint32_t phy; /* convenient holder for the PHY */ @@ -347,12 +345,20 @@ static int fec_init(struct eth_device *dev) /* size of each buffer */ writel(FEC_MAX_PKT_SIZE, fec->regs + FEC_EMRBR); - if (fec->xcv_type != SEVENWIRE) - miidev_restart_aneg(&fec->miidev); - return 0; } +static void fec_update_linkspeed(struct eth_device *edev) +{ + struct fec_priv *fec = (struct fec_priv *)edev->priv; + + if (edev->phydev->speed == SPEED_10) { + u32 rcntl = readl(fec->regs + FEC_R_CNTRL); + rcntl |= FEC_R_CNTRL_RMII_10T; + writel(rcntl, fec->regs + FEC_R_CNTRL); + } +} + /** * Start the FEC engine * @param[in] edev Our device to handle @@ -363,6 +369,17 @@ static int fec_open(struct eth_device *edev) int ret; u32 ecr; + if (fec->xcv_type != SEVENWIRE) { + ret = phy_device_connect(edev, &fec->miibus, fec->phy_addr, + fec_update_linkspeed, fec->phy_flags, + fec->interface); + if (ret) + return ret; + + if (fec->phy_init) + fec->phy_init(edev->phydev); + } + /* * Initialize RxBD/TxBD rings */ @@ -388,24 +405,6 @@ static int fec_open(struct eth_device *edev) */ fec_rx_task_enable(fec); - if (fec->xcv_type != SEVENWIRE) { - ret = miidev_wait_aneg(&fec->miidev); - if (ret) - return ret; - - ret = miidev_get_status(&fec->miidev); - if (ret < 0) - return ret; - - if (ret & MIIDEV_STATUS_IS_10MBIT) { - u32 rcntl = readl(fec->regs + FEC_R_CNTRL); - rcntl |= FEC_R_CNTRL_RMII_10T; - writel(rcntl, fec->regs + FEC_R_CNTRL); - } - - miidev_print_status(&fec->miidev); - } - return 0; } @@ -659,14 +658,30 @@ static int fec_probe(struct device_d *dev) fec->xcv_type = pdata->xcv_type; if (fec->xcv_type != SEVENWIRE) { - fec->miidev.read = fec_miidev_read; - fec->miidev.write = fec_miidev_write; - fec->miidev.address = pdata->phy_addr; - fec->miidev.flags = pdata->xcv_type == MII10 ? MIIDEV_FORCE_10 : 0; - fec->miidev.edev = edev; - fec->miidev.parent = dev; - - mii_register(&fec->miidev); + fec->phy_init = pdata->phy_init; + fec->miibus.read = fec_miibus_read; + fec->miibus.write = fec_miibus_write; + fec->phy_addr = pdata->phy_addr; + switch (pdata->xcv_type) { + case RMII: + fec->interface = PHY_INTERFACE_MODE_RMII; + break; + case RGMII: + fec->interface = PHY_INTERFACE_MODE_RGMII; + break; + case MII10: + fec->phy_flags = PHYLIB_FORCE_10; + case MII100: + fec->interface = PHY_INTERFACE_MODE_MII; + break; + case SEVENWIRE: + fec->interface = PHY_INTERFACE_MODE_NA; + break; + } + fec->miibus.priv = fec; + fec->miibus.parent = dev; + + mdiobus_register(&fec->miibus); } eth_register(edev); |