|
|
|
@ -1378,6 +1378,22 @@ static int mv88e6xxx_atu_new(struct mv88e6xxx_chip *chip, u16 *fid)
|
|
|
|
|
return mv88e6xxx_g1_atu_flush(chip, *fid, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mv88e6xxx_atu_get_hash(struct mv88e6xxx_chip *chip, u8 *hash)
|
|
|
|
|
{
|
|
|
|
|
if (chip->info->ops->atu_get_hash)
|
|
|
|
|
return chip->info->ops->atu_get_hash(chip, hash);
|
|
|
|
|
|
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mv88e6xxx_atu_set_hash(struct mv88e6xxx_chip *chip, u8 hash)
|
|
|
|
|
{
|
|
|
|
|
if (chip->info->ops->atu_set_hash)
|
|
|
|
|
return chip->info->ops->atu_set_hash(chip, hash);
|
|
|
|
|
|
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
|
|
|
|
|
u16 vid_begin, u16 vid_end)
|
|
|
|
|
{
|
|
|
|
@ -2637,6 +2653,78 @@ static int mv88e6390_setup_errata(struct mv88e6xxx_chip *chip)
|
|
|
|
|
return mv88e6xxx_software_reset(chip);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
enum mv88e6xxx_devlink_param_id {
|
|
|
|
|
MV88E6XXX_DEVLINK_PARAM_ID_BASE = DEVLINK_PARAM_GENERIC_ID_MAX,
|
|
|
|
|
MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int mv88e6xxx_devlink_param_get(struct dsa_switch *ds, u32 id,
|
|
|
|
|
struct devlink_param_gset_ctx *ctx)
|
|
|
|
|
{
|
|
|
|
|
struct mv88e6xxx_chip *chip = ds->priv;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
mv88e6xxx_reg_lock(chip);
|
|
|
|
|
|
|
|
|
|
switch (id) {
|
|
|
|
|
case MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH:
|
|
|
|
|
err = mv88e6xxx_atu_get_hash(chip, &ctx->val.vu8);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
err = -EOPNOTSUPP;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mv88e6xxx_reg_unlock(chip);
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mv88e6xxx_devlink_param_set(struct dsa_switch *ds, u32 id,
|
|
|
|
|
struct devlink_param_gset_ctx *ctx)
|
|
|
|
|
{
|
|
|
|
|
struct mv88e6xxx_chip *chip = ds->priv;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
mv88e6xxx_reg_lock(chip);
|
|
|
|
|
|
|
|
|
|
switch (id) {
|
|
|
|
|
case MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH:
|
|
|
|
|
err = mv88e6xxx_atu_set_hash(chip, ctx->val.vu8);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
err = -EOPNOTSUPP;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mv88e6xxx_reg_unlock(chip);
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct devlink_param mv88e6xxx_devlink_params[] = {
|
|
|
|
|
DSA_DEVLINK_PARAM_DRIVER(MV88E6XXX_DEVLINK_PARAM_ID_ATU_HASH,
|
|
|
|
|
"ATU_hash", DEVLINK_PARAM_TYPE_U8,
|
|
|
|
|
BIT(DEVLINK_PARAM_CMODE_RUNTIME)),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int mv88e6xxx_setup_devlink_params(struct dsa_switch *ds)
|
|
|
|
|
{
|
|
|
|
|
return dsa_devlink_params_register(ds, mv88e6xxx_devlink_params,
|
|
|
|
|
ARRAY_SIZE(mv88e6xxx_devlink_params));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mv88e6xxx_teardown_devlink_params(struct dsa_switch *ds)
|
|
|
|
|
{
|
|
|
|
|
dsa_devlink_params_unregister(ds, mv88e6xxx_devlink_params,
|
|
|
|
|
ARRAY_SIZE(mv88e6xxx_devlink_params));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mv88e6xxx_teardown(struct dsa_switch *ds)
|
|
|
|
|
{
|
|
|
|
|
mv88e6xxx_teardown_devlink_params(ds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mv88e6xxx_setup(struct dsa_switch *ds)
|
|
|
|
|
{
|
|
|
|
|
struct mv88e6xxx_chip *chip = ds->priv;
|
|
|
|
@ -2753,7 +2841,11 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
|
|
|
|
|
unlock:
|
|
|
|
|
mv88e6xxx_reg_unlock(chip);
|
|
|
|
|
|
|
|
|
|
return err;
|
|
|
|
|
/* Has to be called without holding the register lock, since
|
|
|
|
|
* it takes the devlink lock, and we later take the locks in
|
|
|
|
|
* the reverse order when getting/setting parameters.
|
|
|
|
|
*/
|
|
|
|
|
return mv88e6xxx_setup_devlink_params(ds);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
|
|
|
|
@ -3113,6 +3205,8 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
|
|
|
|
|
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.phylink_validate = mv88e6185_phylink_validate,
|
|
|
|
@ -3242,6 +3336,8 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
|
|
|
|
|
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.avb_ops = &mv88e6165_avb_ops,
|
|
|
|
@ -3276,6 +3372,8 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
|
|
|
|
|
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.avb_ops = &mv88e6165_avb_ops,
|
|
|
|
@ -3318,6 +3416,8 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
|
|
|
|
|
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.phylink_validate = mv88e6185_phylink_validate,
|
|
|
|
@ -3362,6 +3462,8 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.rmu_disable = mv88e6352_g1_rmu_disable,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.serdes_get_lane = mv88e6352_serdes_get_lane,
|
|
|
|
@ -3405,6 +3507,8 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
|
|
|
|
|
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.phylink_validate = mv88e6185_phylink_validate,
|
|
|
|
@ -3449,6 +3553,8 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.rmu_disable = mv88e6352_g1_rmu_disable,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.serdes_get_lane = mv88e6352_serdes_get_lane,
|
|
|
|
@ -3534,6 +3640,8 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.rmu_disable = mv88e6390_g1_rmu_disable,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6390_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
|
|
|
|
|
.serdes_power = mv88e6390_serdes_power,
|
|
|
|
@ -3583,6 +3691,8 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.rmu_disable = mv88e6390_g1_rmu_disable,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6390_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
|
|
|
|
|
.serdes_power = mv88e6390_serdes_power,
|
|
|
|
@ -3631,6 +3741,8 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.rmu_disable = mv88e6390_g1_rmu_disable,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6390_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
|
|
|
|
|
.serdes_power = mv88e6390_serdes_power,
|
|
|
|
@ -3682,6 +3794,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.rmu_disable = mv88e6352_g1_rmu_disable,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.serdes_get_lane = mv88e6352_serdes_get_lane,
|
|
|
|
@ -3773,6 +3887,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.rmu_disable = mv88e6390_g1_rmu_disable,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6390_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
|
|
|
|
|
.serdes_power = mv88e6390_serdes_power,
|
|
|
|
@ -3959,6 +4075,8 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
|
|
|
|
|
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.phylink_validate = mv88e6185_phylink_validate,
|
|
|
|
@ -3999,6 +4117,8 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
|
|
|
|
.mgmt_rsvd2cpu = mv88e6352_g2_mgmt_rsvd2cpu,
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.avb_ops = &mv88e6352_avb_ops,
|
|
|
|
@ -4045,6 +4165,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.rmu_disable = mv88e6352_g1_rmu_disable,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6352_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6352_g1_vtu_loadpurge,
|
|
|
|
|
.serdes_get_lane = mv88e6352_serdes_get_lane,
|
|
|
|
@ -4101,6 +4223,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.rmu_disable = mv88e6390_g1_rmu_disable,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6390_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
|
|
|
|
|
.serdes_power = mv88e6390_serdes_power,
|
|
|
|
@ -4154,6 +4278,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
|
|
|
|
.pot_clear = mv88e6xxx_g2_pot_clear,
|
|
|
|
|
.reset = mv88e6352_g1_reset,
|
|
|
|
|
.rmu_disable = mv88e6390_g1_rmu_disable,
|
|
|
|
|
.atu_get_hash = mv88e6165_g1_atu_get_hash,
|
|
|
|
|
.atu_set_hash = mv88e6165_g1_atu_set_hash,
|
|
|
|
|
.vtu_getnext = mv88e6390_g1_vtu_getnext,
|
|
|
|
|
.vtu_loadpurge = mv88e6390_g1_vtu_loadpurge,
|
|
|
|
|
.serdes_power = mv88e6390_serdes_power,
|
|
|
|
@ -4929,6 +5055,7 @@ static int mv88e6xxx_port_egress_floods(struct dsa_switch *ds, int port,
|
|
|
|
|
static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
|
|
|
|
.get_tag_protocol = mv88e6xxx_get_tag_protocol,
|
|
|
|
|
.setup = mv88e6xxx_setup,
|
|
|
|
|
.teardown = mv88e6xxx_teardown,
|
|
|
|
|
.phylink_validate = mv88e6xxx_validate,
|
|
|
|
|
.phylink_mac_link_state = mv88e6xxx_link_state,
|
|
|
|
|
.phylink_mac_config = mv88e6xxx_mac_config,
|
|
|
|
@ -4971,6 +5098,8 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
|
|
|
|
|
.port_txtstamp = mv88e6xxx_port_txtstamp,
|
|
|
|
|
.port_rxtstamp = mv88e6xxx_port_rxtstamp,
|
|
|
|
|
.get_ts_info = mv88e6xxx_get_ts_info,
|
|
|
|
|
.devlink_param_get = mv88e6xxx_devlink_param_get,
|
|
|
|
|
.devlink_param_set = mv88e6xxx_devlink_param_set,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip)
|
|
|
|
|