From 8848f975ce42674b8bc8dedb5c7b326a42088e99 Mon Sep 17 00:00:00 2001
From: Calvin Johnson <calvin.johnson@nxp.com>
Date: Mon, 10 Dec 2018 10:22:33 +0530
Subject: [PATCH] staging: fsl_ppfe/eth: separate mdio init from mac init

- separate mdio initialization from mac initialization
- Define pfe_mdio_priv_s structure to hold mii_bus structure and other
  related data.
- Modify functions to work with the separted mdio init model.

Signed-off-by: Calvin Johnson <calvin.johnson@nxp.com>
---
 drivers/staging/fsl_ppfe/pfe_eth.c              | 232 ++++++++++--------------
 drivers/staging/fsl_ppfe/pfe_eth.h              |  17 +-
 drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c |  50 ++---
 drivers/staging/fsl_ppfe/pfe_mod.h              |   1 +
 4 files changed, 126 insertions(+), 174 deletions(-)

--- a/drivers/staging/fsl_ppfe/pfe_eth.c
+++ b/drivers/staging/fsl_ppfe/pfe_eth.c
@@ -790,10 +790,9 @@ const struct ethtool_ops pfe_ethtool_ops
  */
 int pfe_eth_mdio_reset(struct mii_bus *bus)
 {
-	struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
+	struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
 	u32 phy_speed;
 
-	netif_info(priv, hw, priv->ndev, "%s\n", __func__);
 
 	mutex_lock(&bus->mdio_lock);
 
@@ -806,25 +805,25 @@ int pfe_eth_mdio_reset(struct mii_bus *b
 	phy_speed = (DIV_ROUND_UP((pfe->ctrl.sys_clk * 1000), 4000000)
 		     << EMAC_MII_SPEED_SHIFT);
 	phy_speed |= EMAC_HOLDTIME(0x5);
-	__raw_writel(phy_speed, priv->PHY_baseaddr + EMAC_MII_CTRL_REG);
+	__raw_writel(phy_speed, priv->mdio_base + EMAC_MII_CTRL_REG);
 
 	mutex_unlock(&bus->mdio_lock);
 
 	return 0;
 }
 
-/* pfe_eth_gemac_phy_timeout
+/* pfe_eth_mdio_timeout
  *
  */
-static int pfe_eth_gemac_phy_timeout(struct pfe_eth_priv_s *priv, int timeout)
+static int pfe_eth_mdio_timeout(struct pfe_mdio_priv_s *priv, int timeout)
 {
-	while (!(__raw_readl(priv->PHY_baseaddr + EMAC_IEVENT_REG) &
+	while (!(__raw_readl(priv->mdio_base + EMAC_IEVENT_REG) &
 			EMAC_IEVENT_MII)) {
 		if (timeout-- <= 0)
 			return -1;
 		usleep_range(10, 20);
 	}
-	__raw_writel(EMAC_IEVENT_MII, priv->PHY_baseaddr + EMAC_IEVENT_REG);
+	__raw_writel(EMAC_IEVENT_MII, priv->mdio_base + EMAC_IEVENT_REG);
 	return 0;
 }
 
@@ -856,16 +855,15 @@ static int pfe_eth_mdio_mux(u8 muxval)
 static int pfe_eth_mdio_write_addr(struct mii_bus *bus, int mii_id,
 				   int dev_addr, int regnum)
 {
-	struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
+	struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
 
 	__raw_writel(EMAC_MII_DATA_PA(mii_id) |
 		     EMAC_MII_DATA_RA(dev_addr) |
 		     EMAC_MII_DATA_TA | EMAC_MII_DATA(regnum),
-		     priv->PHY_baseaddr + EMAC_MII_DATA_REG);
+		     priv->mdio_base + EMAC_MII_DATA_REG);
 
-	if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-		netdev_err(priv->ndev, "%s: phy MDIO address write timeout\n",
-			   __func__);
+	if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
+		dev_err(&bus->dev, "phy MDIO address write timeout\n");
 		return -1;
 	}
 
@@ -875,7 +873,7 @@ static int pfe_eth_mdio_write_addr(struc
 static int pfe_eth_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
 			      u16 value)
 {
-	struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
+	struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
 
 	/*To access external PHYs on QDS board mux needs to be configured*/
 	if ((mii_id) && (pfe->mdio_muxval[mii_id]))
@@ -888,30 +886,26 @@ static int pfe_eth_mdio_write(struct mii
 			     EMAC_MII_DATA_PA(mii_id) |
 			     EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
 			     EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
-			     priv->PHY_baseaddr + EMAC_MII_DATA_REG);
+			     priv->mdio_base + EMAC_MII_DATA_REG);
 	} else {
 		/* start a write op */
 		__raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_WR |
 			     EMAC_MII_DATA_PA(mii_id) |
 			     EMAC_MII_DATA_RA(regnum) |
 			     EMAC_MII_DATA_TA | EMAC_MII_DATA(value),
-			     priv->PHY_baseaddr + EMAC_MII_DATA_REG);
+			     priv->mdio_base + EMAC_MII_DATA_REG);
 	}
 
