Re: [OpenWrt-Devel] [RFC] Fix VLAN on Atheros AR8327N

2014-09-17 Thread Valentin Spreckels
Hi,

Am 17.09.2014 19:50, schrieb John Crispin:
 
 
 On 17/09/2014 19:47, Florian Fainelli wrote:
 On 08/31/2014 10:42 AM, Jiri Pirko wrote:
 Sat, Jul 19, 2014 at 09:49:38PM CEST, nolt...@gmail.com wrote:
 Commit 40842 reverted the fix for tagged+untagged VLANs on
 AR8327: https://dev.openwrt.org/changeset/40777 
 https://dev.openwrt.org/changeset/40842

 According to jow, some people experienced some issues on
 older devices. Can anyone tell me what were those issues?

 Anyway, that patch modified some parts of the ar8216/ar8236, so
 I suppose any device with those switches were affected. 
 However, I've modified the patch keeping the ar8216/ar8236 as
 much untouched as possible. Could anyone test it on those
 devices?

 BTW, this works for me on a TP-Link WDR4300 (ar8327).


 I tested the patch on TL-WR1043ND v2 with Atheros AR8327 rev. 4.
 Vlans are working as expected. Please include this into BB (might
 need repost)

 Thanks!

 Tested-by: Jiri Pirko j...@resnulli.us

 Unless there are further objections, we should probably just go
 ahead and apply this patch since it affects a bunch of users.
 
 and then the other bunch complains, as we had before. we keep applying
 and reversing this i think. maybe we should just see what the real bug
 is ?
 
   John

I'm interested in this feature. I tried to understand what the revoked
patch changes and rewrote it. I submitted my changes two months ago:
http://patchwork.openwrt.org/patch/5957/
http://patchwork.openwrt.org/patch/5958/

My patches attempt to minimize changes in non-ar8327-specific code.

Neither the revert commit nor ticket #12181 describe the issues. So I'm
not sure, if my patches have them too. Does anyone know details about
the issues?

