[U-Boot] [PATCH v3 2/5] net: fec_mxc: add PHYLIB support
Troy Kisky
troy.kisky at boundarydevices.com
Thu Feb 2 02:14:44 CET 2012
Also, surround non PHYLIB routines miiphy_restart_aneg
and miiphy_wait_aneg with ifndef CONFIG_PHYLIB.
Make fec_miiphy_read, and fec_miiphy_write call a routine
common with PHYLIB version so that when later PHYLIB is required
it is easy to delete the non-PHYLIB code. This separation idea
came from Andy Fleming.
Signed-off-by: Troy Kisky <troy.kisky at boundarydevices.com>
Acked-by: Dirk Behme <dirk.behme at de.bosch.com>
---
drivers/net/fec_mxc.c | 122 +++++++++++++++++++++++++++++++++++++++++-------
drivers/net/fec_mxc.h | 5 ++
2 files changed, 109 insertions(+), 18 deletions(-)
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 7c42b87..e935426 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -88,16 +88,13 @@ static inline struct ethernet_regs *fec_miiphy_fec_to_eth(struct fec_priv *fec)
/*
* MII-interface related functions
*/
-static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr,
- uint16_t *retVal)
+static int fec_mdio_read(struct ethernet_regs *eth, uint8_t phyAddr,
+ uint8_t regAddr)
{
- struct eth_device *edev = eth_get_dev_by_name(dev);
- struct fec_priv *fec = (struct fec_priv *)edev->priv;
- struct ethernet_regs *eth = fec_miiphy_fec_to_eth(fec);
-
uint32_t reg; /* convenient holder for the PHY register */
uint32_t phy; /* convenient holder for the PHY */
uint32_t start;
+ int val;
/*
* reading from any PHY's register is done by properly
@@ -129,10 +126,10 @@ static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr,
/*
* it's now safe to read the PHY's register
*/
- *retVal = readl(ð->mii_data);
+ val = (unsigned short)readl(ð->mii_data);
debug("fec_miiphy_read: phy: %02x reg:%02x val:%#x\n", phyAddr,
- regAddr, *retVal);
- return 0;
+ regAddr, val);
+ return val;
}
static void fec_mii_setspeed(struct fec_priv *fec)
@@ -146,13 +143,10 @@ static void fec_mii_setspeed(struct fec_priv *fec)
debug("fec_init: mii_speed %08x\n",
readl(&fec->eth->mii_speed));
}
-static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr,
- uint16_t data)
-{
- struct eth_device *edev = eth_get_dev_by_name(dev);
- struct fec_priv *fec = (struct fec_priv *)edev->priv;
- struct ethernet_regs *eth = fec_miiphy_fec_to_eth(fec);
+static int fec_mdio_write(struct ethernet_regs *eth, uint8_t phyAddr,
+ uint8_t regAddr, uint16_t data)
+{
uint32_t reg; /* convenient holder for the PHY register */
uint32_t phy; /* convenient holder for the PHY */
uint32_t start;
@@ -184,6 +178,43 @@ static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr,
return 0;
}
+#ifdef CONFIG_PHYLIB
+int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr)
+{
+ return fec_mdio_read(bus->priv, phyAddr, regAddr);
+}
+
+int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr,
+ u16 data)
+{
+ return fec_mdio_write(bus->priv, phyAddr, regAddr, data);
+}
+#else
+
+static int fec_miiphy_read(const char *dev, uint8_t phyAddr, uint8_t regAddr,
+ uint16_t *retVal)
+{
+ struct eth_device *edev = eth_get_dev_by_name(dev);
+ struct fec_priv *fec = (struct fec_priv *)edev->priv;
+ struct ethernet_regs *eth = fec_miiphy_fec_to_eth(fec);
+ int val = fec_mdio_read(eth, phyAddr, regAddr);
+ if (val < 0)
+ return val;
+ *retVal = (uint16_t)val;
+ return 0;
+}
+
+static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr,
+ uint16_t data)
+{
+ struct eth_device *edev = eth_get_dev_by_name(dev);
+ struct fec_priv *fec = (struct fec_priv *)edev->priv;
+ struct ethernet_regs *eth = fec_miiphy_fec_to_eth(fec);
+ return fec_mdio_write(eth, phyAddr, regAddr, data);
+}
+#endif
+
+#ifndef CONFIG_PHYLIB
static int miiphy_restart_aneg(struct eth_device *dev)
{
struct fec_priv *fec = (struct fec_priv *)dev->priv;
@@ -241,6 +272,8 @@ static int miiphy_wait_aneg(struct eth_device *dev)
return 0;
}
+#endif
+
static int fec_rx_task_enable(struct fec_priv *fec)
{
writel(1 << 24, &fec->eth->r_des_active);
@@ -372,6 +405,21 @@ static int fec_set_hwaddr(struct eth_device *dev)
return 0;
}
+static void fec_eth_phy_config(struct eth_device *dev)
+{
+#ifdef CONFIG_PHYLIB
+ struct fec_priv *fec = (struct fec_priv *)dev->priv;
+ struct phy_device *phydev;
+
+ phydev = phy_connect(fec->bus, fec->phy_id, dev,
+ PHY_INTERFACE_MODE_RGMII);
+ if (phydev) {
+ fec->phydev = phydev;
+ phy_config(phydev);
+ }
+#endif
+}
+
/**
* Start the FEC engine
* @param[in] dev Our device to handle
@@ -428,9 +476,21 @@ static int fec_open(struct eth_device *edev)
}
#endif
+#ifdef CONFIG_PHYLIB
+ if (!fec->phydev)
+ fec_eth_phy_config(edev);
+ if (fec->phydev) {
+ /* Start up the PHY */
+ phy_startup(fec->phydev);
+ speed = fec->phydev->speed;
+ } else {
+ speed = _100BASET;
+ }
+#else
miiphy_wait_aneg(edev);
speed = miiphy_speed(edev->name, fec->phy_id);
miiphy_duplex(edev->name, fec->phy_id);
+#endif
#ifdef CONFIG_FEC_QUIRK_ENET_MAC
{
@@ -558,9 +618,10 @@ static int fec_init(struct eth_device *dev, bd_t* bd)
fec_tbd_init(fec);
+#ifndef CONFIG_PHYLIB
if (fec->xcv_type != SEVENWIRE)
miiphy_restart_aneg(dev);
-
+#endif
fec_open(dev);
return 0;
}
@@ -836,15 +897,38 @@ static int fec_probe(bd_t *bd, int dev_id, int phy_id, uint32_t base_addr)
}
fec->phy_id = phy_id;
+#ifdef CONFIG_PHYLIB
+ {
+ struct mii_dev *bus = mdio_alloc();
+ if (!bus) {
+ printf("mdio_alloc failed\n");
+ ret = -ENOMEM;
+ goto err3;
+ }
+ bus->read = fec_phy_read;
+ bus->write = fec_phy_write;
+ sprintf(bus->name, edev->name);
+ bus->priv = fec->eth;
+ ret = mdio_register(bus);
+ if (ret) {
+ printf("mdio_register failed\n");
+ free(bus);
+ ret = -ENOMEM;
+ goto err3;
+ }
+ fec->bus = bus;
+ }
+#else
miiphy_register(edev->name, fec_miiphy_read, fec_miiphy_write);
-
+#endif
eth_register(edev);
if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
memcpy(edev->enetaddr, ethaddr, 6);
}
-
+ /* Configure phy */
+ fec_eth_phy_config(edev);
return ret;
err3:
@@ -877,9 +961,11 @@ int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
return lout;
}
+#ifndef CONFIG_PHYLIB
int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int))
{
struct fec_priv *fec = (struct fec_priv *)dev->priv;
fec->mii_postcall = cb;
return 0;
}
+#endif
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h
index af33d21..5fd99b7 100644
--- a/drivers/net/fec_mxc.h
+++ b/drivers/net/fec_mxc.h
@@ -286,7 +286,12 @@ struct fec_priv {
void *base_ptr;
int dev_id;
int phy_id;
+#ifdef CONFIG_PHYLIB
+ struct mii_dev *bus;
+ struct phy_device *phydev;
+#else
int (*mii_postcall)(int);
+#endif
};
/**
--
1.7.5.4
More information about the U-Boot
mailing list