-	if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-		netdev_err(priv->ndev, "%s: phy MDIO write timeout\n",
-			   __func__);
+	if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
+		dev_err(&bus->dev, "%s: phy MDIO write timeout\n", __func__);
 		return -1;
 	}
-	netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__,
-		   mii_id, regnum, value);
-
 	return 0;
 }
 
 static int pfe_eth_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
 {
-	struct pfe_eth_priv_s *priv = (struct pfe_eth_priv_s *)bus->priv;
+	struct pfe_mdio_priv_s *priv = (struct pfe_mdio_priv_s *)bus->priv;
 	u16 value = 0;
 
 	/*To access external PHYs on QDS board mux needs to be configured*/
@@ -925,65 +919,67 @@ static int pfe_eth_mdio_read(struct mii_
 			     EMAC_MII_DATA_PA(mii_id) |
 			     EMAC_MII_DATA_RA((regnum >> 16) & 0x1f) |
 			     EMAC_MII_DATA_TA,
-			     priv->PHY_baseaddr + EMAC_MII_DATA_REG);
+			     priv->mdio_base + EMAC_MII_DATA_REG);
 	} else {
 		/* start a read op */
 		__raw_writel(EMAC_MII_DATA_ST | EMAC_MII_DATA_OP_RD |
 			     EMAC_MII_DATA_PA(mii_id) |
 			     EMAC_MII_DATA_RA(regnum) |
-			     EMAC_MII_DATA_TA, priv->PHY_baseaddr +
+			     EMAC_MII_DATA_TA, priv->mdio_base +
 			     EMAC_MII_DATA_REG);
 	}
 
