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: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
fb2dabad69
Коммит
2fb5ef09de
|
@ -1458,8 +1458,8 @@ loadpurge:
|
|||
return _mv88e6xxx_vtu_cmd(ds, GLOBAL_VTU_OP_STU_LOAD_PURGE);
|
||||
}
|
||||
|
||||
static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid,
|
||||
struct mv88e6xxx_vtu_stu_entry *entry)
|
||||
static int _mv88e6xxx_vtu_new(struct dsa_switch *ds, u16 vid,
|
||||
struct mv88e6xxx_vtu_stu_entry *entry)
|
||||
{
|
||||
struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
|
||||
struct mv88e6xxx_vtu_stu_entry vlan = {
|
||||
|
@ -1509,6 +1509,35 @@ static int _mv88e6xxx_vlan_init(struct dsa_switch *ds, u16 vid,
|
|||
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,
|
||||
u16 vid_begin, u16 vid_end)
|
||||
{
|
||||
|
@ -1593,20 +1622,10 @@ static int _mv88e6xxx_port_vlan_add(struct dsa_switch *ds, int port, u16 vid,
|
|||
struct mv88e6xxx_vtu_stu_entry vlan;
|
||||
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)
|
||||
return err;
|
||||
|
||||
if (vlan.vid != vid || !vlan.valid) {
|
||||
err = _mv88e6xxx_vlan_init(ds, vid, &vlan);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
vlan.data[port] = untagged ?
|
||||
GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED :
|
||||
GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED;
|
||||
|
@ -1647,16 +1666,12 @@ static int _mv88e6xxx_port_vlan_del(struct dsa_switch *ds, int port, u16 vid)
|
|||
struct mv88e6xxx_vtu_stu_entry vlan;
|
||||
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)
|
||||
return err;
|
||||
|
||||
if (vlan.vid != vid || !vlan.valid ||
|
||||
vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
|
||||
/* Tell switchdev if this VLAN is handled in software */
|
||||
if (vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
|
||||
|
|
Загрузка…
Ссылка в новой задаче