summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.c66
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_wriop.c71
2 files changed, 94 insertions, 43 deletions
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
index 4f0b9774494..fe1c03e9e43 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. */
diff --git a/drivers/net/ldpaa_eth/ldpaa_wriop.c b/drivers/net/ldpaa_eth/ldpaa_wriop.c
index afbb1ca91ed..06a284ad684 100644
--- a/drivers/net/ldpaa_eth/ldpaa_wriop.c
+++ b/drivers/net/ldpaa_eth/ldpaa_wriop.c
@@ -22,11 +22,10 @@ __weak phy_interface_t wriop_dpmac_enet_if(int dpmac_id, int lane_prtc)
void wriop_init_dpmac(int sd, int dpmac_id, int lane_prtcl)
{
phy_interface_t enet_if;
+ int phy_num;
dpmac_info[dpmac_id].enabled = 0;
dpmac_info[dpmac_id].id = 0;
- dpmac_info[dpmac_id].phy_addr = -1;
- dpmac_info[dpmac_id].phydev = NULL;
dpmac_info[dpmac_id].enet_if = PHY_INTERFACE_MODE_NONE;
enet_if = wriop_dpmac_enet_if(dpmac_id, lane_prtcl);
@@ -35,15 +34,23 @@ void wriop_init_dpmac(int sd, int dpmac_id, int lane_prtcl)
dpmac_info[dpmac_id].id = dpmac_id;
dpmac_info[dpmac_id].enet_if = enet_if;
}
+ for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+ dpmac_info[dpmac_id].phydev[phy_num] = NULL;
+ dpmac_info[dpmac_id].phy_addr[phy_num] = -1;
+ }
}
void wriop_init_dpmac_enet_if(int dpmac_id, phy_interface_t enet_if)
{
+ int phy_num;
+
dpmac_info[dpmac_id].enabled = 1;
dpmac_info[dpmac_id].id = dpmac_id;
- dpmac_info[dpmac_id].phy_addr = -1;
dpmac_info[dpmac_id].enet_if = enet_if;
- dpmac_info[dpmac_id].phydev = NULL;
+ for (phy_num = 0; phy_num < WRIOP_MAX_PHY_NUM; phy_num++) {
+ dpmac_info[dpmac_id].phydev[phy_num] = NULL;
+ dpmac_info[dpmac_id].phy_addr[phy_num] = -1;
+ }
}
@@ -60,47 +67,53 @@ static int wriop_dpmac_to_index(int dpmac_id)
return -1;
}
-void wriop_disable_dpmac(int dpmac_id)
+int wriop_disable_dpmac(int dpmac_id)
{
int i = wriop_dpmac_to_index(dpmac_id);
if (i == -1)
- return;
+ return -ENODEV;
dpmac_info[i].enabled = 0;
wriop_dpmac_disable(dpmac_id);
+
+ return 0;
}
-void wriop_enable_dpmac(int dpmac_id)
+int wriop_enable_dpmac(int dpmac_id)
{
int i = wriop_dpmac_to_index(dpmac_id);
if (i == -1)
- return;
+ return -ENODEV;
dpmac_info[i].enabled = 1;
wriop_dpmac_enable(dpmac_id);
+
+ return 0;
}
-u8 wriop_is_enabled_dpmac(int dpmac_id)
+int wriop_is_enabled_dpmac(int dpmac_id)
{
int i = wriop_dpmac_to_index(dpmac_id);
if (i == -1)
- return -1;
+ return -ENODEV;
return dpmac_info[i].enabled;
}
-void wriop_set_mdio(int dpmac_id, struct mii_dev *bus)
+int wriop_set_mdio(int dpmac_id, struct mii_dev *bus)
{
int i = wriop_dpmac_to_index(dpmac_id);
if (i == -1)
- return;
+ return -ENODEV;
dpmac_info[i].bus = bus;
+
+ return 0;
}
struct mii_dev *wriop_get_mdio(int dpmac_id)
@@ -113,44 +126,56 @@ struct mii_dev *wriop_get_mdio(int dpmac_id)
return dpmac_info[i].bus;
}
-void wriop_set_phy_address(int dpmac_id, int address)
+int wriop_set_phy_address(int dpmac_id, int phy_num, int address)
{
int i = wriop_dpmac_to_index(dpmac_id);
if (i == -1)
- return;
+ return -ENODEV;
+ if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+ return -EINVAL;
+
+ dpmac_info[i].phy_addr[phy_num] = address;
- dpmac_info[i].phy_addr = address;
+ return 0;
}
-int wriop_get_phy_address(int dpmac_id)
+int wriop_get_phy_address(int dpmac_id, int phy_num)
{
int i = wriop_dpmac_to_index(dpmac_id);
if (i == -1)
- return -1;
+ return -ENODEV;
+ if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+ return -EINVAL;
- return dpmac_info[i].phy_addr;
+ return dpmac_info[i].phy_addr[phy_num];
}
-void wriop_set_phy_dev(int dpmac_id, struct phy_device *phydev)
+int wriop_set_phy_dev(int dpmac_id, int phy_num, struct phy_device *phydev)
{
int i = wriop_dpmac_to_index(dpmac_id);
if (i == -1)
- return;
+ return -ENODEV;
+ if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+ return -EINVAL;
- dpmac_info[i].phydev = phydev;
+ dpmac_info[i].phydev[phy_num] = phydev;
+
+ return 0;
}
-struct phy_device *wriop_get_phy_dev(int dpmac_id)
+struct phy_device *wriop_get_phy_dev(int dpmac_id, int phy_num)
{
int i = wriop_dpmac_to_index(dpmac_id);
if (i == -1)
return NULL;
+ if (phy_num < 0 || phy_num >= WRIOP_MAX_PHY_NUM)
+ return NULL;
- return dpmac_info[i].phydev;
+ return dpmac_info[i].phydev[phy_num];
}
phy_interface_t wriop_get_enet_if(int dpmac_id)