kernel: ar83xx: add support to configure per port VLAN priority
authorTan Hong Hui <hhtan72@yahoo.com>
Sat, 27 Jan 2018 02:14:57 +0000 (10:14 +0800)
committerJohn Crispin <john@phrozen.org>
Tue, 20 Feb 2018 09:33:34 +0000 (10:33 +0100)
Add support to allow for per switch port VLAN priority (PCP) bits
for the ar8327/8337 chip using the swconfig utility.

Tested on Netgear R7800

Signed-off-by: Tan Hong Hui <hhtan72@yahoo.com>
target/linux/generic/files/drivers/net/phy/ar8216.h
target/linux/generic/files/drivers/net/phy/ar8327.c
target/linux/generic/files/drivers/net/phy/ar8327.h

index d9508b9ff83c4c3d75978ae86546705660661a7f..ba0e0ddccda22c4196f7304d6abdc27b81abef69 100644 (file)
@@ -462,6 +462,7 @@ struct ar8xxx_priv {
        bool mirror_tx;
        int source_port;
        int monitor_port;
+       u8 port_vlan_prio[AR8X16_MAX_PORTS];
 };
 
 u32
index 6ebd2e8aedf33fc198ef25ed24fc2b06f642a8b4..f52f85a5de3a3c5c4fbf1667a609653467589efd 100644 (file)
@@ -926,10 +926,19 @@ ar8327_setup_port(struct ar8xxx_priv *priv, int port, u32 members)
 
        t = pvid << AR8327_PORT_VLAN0_DEF_SVID_S;
        t |= pvid << AR8327_PORT_VLAN0_DEF_CVID_S;
+       if (priv->vlan && priv->port_vlan_prio[port] > 0) {
+               u32 prio = priv->port_vlan_prio[port];
+
+               t |= prio << AR8327_PORT_VLAN0_DEF_SPRI_S;
+               t |= prio << AR8327_PORT_VLAN0_DEF_CPRI_S;
+       }
        ar8xxx_write(priv, AR8327_REG_PORT_VLAN0(port), t);
 
        t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
        t |= egress << AR8327_PORT_VLAN1_OUT_MODE_S;
+       if (priv->vlan && priv->port_vlan_prio[port] > 0)
+               t |= AR8327_PORT_VLAN1_VLAN_PRI_PROP;
+
        ar8xxx_write(priv, AR8327_REG_PORT_VLAN1(port), t);
 
        t = members;
@@ -1268,6 +1277,37 @@ ar8327_sw_set_igmp_v3(struct switch_dev *dev,
        return 0;
 }
 
+static int
+ar8327_sw_set_port_vlan_prio(struct switch_dev *dev, const struct switch_attr *attr,
+                            struct switch_val *val)
+{
+       struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+       int port = val->port_vlan;
+
+       if (port >= dev->ports)
+               return -EINVAL;
+       if (port == 0 || port == 6)
+               return -EOPNOTSUPP;
+       if (val->value.i < 0 || val->value.i > 7)
+               return -EINVAL;
+
+       priv->port_vlan_prio[port] = val->value.i;
+
+       return 0;
+}
+
+static int
+ar8327_sw_get_port_vlan_prio(struct switch_dev *dev, const struct switch_attr *attr,
+                  struct switch_val *val)
+{
+       struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+       int port = val->port_vlan;
+
+       val->value.i = priv->port_vlan_prio[port];
+
+       return 0;
+}
+
 static const struct switch_attr ar8327_sw_attr_globals[] = {
        {
                .type = SWITCH_TYPE_INT,
@@ -1389,6 +1429,14 @@ static const struct switch_attr ar8327_sw_attr_port[] = {
                .get = ar8327_sw_get_port_igmp_snooping,
                .max = 1
        },
+       {
+               .type = SWITCH_TYPE_INT,
+               .name = "vlan_prio",
+               .description = "Port VLAN default priority (VLAN PCP) (0-7)",
+               .set = ar8327_sw_set_port_vlan_prio,
+               .get = ar8327_sw_get_port_vlan_prio,
+               .max = 7,
+       },
 };
 
 static const struct switch_dev_ops ar8327_sw_ops = {
index 828dd28f38617a2256948b8b46460ba459199e73..2309e528994187c5036fee1088d9705c69e2a590 100644 (file)
 #define   AR8327_FRAME_ACK_CTRL_S(_i)          (((_i) % 4) * 8)
 
 #define AR8327_REG_PORT_VLAN0(_i)              (0x420 + (_i) * 0x8)
+#define   AR8327_PORT_VLAN0_DEF_PRI_MASK       BITS(0, 3)
 #define   AR8327_PORT_VLAN0_DEF_SVID           BITS(0, 12)
 #define   AR8327_PORT_VLAN0_DEF_SVID_S         0
+#define   AR8327_PORT_VLAN0_DEF_SPRI           BITS(13, 3)
+#define   AR8327_PORT_VLAN0_DEF_SPRI_S         13
 #define   AR8327_PORT_VLAN0_DEF_CVID           BITS(16, 12)
 #define   AR8327_PORT_VLAN0_DEF_CVID_S         16
+#define   AR8327_PORT_VLAN0_DEF_CPRI           BITS(29, 3)
+#define   AR8327_PORT_VLAN0_DEF_CPRI_S         29
 
 #define AR8327_REG_PORT_VLAN1(_i)              (0x424 + (_i) * 0x8)
+#define   AR8327_PORT_VLAN1_VLAN_PRI_PROP      BIT(4)
 #define   AR8327_PORT_VLAN1_PORT_VLAN_PROP     BIT(6)
 #define   AR8327_PORT_VLAN1_OUT_MODE           BITS(12, 2)
 #define   AR8327_PORT_VLAN1_OUT_MODE_S         12