net: dsa: mv88e6xxx: introduce .port_set_policy
authorVivien Didelot <vivien.didelot@gmail.com>
Sat, 7 Sep 2019 20:00:48 +0000 (16:00 -0400)
committerDavid S. Miller <davem@davemloft.net>
Tue, 10 Sep 2019 15:53:31 +0000 (16:53 +0100)
Introduce a new .port_set_policy operation to configure a port's
Policy Control List, based on mapping such as DA, SA, Etype and so on.

Models similar to 88E6352 and 88E6390 are supported at the moment.

Signed-off-by: Vivien Didelot <vivien.didelot@gmail.com>
Reviewed-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/chip.h
drivers/net/dsa/mv88e6xxx/port.c
drivers/net/dsa/mv88e6xxx/port.h

index 0d54a69..6f4d530 100644 (file)
@@ -3132,6 +3132,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
        .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
        .port_set_speed = mv88e6352_port_set_speed,
        .port_tag_remap = mv88e6095_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
        .port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3218,6 +3219,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
        .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
        .port_set_speed = mv88e6352_port_set_speed,
        .port_tag_remap = mv88e6095_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
        .port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3303,6 +3305,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
        .port_set_speed = mv88e6390_port_set_speed,
        .port_max_speed_mode = mv88e6390_port_max_speed_mode,
        .port_tag_remap = mv88e6390_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
        .port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3351,6 +3354,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
        .port_set_speed = mv88e6390x_port_set_speed,
        .port_max_speed_mode = mv88e6390x_port_max_speed_mode,
        .port_tag_remap = mv88e6390_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
        .port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3448,6 +3452,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
        .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
        .port_set_speed = mv88e6352_port_set_speed,
        .port_tag_remap = mv88e6095_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
        .port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3539,6 +3544,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
        .port_set_speed = mv88e6390_port_set_speed,
        .port_max_speed_mode = mv88e6390_port_max_speed_mode,
        .port_tag_remap = mv88e6390_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
        .port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3809,6 +3815,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
        .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
        .port_set_speed = mv88e6352_port_set_speed,
        .port_tag_remap = mv88e6095_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
        .port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3863,6 +3870,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
        .port_set_speed = mv88e6390_port_set_speed,
        .port_max_speed_mode = mv88e6390_port_max_speed_mode,
        .port_tag_remap = mv88e6390_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
        .port_set_ether_type = mv88e6351_port_set_ether_type,
@@ -3915,6 +3923,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
        .port_set_speed = mv88e6390x_port_set_speed,
        .port_max_speed_mode = mv88e6390x_port_max_speed_mode,
        .port_tag_remap = mv88e6390_port_tag_remap,
+       .port_set_policy = mv88e6352_port_set_policy,
        .port_set_frame_mode = mv88e6351_port_set_frame_mode,
        .port_set_egress_floods = mv88e6352_port_set_egress_floods,
        .port_set_ether_type = mv88e6351_port_set_ether_type,
index 6bc0a4e..04a329a 100644 (file)
@@ -189,6 +189,24 @@ struct mv88e6xxx_port_hwtstamp {
        struct hwtstamp_config tstamp_config;
 };
 
