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.c66
1 files changed, 46 insertions, 20 deletions
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
index 4f0b977449..fe1c03e9e4 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.c
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
@@ -23,26 +23,40 @@ static int init_phy(struct eth_device *dev)
struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)dev->priv;
struct phy_device *phydev = NULL;
struct mii_dev *bus;
- int ret;
+ int phy_addr, phy_num;
+ int ret = 0;
bus = wriop_get_mdio(priv->dpmac_id);
if (bus == NULL)
return 0;
- phydev = phy_connect(bus, wriop_get_phy_address(priv->dpmac_id),
- dev, wriop_get_enet_if(priv->dpmac_id));
- if (!phydev) {
- printf("Failed to connect\n");
- return -1;
- }
-
- wriop_set_phy_dev(priv->dpmac_id, phydev);
+ for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+ phy_addr = wriop_get_phy_address(priv->dpmac_id, phy_num);
+ if (phy_addr < 0)
+ continue;
- ret = phy_config(phydev);
+ phydev = phy_connect(bus, phy_addr, dev,
+ wriop_get_enet_if(priv->dpmac_id));
+ if (!phydev) {
+ printf("Failed to connect\n");
+ ret = -ENODEV;
+ break;
+ }
+ wriop_set_phy_dev(priv->dpmac_id, phy_num, phydev);
+ ret = phy_config(phydev);
+ if (ret)
+ break;
+ }
if (ret) {
- free(phydev);
- wriop_set_phy_dev(priv->dpmac_id, NULL);
+ for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+ phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
+ if (!phydev)
+ continue;
+
+ free(phydev);
+ wriop_set_phy_dev(priv->dpmac_id, phy_num, NULL);
+ }
}
return ret;
@@ -390,10 +404,10 @@ static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv,
{
struct phy_device *phydev = NULL;
phy_interface_t enet_if;
+ int phy_num, phys_detected;
int err;
- /* let's start off with maximum capabilities
- */
+ /* let's start off with maximum capabilities */
enet_if = wriop_get_enet_if(priv->dpmac_id);
switch (enet_if) {
case PHY_INTERFACE_MODE_XGMII:
@@ -405,15 +419,22 @@ static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv,
}
state->up = 1;
+ phys_detected = 0;
#ifdef CONFIG_PHYLIB
state->options |= DPMAC_LINK_OPT_AUTONEG;
- phydev = wriop_get_phy_dev(priv->dpmac_id);
- if (phydev) {
+ /* start the phy devices one by one and update the dpmac state */
+ for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+ phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
+ if (!phydev)
+ continue;
+
+ phys_detected++;
err = phy_startup(phydev);
if (err) {
printf("%s: Could not initialize\n", phydev->dev->name);
state->up = 0;
+ break;
}
if (phydev->link) {
state->rate = min(state->rate, (uint32_t)phydev->speed);
@@ -422,11 +443,13 @@ static int ldpaa_get_dpmac_state(struct ldpaa_eth_priv *priv,
if (!phydev->autoneg)
state->options &= ~DPMAC_LINK_OPT_AUTONEG;
} else {
+ /* break out of loop even if one phy is down */
state->up = 0;
+ break;
}
}
#endif
- if (!phydev)
+ if (!phys_detected)
state->options &= ~DPMAC_LINK_OPT_AUTONEG;
if (!state->up) {
@@ -568,6 +591,7 @@ 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;
struct phy_device *phydev = NULL;
+ int phy_num;
if ((net_dev->state == ETH_STATE_PASSIVE) ||
(net_dev->state == ETH_STATE_INIT))
@@ -600,9 +624,11 @@ static void ldpaa_eth_stop(struct eth_device *net_dev)
printf("dpni_disable() failed\n");
#ifdef CONFIG_PHYLIB
- phydev = wriop_get_phy_dev(priv->dpmac_id);
- if (phydev)
- phy_shutdown(phydev);
+ for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+ phydev = wriop_get_phy_dev(priv->dpmac_id, phy_num);
+ if (phydev)
+ phy_shutdown(phydev);
+ }
#endif
/* Free DPBP handle and reset. */