summaryrefslogtreecommitdiffstats
path: root/drivers/net/fec_imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/fec_imx.c')
-rw-r--r--drivers/net/fec_imx.c89
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);