summaryrefslogtreecommitdiff
path: root/drivers/net/ldpaa_eth/ldpaa_eth.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ldpaa_eth/ldpaa_eth.c')
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.c119
1 files changed, 57 insertions, 62 deletions
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
index ef5286c325b..4f0b9774494 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. */