Skip to content

Commit

Permalink
net: dsa: mv88e6xxx: split VTU entry data member
Browse files Browse the repository at this point in the history
VLAN aware Marvell chips can program 802.1Q VLAN membership as well as
802.1s per VLAN Spanning Tree state using the same 3 VTU Data registers.

Some chips such as 88E6185 use different Data registers offsets for
ports state and membership, and program them in a single operation.

Other chips such as 88E6352 use the same register layout but program
them in distinct operations (an indirect table is used for 802.1s.)

Newer chips such as 88E6390 use the same offsets for both state and
membership in distinct operations, thus require multiple data accesses.

To correctly abstract this, split the "data" structure member of
mv88e6xxx_vtu_entry in two "state" and "member" members, before adding
VTU support for newer chips.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Vivien Didelot authored and David S. Miller committed May 1, 2017
1 parent 3cf3c84 commit bd00e05
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 11 deletions.
21 changes: 11 additions & 10 deletions drivers/net/dsa/mv88e6xxx/chip.c
Original file line number Diff line number Diff line change
Expand Up @@ -1312,7 +1312,7 @@ static int _mv88e6xxx_vtu_stu_data_read(struct mv88e6xxx_chip *chip,
unsigned int shift = (i % 4) * 4 + nibble_offset;
u16 reg = regs[i / 4];

entry->data[i] = (reg >> shift) & GLOBAL_VTU_STU_DATA_MASK;
entry->state[i] = (reg >> shift) & GLOBAL_VTU_STU_DATA_MASK;
}

return 0;
Expand All @@ -1339,7 +1339,7 @@ static int _mv88e6xxx_vtu_stu_data_write(struct mv88e6xxx_chip *chip,

for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
unsigned int shift = (i % 4) * 4 + nibble_offset;
u8 data = entry->data[i];
u8 data = entry->state[i];

regs[i / 4] |= (data & GLOBAL_VTU_STU_DATA_MASK) << shift;
}
Expand Down Expand Up @@ -1461,15 +1461,15 @@ static int mv88e6xxx_port_vlan_dump(struct dsa_switch *ds, int port,
if (!next.valid)
break;

if (next.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
if (next.member[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
continue;

/* reinit and dump this VLAN obj */
vlan->vid_begin = next.vid;
vlan->vid_end = next.vid;
vlan->flags = 0;

if (next.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED)
if (next.member[port] == GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED)
vlan->flags |= BRIDGE_VLAN_INFO_UNTAGGED;

if (next.vid == pvid)
Expand Down Expand Up @@ -1669,7 +1669,8 @@ static int _mv88e6xxx_vtu_new(struct mv88e6xxx_chip *chip, u16 vid,

/* exclude all ports except the CPU and DSA ports */
for (i = 0; i < mv88e6xxx_num_ports(chip); ++i)
vlan.data[i] = dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i)
vlan.member[i] = dsa_is_cpu_port(ds, i) ||
dsa_is_dsa_port(ds, i)
? GLOBAL_VTU_DATA_MEMBER_TAG_UNMODIFIED
: GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;

Expand Down Expand Up @@ -1765,7 +1766,7 @@ static int mv88e6xxx_port_check_hw_vlan(struct dsa_switch *ds, int port,
if (!ds->ports[port].netdev)
continue;

if (vlan.data[i] ==
if (vlan.member[i] ==
GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
continue;

Expand Down Expand Up @@ -1844,7 +1845,7 @@ static int _mv88e6xxx_port_vlan_add(struct mv88e6xxx_chip *chip, int port,
if (err)
return err;

vlan.data[port] = untagged ?
vlan.member[port] = untagged ?
GLOBAL_VTU_DATA_MEMBER_TAG_UNTAGGED :
GLOBAL_VTU_DATA_MEMBER_TAG_TAGGED;

Expand Down Expand Up @@ -1890,18 +1891,18 @@ static int _mv88e6xxx_port_vlan_del(struct mv88e6xxx_chip *chip,
return err;

/* Tell switchdev if this VLAN is handled in software */
if (vlan.data[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
if (vlan.member[port] == GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER)
return -EOPNOTSUPP;

vlan.data[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;
vlan.member[port] = GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER;

/* keep the VLAN unless all ports are excluded */
vlan.valid = false;
for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) {
if (dsa_is_cpu_port(ds, i) || dsa_is_dsa_port(ds, i))
continue;

if (vlan.data[i] != GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
if (vlan.member[i] != GLOBAL_VTU_DATA_MEMBER_TAG_NON_MEMBER) {
vlan.valid = true;
break;
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,8 @@ struct mv88e6xxx_vtu_entry {
u16 fid;
u8 sid;
bool valid;
u8 data[DSA_MAX_PORTS];
u8 member[DSA_MAX_PORTS];
u8 state[DSA_MAX_PORTS];
};

struct mv88e6xxx_bus_ops;
Expand Down

0 comments on commit bd00e05

Please sign in to comment.