Browse Source

driver: net: fsl-mc: Modify the dpmac link detection method

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@nxp.com>
Acked-by: Joe Hershberger <joe.hershberger@ni.com>
Pankaj Bansal 6 years ago
parent
commit
a3cb5340f1
1 changed files with 57 additions and 62 deletions
  1. 57 62
      drivers/net/ldpaa_eth/ldpaa_eth.c

+ 57 - 62
drivers/net/ldpaa_eth/ldpaa_eth.c

@@ -385,6 +385,59 @@ error:
 	return err;
 	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)
 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;
 	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;
 	struct dpni_link_state link_state;
 #endif
 #endif
 	int err = 0;
 	int err = 0;
-	struct mii_dev *bus;
-	phy_interface_t enet_if;
 	struct dpni_queue d_queue;
 	struct dpni_queue d_queue;
-	struct phy_device *phydev = NULL;
 
 
 	if (net_dev->state == ETH_STATE_ACTIVE)
 	if (net_dev->state == ETH_STATE_ACTIVE)
 		return 0;
 		return 0;
@@ -416,45 +466,9 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 	if (err < 0)
 	if (err < 0)
 		goto err_dpmac_setup;
 		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;
 		goto err_dpmac_bind;
-	}
 
 
 	/* DPMAC binding DPNI */
 	/* DPMAC binding DPNI */
 	err = ldpaa_dpmac_bind(priv);
 	err = ldpaa_dpmac_bind(priv);
@@ -488,18 +502,6 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 		return err;
 		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,
 	err = dpmac_set_link_state(dflt_mc_io, MC_CMD_NO_FLAGS,
 				  priv->dpmac_handle, &dpmac_link_state);
 				  priv->dpmac_handle, &dpmac_link_state);
 	if (err < 0) {
 	if (err < 0) {
@@ -542,7 +544,7 @@ static int ldpaa_eth_open(struct eth_device *net_dev, bd_t *bd)
 		goto err_qdid;
 		goto err_qdid;
 	}
 	}
 
 
-	return phydev->link;
+	return dpmac_link_state.up;
 
 
 err_qdid:
 err_qdid:
 err_get_queue:
 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;
 	struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
 	int err = 0;
 	int err = 0;
-#ifdef CONFIG_PHYLIB
-	struct mii_dev *bus = wriop_get_mdio(priv->dpmac_id);
-#endif
 	struct phy_device *phydev = NULL;
 	struct phy_device *phydev = NULL;
 
 
 	if ((net_dev->state == ETH_STATE_PASSIVE) ||
 	if ((net_dev->state == ETH_STATE_PASSIVE) ||
@@ -602,12 +601,8 @@ static void ldpaa_eth_stop(struct eth_device *net_dev)
 
 
 #ifdef CONFIG_PHYLIB
 #ifdef CONFIG_PHYLIB
 	phydev = wriop_get_phy_dev(priv->dpmac_id);
 	phydev = wriop_get_phy_dev(priv->dpmac_id);
-	if (phydev && bus) {
+	if (phydev)
 		phy_shutdown(phydev);
 		phy_shutdown(phydev);
-	} else {
-		free(phydev);
-		wriop_set_phy_dev(priv->dpmac_id, NULL);
-	}
 #endif
 #endif
 
 
 	/* Free DPBP handle and reset. */
 	/* Free DPBP handle and reset. */