@@ -5550,6 +5550,44 @@ static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds,
return chip->tag_protocol;
}
+static int mv88e6xxx_change_tag_protocol(struct dsa_switch *ds, int port,
+ enum dsa_tag_protocol proto)
+{
+ struct mv88e6xxx_chip *chip = ds->priv;
+ enum dsa_tag_protocol old_protocol;
+ int err;
+
+ switch (proto) {
+ case DSA_TAG_PROTO_EDSA:
+ switch (chip->info->edsa_support) {
+ case MV88E6XXX_EDSA_UNSUPPORTED:
+ return -EPROTONOSUPPORT;
+ case MV88E6XXX_EDSA_UNDOCUMENTED:
+ dev_warn(chip->dev, "Relying on undocumented EDSA tagging behavior\n");
+ fallthrough;
+ case MV88E6XXX_EDSA_SUPPORTED:
+ break;
+ }
+ break;
+ case DSA_TAG_PROTO_DSA:
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ old_protocol = chip->tag_protocol;
+ chip->tag_protocol = proto;
+
+ mv88e6xxx_reg_lock(chip);
+ err = mv88e6xxx_setup_port_mode(chip, port);
+ mv88e6xxx_reg_unlock(chip);
+
+ if (err)
+ chip->tag_protocol = old_protocol;
+
+ return err;
+}
+
static int mv88e6xxx_port_mdb_add(struct dsa_switch *ds, int port,
const struct switchdev_obj_port_mdb *mdb)
{
@@ -6012,6 +6050,7 @@ static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index,
static const struct dsa_switch_ops mv88e6xxx_switch_ops = {
.get_tag_protocol = mv88e6xxx_get_tag_protocol,
+ .change_tag_protocol = mv88e6xxx_change_tag_protocol,
.setup = mv88e6xxx_setup,
.teardown = mv88e6xxx_teardown,
.phylink_validate = mv88e6xxx_validate,