if (err)
return err;
- err = dsa_8021q_setup(ds, true);
- if (err)
- goto out_tag_8021q_unregister;
-
err = felix_setup_mmio_filtering(felix);
if (err)
- goto out_teardown_dsa_8021q;
+ goto out_tag_8021q_unregister;
return 0;
-out_teardown_dsa_8021q:
- dsa_8021q_setup(ds, false);
out_tag_8021q_unregister:
dsa_tag_8021q_unregister(ds);
return err;
dev_err(ds->dev, "felix_teardown_mmio_filtering returned %d",
err);
- err = dsa_8021q_setup(ds, false);
- if (err)
- dev_err(ds->dev, "dsa_8021q_setup returned %d", err);
-
dsa_tag_8021q_unregister(ds);
for (port = 0; port < ds->num_ports; port++) {
}
}
-static int sja1105_setup_8021q_tagging(struct dsa_switch *ds, bool enabled)
-{
- int rc;
-
- rc = dsa_8021q_setup(ds, enabled);
- if (rc)
- return rc;
-
- dev_info(ds->dev, "%s switch tagging\n",
- enabled ? "Enabled" : "Disabled");
- return 0;
-}
-
static enum dsa_tag_protocol
sja1105_get_tag_protocol(struct dsa_switch *ds, int port,
enum dsa_tag_protocol mp)
if (rc < 0)
goto out_static_config_free;
- /* The DSA/switchdev model brings up switch ports in standalone mode by
- * default, and that means vlan_filtering is 0 since they're not under
- * a bridge, so it's safe to set up switch tagging at this time.
- */
rtnl_lock();
- rc = sja1105_setup_8021q_tagging(ds, true);
+ rc = dsa_tag_8021q_register(ds, htons(ETH_P_8021Q));
rtnl_unlock();
if (rc)
goto out_devlink_teardown;
struct sja1105_bridge_vlan *v, *n;
int port;
+ rtnl_lock();
+ dsa_tag_8021q_unregister(ds);
+ rtnl_unlock();
+
for (port = 0; port < ds->num_ports; port++) {
struct sja1105_port *sp = &priv->ports[port];
mutex_init(&priv->ptp_data.lock);
mutex_init(&priv->mgmt_lock);
- rc = dsa_tag_8021q_register(ds, htons(ETH_P_8021Q));
- if (rc)
- return rc;
-
INIT_LIST_HEAD(&priv->bridge_vlans);
INIT_LIST_HEAD(&priv->dsa_8021q_vlans);
rc = dsa_register_switch(priv->ds);
if (rc)
- goto out_tag_8021q_unregister;
+ return rc;
if (IS_ENABLED(CONFIG_NET_SCH_CBS)) {
priv->cbs = devm_kcalloc(dev, priv->info->num_cbs_shapers,
out_unregister_switch:
dsa_unregister_switch(ds);
-out_tag_8021q_unregister:
- dsa_tag_8021q_unregister(ds);
return rc;
}
struct dsa_switch *ds = priv->ds;
dsa_unregister_switch(ds);
- dsa_tag_8021q_unregister(ds);
return 0;
}
return err;
}
-int dsa_8021q_setup(struct dsa_switch *ds, bool enabled)
+static int dsa_8021q_setup(struct dsa_switch *ds, bool enabled)
{
int err, port;
return 0;
}
-EXPORT_SYMBOL_GPL(dsa_8021q_setup);
static int dsa_8021q_crosschip_link_apply(struct dsa_switch *ds, int port,
struct dsa_switch *other_ds,
ds->tag_8021q_ctx = ctx;
- return 0;
+ return dsa_8021q_setup(ds, true);
}
EXPORT_SYMBOL_GPL(dsa_tag_8021q_register);
{
struct dsa_8021q_context *ctx = ds->tag_8021q_ctx;
struct dsa_8021q_crosschip_link *c, *n;
+ int err;
+
+ err = dsa_8021q_setup(ds, false);
+ if (err)
+ dev_err(ds->dev, "failed to tear down tag_8021q VLANs: %pe\n",
+ ERR_PTR(err));
list_for_each_entry_safe(c, n, &ctx->crosschip_links, list) {
list_del(&c->list);