[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(&eth->mii_data);
+	val = (unsigned short)readl(&eth->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