net: dsa: mv88e6xxx: Monitor and Management tables
authorAndrew Lunn <andrew@lunn.ch>
Sat, 3 Dec 2016 03:35:17 +0000 (04:35 +0100)
committerDavid S. Miller <davem@davemloft.net>
Sun, 4 Dec 2016 04:15:00 +0000 (23:15 -0500)
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>
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/global1.c
drivers/net/dsa/mv88e6xxx/global1.h
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h

index ff4bd2f7435796e803cbbc6f50cfcbcfd0e809b6..6e981bedd028590e51c706bf67a3541f242614b4 100644 (file)
@@ -2747,15 +2747,17 @@ static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
        if (err)
                return err;
 
-       /* Configure the upstream port, and configure it as the port to which
-        * ingress and egress and ARP monitor frames are to be sent.
-        */
-       reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
-               upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
-               upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
-       err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
-       if (err)
-               return err;
+       if (chip->info->ops->g1_set_cpu_port) {
+               err = chip->info->ops->g1_set_cpu_port(chip, upstream_port);
+               if (err)
+                       return err;
+       }
+
+       if (chip->info->ops->g1_set_egress_port) {
+               err = chip->info->ops->g1_set_egress_port(chip, upstream_port);
+               if (err)
+                       return err;
+       }
 
        /* Disable remote management, and set the switch's DSA device number. */
        err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL_2,
@@ -3184,6 +3186,8 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6095_ops = {
@@ -3213,6 +3217,8 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6123_ops = {
@@ -3227,6 +3233,8 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6131_ops = {
@@ -3242,6 +3250,8 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6161_ops = {
@@ -3257,6 +3267,8 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6165_ops = {
@@ -3271,6 +3283,8 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6171_ops = {
@@ -3287,6 +3301,8 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6172_ops = {
@@ -3305,6 +3321,8 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6175_ops = {
@@ -3321,6 +3339,8 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6176_ops = {
@@ -3339,6 +3359,8 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6185_ops = {
@@ -3353,6 +3375,8 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6190_ops = {
@@ -3370,6 +3394,8 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6390_stats_get_stats,
+       .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6390_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6190x_ops = {
@@ -3387,6 +3413,8 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6390_stats_get_stats,
+       .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6390_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6191_ops = {
@@ -3404,6 +3432,8 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6390_stats_get_stats,
+       .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6390_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6240_ops = {
@@ -3422,6 +3452,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6290_ops = {
@@ -3439,6 +3471,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6390_stats_get_stats,
+       .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6390_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6320_ops = {
@@ -3456,6 +3490,8 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6320_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6321_ops = {
@@ -3473,6 +3509,8 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6320_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6350_ops = {
@@ -3489,6 +3527,8 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6351_ops = {
@@ -3505,6 +3545,8 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6352_ops = {
@@ -3523,6 +3565,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
        .stats_get_sset_count = mv88e6095_stats_get_sset_count,
        .stats_get_strings = mv88e6095_stats_get_strings,
        .stats_get_stats = mv88e6095_stats_get_stats,
+       .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6095_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6390_ops = {
@@ -3540,6 +3584,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6390_stats_get_stats,
+       .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6390_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6390x_ops = {
@@ -3557,6 +3603,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6390_stats_get_stats,
+       .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6390_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_ops mv88e6391_ops = {
@@ -3574,6 +3622,8 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
        .stats_get_sset_count = mv88e6320_stats_get_sset_count,
        .stats_get_strings = mv88e6320_stats_get_strings,
        .stats_get_stats = mv88e6390_stats_get_stats,
+       .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+       .g1_set_egress_port = mv88e6390_g1_set_egress_port,
 };
 
 static const struct mv88e6xxx_info mv88e6xxx_table[] = {
index 5fcf23dbf04bdc3cff53a9197c53fd7355044a39..688547026e15fc3b34ec68c03cae9920e7a31f49 100644 (file)
@@ -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, &reg);
+       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, &reg);
+       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)
index df3794cdbfb9aed287e9dfb948fc28d36d16b7c4..0c979550052fd264d619c7254ac303cc4d39ba9a 100644 (file)
@@ -25,5 +25,9 @@ int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port);
 int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port);
 int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip);
 void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val);
+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_cpu_port(struct mv88e6xxx_chip *chip, int port);
+int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
 
 #endif /* _MV88E6XXX_GLOBAL1_H */
index a6e9dba665c1ccab4a102d4fa1597846e585035c..a6dd192652e8c7a591f1353535852ba8a65cabaa 100644 (file)
 #define GLOBAL_CORE_TAG_TYPE   0x19
 #define GLOBAL_MONITOR_CONTROL 0x1a
 #define GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT   12
+#define GLOBAL_MONITOR_CONTROL_INGRESS_MASK    (0xf << 12)
 #define GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT    8
+#define GLOBAL_MONITOR_CONTROL_EGRESS_MASK     (0xf << 8)
 #define GLOBAL_MONITOR_CONTROL_ARP_SHIFT       4
+#define GLOBAL_MONITOR_CONTROL_ARP_MASK                (0xf << 4)
 #define GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT    0
 #define GLOBAL_MONITOR_CONTROL_ARP_DISABLED    (0xf0)
+#define GLOBAL_MONITOR_CONTROL_UPDATE                  BIT(15)
+#define GLOBAL_MONITOR_CONTROL_0180C280000000XLO       (0x00 << 8)
+#define GLOBAL_MONITOR_CONTROL_0180C280000000XHI       (0x01 << 8)
+#define GLOBAL_MONITOR_CONTROL_0180C280000002XLO       (0x02 << 8)
+#define GLOBAL_MONITOR_CONTROL_0180C280000002XHI       (0x03 << 8)
+#define GLOBAL_MONITOR_CONTROL_INGRESS                 (0x20 << 8)
+#define GLOBAL_MONITOR_CONTROL_EGRESS                  (0x21 << 8)
+#define GLOBAL_MONITOR_CONTROL_CPU_DEST                        (0x30 << 8)
 #define GLOBAL_CONTROL_2       0x1c
 #define GLOBAL_CONTROL_2_NO_CASCADE            0xe000
 #define GLOBAL_CONTROL_2_MULTIPLE_CASCADE      0xf000
@@ -827,6 +838,8 @@ struct mv88e6xxx_ops {
        void (*stats_get_strings)(struct mv88e6xxx_chip *chip,  uint8_t *data);
        void (*stats_get_stats)(struct mv88e6xxx_chip *chip,  int port,
                                uint64_t *data);
+       int (*g1_set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
+       int (*g1_set_egress_port)(struct mv88e6xxx_chip *chip, int port);
 };
 
 #define STATS_TYPE_PORT                BIT(0)