Patchwork [U-Boot,V3,8/9] net: fec_mxc: get phydev before fec_probe

login
register
mail settings
Submitter Troy Kisky
Date Oct. 23, 2012, 2:40 a.m.
Message ID <1350960047-23404-9-git-send-email-troy.kisky@boundarydevices.com>
Download mbox | patch
Permalink /patch/193321/
State Awaiting Upstream
Delegated to: Stefano Babic
Headers show

Comments

Troy Kisky - Oct. 23, 2012, 2:40 a.m.
Signed-off-by: Troy Kisky <troy.kisky@boundarydevices.com>
---
 drivers/net/fec_mxc.c |  117 +++++++++++++++++++++++++++++++------------------
 drivers/net/fec_mxc.h |    2 +-
 include/netdev.h      |    7 +++
 3 files changed, 83 insertions(+), 43 deletions(-)

Patch

diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index 913c561..4dbcdca 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -901,12 +901,16 @@  static void fec_set_dev_name(char *dest, int dev_id)
 	sprintf(dest, (dev_id == -1) ? "FEC" : "FEC%i", dev_id);
 }
 
-static int fec_probe(bd_t *bd, int dev_id, int phy_id, uint32_t base_addr)
+#ifdef CONFIG_PHYLIB
+int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
+		struct mii_dev *bus, struct phy_device *phydev)
+#else
+static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
+		struct mii_dev *bus, int phy_id)
+#endif
 {
-	struct phy_device *phydev;
 	struct eth_device *edev;
 	struct fec_priv *fec;
-	struct mii_dev *bus;
 	unsigned char ethaddr[6];
 	uint32_t start;
 	int ret = 0;
@@ -953,69 +957,98 @@  static int fec_probe(bd_t *bd, int dev_id, int phy_id, uint32_t base_addr)
 	}
 
 	fec_reg_setup(fec);
-
 	fec_set_dev_name(edev->name, dev_id);
 	fec->dev_id = (dev_id == -1) ? 0 : dev_id;
+	fec->bus = bus;
+	fec_mii_setspeed(bus->priv);
+#ifdef CONFIG_PHYLIB
+	fec->phydev = phydev;
+	phy_connect_dev(phydev, edev);
+	/* Configure phy */
+	phy_config(phydev);
+#else
 	fec->phy_id = phy_id;
+#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);
+	}
+	return ret;
+err3:
+	free(fec);
+err2:
+	free(edev);
+err1:
+	return ret;
+}
+
+struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id)
+{
+	struct ethernet_regs *eth = (struct ethernet_regs *)base_addr;
+	struct mii_dev *bus;
+	int ret;
 
 	bus = mdio_alloc();
 	if (!bus) {
 		printf("mdio_alloc failed\n");
-		ret = -ENOMEM;
-		goto err3;
+		return NULL;
 	}
 	bus->read = fec_phy_read;
 	bus->write = fec_phy_write;
+	bus->priv = eth;
 	fec_set_dev_name(bus->name, dev_id);
+
+	ret = mdio_register(bus);
+	if (ret) {
+		printf("mdio_register failed\n");
+		free(bus);
+		return NULL;
+	}
+	fec_mii_setspeed(eth);
+	return bus;
+}
+
+int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
+{
+	uint32_t base_mii;
+	struct mii_dev *bus = NULL;
+#ifdef CONFIG_PHYLIB
+	struct phy_device *phydev = NULL;
+#endif
+	int ret;
+
 #ifdef CONFIG_MX28
 	/*
 	 * The i.MX28 has two ethernet interfaces, but they are not equal.
 	 * Only the first one can access the MDIO bus.
 	 */
-	bus->priv = (struct ethernet_regs *)MXS_ENET0_BASE;
+	base_mii = MXS_ENET0_BASE;
 #else
-	bus->priv = fec->eth;
+	base_mii = addr;
 #endif
-	fec_mii_setspeed(bus->priv);
-	ret = mdio_register(bus);
-	if (ret) {
-		printf("mdio_register failed\n");
-		free(bus);
-		ret = -ENOMEM;
-		goto err3;
-	}
-	fec->bus = bus;
-	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 */
+	debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr);
+	bus = fec_get_miibus(base_mii, dev_id);
+	if (!bus)
+		return -ENOMEM;
 #ifdef CONFIG_PHYLIB
-	phydev = phy_connect(fec->bus, phy_id, edev, PHY_INTERFACE_MODE_RGMII);
+	phydev = phy_find_by_mask(bus, 1 << phy_id, PHY_INTERFACE_MODE_RGMII);
 	if (!phydev) {
 		free(bus);
-		ret = -ENOMEM;
-		goto err3;
+		return -ENOMEM;
 	}
-	fec->phydev = phydev;
-	phy_config(phydev);
+	ret = fec_probe(bd, dev_id, addr, bus, phydev);
+#else
+	ret = fec_probe(bd, dev_id, addr, bus, phy_id);
 #endif
+	if (ret) {
+#ifdef CONFIG_PHYLIB
+		free(phydev);
+#endif
+		free(bus);
+	}
 	return ret;
-
-err3:
-	free(fec);
-err2:
-	free(edev);
-err1:
-	return ret;
-}
-
-int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
-{
-	debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr);
-	return fec_probe(bd, dev_id, phy_id, addr);
 }
 
 #ifdef CONFIG_FEC_MXC_PHYADDR
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h
index 203285a..b8f0da3 100644
--- a/drivers/net/fec_mxc.h
+++ b/drivers/net/fec_mxc.h
@@ -271,11 +271,11 @@  struct fec_priv {
 	bd_t *bd;
 	uint8_t *tdb_ptr;
 	int dev_id;
-	int phy_id;
 	struct mii_dev *bus;
 #ifdef CONFIG_PHYLIB
 	struct phy_device *phydev;
 #else
+	int phy_id;
 	int (*mii_postcall)(int);
 #endif
 };
diff --git a/include/netdev.h b/include/netdev.h
index b8d303d..62aef79 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -204,9 +204,16 @@  struct mv88e61xx_config {
 int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig);
 #endif /* CONFIG_MV88E61XX_SWITCH */
 
+struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id);
+#ifdef CONFIG_PHYLIB
+struct phy_device;
+int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
+		struct mii_dev *bus, struct phy_device *phydev);
+#else
 /*
  * Allow FEC to fine-tune MII configuration on boards which require this.
  */
 int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int));
+#endif
 
 #endif /* _NETDEV_H_ */