net: dsa: mv88e6xxx: rework port mode setup
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>
Sat, 11 Mar 2017 21:12:59 +0000 (16:12 -0500)
committerDavid S. Miller <davem@davemloft.net>
Mon, 13 Mar 2017 06:54:07 +0000 (23:54 -0700)
A switch port mode is defined by the association of its egress mode, its
frame mode and if supported or required, the ether type value.

Pack all this in a mv88e6xxx_set_port_mode function and provide helpers
for the Normal Network mode, the DSA mode, and the Ether Type DSA mode,
as well as an helper to setup a port's mode depending on its nature.

Define PORT_ETH_TYPE_DEFAULT for the 0x9100 reset value of port E Type.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/dsa/mv88e6xxx/chip.c
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h

index e9533d4919bc8a79c228055296e5429953701b07..5f5023215ce176917433be5b5a1ef66ed8234c0a 100644 (file)
@@ -2199,69 +2199,82 @@ static int mv88e6xxx_serdes_power_on(struct mv88e6xxx_chip *chip)
        return err;
 }
 
-static int mv88e6xxx_setup_port_dsa(struct mv88e6xxx_chip *chip, int port,
-                                   int upstream_port)
+static int mv88e6xxx_set_port_mode(struct mv88e6xxx_chip *chip, int port,
+                                  enum mv88e6xxx_frame_mode frame, u16 egress,
+                                  u16 etype)
 {
        int err;
 
-       err = chip->info->ops->port_set_frame_mode(
-               chip, port, MV88E6XXX_FRAME_MODE_DSA);
+       if (!chip->info->ops->port_set_frame_mode)
+               return -EOPNOTSUPP;
+
+       err = mv88e6xxx_port_set_egress_mode(chip, port, egress);
        if (err)
                return err;
 
-       return chip->info->ops->port_set_egress_unknowns(
-               chip, port, port == upstream_port);
+       err = chip->info->ops->port_set_frame_mode(chip, port, frame);
+       if (err)
+               return err;
+
+       if (chip->info->ops->port_set_ether_type)
+               return chip->info->ops->port_set_ether_type(chip, port, etype);
+
+       return 0;
 }
 
-static int mv88e6xxx_setup_port_cpu(struct mv88e6xxx_chip *chip, int port)
+static int mv88e6xxx_set_port_mode_normal(struct mv88e6xxx_chip *chip, int port)
 {
-       int err;
+       return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_NORMAL,
+                                      PORT_CONTROL_EGRESS_UNMODIFIED,
+                                      PORT_ETH_TYPE_DEFAULT);
+}
 
-       switch (chip->info->tag_protocol) {
-       case DSA_TAG_PROTO_EDSA:
-               err = chip->info->ops->port_set_frame_mode(
-                       chip, port, MV88E6XXX_FRAME_MODE_ETHERTYPE);
-               if (err)
-                       return err;
+static int mv88e6xxx_set_port_mode_dsa(struct mv88e6xxx_chip *chip, int port)
+{
+       return mv88e6xxx_set_port_mode(chip, port, MV88E6XXX_FRAME_MODE_DSA,
+                                      PORT_CONTROL_EGRESS_UNMODIFIED,
+                                      PORT_ETH_TYPE_DEFAULT);
+}
 
-               err = mv88e6xxx_port_set_egress_mode(
-                       chip, port, PORT_CONTROL_EGRESS_ADD_TAG);
-               if (err)
-                       return err;
+static int mv88e6xxx_set_port_mode_edsa(struct mv88e6xxx_chip *chip, int port)
+{
+       return mv88e6xxx_set_port_mode(chip, port,
+                                      MV88E6XXX_FRAME_MODE_ETHERTYPE,
+                                      PORT_CONTROL_EGRESS_ADD_TAG, ETH_P_EDSA);
+}
 
-               if (chip->info->ops->port_set_ether_type)
-                       err = chip->info->ops->port_set_ether_type(
-                               chip, port, ETH_P_EDSA);
-               break;
+static int mv88e6xxx_setup_port_mode(struct mv88e6xxx_chip *chip, int port)
+{
+       if (dsa_is_dsa_port(chip->ds, port))
+               return mv88e6xxx_set_port_mode_dsa(chip, port);
 
-       case DSA_TAG_PROTO_DSA:
-               err = chip->info->ops->port_set_frame_mode(
-                       chip, port, MV88E6XXX_FRAME_MODE_DSA);
-               if (err)
-                       return err;
+       if (dsa_is_normal_port(chip->ds, port))
+               return mv88e6xxx_set_port_mode_normal(chip, port);
 
-               err = mv88e6xxx_port_set_egress_mode(
-                       chip, port, PORT_CONTROL_EGRESS_UNMODIFIED);
-               break;
-       default:
-               err = -EINVAL;
-       }
+       /* Setup CPU port mode depending on its supported tag format */
+       if (chip->info->tag_protocol == DSA_TAG_PROTO_DSA)
+               return mv88e6xxx_set_port_mode_dsa(chip, port);
 
-       if (err)
-               return err;
+       if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA)
+               return mv88e6xxx_set_port_mode_edsa(chip, port);
 
-       return chip->info->ops->port_set_egress_unknowns(chip, port, true);
+       return -EINVAL;
 }
 
-static int mv88e6xxx_setup_port_normal(struct mv88e6xxx_chip *chip, int port)
+static int mv88e6xxx_setup_port_dsa(struct mv88e6xxx_chip *chip, int port,
+                                   int upstream_port)
 {
-       int err;
+       return chip->info->ops->port_set_egress_unknowns(
+               chip, port, port == upstream_port);
+}
 
-       err = chip->info->ops->port_set_frame_mode(
-               chip, port, MV88E6XXX_FRAME_MODE_NORMAL);
-       if (err)
-               return err;
+static int mv88e6xxx_setup_port_cpu(struct mv88e6xxx_chip *chip, int port)
+{
+       return chip->info->ops->port_set_egress_unknowns(chip, port, true);
+}
 
+static int mv88e6xxx_setup_port_normal(struct mv88e6xxx_chip *chip, int port)
+{
        return chip->info->ops->port_set_egress_unknowns(chip, port, false);
 }
 
@@ -2325,6 +2338,10 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
        if (err)
                return err;
 
+       err = mv88e6xxx_setup_port_mode(chip, port);
+       if (err)
+               return err;
+
        /* If this port is connected to a SerDes, make sure the SerDes is not
         * powered down.
         */
@@ -3554,11 +3571,6 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
 static int mv88e6xxx_verify_madatory_ops(struct mv88e6xxx_chip *chip,
                                         const struct mv88e6xxx_ops *ops)
 {
-       if (!ops->port_set_frame_mode) {
-               dev_err(chip->dev, "Missing port_set_frame_mode");
-               return -EINVAL;
-       }
-
        if (!ops->port_set_egress_unknowns) {
                dev_err(chip->dev, "Missing port_set_egress_mode");
                return -EINVAL;
index 69acb4c40fdc9bf015d0702a5368236ecd3acbea..185be543498071f42bae1df48bba0815e25dc4ef 100644 (file)
 #define PORT_ATU_CONTROL       0x0c
 #define PORT_PRI_OVERRIDE      0x0d
 #define PORT_ETH_TYPE          0x0f
+#define PORT_ETH_TYPE_DEFAULT  0x9100
 #define PORT_IN_DISCARD_LO     0x10
 #define PORT_IN_DISCARD_HI     0x11
 #define PORT_IN_FILTERED       0x12