generic: backport mv88e6xxx port mirroring support
authorDENG Qingfang <dengqf6@mail2.sysu.edu.cn>
Sun, 19 Apr 2020 08:04:06 +0000 (16:04 +0800)
committerAdrian Schmutzler <freifunk@adrianschmutzler.de>
Wed, 3 Jun 2020 18:34:15 +0000 (20:34 +0200)
Backport port mirroring support for mv88e6xxx

Signed-off-by: DENG Qingfang <dengqf6@mail2.sysu.edu.cn>
target/linux/generic/backport-5.4/746-v5.5-net-dsa-mv88e6xxx-Split-monitor-port-configuration.patch [new file with mode: 0644]
target/linux/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch [new file with mode: 0644]
target/linux/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch [new file with mode: 0644]
target/linux/generic/backport-5.4/749-v5.5-net-dsa-mv88e6xxx-Fix-masking-of-egress-port.patch [new file with mode: 0644]

diff --git a/target/linux/generic/backport-5.4/746-v5.5-net-dsa-mv88e6xxx-Split-monitor-port-configuration.patch b/target/linux/generic/backport-5.4/746-v5.5-net-dsa-mv88e6xxx-Split-monitor-port-configuration.patch
new file mode 100644 (file)
index 0000000..73dbcbe
--- /dev/null
@@ -0,0 +1,149 @@
+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
+@@ -2378,7 +2378,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
+@@ -263,7 +263,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;
+@@ -272,11 +274,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);
+ }
+@@ -310,17 +321,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
+@@ -288,8 +288,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);
diff --git a/target/linux/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch b/target/linux/generic/backport-5.4/747-v5.5-net-dsa-mv88e6xxx-Add-support-for-port-mirroring.patch
new file mode 100644 (file)
index 0000000..23c9bdd
--- /dev/null
@@ -0,0 +1,266 @@
+From f0942e00a1abb6404ca4302c66497fc623676c11 Mon Sep 17 00:00:00 2001
+From: Iwan R Timmer <irtimmer@gmail.com>
+Date: Thu, 7 Nov 2019 22:11:14 +0100
+Subject: [PATCH] net: dsa: mv88e6xxx: Add support for port mirroring
+
+Add support for configuring port mirroring through the cls_matchall
+classifier. We do a full ingress and/or egress capture towards a
+capture port. It allows setting a different capture port for ingress
+and egress traffic.
+
+It keeps track of the mirrored ports and the destination ports to
+prevent changes to the capture port while other ports are being
+mirrored.
+
+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    | 76 +++++++++++++++++++++++++++++
+ drivers/net/dsa/mv88e6xxx/chip.h    |  6 +++
+ drivers/net/dsa/mv88e6xxx/global1.c | 18 +++++--
+ drivers/net/dsa/mv88e6xxx/port.c    | 37 ++++++++++++++
+ drivers/net/dsa/mv88e6xxx/port.h    |  3 ++
+ 5 files changed, 136 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -4921,6 +4921,80 @@ static int mv88e6xxx_port_mdb_del(struct
+       return err;
+ }
++static int mv88e6xxx_port_mirror_add(struct dsa_switch *ds, int port,
++                                   struct dsa_mall_mirror_tc_entry *mirror,
++                                   bool ingress)
++{
++      enum mv88e6xxx_egress_direction direction = ingress ?
++                                              MV88E6XXX_EGRESS_DIR_INGRESS :
++                                              MV88E6XXX_EGRESS_DIR_EGRESS;
++      struct mv88e6xxx_chip *chip = ds->priv;
++      bool other_mirrors = false;
++      int i;
++      int err;
++
++      if (!chip->info->ops->set_egress_port)
++              return -EOPNOTSUPP;
++
++      mutex_lock(&chip->reg_lock);
++      if ((ingress ? chip->ingress_dest_port : chip->egress_dest_port) !=
++          mirror->to_local_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;
++              }
++
++              err = chip->info->ops->set_egress_port(chip,
++                                                     direction,
++                                                     mirror->to_local_port);
++              if (err)
++                      goto out;
++      }
++
++      err = mv88e6xxx_port_set_mirror(chip, port, direction, true);
++out:
++      mutex_unlock(&chip->reg_lock);
++
++      return err;
++}
++
++static void mv88e6xxx_port_mirror_del(struct dsa_switch *ds, int port,
++                                    struct dsa_mall_mirror_tc_entry *mirror)
++{
++      enum mv88e6xxx_egress_direction direction = mirror->ingress ?
++                                              MV88E6XXX_EGRESS_DIR_INGRESS :
++                                              MV88E6XXX_EGRESS_DIR_EGRESS;
++      struct mv88e6xxx_chip *chip = ds->priv;
++      bool other_mirrors = false;
++      int i;
++
++      mutex_lock(&chip->reg_lock);
++      if (mv88e6xxx_port_set_mirror(chip, port, direction, false))
++              dev_err(ds->dev, "p%d: failed to disable mirroring\n", port);
++
++      for (i = 0; i < mv88e6xxx_num_ports(chip); i++)
++              other_mirrors |= mirror->ingress ?
++                               chip->ports[i].mirror_ingress :
++                               chip->ports[i].mirror_egress;
++
++      /* Reset egress port when no other mirror is active */
++      if (!other_mirrors) {
++              if (chip->info->ops->set_egress_port(chip,
++                                                   direction,
++                                                   dsa_upstream_port(ds,
++                                                                     port)));
++                      dev_err(ds->dev, "failed to set egress port\n");
++      }
++
++      mutex_unlock(&chip->reg_lock);
++}
++
+ static int mv88e6xxx_port_egress_floods(struct dsa_switch *ds, int port,
+                                        bool unicast, bool multicast)
+ {
+@@ -4975,6 +5049,8 @@ static const struct dsa_switch_ops mv88e
+       .port_mdb_prepare       = mv88e6xxx_port_mdb_prepare,
+       .port_mdb_add           = mv88e6xxx_port_mdb_add,
+       .port_mdb_del           = mv88e6xxx_port_mdb_del,
++      .port_mirror_add        = mv88e6xxx_port_mirror_add,
++      .port_mirror_del        = mv88e6xxx_port_mirror_del,
+       .crosschip_bridge_join  = mv88e6xxx_crosschip_bridge_join,
+       .crosschip_bridge_leave = mv88e6xxx_crosschip_bridge_leave,
+       .port_hwtstamp_set      = mv88e6xxx_port_hwtstamp_set,
+--- a/drivers/net/dsa/mv88e6xxx/chip.h
++++ b/drivers/net/dsa/mv88e6xxx/chip.h
+@@ -232,6 +232,8 @@ struct mv88e6xxx_port {
+       u64 vtu_member_violation;
+       u64 vtu_miss_violation;
+       u8 cmode;
++      bool mirror_ingress;
++      bool mirror_egress;
+       unsigned int serdes_irq;
+ };
+@@ -315,6 +317,10 @@ struct mv88e6xxx_chip {
+       u16 evcap_config;
+       u16 enable_count;
++      /* Current ingress and egress monitor ports */
++      int egress_dest_port;
++      int ingress_dest_port;
++
+       /* Per-port timestamping resources. */
+       struct mv88e6xxx_port_hwtstamp port_hwtstamp[DSA_MAX_PORTS];
+--- a/drivers/net/dsa/mv88e6xxx/global1.c
++++ b/drivers/net/dsa/mv88e6xxx/global1.c
+@@ -267,6 +267,7 @@ int mv88e6095_g1_set_egress_port(struct
+                                enum mv88e6xxx_egress_direction direction,
+                                int port)
+ {
++      int *dest_port_chip;
+       u16 reg;
+       int err;
+@@ -276,11 +277,13 @@ int mv88e6095_g1_set_egress_port(struct
+       switch (direction) {
+       case MV88E6XXX_EGRESS_DIR_INGRESS:
++              dest_port_chip = &chip->ingress_dest_port;
+               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:
++              dest_port_chip = &chip->egress_dest_port;
+               reg &= MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK;
+               reg |= port <<
+                      __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK);
+@@ -289,7 +292,11 @@ int mv88e6095_g1_set_egress_port(struct
+               return -EINVAL;
+       }
+-      return mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg);
++      err = mv88e6xxx_g1_write(chip, MV88E6185_G1_MONITOR_CTL, reg);
++      if (!err)
++              *dest_port_chip = port;
++
++      return err;
+ }
+ /* Older generations also call this the ARP destination. It has been
+@@ -325,14 +332,17 @@ int mv88e6390_g1_set_egress_port(struct
+                                enum mv88e6xxx_egress_direction direction,
+                                int port)
+ {
++      int *dest_port_chip;
+       u16 ptr;
+       int err;
+       switch (direction) {
+       case MV88E6XXX_EGRESS_DIR_INGRESS:
++              dest_port_chip = &chip->ingress_dest_port;
+               ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_INGRESS_DEST;
+               break;
+       case MV88E6XXX_EGRESS_DIR_EGRESS:
++              dest_port_chip = &chip->egress_dest_port;
+               ptr = MV88E6390_G1_MONITOR_MGMT_CTL_PTR_EGRESS_DEST;
+               break;
+       default:
+@@ -340,10 +350,10 @@ int mv88e6390_g1_set_egress_port(struct
+       }
+       err = mv88e6390_g1_monitor_write(chip, ptr, port);
+-      if (err)
+-              return err;
++      if (!err)
++              *dest_port_chip = port;
+-      return 0;
++      return err;
+ }
+ int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port)
+--- a/drivers/net/dsa/mv88e6xxx/port.c
++++ b/drivers/net/dsa/mv88e6xxx/port.c
+@@ -1181,6 +1181,43 @@ int mv88e6095_port_set_upstream_port(str
+       return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
+ }
++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;
++
++      err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_CTL2, &reg);
++      if (err)
++              return err;
++
++      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;
++      }
++
++      reg &= ~bit;
++      if (mirror)
++              reg |= bit;
++
++      err = mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_CTL2, reg);
++      if (!err)
++              *mirror_port = mirror;
++
++      return err;
++}
++
+ int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
+                                 u16 mode)
+ {
+--- a/drivers/net/dsa/mv88e6xxx/port.h
++++ b/drivers/net/dsa/mv88e6xxx/port.h
+@@ -368,6 +368,9 @@ int mv88e6352_port_link_state(struct mv8
+ int mv88e6xxx_port_set_map_da(struct mv88e6xxx_chip *chip, int port);
+ int mv88e6095_port_set_upstream_port(struct mv88e6xxx_chip *chip, int port,
+                                    int upstream_port);
++int mv88e6xxx_port_set_mirror(struct mv88e6xxx_chip *chip, int port,
++                            enum mv88e6xxx_egress_direction direction,
++                            bool mirror);
+ int mv88e6xxx_port_disable_learn_limit(struct mv88e6xxx_chip *chip, int port);
+ int mv88e6xxx_port_disable_pri_override(struct mv88e6xxx_chip *chip, int port);
diff --git a/target/linux/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch b/target/linux/generic/backport-5.4/748-v5.5-net-dsa-mv88e6xxx-fix-broken-if-statement-because-of.patch
new file mode 100644 (file)
index 0000000..d9d5a5f
--- /dev/null
@@ -0,0 +1,30 @@
+From 4e4637b10374ede3cd33d7e1b389e6cea6343ea3 Mon Sep 17 00:00:00 2001
+From: Colin Ian King <colin.king@canonical.com>
+Date: Tue, 12 Nov 2019 13:05:23 +0000
+Subject: [PATCH] net: dsa: mv88e6xxx: fix broken if statement because of a
+ stray semicolon
+
+There is a stray semicolon in an if statement that will cause a dev_err
+message to be printed unconditionally. Fix this by removing the stray
+semicolon.
+
+Addresses-Coverity: ("Stay semicolon")
+Fixes: f0942e00a1ab ("net: dsa: mv88e6xxx: Add support for port mirroring")
+Signed-off-by: Colin Ian King <colin.king@canonical.com>
+Reviewed-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/mv88e6xxx/chip.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -4988,7 +4988,7 @@ static void mv88e6xxx_port_mirror_del(st
+               if (chip->info->ops->set_egress_port(chip,
+                                                    direction,
+                                                    dsa_upstream_port(ds,
+-                                                                     port)));
++                                                                     port)))
+                       dev_err(ds->dev, "failed to set egress port\n");
+       }
diff --git a/target/linux/generic/backport-5.4/749-v5.5-net-dsa-mv88e6xxx-Fix-masking-of-egress-port.patch b/target/linux/generic/backport-5.4/749-v5.5-net-dsa-mv88e6xxx-Fix-masking-of-egress-port.patch
new file mode 100644 (file)
index 0000000..50f655c
--- /dev/null
@@ -0,0 +1,34 @@
+From 3ee339eb28959629db33aaa2b8cde4c63c6289eb Mon Sep 17 00:00:00 2001
+From: Andrew Lunn <andrew@lunn.ch>
+Date: Thu, 27 Feb 2020 21:20:49 +0100
+Subject: [PATCH] net: dsa: mv88e6xxx: Fix masking of egress port
+
+Add missing ~ to the usage of the mask.
+
+Reported-by: Kevin Benson <Kevin.Benson@zii.aero>
+Reported-by: Chris Healy <Chris.Healy@zii.aero>
+Fixes: 5c74c54ce6ff ("net: dsa: mv88e6xxx: Split monitor port configuration")
+Signed-off-by: Andrew Lunn <andrew@lunn.ch>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/dsa/mv88e6xxx/global1.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/dsa/mv88e6xxx/global1.c
++++ b/drivers/net/dsa/mv88e6xxx/global1.c
+@@ -278,13 +278,13 @@ int mv88e6095_g1_set_egress_port(struct
+       switch (direction) {
+       case MV88E6XXX_EGRESS_DIR_INGRESS:
+               dest_port_chip = &chip->ingress_dest_port;
+-              reg &= MV88E6185_G1_MONITOR_CTL_INGRESS_DEST_MASK;
++              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:
+               dest_port_chip = &chip->egress_dest_port;
+-              reg &= MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK;
++              reg &= ~MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK;
+               reg |= port <<
+                      __bf_shf(MV88E6185_G1_MONITOR_CTL_EGRESS_DEST_MASK);
+               break;