[U-Boot] [PATCH v2 4/6] driver: net: fsl-mc: Modify the dpmac link detection method

Pankaj Bansal pankaj.bansal at nxp.com
Mon Jul 30 13:15:03 UTC 2018


when there is no phy present for a dpmac, a dummy phy device is created.
when we move to multiple phy method, we need to create as many dummy phy
devices.

Change this method so that we don't need to create dummy phy devices.
We always report linkup if no phy is present.

Signed-off-by: Pankaj Bansal <pankaj.bansal at nxp.com>
---

Notes:
    V2:
    - Change (phydev->link == 1) to (phydev->link)
    - Use min macro instead of ternary operator
    - return -ENOLINK instead of -1 from ldpaa_get_dpmac_state
    - Change (state->up == 0) to (!state->up)

 drivers/net/ldpaa_eth/ldpaa_eth.c | 119 +++++++++++++---------------
 1 file changed, 57 insertions(+), 62 deletions(-)

diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
index 4231fb6119..d2bec31dd7 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.c
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
@@ -385,6 +385,59 @@ error:
 	return err;
 }
 
+static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv,
+				 struct dpmac_link_state *state)
+{
+	struct phy_device *phydev = NULL;
+	phy_interface_t enet_if;
+	int err;
+
+	/* let's start off with maximum capabilities
+	 */
+	enet_if = wriop_get_enet_if(priv->dpmac_id);
+	switch (enet_if) {
+	case PHY_INTERFACE_MODE_XGMII:
+		state->rate = SPEED_10000;
+		break;
+	default:
+		state->rate = SPEED_1000;
+		break;
+	}
+	state->up = 1;
+
+#ifdef CONFIG_PHYLIB
+	state->options |= DPMAC_LINK_OPT_AUTONEG;
+
+	phydev = wriop_get_phy_dev(priv->dpmac_id);
+	if (phydev) {
+		err = phy_startup(phydev);
+		if (err) {
+			printf("%s: Could not initialize\n", phydev->dev->name);
+			state->up = 0;
+		}
+		if (phydev->link) {
+			state->rate = min(state->rate, (uint32_t)phydev->speed);
+			if (!phydev->duplex)
+				state->options |= DPMAC_LINK_OPT_HALF_DUPLEX;
+			if (!phydev->autoneg)
+				state->options &= ~DPMAC_LINK_OPT_AUTONEG;
+		} else {
+			state->up = 0;
+		}
+	}
+#endif
+	if (!phydev)
+		state->options &= ~DPMAC_LINK_OPT_AUTONEG;
+
+	if (!state->up) {
+		state->rate = 0;
+		state->options = 0;
+		return -ENOLINK;
+	}
+
+	return 0;
+}
+
 static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 {
 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
@@ -393,10 +446,7 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 	struct dpni_link_state link_state;
 #endif
 	int err = 0;
-	struct mii_dev *bus;
-	phy_interface_t enet_if;
 	struct dpni_queue d_queue;
-	struct phy_device *phydev = NULL;
 
 	if (net_dev->state == ETH_STATE_ACTIVE)
 		return 0;
@@ -416,45 +466,9 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 	if (err < 0)
 		goto err_dpmac_setup;
 
-#ifdef CONFIG_PHYLIB
-	phydev = wriop_get_phy_dev(priv->dpmac_id);
-	if (phydev) {
-		err = phy_startup(phydev);
-		if (err) {
-			printf("%s: Could not initialize\n",
-			       phydev->dev->name);
-			goto err_dpmac_bind;
-		}
-	}
-#else
-	phydev = (struct phy_device *)malloc(sizeof(struct phy_device));
-	memset(phydev, 0, sizeof(struct phy_device));
-	wriop_set_phy_dev(priv->dpmac_id, phydev);
-
-	phydev->speed = SPEED_1000;
-	phydev->link = 1;
-	phydev->duplex = DUPLEX_FULL;
-#endif
-
-	bus = wriop_get_mdio(priv->dpmac_id);
-	enet_if = wriop_get_enet_if(priv->dpmac_id);
-	if ((bus == NULL) &&
-	    (enet_if == PHY_INTERFACE_MODE_XGMII)) {
-		phydev = (struct phy_device *)
-				malloc(sizeof(struct phy_device));
-		memset(phydev, 0, sizeof(struct phy_device));
-		wriop_set_phy_dev(priv->dpmac_id, phydev);
-
-		phydev->speed = SPEED_10000;
-		phydev->link = 1;
-		phydev->duplex = DUPLEX_FULL;
-	}
-
-	if (!phydev->link) {
-		printf("%s: No link.\n", phydev->dev->name);
-		err = -1;
+	err = ldpaa_get_dpmac_state(priv, &dpmac_link_state);
+	if (err < 0)
 		goto err_dpmac_bind;
-	}
 
 	/* DPMAC binding DPNI */
 	err = ldpaa_dpmac_bind(priv);
@@ -488,18 +502,6 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 		return err;
 	}
 
-	dpmac_link_state.rate = phydev->speed;
-
-	if (phydev->autoneg == AUTONEG_DISABLE)
-		dpmac_link_state.options &= ~DPMAC_LINK_OPT_AUTONEG;
-	else
-		dpmac_link_state.options |= DPMAC_LINK_OPT_AUTONEG;
-
-	if (phydev->duplex == DUPLEX_HALF)
-		dpmac_link_state.options |= DPMAC_LINK_OPT_HALF_DUPLEX;
-
-	dpmac_link_state.up = phydev->link;
-
 	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
 				  priv->dpmac_handle, &dpmac_link_state);
 	if (err < 0) {
@@ -542,7 +544,7 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 		goto err_qdid;
 	}
 
-	return phydev->link;
+	return dpmac_link_state.up;
 
 err_qdid:
 err_get_queue:
@@ -565,9 +567,6 @@ static void ldpaa_eth_stop(struct eth_device *net_dev)
 {
 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
 	int err = 0;
-#ifdef CONFIG_PHYLIB
-	struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id);
-#endif
 	struct phy_device *phydev = NULL;
 
 	if ((net_dev->state == ETH_STATE_PASSIVE) ||
@@ -602,12 +601,8 @@ static void ldpaa_eth_stop(struct eth_device *net_dev)
 
 #ifdef CONFIG_PHYLIB
 	phydev = wriop_get_phy_dev(priv->dpmac_id);
-	if (phydev && bus)
+	if (phydev)
 		phy_shutdown(phydev);
-	else {
-		free(phydev);
-		wriop_set_phy_dev(priv->dpmac_id, NULL);
-	}
 #endif
 
 	/* Free DPBP handle and reset. */
-- 
2.17.1



More information about the U-Boot mailing list