- Valentin Spreckels

 




 Signed-off-by: Saverio Proto ziopr...@gmail.com 
 Signed-off-by: Álvaro Fernández nolt...@gmail.com --- diff
 --git a/target/linux/generic/files/drivers/net/phy/ar8216.c
 b/target/linux/generic/files/drivers/net/phy/ar8216.c index
 3846159..9eae624 100644 ---
 a/target/linux/generic/files/drivers/net/phy/ar8216.c +++
 b/target/linux/generic/files/drivers/net/phy/ar8216.c @@ -78,7
 +78,7 @@ struct ar8xxx_chip { u32 (*read_port_status)(struct
 ar8xxx_priv *priv, int port); int (*atu_flush)(struct
 ar8xxx_priv *priv); void (*vtu_flush)(struct ar8xxx_priv
 *priv); -  void (*vtu_load_vlan)(struct ar8xxx_priv *priv, u32
 vid, u32 port_mask); + void (*vtu_load_vlan)(struct ar8xxx_priv
 *priv, u32 vlan);

 const struct ar8xxx_mib_desc *mib_decs; unsigned num_mibs; @@
 -112,7 +112,12 @@ struct ar8327_led { enum ar8327_led_pattern
 pattern; };

 +struct ar8216_data { +u8 vlan_tagged; +}; + struct
 ar8327_data { +u8 vlan_tagged[AR8X16_MAX_VLANS]; u32
 port0_status; u32 port6_status;

 @@ -138,6 +143,7 @@ struct ar8xxx_priv { u8 chip_rev; const
 struct ar8xxx_chip *chip; union { +struct ar8216_data
 ar8216; struct ar8327_data ar8327; } chip_data; bool
 initialized; @@ -159,7 +165,6 @@ struct ar8xxx_priv { bool
 vlan; u16 vlan_id[AR8X16_MAX_VLANS]; u8
 vlan_table[AR8X16_MAX_VLANS]; -u8 vlan_tagged; u16
 pvid[AR8X16_MAX_PORTS];

 /* mirroring */ @@ -641,7 +646,7 @@ ar8216_mangle_rx(struct
 net_device *dev, struct sk_buff *skb) port = buf[0]  0xf;

 /* no need to fix up packets coming from a tagged source */ -
 if (priv-vlan_tagged  (1  port)) + if
 (priv-chip_data.ar8216.vlan_tagged  BIT(port)) return;

 /* lookup port vid from local table, the switch passes an
 invalid vlan id */ @@ -695,10 +700,13 @@
 ar8216_vtu_flush(struct ar8xxx_priv *priv) }

 static void -ar8216_vtu_load_vlan(struct ar8xxx_priv *priv, u32
 vid, u32 port_mask) +ar8216_vtu_load_vlan(struct ar8xxx_priv
 *priv, u32 vlan) { u32 op;

 +  u32 vid = priv-vlan_id[vlan]; +u32 port_mask =
 priv-vlan_table[vlan]; + op = AR8216_VTU_OP_LOAD | (vid 
 AR8216_VTU_VID_S); ar8216_vtu_op(priv, op, port_mask); } @@
 -1705,12 +1713,16 @@ ar8327_vtu_flush(struct ar8xxx_priv
 *priv) }

 static void -ar8327_vtu_load_vlan(struct ar8xxx_priv *priv, u32
 vid, u32 port_mask) +ar8327_vtu_load_vlan(struct ar8xxx_priv
 *priv, u32 vlan) { u32 op; u32 val; int i;

 +  u32 vid = priv-vlan_id[vlan]; +u32 port_mask =
 priv-vlan_table[vlan]; +  u32 tagged =
 priv-chip_data.ar8327.vlan_tagged[vlan]; + op =
 AR8327_VTU_FUNC1_OP_LOAD | (vid  AR8327_VTU_FUNC1_VID_S); val
 = AR8327_VTU_FUNC0_VALID | AR8327_VTU_FUNC0_IVL; for (i = 0; i
  AR8327_NUM_PORTS; i++) { @@ -1720,7 +1732,7 @@
 ar8327_vtu_load_vlan(struct ar8xxx_priv *priv, u32 vid, u32
 port_mask) mode = AR8327_VTU_FUNC0_EG_MODE_NOT; else if
 (priv-vlan == 0) mode = AR8327_VTU_FUNC0_EG_MODE_KEEP; -  else
 if (priv-vlan_tagged  BIT(i)) +  else if (tagged  BIT(i)) 
 mode = AR8327_VTU_FUNC0_EG_MODE_TAG; else mode =
 AR8327_VTU_FUNC0_EG_MODE_UNTAG; @@ -1734,26 +1746,22 @@ static
 void ar8327_setup_port(struct ar8xxx_priv *priv, int port, u32
 egress, u32 ingress, u32 members, u32 pvid) { -u32 t; -u32
 mode; +u32 mode, t

[OpenWrt-Devel] [PATCH 1/2] ar71xx: ar8216: move policies, pvid to setup_port

2014-07-22 Thread Valentin Spreckels
From: Valentin Spreckels valentin.spreck...@informatik.uni-oldenburg.de

This moves ingress, egress policy and pvid decisions to setup_port methods.
They arenow device type dependent.

This allows policy changes on only one device type which is needed to allow
tagged + untagged operation on ar8327.

Tested on TP-LINK WDR-3600 (ar8327N).

Signed-off-by: Valentin Spreckels 
valentin.spreck...@informatik.uni-oldenburg.de
---
 .../linux/generic/files/drivers/net/phy/ar8216.c   | 93 --
 1 file changed, 52 insertions(+), 41 deletions(-)

diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c 
b/target/linux/generic/files/drivers/net/phy/ar8216.c
index 3846159..3efd460 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -73,8 +73,7 @@ struct ar8xxx_chip {
 
void (*init_globals)(struct ar8xxx_priv *priv);
void (*init_port)(struct ar8xxx_priv *priv, int port);
-   void (*setup_port)(struct ar8xxx_priv *priv, int port, u32 egress,
-  u32 ingress, u32 members, u32 pvid);
+   void (*setup_port)(struct ar8xxx_priv *priv, int port, u32 members);
u32 (*read_port_status)(struct ar8xxx_priv *priv, int port);
int (*atu_flush)(struct ar8xxx_priv *priv);
void (*vtu_flush)(struct ar8xxx_priv *priv);
@@ -722,10 +721,24 @@ ar8216_read_port_status(struct ar8xxx_priv *priv, int 
port)
 }
 
 static void
-ar8216_setup_port(struct ar8xxx_priv *priv, int port, u32 egress, u32 ingress,
- u32 members, u32 pvid)
+ar8216_setup_port(struct ar8xxx_priv *priv, int port, u32 members)
 {
u32 header;
+   u32 egress, ingress;
+   u32 pvid;
+
+   if (priv-vlan) {
+   pvid = priv-vlan_id[priv-pvid[port]];
+   if (priv-vlan_tagged  (1  port))
+   egress = AR8216_OUT_ADD_VLAN;
+   else
+   egress = AR8216_OUT_STRIP_VLAN;
+   ingress = AR8216_IN_SECURE;
+   } else {
+   pvid = port;
+   egress = AR8216_OUT_KEEP;
+   ingress = AR8216_IN_PORT_ONLY;
+   }
 
if (chip_is_ar8216(priv)  priv-vlan  port == AR8216_PORT_CPU)
header = AR8216_PORT_CTRL_HEADER;
@@ -807,9 +820,24 @@ static const struct ar8xxx_chip ar8216_chip = {
 };
 
 static void
-ar8236_setup_port(struct ar8xxx_priv *priv, int port, u32 egress, u32 ingress,
- u32 members, u32 pvid)
+ar8236_setup_port(struct ar8xxx_priv *priv, int port, u32 members)
 {
+   u32 egress, ingress;
+   u32 pvid;
+
+   if (priv-vlan) {
+   pvid = priv-vlan_id[priv-pvid[port]];
+   if (priv-vlan_tagged  (1  port))
+   egress = AR8216_OUT_ADD_VLAN;
+   else
+   egress = AR8216_OUT_STRIP_VLAN;
+   ingress = AR8216_IN_SECURE;
+   } else {
+   pvid = port;
+   egress = AR8216_OUT_KEEP;
+   ingress = AR8216_IN_PORT_ONLY;
+   }
+
ar8xxx_rmw(priv, AR8216_REG_PORT_CTRL(port),
   AR8216_PORT_CTRL_LEARN | AR8216_PORT_CTRL_VLAN_MODE |
   AR8216_PORT_CTRL_SINGLE_VLAN | AR8216_PORT_CTRL_STATE |
@@ -1731,31 +1759,31 @@ ar8327_vtu_load_vlan(struct ar8xxx_priv *priv, u32 vid, 
u32 port_mask)
 }
 
 static void
-ar8327_setup_port(struct ar8xxx_priv *priv, int port, u32 egress, u32 ingress,
- u32 members, u32 pvid)
+ar8327_setup_port(struct ar8xxx_priv *priv, int port, u32 members)
 {
u32 t;
-   u32 mode;
+   u32 egress, ingress;
+   u32 pvid;
+
+   if (priv-vlan) {
+   pvid = priv-vlan_id[priv-pvid[port]];
+   if (priv-vlan_tagged  (1  port))
+   egress = AR8327_PORT_VLAN1_OUT_MODE_TAG;
+   else
+   egress = AR8327_PORT_VLAN1_OUT_MODE_UNTAG;
+   ingress = AR8216_IN_SECURE;
+   } else {
+   pvid = port;
+   egress = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
+   ingress = AR8216_IN_PORT_ONLY;
+   }
 
t = pvid  AR8327_PORT_VLAN0_DEF_SVID_S;
t |= pvid  AR8327_PORT_VLAN0_DEF_CVID_S;
priv-write(priv, AR8327_REG_PORT_VLAN0(port), t);
 
-   mode = AR8327_PORT_VLAN1_OUT_MODE_UNMOD;
-   switch (egress) {
-   case AR8216_OUT_KEEP:
-   mode = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH;
-   break;
-   case AR8216_OUT_STRIP_VLAN:
-   mode = AR8327_PORT_VLAN1_OUT_MODE_UNTAG;
-   break;
-   case AR8216_OUT_ADD_VLAN:
-   mode = AR8327_PORT_VLAN1_OUT_MODE_TAG;
-   break;
-   }
-
t = AR8327_PORT_VLAN1_PORT_VLAN_PROP;
-   t |= mode  AR8327_PORT_VLAN1_OUT_MODE_S;
+   t |= egress  AR8327_PORT_VLAN1_OUT_MODE_S;
priv-write(priv, AR8327_REG_PORT_VLAN1(port), t);
 
t = members;
@@ -2041,24 +2069,7

[OpenWrt-Devel] [PATCH 2/2] ar71xx: ar8216: tagged+untagged on ar8327 (#12181)

2014-07-22 Thread Valentin Spreckels
From: Valentin Spreckels valentin.spreck...@informatik.uni-oldenburg.de

This allows tagged and untagged traffic together on the same port on ar8327
switch devices.

I looked at the first attempt to do this in r40777 (ar71xx: Fix tagged+untagged
operation on AR8327N (#12181)). I also set the vlan and port egress policies
like that change. But I change vlan_tagged in an less intrusive way. The
tagged/untagged decision is now based on the following rules:
- if vid != pvid then traffic is always tagged
- if vid == pvid then vlan_tagged stores if the traffic should be tagged

Tested on TP-Link WDR-3600 (ar8327N).

Signed-off-by: Valentin Spreckels 
valentin.spreck...@informatik.uni-oldenburg.de
---
 .../linux/generic/files/drivers/net/phy/ar8216.c   | 60 +++---
 1 file changed, 53 insertions(+), 7 deletions(-)

diff --git a/target/linux/generic/files/drivers/net/phy/ar8216.c 
b/target/linux/generic/files/drivers/net/phy/ar8216.c
index 3efd460..bd6cc97 100644
--- a/target/linux/generic/files/drivers/net/phy/ar8216.c
+++ b/target/linux/generic/files/drivers/net/phy/ar8216.c
@@ -1748,7 +1748,7 @@ ar8327_vtu_load_vlan(struct ar8xxx_priv *priv, u32 vid, 
u32 port_mask)
mode = AR8327_VTU_FUNC0_EG_MODE_NOT;
else if (priv-vlan == 0)
mode = AR8327_VTU_FUNC0_EG_MODE_KEEP;
-   else if (priv-vlan_tagged  BIT(i))
+   else if ((priv-vlan_tagged  BIT(i)) || 
(priv-vlan_id[priv-pvid[i]] != vid))
mode = AR8327_VTU_FUNC0_EG_MODE_TAG;
else
mode = AR8327_VTU_FUNC0_EG_MODE_UNTAG;
@@ -1767,10 +1767,7 @@ ar8327_setup_port(struct ar8xxx_priv *priv, int port, 
u32 members)
 
if (priv-vlan) {
pvid = priv-vlan_id[priv-pvid[port]];
-   if (priv-vlan_tagged  (1  port))
-   egress = AR8327_PORT_VLAN1_OUT_MODE_TAG;
-   else
-   egress = AR8327_PORT_VLAN1_OUT_MODE_UNTAG;
+   egress = AR8327_PORT_VLAN1_OUT_MODE_UNMOD;
ingress = AR8216_IN_SECURE;
} else {
pvid = port;
@@ -1903,6 +1900,30 @@ ar8xxx_sw_get_ports(struct switch_dev *dev, struct 
switch_val *val)
 }
 
 static int
+ar8327_sw_get_ports(struct switch_dev *dev, struct switch_val *val)
+{
+   struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+   u8 ports = priv-vlan_table[val-port_vlan];
+   int i;
+
+   val-len = 0;
+   for (i = 0; i  dev-ports; i++) {
+   struct switch_port *p;
+
+   if (!(ports  (1  i)))
+   continue;
+
+   p = val-value.ports[val-len++];
+   p-id = i;
+   if ((priv-vlan_tagged  (1  i)) || (priv-pvid[i] != 
val-port_vlan))
+   p-flags = (1  SWITCH_PORT_FLAG_TAGGED);
+   else
+   p-flags = 0;
+   }
+   return 0;
+}
+
+static int
 ar8xxx_sw_set_ports(struct switch_dev *dev, struct switch_val *val)
 {
struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
@@ -1933,6 +1954,31 @@ ar8xxx_sw_set_ports(struct switch_dev *dev, struct 
switch_val *val)
return 0;
 }
 
+static int
+ar8327_sw_set_ports(struct switch_dev *dev, struct switch_val *val)
+{
+   struct ar8xxx_priv *priv = swdev_to_ar8xxx(dev);
+   u8 *vt = priv-vlan_table[val-port_vlan];
+   int i, j;
+
+   *vt = 0;
+   for (i = 0; i  val-len; i++) {
+   struct switch_port *p = val-value.ports[i];
+
+   if (p-flags  (1  SWITCH_PORT_FLAG_TAGGED)) {
+   if (val-port_vlan == priv-pvid[p-id]) {
+   priv-vlan_tagged |= (1  p-id);
+   }
+   } else {
+   priv-vlan_tagged = ~(1  p-id);
+   priv-pvid[p-id] = val-port_vlan;
+   }
+
+   *vt |= 1  p-id;
+   }
+   return 0;
+}
+
 static void
 ar8327_set_mirror_regs(struct ar8xxx_priv *priv)
 {
@@ -2475,8 +2521,8 @@ static const struct switch_dev_ops ar8327_sw_ops = {
},
.get_port_pvid = ar8xxx_sw_get_pvid,
.set_port_pvid = ar8xxx_sw_set_pvid,
-   .get_vlan_ports = ar8xxx_sw_get_ports,
-   .set_vlan_ports = ar8xxx_sw_set_ports,
+   .get_vlan_ports = ar8327_sw_get_ports,
+   .set_vlan_ports = ar8327_sw_set_ports,
.apply_config = ar8xxx_sw_hw_apply,
.reset_switch = ar8xxx_sw_reset_switch,
.get_port_link = ar8xxx_sw_get_port_link,
-- 
1.8.5.5
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel


[OpenWrt-Devel] [PATCH 0/2] ar71xx: ar8216: tagged+untagged on ar8327 (#12181)

2014-07-22 Thread Valentin Spreckels
From: Valentin Spreckels valentin.spreck...@informatik.uni-oldenburg.de

Hi,

This is a small patch set to allow taged+untagged traffic on the same port of an
ar8327 switch. The first patch does small refactoring. The real changes are in
the second patch.

I only included the changes for ar8327, because I only have ar8327 devices, but
I think, that other ar8xxx types (but not ar8216) can also support this similar
to ar8327.

Valentin Spreckels (2):
  ar71xx: ar8216: move policies, pvid to setup_port
  ar71xx: ar8216: tagged+untagged on ar8327 (#12181)

 .../linux/generic/files/drivers/net/phy/ar8216.c   | 145 ++---
 1 file changed, 101 insertions(+), 44 deletions(-)

-- 
1.8.5.5
___
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel