This commit implements the port_vlan_add and port_vlan_del functions in
the dsa_switch_driver structure for Marvell 88E6xxx compatible switches.
This allows to access a switch VLAN Table Unit, and thus define VLANs
from standard userspace commands such as "bridge vlan".
Signed-off-by: Vivien Didelot <vivien.didelot@xxxxxxxxxxxxxxxxxxxx>
---
+
+int mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid,
+ u16 bridge_flags)
+{
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
+ struct mv88e6xxx_vtu_entry entry = { 0 };
+ int prev_vid = vid ? vid - 1 : 4095;
+ int i, ret;
+
+ /* Bringing an interface up adds it to the VLAN 0. Ignore this. */
+ if (!vid)
+ return 0;
+
+ /* The DSA port-based VLAN setup reserves FID 0 to DSA_MAX_PORTS;
+ * we will use the next FIDs for 802.1q;
+ * thus, forbid the last DSA_MAX_PORTS VLANs.
+ */
+ if (vid > 4095 - DSA_MAX_PORTS)
+ return -EINVAL;
+
+ mutex_lock(&ps->smi_mutex);
+ ret = _mv88e6xxx_vtu_getnext(ds, prev_vid, &entry);
+ if (ret < 0)
+ goto unlock;
+
+ /* If the VLAN does not exist, re-initialize the entry for addition */
+ if (entry.vid != vid || !entry.valid) {
+ memset(&entry, 0, sizeof(entry));
+ entry.valid = true;
+ entry.vid = vid;
+ entry.fid = DSA_MAX_PORTS + vid;