diff options
author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2017-05-01 21:05:18 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-05-01 22:03:11 +0300 |
commit | c499a64f349d063d8cdb40c0b96e84c35bbc414c (patch) | |
tree | 85ba5c1565f2f8cc8537705c8195b52acf537066 /drivers/net/dsa/mv88e6xxx/global1_vtu.c | |
parent | f169e5ee5f29f81c1c8d647fa6fb5387ee793131 (diff) | |
download | linux-c499a64f349d063d8cdb40c0b96e84c35bbc414c.tar.xz |
net: dsa: mv88e6xxx: move VTU Data accessors
The code to access the VTU Data registers currently only supports the
88E6185 family and alike: 2-bit membership adjacent to 2-bit port state.
Even though the 88E6352 family introduced an indirect table to program
the VLAN Spanning Tree states, the usage of the VTU Data registers
remains the same regardless the VTU or STU operation.
Now that the mv88e6xxx_vtu_entry structure contains both port membership
and states data, factorize the code to access them in global1_vtu.c.
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>
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/global1_vtu.c')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global1_vtu.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/global1_vtu.c b/drivers/net/dsa/mv88e6xxx/global1_vtu.c index c3f55be873b3..060c4a5a802d 100644 --- a/drivers/net/dsa/mv88e6xxx/global1_vtu.c +++ b/drivers/net/dsa/mv88e6xxx/global1_vtu.c @@ -111,6 +111,67 @@ int mv88e6xxx_g1_vtu_vid_write(struct mv88e6xxx_chip *chip, return mv88e6xxx_g1_write(chip, GLOBAL_VTU_VID, val); } +/* Offset 0x07: VTU/STU Data Register 1 + * Offset 0x08: VTU/STU Data Register 2 + * Offset 0x09: VTU/STU Data Register 3 + */ + +int mv88e6185_g1_vtu_data_read(struct mv88e6xxx_chip *chip, + struct mv88e6xxx_vtu_entry *entry) +{ + u16 regs[3]; + int i; + + /* Read all 3 VTU/STU Data registers */ + for (i = 0; i < 3; ++i) { + u16 *reg = ®s[i]; + int err; + + err = mv88e6xxx_g1_read(chip, GLOBAL_VTU_DATA_0_3 + i, reg); + if (err) + return err; + } + + /* Extract MemberTag and PortState data */ + for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { + unsigned int member_offset = (i % 4) * 4; + unsigned int state_offset = member_offset + 2; + + entry->member[i] = (regs[i / 4] >> member_offset) & 0x3; + entry->state[i] = (regs[i / 4] >> state_offset) & 0x3; + } + + return 0; +} + +int mv88e6185_g1_vtu_data_write(struct mv88e6xxx_chip *chip, + struct mv88e6xxx_vtu_entry *entry) +{ + u16 regs[3] = { 0 }; + int i; + + /* Insert MemberTag and PortState data */ + for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { + unsigned int member_offset = (i % 4) * 4; + unsigned int state_offset = member_offset + 2; + + regs[i / 4] |= (entry->member[i] & 0x3) << member_offset; + regs[i / 4] |= (entry->state[i] & 0x3) << state_offset; + } + + /* Write all 3 VTU/STU Data registers */ + for (i = 0; i < 3; ++i) { + u16 reg = regs[i]; + int err; + + err = mv88e6xxx_g1_write(chip, GLOBAL_VTU_DATA_0_3 + i, reg); + if (err) + return err; + } + + return 0; +} + /* VLAN Translation Unit Operations */ int mv88e6xxx_g1_vtu_getnext(struct mv88e6xxx_chip *chip, |