-	if (pfe_eth_gemac_phy_timeout(priv, EMAC_MDIO_TIMEOUT)) {
-		netdev_err(priv->ndev, "%s: phy MDIO read timeout\n", __func__);
+	if (pfe_eth_mdio_timeout(priv, EMAC_MDIO_TIMEOUT)) {
+		dev_err(&bus->dev, "%s: phy MDIO read timeout\n", __func__);
 		return -1;
 	}
 
-	value = EMAC_MII_DATA(__raw_readl(priv->PHY_baseaddr +
+	value = EMAC_MII_DATA(__raw_readl(priv->mdio_base +
 						EMAC_MII_DATA_REG));
-	netif_info(priv, hw, priv->ndev, "%s: phy %x reg %x val %x\n", __func__,
-		   mii_id, regnum, value);
 	return value;
 }
 
-static int pfe_eth_mdio_init(struct pfe_eth_priv_s *priv,
-			     struct ls1012a_mdio_platform_data *minfo)
+static int pfe_eth_mdio_init(struct pfe *pfe,
+			     struct ls1012a_pfe_platform_data *pfe_info,
+			     int ii)
 {
+	struct pfe_mdio_priv_s *priv = NULL;
+	struct ls1012a_mdio_platform_data *mdio_info;
 	struct mii_bus *bus;
 	struct device_node *mdio_node;
-	int rc = 0, ii;
-	struct phy_device *phydev;
+	int rc = 0;
 
-	netif_info(priv, drv, priv->ndev, "%s\n", __func__);
-	pr_info("%s\n", __func__);
+	mdio_info = (struct ls1012a_mdio_platform_data *)
+					pfe_info->ls1012a_mdio_pdata;
+	mdio_info->id = ii;
 
-	bus = mdiobus_alloc();
+	bus = mdiobus_alloc_size(sizeof(struct pfe_mdio_priv_s));
 	if (!bus) {
-		netdev_err(priv->ndev, "mdiobus_alloc() failed\n");
+		pr_err("mdiobus_alloc() failed\n");
 		rc = -ENOMEM;
-		goto err0;
+		goto err_mdioalloc;
 	}
 
 	bus->name = "ls1012a MDIO Bus";
-	snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", priv->id);
+	snprintf(bus->id, MII_BUS_ID_SIZE, "ls1012a-%x", mdio_info->id);
 
-	bus->priv = priv;
 	bus->read = &pfe_eth_mdio_read;
 	bus->write = &pfe_eth_mdio_write;
 	bus->reset = &pfe_eth_mdio_reset;
-	bus->parent = priv->pfe->dev;
-	bus->phy_mask = minfo->phy_mask;
-	bus->irq[0] = minfo->irq[0];
+	bus->parent = pfe->dev;
+	bus->phy_mask = mdio_info->phy_mask;
+	bus->irq[0] = mdio_info->irq[0];
+	priv = bus->priv;
+	priv->mdio_base = cbus_emac_base[ii];
 
-	priv->mdc_div = minfo->mdc_div;
+	priv->mdc_div = mdio_info->mdc_div;
 	if (!priv->mdc_div)
 		priv->mdc_div = 64;
-	netif_info(priv, drv, priv->ndev, "%s: mdc_div: %d, phy_mask: %x\n",
-		   __func__, priv->mdc_div, bus->phy_mask);
+		dev_info(bus->parent, "%s: mdc_div: %d, phy_mask: %x\n",
+			 __func__, priv->mdc_div, bus->phy_mask);
 
-	mdio_node = of_get_child_by_name(priv->pfe->dev->of_node, "mdio");
-	if (mdio_node) {
+	mdio_node = of_get_child_by_name(pfe->dev->of_node, "mdio");
+	if ((mdio_info->id == 0) && mdio_node) {
 		rc = of_mdiobus_register(bus, mdio_node);
 		of_node_put(mdio_node);
 	} else {
@@ -991,56 +987,34 @@ static int pfe_eth_mdio_init(struct pfe_
 	}
 
 	if (rc) {
-		netdev_err(priv->ndev, "mdiobus_register(%s) failed\n",
-			   bus->name);
-		goto err1;
+		dev_err(bus->parent, "mdiobus_register(%s) failed\n",
+			bus->name);
+		goto err_mdioregister;
 	}
 
 	priv->mii_bus = bus;
-
-	/* For clause 45 we need to call get_phy_device() with it's
-	 * 3rd argument as true and then register the phy device
-	 * via phy_device_register()
-	 */
-	if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII) {
-		for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
-			phydev = get_phy_device(priv->mii_bus,
-					priv->einfo->phy_id + ii, true);
-			if (!phydev || IS_ERR(phydev)) {
-				rc = -EIO;
-				netdev_err(priv->ndev, "fail to get device\n");
-				goto err1;
-			}
-			rc = phy_device_register(phydev);
-			if (rc) {
-				phy_device_free(phydev);
-				netdev_err(priv->ndev,
-					"phy_device_register() failed\n");
-				goto err1;
-			}
-		}
-	}
+	pfe->mdio.mdio_priv[ii] = priv;
 
 	pfe_eth_mdio_reset(bus);
 
 	return 0;
 
-err1:
+err_mdioregister:
 	mdiobus_free(bus);
-err0:
+err_mdioalloc:
 	return rc;
 }
 
 /* pfe_eth_mdio_exit
  */
-static void pfe_eth_mdio_exit(struct mii_bus *bus)
+static void pfe_eth_mdio_exit(struct pfe *pfe,
+			      int ii)
 {
+	struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[ii];
+	struct mii_bus *bus = mdio_priv->mii_bus;
+
 	if (!bus)
 		return;
-
-	netif_info((struct pfe_eth_priv_s *)bus->priv, drv, ((struct
-			pfe_eth_priv_s *)(bus->priv))->ndev, "%s\n", __func__);
-
 	mdiobus_unregister(bus);
 	mdiobus_free(bus);
 }
@@ -1221,15 +1195,16 @@ static int pfe_eth_start(struct pfe_eth_
  */
 static void ls1012a_configure_serdes(struct net_device *ndev)
 {
-	struct pfe_eth_priv_s *priv = pfe->eth.eth_priv[0];
+	struct pfe_eth_priv_s *eth_priv = netdev_priv(ndev);
+	struct pfe_mdio_priv_s *mdio_priv = pfe->mdio.mdio_priv[eth_priv->id];
 	int sgmii_2500 = 0;
-	struct mii_bus *bus = priv->mii_bus;
+	struct mii_bus *bus = mdio_priv->mii_bus;
 	u16 value = 0;
 
-	if (priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
+	if (eth_priv->einfo->mii_config == PHY_INTERFACE_MODE_2500SGMII)
 		sgmii_2500 = 1;
 
-	netif_info(priv, drv, ndev, "%s\n", __func__);
+	netif_info(eth_priv, drv, ndev, "%s\n", __func__);
 	/* PCS configuration done with corresponding GEMAC */
 
 	pfe_eth_mdio_read(bus, 0, MDIO_SGMII_CR);
@@ -2333,26 +2308,15 @@ static const struct net_device_ops pfe_n
 
 /* pfe_eth_init_one
  */
-static int pfe_eth_init_one(struct pfe *pfe, int id)
+static int pfe_eth_init_one(struct pfe *pfe,
+			    struct ls1012a_pfe_platform_data *pfe_info,
+			    int id)
 {
 	struct net_device *ndev = NULL;
 	struct pfe_eth_priv_s *priv = NULL;
 	struct ls1012a_eth_platform_data *einfo;
-	struct ls1012a_mdio_platform_data *minfo;
-	struct ls1012a_pfe_platform_data *pfe_info;
 	int err;
 
-	/* Extract pltform data */
-	pfe_info = (struct ls1012a_pfe_platform_data *)
-					pfe->dev->platform_data;
-	if (!pfe_info) {
-		pr_err(
-			"%s: pfe missing additional platform data\n"
-			, __func__);
-		err = -ENODEV;
-		goto err0;
-	}
-
 	einfo = (struct ls1012a_eth_platform_data *)
 				pfe_info->ls1012a_eth_pdata;
 
@@ -2365,18 +2329,6 @@ static int pfe_eth_init_one(struct pfe *
 		goto err0;
 	}
 
-	minfo = (struct ls1012a_mdio_platform_data *)
-				pfe_info->ls1012a_mdio_pdata;
-
-	/* einfo never be NULL, but no harm in having this check */
-	if (!minfo) {
-		pr_err(
-			"%s: pfe missing additional mdios platform data\n",
-			 __func__);
-		err = -ENODEV;
-		goto err0;
-	}
-
 	if (us)
 		emac_txq_cnt = EMAC_TXQ_CNT;
 	/* Create an ethernet device instance */
@@ -2402,7 +2354,6 @@ static int pfe_eth_init_one(struct pfe *
 	/* Set the info in the priv to the current info */
 	priv->einfo = &einfo[id];
 	priv->EMAC_baseaddr = cbus_emac_base[id];
-	priv->PHY_baseaddr = cbus_emac_base[0];
 	priv->GPI_baseaddr = cbus_gpi_base[id];
 
 	spin_lock_init(&priv->lock);
@@ -2412,13 +2363,6 @@ static int pfe_eth_init_one(struct pfe *
 	/* Copy the station address into the dev structure, */
 	memcpy(ndev->dev_addr, einfo[id].mac_addr, ETH_ALEN);
 
-	/* Initialize mdio */
-	err = pfe_eth_mdio_init(priv, &minfo[id]);
-	if (err) {
-		netdev_err(ndev, "%s: pfe_eth_mdio_init() failed\n", __func__);
-		goto err1;
-	}
-
 	if (us)
 		goto phy_init;
 
@@ -2463,7 +2407,7 @@ static int pfe_eth_init_one(struct pfe *
 	err = register_netdev(ndev);
 	if (err) {
 		netdev_err(ndev, "register_netdev() failed\n");
-		goto err2;
+		goto err1;
 	}
 
 	if ((!(pfe_use_old_dts_phy) && !(priv->phy_node)) ||
@@ -2480,7 +2424,7 @@ phy_init:
 	if (err) {
 		netdev_err(ndev, "%s: pfe_phy_init() failed\n",
 			   __func__);
-		goto err3;
+		goto err2;
 	}
 
 	if (us) {
@@ -2494,21 +2438,19 @@ phy_init:
 skip_phy_init:
 	/* Create all the sysfs files */
 	if (pfe_eth_sysfs_init(ndev))
-		goto err4;
+		goto err3;
 
 	netif_info(priv, probe, ndev, "%s: created interface, baseaddr: %p\n",
 		   __func__, priv->EMAC_baseaddr);
 
 	return 0;
 
-err4:
-	pfe_phy_exit(priv->ndev);
 err3:
+	pfe_phy_exit(priv->ndev);
+err2:
 	if (us)
-		goto err2;
+		goto err1;
 	unregister_netdev(ndev);
-err2:
-	pfe_eth_mdio_exit(priv->mii_bus);
 err1:
 	free_netdev(priv->ndev);
 err0:
@@ -2521,6 +2463,7 @@ int pfe_eth_init(struct pfe *pfe)
 {
 	int ii = 0;
 	int err;
+	struct ls1012a_pfe_platform_data *pfe_info;
 
 	pr_info("%s\n", __func__);
 
@@ -2530,24 +2473,43 @@ int pfe_eth_init(struct pfe *pfe)
 	cbus_gpi_base[0] = EGPI1_BASE_ADDR;
 	cbus_gpi_base[1] = EGPI2_BASE_ADDR;
 
+	pfe_info = (struct ls1012a_pfe_platform_data *)
+					pfe->dev->platform_data;
+	if (!pfe_info) {
+		pr_err("%s: pfe missing additional platform data\n", __func__);
+		err = -ENODEV;
+		goto err_pdata;
+	}
+
+	for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
+		err = pfe_eth_mdio_init(pfe, pfe_info, ii);
+		if (err) {
+			pr_err("%s: pfe_eth_mdio_init() failed\n", __func__);
+			goto err_mdio_init;
+		}
+	}
+
 	if (fsl_guts_get_svr() == LS1012A_REV_1_0)
 		pfe_errata_a010897 = true;
 	else
 		pfe_errata_a010897 = false;
 
 	for (ii = 0; ii < NUM_GEMAC_SUPPORT; ii++) {
-		err = pfe_eth_init_one(pfe, ii);
+		err = pfe_eth_init_one(pfe, pfe_info, ii);
 		if (err)
-			goto err0;
+			goto err_eth_init;
 	}
 
 	return 0;
 
-err0:
-	while (ii--)
+err_eth_init:
+	while (ii--) {
 		pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
+		pfe_eth_mdio_exit(pfe, ii);
+	}
 
-	/* Register three network devices in the kernel */
+err_mdio_init:
+err_pdata:
 	return err;
 }
 
@@ -2573,9 +2535,6 @@ skip_phy_exit:
 	if (!us)
 		unregister_netdev(priv->ndev);
 
-	if (priv->mii_bus)
-		pfe_eth_mdio_exit(priv->mii_bus);
-
 	free_netdev(priv->ndev);
 }
 
@@ -2589,4 +2548,7 @@ void pfe_eth_exit(struct pfe *pfe)
 
 	for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
 		pfe_eth_exit_one(pfe->eth.eth_priv[ii]);
+
+	for (ii = NUM_GEMAC_SUPPORT - 1; ii >= 0; ii--)
+		pfe_eth_mdio_exit(pfe, ii);
 }
--- a/drivers/staging/fsl_ppfe/pfe_eth.h
+++ b/drivers/staging/fsl_ppfe/pfe_eth.h
@@ -48,7 +48,7 @@ struct ls1012a_eth_platform_data {
 };
 
 struct ls1012a_mdio_platform_data {
-	int enabled;
+	int id;
 	int irq[32];
 	u32 phy_mask;
 	int mdc_div;
@@ -120,8 +120,6 @@ struct  pfe_eth_priv_s {
 	unsigned int		event_status;
 	int			irq;
 	void			*EMAC_baseaddr;
-	/* This points to the EMAC base from where we access PHY */
-	void			*PHY_baseaddr;
 	void			*GPI_baseaddr;
 	/* PHY stuff */
 	struct phy_device	*phydev;
@@ -129,9 +127,6 @@ struct  pfe_eth_priv_s {
 	int			oldduplex;
 	int			oldlink;
 	struct device_node	*phy_node;
-	/* mdio info */
-	int			mdc_div;
-	struct mii_bus		*mii_bus;
 	struct clk		*gemtx_clk;
 	int			wol;
 	int			pause_flag;
@@ -161,6 +156,16 @@ struct pfe_eth {
 	struct pfe_eth_priv_s *eth_priv[3];
 };
 
+struct pfe_mdio_priv_s {
+	void __iomem *mdio_base;
+	int			mdc_div;
+	struct mii_bus		*mii_bus;
+};
+
+struct pfe_mdio {
+	struct pfe_mdio_priv_s *mdio_priv[3];
+};
+
 int pfe_eth_init(struct pfe *pfe);
 void pfe_eth_exit(struct pfe *pfe);
 int pfe_eth_suspend(struct net_device *dev);
--- a/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
+++ b/drivers/staging/fsl_ppfe/pfe_ls1012a_platform.c
@@ -21,31 +21,18 @@
 extern bool pfe_use_old_dts_phy;
 struct ls1012a_pfe_platform_data pfe_platform_data;
 
-static int pfe_get_gemac_if_properties(struct device_node *parent, int port, int
-					if_cnt,
-					struct ls1012a_pfe_platform_data
-					*pdata)
+static int pfe_get_gemac_if_properties(struct device_node *gem,
+				       int port,
+				       struct ls1012a_pfe_platform_data	*pdata)
 {
-	struct device_node *gem = NULL, *phy = NULL, *phy_node = NULL;
+	struct device_node *phy_node = NULL;
 	int size;
-	int ii = 0, phy_id = 0;
+	int phy_id = 0;
 	const u32 *addr;
 	const void *mac_addr;
 
-	for (ii = 0; ii < if_cnt; ii++) {
-		gem = of_get_next_child(parent, gem);
-		if (!gem)
-			goto err;
-		addr = of_get_property(gem, "reg", &size);
-		if (addr && (be32_to_cpup(addr) == port))
-			break;
-	}
-
-	if (ii >= if_cnt) {
-		pr_err("%s:%d Failed to find interface = %d\n",
-		       __func__, __LINE__, if_cnt);
-		goto err;
-	}
+	addr = of_get_property(gem, "reg", &size);
+	port = be32_to_cpup(addr);
 
 	pdata->ls1012a_eth_pdata[port].gem_id = port;
 
@@ -88,14 +75,6 @@ static int pfe_get_gemac_if_properties(s
 		if (pdata->ls1012a_eth_pdata[port].phy_flags & GEMAC_NO_PHY)
 			goto done;
 
-		phy = of_get_next_child(gem, NULL);
-		addr = of_get_property(phy, "reg", &size);
-		if (!addr)
-			pr_err("%s:%d Invalid phy enable flag....\n",
-			       __func__, __LINE__);
-		else
-			pdata->ls1012a_mdio_pdata[port].enabled =
-							be32_to_cpup(addr);
 	} else {
 		pr_info("%s: No PHY or fixed-link\n", __func__);
 		return 0;
@@ -140,7 +119,7 @@ static int pfe_platform_probe(struct pla
 	struct resource res;
 	int ii, rc, interface_count = 0, size = 0;
 	const u32 *prop;
-	struct device_node  *np;
+	struct device_node *np, *gem = NULL;
 	struct clk *pfe_clk;
 
 	np = pdev->dev.of_node;
@@ -224,8 +203,13 @@ static int pfe_platform_probe(struct pla
 	pfe_platform_data.ls1012a_mdio_pdata[0].phy_mask = 0xffffffff;
 
 	for (ii = 0; ii < interface_count; ii++) {
-		pfe_get_gemac_if_properties(np, ii, interface_count,
-					    &pfe_platform_data);
+		gem = of_get_next_child(np, gem);
+		if (gem)
+			pfe_get_gemac_if_properties(gem, ii,
+						    &pfe_platform_data);
+		else
+			pr_err("Unable to find interface %d\n", ii);
+
 	}
 
 	pfe->dev = &pdev->dev;
@@ -347,8 +331,8 @@ static int pfe_platform_resume(struct de
 	for (i = 0; i < (NUM_GEMAC_SUPPORT); i++) {
 		netdev = pfe->eth.eth_priv[i]->ndev;
 
-		if (pfe->eth.eth_priv[i]->mii_bus)
-			pfe_eth_mdio_reset(pfe->eth.eth_priv[i]->mii_bus);
+		if (pfe->mdio.mdio_priv[i]->mii_bus)
+			pfe_eth_mdio_reset(pfe->mdio.mdio_priv[i]->mii_bus);
 
 		if (netif_running(netdev))
 			pfe_eth_resume(netdev);
--- a/drivers/staging/fsl_ppfe/pfe_mod.h
+++ b/drivers/staging/fsl_ppfe/pfe_mod.h
@@ -52,6 +52,7 @@ struct pfe {
 	struct pfe_ctrl ctrl;
 	struct pfe_hif hif;
 	struct pfe_eth eth;
+	struct pfe_mdio mdio;
 	struct hif_client_s *hif_client[HIF_CLIENTS_MAX];
 #if defined(CFG_DIAGS)
 	struct pfe_diags diags;
