net: dsa: mv88e6xxx: add phylink support
Add rudimentary phylink support to mv88e6xxx. TODO: - needs to call phylink_mac_change() when the port link comes up/goes down. Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk> Signed-off-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
624c0f0239
commit
6c422e34b1
|
@ -598,10 +598,92 @@ static void mv88e6xxx_adjust_link(struct dsa_switch *ds, int port,
|
|||
dev_err(ds->dev, "p%d: failed to configure MAC\n", port);
|
||||
}
|
||||
|
||||
static void mv88e6065_phylink_validate(struct mv88e6xxx_chip *chip, int port,
|
||||
unsigned long *mask,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
if (!phy_interface_mode_is_8023z(state->interface)) {
|
||||
/* 10M and 100M are only supported in non-802.3z mode */
|
||||
phylink_set(mask, 10baseT_Half);
|
||||
phylink_set(mask, 10baseT_Full);
|
||||
phylink_set(mask, 100baseT_Half);
|
||||
phylink_set(mask, 100baseT_Full);
|
||||
}
|
||||
}
|
||||
|
||||
static void mv88e6185_phylink_validate(struct mv88e6xxx_chip *chip, int port,
|
||||
unsigned long *mask,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
/* FIXME: if the port is in 1000Base-X mode, then it only supports
|
||||
* 1000M FD speeds. In this case, CMODE will indicate 5.
|
||||
*/
|
||||
phylink_set(mask, 1000baseT_Full);
|
||||
phylink_set(mask, 1000baseX_Full);
|
||||
|
||||
mv88e6065_phylink_validate(chip, port, mask, state);
|
||||
}
|
||||
|
||||
static void mv88e6352_phylink_validate(struct mv88e6xxx_chip *chip, int port,
|
||||
unsigned long *mask,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
/* No ethtool bits for 200Mbps */
|
||||
phylink_set(mask, 1000baseT_Full);
|
||||
phylink_set(mask, 1000baseX_Full);
|
||||
|
||||
mv88e6065_phylink_validate(chip, port, mask, state);
|
||||
}
|
||||
|
||||
static void mv88e6390_phylink_validate(struct mv88e6xxx_chip *chip, int port,
|
||||
unsigned long *mask,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
if (port >= 9)
|
||||
phylink_set(mask, 2500baseX_Full);
|
||||
|
||||
/* No ethtool bits for 200Mbps */
|
||||
phylink_set(mask, 1000baseT_Full);
|
||||
phylink_set(mask, 1000baseX_Full);
|
||||
|
||||
mv88e6065_phylink_validate(chip, port, mask, state);
|
||||
}
|
||||
|
||||
static void mv88e6390x_phylink_validate(struct mv88e6xxx_chip *chip, int port,
|
||||
unsigned long *mask,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
if (port >= 9) {
|
||||
phylink_set(mask, 10000baseT_Full);
|
||||
phylink_set(mask, 10000baseKR_Full);
|
||||
}
|
||||
|
||||
mv88e6390_phylink_validate(chip, port, mask, state);
|
||||
}
|
||||
|
||||
static void mv88e6xxx_validate(struct dsa_switch *ds, int port,
|
||||
unsigned long *supported,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
|
||||
struct mv88e6xxx_chip *chip = ds->priv;
|
||||
|
||||
/* Allow all the expected bits */
|
||||
phylink_set(mask, Autoneg);
|
||||
phylink_set(mask, Pause);
|
||||
phylink_set_port_modes(mask);
|
||||
|
||||
if (chip->info->ops->phylink_validate)
|
||||
chip->info->ops->phylink_validate(chip, port, mask, state);
|
||||
|
||||
bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||
bitmap_and(state->advertising, state->advertising, mask,
|
||||
__ETHTOOL_LINK_MODE_MASK_NBITS);
|
||||
|
||||
/* We can only operate at 2500BaseX or 1000BaseX. If requested
|
||||
* to advertise both, only report advertising at 2500BaseX.
|
||||
*/
|
||||
phylink_helper_basex_speed(state);
|
||||
}
|
||||
|
||||
static int mv88e6xxx_link_state(struct dsa_switch *ds, int port,
|
||||
|
@ -611,7 +693,10 @@ static int mv88e6xxx_link_state(struct dsa_switch *ds, int port,
|
|||
int err;
|
||||
|
||||
mutex_lock(&chip->reg_lock);
|
||||
err = mv88e6xxx_port_link_state(chip, port, state);
|
||||
if (chip->info->ops->port_link_state)
|
||||
err = chip->info->ops->port_link_state(chip, port, state);
|
||||
else
|
||||
err = -EOPNOTSUPP;
|
||||
mutex_unlock(&chip->reg_lock);
|
||||
|
||||
return err;
|
||||
|
@ -2611,6 +2696,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2627,6 +2713,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
|
|||
.rmu_disable = mv88e6085_g1_rmu_disable,
|
||||
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6095_ops = {
|
||||
|
@ -2642,6 +2729,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
|
|||
.port_set_frame_mode = mv88e6085_port_set_frame_mode,
|
||||
.port_set_egress_floods = mv88e6185_port_set_egress_floods,
|
||||
.port_set_upstream_port = mv88e6095_port_set_upstream_port,
|
||||
.port_link_state = mv88e6185_port_link_state,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2653,6 +2741,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
|
|||
.reset = mv88e6185_g1_reset,
|
||||
.vtu_getnext = mv88e6185_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6097_ops = {
|
||||
|
@ -2675,6 +2764,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2689,6 +2779,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
|
|||
.rmu_disable = mv88e6085_g1_rmu_disable,
|
||||
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6123_ops = {
|
||||
|
@ -2706,6 +2797,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
|
|||
.port_set_egress_floods = mv88e6352_port_set_egress_floods,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2719,6 +2811,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
|
|||
.reset = mv88e6352_g1_reset,
|
||||
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6131_ops = {
|
||||
|
@ -2740,6 +2833,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
|
|||
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
|
||||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_set_pause = mv88e6185_port_set_pause,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2755,6 +2849,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
|
|||
.reset = mv88e6185_g1_reset,
|
||||
.vtu_getnext = mv88e6185_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6141_ops = {
|
||||
|
@ -2780,6 +2875,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -2795,6 +2891,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
|
|||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.serdes_power = mv88e6341_serdes_power,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.phylink_validate = mv88e6390_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6161_ops = {
|
||||
|
@ -2817,6 +2914,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2832,6 +2930,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
|
|||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.avb_ops = &mv88e6165_avb_ops,
|
||||
.ptp_ops = &mv88e6165_ptp_ops,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6165_ops = {
|
||||
|
@ -2847,6 +2946,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
|
|||
.port_set_speed = mv88e6185_port_set_speed,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2862,6 +2962,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
|
|||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.avb_ops = &mv88e6165_avb_ops,
|
||||
.ptp_ops = &mv88e6165_ptp_ops,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6171_ops = {
|
||||
|
@ -2885,6 +2986,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2898,6 +3000,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
|
|||
.reset = mv88e6352_g1_reset,
|
||||
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6172_ops = {
|
||||
|
@ -2923,6 +3026,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2939,6 +3043,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
|||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.serdes_power = mv88e6352_serdes_power,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.phylink_validate = mv88e6352_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6175_ops = {
|
||||
|
@ -2962,6 +3067,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2975,6 +3081,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
|
|||
.reset = mv88e6352_g1_reset,
|
||||
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6176_ops = {
|
||||
|
@ -3000,6 +3107,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3016,6 +3124,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
|||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.serdes_power = mv88e6352_serdes_power,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.phylink_validate = mv88e6352_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6185_ops = {
|
||||
|
@ -3033,6 +3142,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
|
|||
.port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
|
||||
.port_set_upstream_port = mv88e6095_port_set_upstream_port,
|
||||
.port_set_pause = mv88e6185_port_set_pause,
|
||||
.port_link_state = mv88e6185_port_link_state,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3048,6 +3158,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
|
|||
.reset = mv88e6185_g1_reset,
|
||||
.vtu_getnext = mv88e6185_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6185_g1_vtu_loadpurge,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6190_ops = {
|
||||
|
@ -3069,6 +3180,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
|||
.port_pause_limit = mv88e6390_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3085,6 +3197,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
|||
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
|
||||
.serdes_power = mv88e6390_serdes_power,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.phylink_validate = mv88e6390_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
||||
|
@ -3106,6 +3219,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
|||
.port_pause_limit = mv88e6390_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3122,6 +3236,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
|||
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
|
||||
.serdes_power = mv88e6390_serdes_power,
|
||||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.phylink_validate = mv88e6390x_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6191_ops = {
|
||||
|
@ -3143,6 +3258,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
|||
.port_pause_limit = mv88e6390_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3160,6 +3276,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
|||
.serdes_power = mv88e6390_serdes_power,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_validate = mv88e6390_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6240_ops = {
|
||||
|
@ -3185,6 +3302,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3203,6 +3321,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
|||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_validate = mv88e6352_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6290_ops = {
|
||||
|
@ -3225,6 +3344,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
|||
.port_set_cmode = mv88e6390x_port_set_cmode,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3243,6 +3363,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
|||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_validate = mv88e6390_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6320_ops = {
|
||||
|
@ -3267,6 +3388,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3282,6 +3404,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
|||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6321_ops = {
|
||||
|
@ -3306,6 +3429,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3319,6 +3443,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
|||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6341_ops = {
|
||||
|
@ -3344,6 +3469,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3361,6 +3487,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
|||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_validate = mv88e6390_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6350_ops = {
|
||||
|
@ -3384,6 +3511,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3397,6 +3525,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
|
|||
.reset = mv88e6352_g1_reset,
|
||||
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6351_ops = {
|
||||
|
@ -3420,6 +3549,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3435,6 +3565,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
|||
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_validate = mv88e6185_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6352_ops = {
|
||||
|
@ -3460,6 +3591,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
|||
.port_pause_limit = mv88e6097_port_pause_limit,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3481,6 +3613,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
|||
.serdes_get_sset_count = mv88e6352_serdes_get_sset_count,
|
||||
.serdes_get_strings = mv88e6352_serdes_get_strings,
|
||||
.serdes_get_stats = mv88e6352_serdes_get_stats,
|
||||
.phylink_validate = mv88e6352_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6390_ops = {
|
||||
|
@ -3505,6 +3638,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
|||
.port_set_cmode = mv88e6390x_port_set_cmode,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3523,6 +3657,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
|||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_validate = mv88e6390_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
||||
|
@ -3547,6 +3682,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
|||
.port_set_cmode = mv88e6390x_port_set_cmode,
|
||||
.port_disable_learn_limit = mv88e6xxx_port_disable_learn_limit,
|
||||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3565,6 +3701,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
|||
.gpio_ops = &mv88e6352_gpio_ops,
|
||||
.avb_ops = &mv88e6390_avb_ops,
|
||||
.ptp_ops = &mv88e6352_ptp_ops,
|
||||
.phylink_validate = mv88e6390x_phylink_validate,
|
||||
};
|
||||
|
||||
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
||||
|
|
|
@ -396,6 +396,9 @@ struct mv88e6xxx_ops {
|
|||
*/
|
||||
int (*port_set_upstream_port)(struct mv88e6xxx_chip *chip, int port,
|
||||
int upstream_port);
|
||||
/* Return the port link state, as required by phylink */
|
||||
int (*port_link_state)(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_link_state *state);
|
||||
|
||||
/* Snapshot the statistics for a port. The statistics can then
|
||||
* be read back a leisure but still with a consistent view.
|
||||
|
@ -451,6 +454,11 @@ struct mv88e6xxx_ops {
|
|||
|
||||
/* Precision Time Protocol operations */
|
||||
const struct mv88e6xxx_ptp_ops *ptp_ops;
|
||||
|
||||
/* Phylink */
|
||||
void (*phylink_validate)(struct mv88e6xxx_chip *chip, int port,
|
||||
unsigned long *mask,
|
||||
struct phylink_link_state *state);
|
||||
};
|
||||
|
||||
struct mv88e6xxx_irq_ops {
|
||||
|
|
|
@ -388,6 +388,19 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* mv88e6185 only has 3 bits for CMODE */
|
||||
static int mv88e6185_port_get_cmode(struct mv88e6xxx_chip *chip, int port)
|
||||
{
|
||||
int err;
|
||||
u16 reg;
|
||||
|
||||
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, ®);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return reg & MV88E6185_PORT_STS_CMODE_MASK;
|
||||
}
|
||||
|
||||
int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
|
||||
{
|
||||
int err;
|
||||
|
@ -402,7 +415,7 @@ int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mv88e6xxx_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
int err;
|
||||
|
@ -423,7 +436,7 @@ int mv88e6xxx_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
|||
state->speed = SPEED_1000;
|
||||
break;
|
||||
case MV88E6XXX_PORT_STS_SPEED_10000:
|
||||
if ((reg &MV88E6XXX_PORT_STS_CMODE_MASK) ==
|
||||
if ((reg & MV88E6XXX_PORT_STS_CMODE_MASK) ==
|
||||
MV88E6XXX_PORT_STS_CMODE_2500BASEX)
|
||||
state->speed = SPEED_2500;
|
||||
else
|
||||
|
@ -440,6 +453,45 @@ int mv88e6xxx_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_link_state *state)
|
||||
{
|
||||
if (state->interface == PHY_INTERFACE_MODE_1000BASEX) {
|
||||
int cmode = mv88e6185_port_get_cmode(chip, port);
|
||||
|
||||
if (cmode < 0)
|
||||
return cmode;
|
||||
|
||||
/* When a port is in "Cross-chip serdes" mode, it uses
|
||||
* 1000Base-X full duplex mode, but there is no automatic
|
||||
* link detection. Use the sync OK status for link (as it
|
||||
* would do for 1000Base-X mode.)
|
||||
*/
|
||||
if (cmode == MV88E6185_PORT_STS_CMODE_SERDES) {
|
||||
u16 mac;
|
||||
int err;
|
||||
|
||||
err = mv88e6xxx_port_read(chip, port,
|
||||
MV88E6XXX_PORT_MAC_CTL, &mac);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
state->link = !!(mac & MV88E6185_PORT_MAC_CTL_SYNC_OK);
|
||||
state->an_enabled = 1;
|
||||
state->an_complete =
|
||||
!!(mac & MV88E6185_PORT_MAC_CTL_AN_DONE);
|
||||
state->duplex =
|
||||
state->link ? DUPLEX_FULL : DUPLEX_UNKNOWN;
|
||||
state->speed =
|
||||
state->link ? SPEED_1000 : SPEED_UNKNOWN;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return mv88e6352_port_link_state(chip, port, state);
|
||||
}
|
||||
|
||||
/* Offset 0x02: Jamming Control
|
||||
*
|
||||
* Do not limit the period of time that this port can be paused for by
|
||||
|
|
|
@ -42,14 +42,28 @@
|
|||
#define MV88E6XXX_PORT_STS_CMODE_2500BASEX 0x000b
|
||||
#define MV88E6XXX_PORT_STS_CMODE_XAUI 0x000c
|
||||
#define MV88E6XXX_PORT_STS_CMODE_RXAUI 0x000d
|
||||
#define MV88E6185_PORT_STS_CDUPLEX 0x0008
|
||||
#define MV88E6185_PORT_STS_CMODE_MASK 0x0007
|
||||
#define MV88E6185_PORT_STS_CMODE_GMII_FD 0x0000
|
||||
#define MV88E6185_PORT_STS_CMODE_MII_100_FD_PS 0x0001
|
||||
#define MV88E6185_PORT_STS_CMODE_MII_100 0x0002
|
||||
#define MV88E6185_PORT_STS_CMODE_MII_10 0x0003
|
||||
#define MV88E6185_PORT_STS_CMODE_SERDES 0x0004
|
||||
#define MV88E6185_PORT_STS_CMODE_1000BASE_X 0x0005
|
||||
#define MV88E6185_PORT_STS_CMODE_PHY 0x0006
|
||||
#define MV88E6185_PORT_STS_CMODE_DISABLED 0x0007
|
||||
|
||||
/* Offset 0x01: MAC (or PCS or Physical) Control Register */
|
||||
#define MV88E6XXX_PORT_MAC_CTL 0x01
|
||||
#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_RXCLK 0x8000
|
||||
#define MV88E6XXX_PORT_MAC_CTL_RGMII_DELAY_TXCLK 0x4000
|
||||
#define MV88E6185_PORT_MAC_CTL_SYNC_OK 0x4000
|
||||
#define MV88E6390_PORT_MAC_CTL_FORCE_SPEED 0x2000
|
||||
#define MV88E6390_PORT_MAC_CTL_ALTSPEED 0x1000
|
||||
#define MV88E6352_PORT_MAC_CTL_200BASE 0x1000
|
||||
#define MV88E6185_PORT_MAC_CTL_AN_EN 0x0400
|
||||
#define MV88E6185_PORT_MAC_CTL_AN_RESTART 0x0200
|
||||
#define MV88E6185_PORT_MAC_CTL_AN_DONE 0x0100
|
||||
#define MV88E6XXX_PORT_MAC_CTL_FC 0x0080
|
||||
#define MV88E6XXX_PORT_MAC_CTL_FORCE_FC 0x0040
|
||||
#define MV88E6XXX_PORT_MAC_CTL_LINK_UP 0x0020
|
||||
|
@ -298,7 +312,9 @@ int mv88e6390_port_pause_limit(struct mv88e6xxx_chip *chip, int port, u8 in,
|
|||
int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
|
||||
phy_interface_t mode);
|
||||
int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
|
||||
int mv88e6xxx_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
int mv88e6185_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_link_state *state);
|
||||
int mv88e6352_port_link_state(struct mv88e6xxx_chip *chip, int port,
|
||||
struct phylink_link_state *state);
|
||||
int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port);
|
||||
int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
|
||||
|
|
Loading…
Reference in New Issue