@@ -512,7 +512,8 @@ int stmmac_mdio_register(struct net_device *ndev)
/* Try to probe the XPCS by scanning all addresses. */
if (priv->hw->xpcs) {
struct mdio_xpcs_args *xpcs = &priv->hw->xpcs_args;
- int ret, mode = priv->plat->phy_interface;
+ int ret;
+
max_addr = PHY_MAX_ADDR;
xpcs->bus = new_bus;
@@ -521,7 +522,7 @@ int stmmac_mdio_register(struct net_device *ndev)
for (addr = 0; addr < max_addr; addr++) {
xpcs->addr = addr;
- ret = stmmac_xpcs_probe(priv, xpcs, mode);
+ ret = stmmac_xpcs_probe(priv, xpcs);
if (!ret) {
found = 1;
break;
@@ -662,6 +662,30 @@ static int xpcs_validate(struct mdio_xpcs_args *xpcs,
unsigned long *supported,
struct phylink_link_state *state)
{
+ bool valid_interface;
+
+ if (state->interface == PHY_INTERFACE_MODE_NA) {
+ valid_interface = true;
+ } else {
+ struct xpcs_id *id = xpcs->id;
+ int i;
+
+ valid_interface = false;
+
+ for (i = 0; id->interface[i] != PHY_INTERFACE_MODE_MAX; i++) {
+ if (id->interface[i] != state->interface)
+ continue;
+
+ valid_interface = true;
+ break;
+ }
+ }
+
+ if (!valid_interface) {
+ bitmap_zero(supported, __ETHTOOL_LINK_MODE_MASK_NBITS);
+ return 0;
+ }
+
linkmode_and(supported, supported, xpcs->supported);
linkmode_and(state->advertising, state->advertising, xpcs->supported);
return 0;
@@ -910,43 +934,24 @@ static u32 xpcs_get_id(struct mdio_xpcs_args *xpcs)
return 0xffffffff;
}
-static bool xpcs_check_features(struct mdio_xpcs_args *xpcs,
- struct xpcs_id *match,
- phy_interface_t interface)
-{
- int i;
-
- for (i = 0; match->interface[i] != PHY_INTERFACE_MODE_MAX; i++) {
- if (match->interface[i] == interface)
- break;
- }
-
- if (match->interface[i] == PHY_INTERFACE_MODE_MAX)
- return false;
-
- for (i = 0; match->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
- set_bit(match->supported[i], xpcs->supported);
-
- xpcs->an_mode = match->an_mode;
-
- return true;
-}
-
-static int xpcs_probe(struct mdio_xpcs_args *xpcs, phy_interface_t interface)
+static int xpcs_probe(struct mdio_xpcs_args *xpcs)
{
u32 xpcs_id = xpcs_get_id(xpcs);
- struct xpcs_id *match = NULL;
int i;
for (i = 0; i < ARRAY_SIZE(xpcs_id_list); i++) {
struct xpcs_id *entry = &xpcs_id_list[i];
- if ((xpcs_id & entry->mask) == entry->id) {
- match = entry;
+ if ((xpcs_id & entry->mask) != entry->id)
+ continue;
- if (xpcs_check_features(xpcs, match, interface))
- return xpcs_soft_reset(xpcs);
- }
+ for (i = 0; entry->supported[i] != __ETHTOOL_LINK_MODE_MASK_NBITS; i++)
+ set_bit(entry->supported[i], xpcs->supported);
+
+ xpcs->id = entry;
+ xpcs->an_mode = entry->an_mode;
+
+ return xpcs_soft_reset(xpcs);
}
return -ENODEV;
@@ -14,9 +14,12 @@
#define DW_AN_C73 1
#define DW_AN_C37_SGMII 2
+struct xpcs_id;
+
struct mdio_xpcs_args {
__ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
struct mii_bus *bus;
+ struct xpcs_id *id;
int addr;
int an_mode;
};
@@ -31,7 +34,7 @@ struct mdio_xpcs_ops {
struct phylink_link_state *state);
int (*link_up)(struct mdio_xpcs_args *xpcs, int speed,
phy_interface_t interface);
- int (*probe)(struct mdio_xpcs_args *xpcs, phy_interface_t interface);
+ int (*probe)(struct mdio_xpcs_args *xpcs);
int (*config_eee)(struct mdio_xpcs_args *xpcs, int mult_fact_100ns,
int enable);
};