@@ -282,6 +282,13 @@ struct dsa_switch {
*/
bool vlan_filtering_is_global;
+ /* Pass .port_vlan_add and .port_vlan_del to drivers even for bridges
+ * that have vlan_filtering=0. All drivers should ideally set this (and
+ * then the option would get removed), but it is unknown whether this
+ * would break things or not.
+ */
+ bool configure_vlans_while_disabled;
+
/* In case vlan_filtering_is_global is set, the VLAN awareness state
* should be retrieved from here and not from the per-port settings.
*/
@@ -314,7 +314,8 @@ static int dsa_slave_vlan_add(struct net_device *dev,
if (obj->orig_dev != dev)
return -EOPNOTSUPP;
- if (dp->bridge_dev && !br_vlan_enabled(dp->bridge_dev))
+ if (dp->bridge_dev && !br_vlan_enabled(dp->bridge_dev) &&
+ !dp->ds->configure_vlans_while_disabled)
return 0;
vlan = *SWITCHDEV_OBJ_PORT_VLAN(obj);
@@ -381,7 +382,8 @@ static int dsa_slave_vlan_del(struct net_device *dev,
if (obj->orig_dev != dev)
return -EOPNOTSUPP;
- if (dp->bridge_dev && !br_vlan_enabled(dp->bridge_dev))
+ if (dp->bridge_dev && !br_vlan_enabled(dp->bridge_dev) &&
+ !dp->ds->configure_vlans_while_disabled)
return 0;
/* Do not deprogram the CPU port as it may be shared with other user
@@ -1240,7 +1242,8 @@ static int dsa_slave_vlan_rx_add_vid(struct net_device *dev, __be16 proto,
* need to emulate the switchdev prepare + commit phase.
*/
if (dp->bridge_dev) {
- if (!br_vlan_enabled(dp->bridge_dev))
+ if (!dp->ds->configure_vlans_while_disabled &&
+ !br_vlan_enabled(dp->bridge_dev))
return 0;
/* br_vlan_get_info() returns -EINVAL or -ENOENT if the
@@ -1274,7 +1277,8 @@ static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto,
* need to emulate the switchdev prepare + commit phase.
*/
if (dp->bridge_dev) {
- if (!br_vlan_enabled(dp->bridge_dev))
+ if (!dp->ds->configure_vlans_while_disabled &&
+ !br_vlan_enabled(dp->bridge_dev))
return 0;
/* br_vlan_get_info() returns -EINVAL or -ENOENT if the