aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Crispin <john@openwrt.org>2015-10-05 10:26:09 +0000
committerJohn Crispin <john@openwrt.org>2015-10-05 10:26:09 +0000
commit1aab21df9f92194f78cd5864974f5c81d426e479 (patch)
treeecdae807ce5cc7e7528d525dbeb89899ccf3edf5
parentdd8f5abb23c7222e427ad10703164c9aef13b148 (diff)
downloadupstream-1aab21df9f92194f78cd5864974f5c81d426e479.tar.gz
upstream-1aab21df9f92194f78cd5864974f5c81d426e479.tar.bz2
upstream-1aab21df9f92194f78cd5864974f5c81d426e479.zip
ramips: Allow to receive vlan over untag ports on MT7530
The MT7530 switch driver with enable_vlan set will automatically set all ports to the user port mode. The hardware will remove the incoming vlan tag on these ports and use it for its internal vlan. This is usually not wanted and makes it impossible to communicate via vlan over the switch in both directions. It is possible to configure a switch port to "transparent mode" when this port is only used as untag in the switch VLANs. This will disable the VLAN untagging of packets when they were received on this port. The tagging on "tag" ports based on the vlan id is still working. The transparent port mode cannot be used when a port is both used in a VLAN as "tag" and in another one as "untag" port. Signed-off-by: Sven Eckelmann <sven@open-mesh.com> SVN-Revision: 47114
-rw-r--r--target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c36
1 files changed, 33 insertions, 3 deletions
diff --git a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
index 51e16f26b9..4e00315452 100644
--- a/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
+++ b/target/linux/ramips/files/drivers/net/ethernet/ralink/mt7530.c
@@ -484,6 +484,8 @@ mt7530_apply_config(struct switch_dev *dev)
{
struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
int i, j;
+ u8 tag_ports;
+ u8 untag_ports;
if (!priv->global_vlan_enable) {
for (i = 0; i < MT7530_NUM_PORTS; i++)
@@ -499,9 +501,37 @@ mt7530_apply_config(struct switch_dev *dev)
for (i = 0; i < MT7530_NUM_PORTS; i++)
mt7530_w32(priv, REG_ESW_PORT_PCR(i), 0x00ff0003);
- /* set all ports as user port */
- for (i = 0; i < MT7530_NUM_PORTS; i++)
- mt7530_w32(priv, REG_ESW_PORT_PVC(i), 0x81000000);
+ /* check if a port is used in tag/untag vlan egress mode */
+ tag_ports = 0;
+ untag_ports = 0;
+
+ for (i = 0; i < MT7530_NUM_VLANS; i++) {
+ u8 member = priv->vlan_entries[i].member;
+ u8 etags = priv->vlan_entries[i].etags;
+
+ if (!member)
+ continue;
+
+ for (j = 0; j < MT7530_NUM_PORTS; j++) {
+ if (!(member & BIT(j)))
+ continue;
+
+ if (etags & BIT(j))
+ tag_ports |= 1u << j;
+ else
+ untag_ports |= 1u << j;
+ }
+ }
+
+ /* set all untag-only ports as transparent and the rest as user port */
+ for (i = 0; i < MT7530_NUM_PORTS; i++) {
+ u32 pvc_mode = 0x81000000;
+
+ if (untag_ports & BIT(i) && !(tag_ports & BIT(i)))
+ pvc_mode = 0x810000c0;
+
+ mt7530_w32(priv, REG_ESW_PORT_PVC(i), pvc_mode);
+ }
for (i = 0; i < MT7530_NUM_VLANS; i++) {
u16 vid = priv->vlan_entries[i].vid;