[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <cacf47599957ac92edddfa372bac5ac9890e4e85.1704449760.git.ante.knezic@helmholz.de>
Date: Fri, 5 Jan 2024 11:46:19 +0100
From: Ante Knezic <ante.knezic@...mholz.de>
To: <netdev@...r.kernel.org>
CC: <andrew@...n.ch>, <f.fainelli@...il.com>, <olteanv@...il.com>,
<davem@...emloft.net>, <edumazet@...gle.com>, <kuba@...nel.org>,
<pabeni@...hat.com>, <ante.knezic@...mholz.de>
Subject: [RFC PATCH net-next 6/6] net: dsa: mv88e6xxx add cross-chip mirroring
modify mv88e6xxx port mirroring to support cross-chip mirroring.
Remove mirror_ingress and mirror_egress as they are no longer
needed.
Do not allow setting dsa ports as mirror source port as
recommended by the Switch Functional Specification.
Signed-off-by: Ante Knezic <ante.knezic@...mholz.de>
---
drivers/net/dsa/mv88e6xxx/chip.c | 77 +++++++++++++++++++++++++---------------
drivers/net/dsa/mv88e6xxx/chip.h | 2 --
drivers/net/dsa/mv88e6xxx/port.c | 5 ---
3 files changed, 48 insertions(+), 36 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index ce3a5d61edb4..fab92c3cb511 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3568,6 +3568,28 @@ static int mv88e6xxx_stats_setup(struct mv88e6xxx_chip *chip)
return mv88e6xxx_g1_stats_clear(chip);
}
+static int mv88e6xxx_mirror_setup(struct mv88e6xxx_chip *chip)
+{
+ int err, port, i;
+ const enum mv88e6xxx_egress_direction direction[] = {
+ MV88E6XXX_EGRESS_DIR_INGRESS, MV88E6XXX_EGRESS_DIR_EGRESS};
+
+ for (i = 0; i < ARRAY_SIZE(direction); i++) {
+ err = mv88e6xxx_set_egress_port(chip, i,
+ MV88E6XXX_EGRESS_DEST_DISABLE);
+ if (err)
+ return err;
+
+ for (port = 0; port < mv88e6xxx_num_ports(chip); port++) {
+ err = mv88e6xxx_port_set_mirror(chip, port, i, false);
+ if (err)
+ return err;
+ }
+ }
+
+ return 0;
+}
+
/* Check if the errata has already been applied. */
static bool mv88e6390_setup_errata_applied(struct mv88e6xxx_chip *chip)
{
@@ -3966,6 +3988,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
if (err)
goto unlock;
+ err = mv88e6xxx_mirror_setup(chip);
+ if (err)
+ goto unlock;
+
unlock:
mv88e6xxx_reg_unlock(chip);
@@ -6488,31 +6514,26 @@ static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int from_port,
MV88E6XXX_EGRESS_DIR_INGRESS :
MV88E6XXX_EGRESS_DIR_EGRESS;
struct mv88e6xxx_chip *chip = ds->priv;
- bool other_mirrors = false;
- int i;
+ int *dest_port;
int err;
mutex_lock(&chip->reg_lock);
- if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) !=
- to_port) {
- for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
- other_mirrors |= ingress ?
- chip->ports[i].mirror_ingress :
- chip->ports[i].mirror_egress;
-
- /* Can't change egress port when other mirror is active */
- if (other_mirrors) {
- err = -EBUSY;
- goto out;
- }
+ dest_port = ingress ? &chip->ingress_dest_port : &chip->egress_dest_port;
- err = mv88e6xxx_set_egress_port(chip, direction,
- to_port);
- if (err)
- goto out;
+ /* Can't change egress port when mirroring is active */
+ if (*dest_port != MV88E6XXX_EGRESS_DEST_DISABLE &&
+ *dest_port != to_port) {
+ err = -EBUSY;
+ goto out;
}
- err = mv88e6xxx_port_set_mirror(chip, from_port, direction, true);
+ err = mv88e6xxx_set_egress_port(chip, direction, to_port);
+ if (err)
+ goto out;
+
+ if (dsa_port_is_user(dsa_to_port(ds, from_port)))
+ err = mv88e6xxx_port_set_mirror(chip, from_port, direction, true);
+
out:
mutex_unlock(&chip->reg_lock);
@@ -6527,20 +6548,18 @@ static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int from_port,
MV88E6XXX_EGRESS_DIR_INGRESS :
MV88E6XXX_EGRESS_DIR_EGRESS;
struct mv88e6xxx_chip *chip = ds->priv;
- bool other_mirrors = false;
- int i;
+ int *dest_port;
mutex_lock(&chip->reg_lock);
- if (mv88e6xxx_port_set_mirror(chip, from_port, direction, false))
- dev_err(ds->dev, "p%d: failed to disable mirroring\n", from_port);
+ dest_port = ingress ? &chip->ingress_dest_port : &chip->egress_dest_port;
- for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
- other_mirrors |= ingress ?
- chip->ports[i].mirror_ingress :
- chip->ports[i].mirror_egress;
+ if (!(route_status & DSA_ROUTE_SRC_PORT_BUSY)) {
+ if (mv88e6xxx_port_set_mirror(chip, from_port, direction, false))
+ dev_err(ds->dev, "p%d: failed to disable mirroring\n", from_port);
+ }
- /* Reset egress port when no other mirror is active */
- if (!other_mirrors) {
+ if (!(route_status & DSA_ROUTE_DEST_PORT_BUSY) &&
+ *dest_port == to_port) {
if (mv88e6xxx_set_egress_port(chip, direction,
MV88E6XXX_EGRESS_DEST_DISABLE))
dev_err(ds->dev, "failed to set egress port\n");
diff --git a/drivers/net/dsa/mv88e6xxx/chip.h b/drivers/net/dsa/mv88e6xxx/chip.h
index a73da4e965ec..0000a7aa3fbc 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.h
+++ b/drivers/net/dsa/mv88e6xxx/chip.h
@@ -284,8 +284,6 @@ struct mv88e6xxx_port {
u64 vtu_miss_violation;
phy_interface_t interface;
u8 cmode;
- bool mirror_ingress;
- bool mirror_egress;
struct devlink_region *region;
void *pcs_private;
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 5394a8cf7bf1..777515ee722b 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -1183,7 +1183,6 @@ int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
enum mv88e6xxx_egress_direction direction,
bool mirror)
{
- bool *mirror_port;
u16 reg;
u16 bit;
int err;
@@ -1195,11 +1194,9 @@ int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
switch (direction) {
case MV88E6XXX_EGRESS_DIR_INGRESS:
bit = MV88E6XXX_PORT_CTL2_INGRESS_MONITOR;
- mirror_port = &chip->ports[port].mirror_ingress;
break;
case MV88E6XXX_EGRESS_DIR_EGRESS:
bit = MV88E6XXX_PORT_CTL2_EGRESS_MONITOR;
- mirror_port = &chip->ports[port].mirror_egress;
break;
default:
return -EINVAL;
@@ -1210,8 +1207,6 @@ int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
reg |= bit;
err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
- if (!err)
- *mirror_port = mirror;
return err;
}
--
2.11.0
Powered by blists - more mailing lists