|
@@ -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. */
|