diff options
author | Andrew Lunn <andrew@lunn.ch> | 2016-12-03 06:35:17 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-12-04 07:15:00 +0300 |
commit | 33641994a676f43f59d5fe02916c3965983522c2 (patch) | |
tree | e01b3722a1365c33db444f8e3a91e87238e8fa5f /drivers/net/dsa/mv88e6xxx/global1.c | |
parent | ef0a731882a2bf120511072a08d973f65d00d979 (diff) | |
download | linux-33641994a676f43f59d5fe02916c3965983522c2.tar.xz |
net: dsa: mv88e6xxx: Monitor and Management tables
The mv88e6390 changes the monitor control register into the Monitor
and Management control, which is an indirection register to various
registers.
Add ops to set the CPU port and the ingress/egress port for both
register layouts, to global1
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa/mv88e6xxx/global1.c')
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/global1.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c index 5fcf23dbf04b..688547026e15 100644 --- a/drivers/net/dsa/mv88e6xxx/global1.c +++ b/drivers/net/dsa/mv88e6xxx/global1.c @@ -33,6 +33,75 @@ int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask) return mv88e6xxx_wait(chip, chip->info->global1_addr, reg, mask); } +/* Offset 0x1a: Monitor Control */ +/* Offset 0x1a: Monitor & MGMT Control on some devices */ + +int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port) +{ + u16 reg; + int err; + + err = mv88e6xxx_g1_read(chip, GLOBAL_MONITOR_CONTROL, ®); + if (err) + return err; + + reg &= ~(GLOBAL_MONITOR_CONTROL_INGRESS_MASK | + GLOBAL_MONITOR_CONTROL_EGRESS_MASK); + + reg |= port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT | + port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT; + + return mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg); +} + +/* Older generations also call this the ARP destination. It has been + * generalized in more modern devices such that more than ARP can + * egress it + */ +int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port) +{ + u16 reg; + int err; + + err = mv88e6xxx_g1_read(chip, GLOBAL_MONITOR_CONTROL, ®); + if (err) + return err; + + reg &= ~GLOBAL_MONITOR_CONTROL_ARP_MASK; + reg |= port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT; + + return mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg); +} + +static int mv88e6390_g1_monitor_write(struct mv88e6xxx_chip *chip, + u16 pointer, u8 data) +{ + u16 reg; + + reg = GLOBAL_MONITOR_CONTROL_UPDATE | pointer | data; + + return mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg); +} + +int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port) +{ + int err; + + err = mv88e6390_g1_monitor_write(chip, GLOBAL_MONITOR_CONTROL_INGRESS, + port); + if (err) + return err; + + return mv88e6390_g1_monitor_write(chip, GLOBAL_MONITOR_CONTROL_EGRESS, + port); +} + +int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port) +{ + return mv88e6390_g1_monitor_write(chip, GLOBAL_MONITOR_CONTROL_CPU_DEST, + port); +} + /* Offset 0x1c: Global Control 2 */ int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip) |