Commit 2fb5ef09 authored by Vivien Didelot's avatar Vivien Didelot Committed by David S. Miller

net: dsa: mv88e6xxx: extract single VLAN retrieval

Rename _mv88e6xxx_vlan_init in _mv88e6xxx_vtu_new, eventually called
from a new _mv88e6xxx_vtu_get function, which abstracts the VTU GetNext
VID-1 trick to retrieve a single entry.
Signed-off-by: default avatarVivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent fb2dabad
...@@ -1458,8 +1458,8 @@ static int _mv88e6xxx_stu_loadpurge(struct dsa_switch *ds, ...@@ -1458,8 +1458,8 @@ static int _mv88e6xxx_stu_loadpurge(struct dsa_switch *ds,
return _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_STU_LOAD_PURGE); return _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_STU_LOAD_PURGE);
} }
static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid, static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid,
struct mv88e6xxx_vtu_stu_entry *entry) struct mv88e6xxx_vtu_stu_entry *entry)
{ {
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
struct mv88e6xxx_vtu_stu_entry vlan = { struct mv88e6xxx_vtu_stu_entry vlan = {
...@@ -1509,6 +1509,35 @@ static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid, ...@@ -1509,6 +1509,35 @@ static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid,
return 0; return 0;
} }
static int _mv88e6xxx_vtu_get(struct dsa_switch *ds, u16 vid,
struct mv88e6xxx_vtu_stu_entry *entry, bool creat)
{
int err;
if (!vid)
return -EINVAL;
err = _mv88e6xxx_vtu_vid_write(ds, vid - 1);
if (err)
return err;
err = _mv88e6xxx_vtu_getnext(ds, entry);
if (err)
return err;
if (entry->vid != vid || !entry->valid) {
if (!creat)
return -EOPNOTSUPP;
/* -ENOENT would've been more appropriate, but switchdev expects
* -EOPNOTSUPP to inform bridge about an eventual software VLAN.
*/
err = _mv88e6xxx_vtu_new(ds, vid, entry);
}
return err;
}
static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port, static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
u16 vid_begin, u16 vid_end) u16 vid_begin, u16 vid_end)
{ {
...@@ -1593,20 +1622,10 @@ static int _mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid, ...@@ -1593,20 +1622,10 @@ static int _mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid,
struct mv88e6xxx_vtu_stu_entry vlan; struct mv88e6xxx_vtu_stu_entry vlan;
int err; int err;
err = _mv88e6xxx_vtu_vid_write(ds, vid - 1); err = _mv88e6xxx_vtu_get(ds, vid, &vlan, true);
if (err)
return err;
err = _mv88e6xxx_vtu_getnext(ds, &vlan);
if (err) if (err)
return err; return err;
if (vlan.vid != vid || !vlan.valid) {
err = _mv88e6xxx_vlan_init(ds, vid, &vlan);
if (err)
return err;
}
vlan.data[port] = untagged ? vlan.data[port] = untagged ?
GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED : GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED :
GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED; GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED;
...@@ -1647,16 +1666,12 @@ static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid) ...@@ -1647,16 +1666,12 @@ static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
struct mv88e6xxx_vtu_stu_entry vlan; struct mv88e6xxx_vtu_stu_entry vlan;
int i, err; int i, err;
err = _mv88e6xxx_vtu_vid_write(ds, vid - 1); err = _mv88e6xxx_vtu_get(ds, vid, &vlan, false);
if (err)
return err;
err = _mv88e6xxx_vtu_getnext(ds, &vlan);
if (err) if (err)
return err; return err;
if (vlan.vid != vid || !vlan.valid || /* Tell switchdev if this VLAN is handled in software */
vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) if (vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
return -EOPNOTSUPP; return -EOPNOTSUPP;
vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER; vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment