150 lines
5.2 KiB
Diff
150 lines
5.2 KiB
Diff
From 5c74c54ce6fff719999ff48f128cf4150ee4ff59 Mon Sep 17 00:00:00 2001
|
|
From: Iwan R Timmer <irtimmer@gmail.com>
|
|
Date: Thu, 7 Nov 2019 22:11:13 +0100
|
|
Subject: [PATCH] net: dsa: mv88e6xxx: Split monitor port configuration
|
|
|
|
Separate the configuration of the egress and ingress monitor port.
|
|
This allows the port mirror functionality to do ingress and egress
|
|
port mirroring to separate ports.
|
|
|
|
Signed-off-by: Iwan R Timmer <irtimmer@gmail.com>
|
|
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
|
|
Signed-off-by: David S. Miller <davem@davemloft.net>
|
|
---
|
|
drivers/net/dsa/mv88e6xxx/chip.c | 9 ++++++-
|
|
drivers/net/dsa/mv88e6xxx/chip.h | 9 ++++++-
|
|
drivers/net/dsa/mv88e6xxx/global1.c | 42 ++++++++++++++++++++---------
|
|
drivers/net/dsa/mv88e6xxx/global1.h | 8 ++++--
|
|
4 files changed, 52 insertions(+), 16 deletions(-)
|
|
|
|
--- a/drivers/net/dsa/mv88e6xxx/chip.c
|
|
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
|
|
@@ -2380,7 +2380,14 @@ static int mv88e6xxx_setup_upstream_port
|
|
|
|
if (chip->info->ops->set_egress_port) {
|
|
err = chip->info->ops->set_egress_port(chip,
|
|
- upstream_port);
|
|
+ MV88E6XXX_EGRESS_DIR_INGRESS,
|
|
+ upstream_port);
|
|
+ if (err)
|
|
+ return err;
|
|
+
|
|
+ err = chip->info->ops->set_egress_port(chip,
|
|
+ MV88E6XXX_EGRESS_DIR_EGRESS,
|
|
+ upstream_port);
|
|
if (err)
|
|
return err;
|
|
}
|
|
--- a/drivers/net/dsa/mv88e6xxx/chip.h
|
|
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
|
|
@@ -33,6 +33,11 @@ enum mv88e6xxx_egress_mode {
|
|
MV88E6XXX_EGRESS_MODE_ETHERTYPE,
|
|
};
|
|
|
|
+enum mv88e6xxx_egress_direction {
|
|
+ MV88E6XXX_EGRESS_DIR_INGRESS,
|
|
+ MV88E6XXX_EGRESS_DIR_EGRESS,
|
|
+};
|
|
+
|
|
enum mv88e6xxx_frame_mode {
|
|
MV88E6XXX_FRAME_MODE_NORMAL,
|
|
MV88E6XXX_FRAME_MODE_DSA,
|
|
@@ -464,7 +469,9 @@ struct mv88e6xxx_ops {
|
|
int (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port,
|
|
uint64_t *data);
|
|
int (*set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
|
|
- int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port);
|
|
+ int (*set_egress_port)(struct mv88e6xxx_chip *chip,
|
|
+ enum mv88e6xxx_egress_direction direction,
|
|
+ int port);
|
|
|
|
#define MV88E6XXX_CASCADE_PORT_NONE 0xe
|
|
#define MV88E6XXX_CASCADE_PORT_MULTIPLE 0xf
|
|
--- a/drivers/net/dsa/mv88e6xxx/global1.c
|
|
+++ b/drivers/net/dsa/mv88e6xxx/global1.c
|
|
@@ -294,7 +294,9 @@ int mv88e6250_g1_ieee_pri_map(struct mv8
|
|
/* Offset 0x1a: Monitor Control */
|
|
/* Offset 0x1a: Monitor & MGMT Control on some devices */
|
|
|
|
-int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port)
|
|
+int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip,
|
|
+ enum mv88e6xxx_egress_direction direction,
|
|
+ int port)
|
|
{
|
|
u16 reg;
|
|
int err;
|
|
@@ -303,11 +305,20 @@ int mv88e6095_g1_set_egress_port(struct
|
|
if (err)
|
|
return err;
|
|
|
|
- reg &= ~(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK |
|
|
- MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK);
|
|
-
|
|
- reg |= port << __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK) |
|
|
- port << __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK);
|
|
+ switch (direction) {
|
|
+ case MV88E6XXX_EGRESS_DIR_INGRESS:
|
|
+ reg &= MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK;
|
|
+ reg |= port <<
|
|
+ __bf_shf(MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK);
|
|
+ break;
|
|
+ case MV88E6XXX_EGRESS_DIR_EGRESS:
|
|
+ reg &= MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK;
|
|
+ reg |= port <<
|
|
+ __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK);
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
|
|
return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg);
|
|
}
|
|
@@ -341,17 +352,24 @@ static int mv88e6390_g1_monitor_write(st
|
|
return mv88e6xxx_g1_write(chip, MV88E6390_G1_MONITOR_MGMT_CTL, reg);
|
|
}
|
|
|
|
-int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port)
|
|
+int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip,
|
|
+ enum mv88e6xxx_egress_direction direction,
|
|
+ int port)
|
|
{
|
|
u16 ptr;
|
|
int err;
|
|
|
|
- ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST;
|
|
- err = mv88e6390_g1_monitor_write(chip, ptr, port);
|
|
- if (err)
|
|
- return err;
|
|
+ switch (direction) {
|
|
+ case MV88E6XXX_EGRESS_DIR_INGRESS:
|
|
+ ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST;
|
|
+ break;
|
|
+ case MV88E6XXX_EGRESS_DIR_EGRESS:
|
|
+ ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST;
|
|
+ break;
|
|
+ default:
|
|
+ return -EINVAL;
|
|
+ }
|
|
|
|
- ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST;
|
|
err = mv88e6390_g1_monitor_write(chip, ptr, port);
|
|
if (err)
|
|
return err;
|
|
--- a/drivers/net/dsa/mv88e6xxx/global1.h
|
|
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
|
|
@@ -289,8 +289,12 @@ int mv88e6095_g1_stats_set_histogram(str
|
|
int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip);
|
|
void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val);
|
|
int mv88e6xxx_g1_stats_clear(struct mv88e6xxx_chip *chip);
|
|
-int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port);
|
|
-int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port);
|
|
+int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip,
|
|
+ enum mv88e6xxx_egress_direction direction,
|
|
+ int port);
|
|
+int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip,
|
|
+ enum mv88e6xxx_egress_direction direction,
|
|
+ int port);
|
|
int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
|
|
int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
|
|
int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
|