+enum mv88e6xxx_policy_mapping {
+       MV88E6XXX_POLICY_MAPPING_DA,
+       MV88E6XXX_POLICY_MAPPING_SA,
+       MV88E6XXX_POLICY_MAPPING_VTU,
+       MV88E6XXX_POLICY_MAPPING_ETYPE,
+       MV88E6XXX_POLICY_MAPPING_PPPOE,
+       MV88E6XXX_POLICY_MAPPING_VBAS,
+       MV88E6XXX_POLICY_MAPPING_OPT82,
+       MV88E6XXX_POLICY_MAPPING_UDP,
+};
+
+enum mv88e6xxx_policy_action {
+       MV88E6XXX_POLICY_ACTION_NORMAL,
+       MV88E6XXX_POLICY_ACTION_MIRROR,
+       MV88E6XXX_POLICY_ACTION_TRAP,
+       MV88E6XXX_POLICY_ACTION_DISCARD,
+};
+
 struct mv88e6xxx_port {
        struct mv88e6xxx_chip *chip;
        int port;
@@ -381,6 +399,10 @@ struct mv88e6xxx_ops {
 
        int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
 
+       int (*port_set_policy)(struct mv88e6xxx_chip *chip, int port,
+                              enum mv88e6xxx_policy_mapping mapping,
+                              enum mv88e6xxx_policy_action action);
+
        int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port,
                                   enum mv88e6xxx_frame_mode mode);
        int (*port_set_egress_floods)(struct mv88e6xxx_chip *chip, int port,
index 0400634..15ef816 100644 (file)
@@ -1341,3 +1341,77 @@ int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
 
        return 0;
 }
+
+/* Offset 0x0E: Policy Control Register */
+
+int mv88e6352_port_set_policy(struct mv88e6xxx_chip *chip, int port,
+                             enum mv88e6xxx_policy_mapping mapping,
+                             enum mv88e6xxx_policy_action action)
+{
+       u16 reg, mask, val;
+       int shift;
+       int err;
+
+       switch (mapping) {
+       case MV88E6XXX_POLICY_MAPPING_DA:
+               shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_DA_MASK);
+               mask = MV88E6XXX_PORT_POLICY_CTL_DA_MASK;
+               break;
+       case MV88E6XXX_POLICY_MAPPING_SA:
+               shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_SA_MASK);
+               mask = MV88E6XXX_PORT_POLICY_CTL_SA_MASK;
+               break;
+       case MV88E6XXX_POLICY_MAPPING_VTU:
+               shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VTU_MASK);
+               mask = MV88E6XXX_PORT_POLICY_CTL_VTU_MASK;
+               break;
+       case MV88E6XXX_POLICY_MAPPING_ETYPE:
+               shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK);
+               mask = MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK;
+               break;
+       case MV88E6XXX_POLICY_MAPPING_PPPOE:
+               shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK);
+               mask = MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK;
+               break;
+       case MV88E6XXX_POLICY_MAPPING_VBAS:
+               shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK);
+               mask = MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK;
+               break;
+       case MV88E6XXX_POLICY_MAPPING_OPT82:
+               shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK);
+               mask = MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK;
+               break;
+       case MV88E6XXX_POLICY_MAPPING_UDP:
+               shift = __bf_shf(MV88E6XXX_PORT_POLICY_CTL_UDP_MASK);
+               mask = MV88E6XXX_PORT_POLICY_CTL_UDP_MASK;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       switch (action) {
+       case MV88E6XXX_POLICY_ACTION_NORMAL:
+               val = MV88E6XXX_PORT_POLICY_CTL_NORMAL;
+               break;
+       case MV88E6XXX_POLICY_ACTION_MIRROR:
+               val = MV88E6XXX_PORT_POLICY_CTL_MIRROR;
+               break;
+       case MV88E6XXX_POLICY_ACTION_TRAP:
+               val = MV88E6XXX_PORT_POLICY_CTL_TRAP;
+               break;
+       case MV88E6XXX_POLICY_ACTION_DISCARD:
+               val = MV88E6XXX_PORT_POLICY_CTL_DISCARD;
+               break;
+       default:
+               return -EOPNOTSUPP;
+       }
+
+       err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_POLICY_CTL, &reg);
+       if (err)
+               return err;
+
+       reg &= ~mask;
+       reg |= (val << shift) & mask;
+
+       return mv88e6xxx_port_write(chip, port, MV88E6XXX_PORT_POLICY_CTL, reg);
+}
index d4e9bea..03a480c 100644 (file)
 #define MV88E6XXX_PORT_PRI_OVERRIDE    0x0d
 
 /* Offset 0x0E: Policy Control Register */
-#define MV88E6XXX_PORT_POLICY_CTL      0x0e
+#define MV88E6XXX_PORT_POLICY_CTL              0x0e
+#define MV88E6XXX_PORT_POLICY_CTL_DA_MASK      0xc000
+#define MV88E6XXX_PORT_POLICY_CTL_SA_MASK      0x3000
+#define MV88E6XXX_PORT_POLICY_CTL_VTU_MASK     0x0c00
+#define MV88E6XXX_PORT_POLICY_CTL_ETYPE_MASK   0x0300
+#define MV88E6XXX_PORT_POLICY_CTL_PPPOE_MASK   0x00c0
+#define MV88E6XXX_PORT_POLICY_CTL_VBAS_MASK    0x0030
+#define MV88E6XXX_PORT_POLICY_CTL_OPT82_MASK   0x000c
+#define MV88E6XXX_PORT_POLICY_CTL_UDP_MASK     0x0003
+#define MV88E6XXX_PORT_POLICY_CTL_NORMAL       0x0000
+#define MV88E6XXX_PORT_POLICY_CTL_MIRROR       0x0001
+#define MV88E6XXX_PORT_POLICY_CTL_TRAP         0x0002
+#define MV88E6XXX_PORT_POLICY_CTL_DISCARD      0x0003
 
 /* Offset 0x0F: Port Special Ether Type */
 #define MV88E6XXX_PORT_ETH_TYPE                0x0f
@@ -324,6 +336,9 @@ int mv88e6185_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
                                     bool unicast, bool multicast);
 int mv88e6352_port_set_egress_floods(struct mv88e6xxx_chip *chip, int port,
                                     bool unicast, bool multicast);
+int mv88e6352_port_set_policy(struct mv88e6xxx_chip *chip, int port,
+                             enum mv88e6xxx_policy_mapping mapping,
+                             enum mv88e6xxx_policy_action action);
 int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
                                  u16 etype);
 int mv88e6xxx_port_set_message_port(struct mv88e6xxx_chip *chip, int port,