[openwrt/openwrt] ramips: backport mt7530/762x switch fixes

LEDE Commits lede-commits at lists.infradead.org
Thu Feb 15 01:48:45 PST 2018


jow pushed a commit to openwrt/openwrt.git, branch lede-17.01:
https://git.lede-project.org/623cdc4ffeef8e95ba7ab02288c044b2186d121a

commit 623cdc4ffeef8e95ba7ab02288c044b2186d121a
Author: Jo-Philipp Wich <jo at mein.io>
AuthorDate: Thu Feb 15 10:47:04 2018 +0100

    ramips: backport mt7530/762x switch fixes
    
    dc7a1e8555 ("ramips: fix reporting effective VLAN ID on MT7621 switches")
    341b1427fc ("ramips: properly map pvid for vlans with remapped vid on mt7530/762x switches")
    bb4002c79d ("ramips: don't clobber vlans with remapped vid on mt7530/762x switches")
    
    Fixes FS#991, FS#1147, FS#1341
    
    Signed-off-by: Jo-Philipp Wich <jo at mein.io>
---
 .../linux/ramips/patches-4.4/0519-gsw_mt7621.patch | 259 +++++++++++++++++++--
 1 file changed, 239 insertions(+), 20 deletions(-)

diff --git a/target/linux/ramips/patches-4.4/0519-gsw_mt7621.patch b/target/linux/ramips/patches-4.4/0519-gsw_mt7621.patch
index e146de2..5f0594c 100644
--- a/target/linux/ramips/patches-4.4/0519-gsw_mt7621.patch
+++ b/target/linux/ramips/patches-4.4/0519-gsw_mt7621.patch
@@ -1,31 +1,250 @@
 --- a/drivers/net/ethernet/mediatek/mt7530.c
 +++ b/drivers/net/ethernet/mediatek/mt7530.c
-@@ -547,6 +547,7 @@ mt7530_apply_config(struct switch_dev *d
- 		u8 etags = priv->vlan_entries[i].etags;
- 		u32 val;
+@@ -44,6 +44,12 @@
+ #define MT7530_MAX_VID		4095
+ #define MT7530_MIN_VID		0
+ 
++#define MT7530_PORT_MIB_TXB_ID	2	/* TxGOC */
++#define MT7530_PORT_MIB_RXB_ID	6	/* RxGOC */
++
++#define MT7621_PORT_MIB_TXB_ID	18	/* TxByte */
++#define MT7621_PORT_MIB_RXB_ID	37	/* RxByte */
++
+ /* registers */
+ #define REG_ESW_VLAN_VTCR		0x90
+ #define REG_ESW_VLAN_VAWD1		0x94
+@@ -214,6 +220,12 @@ struct mt7530_mapping {
+ 		.members = { 0, 0x7e, 0x41 },
+ 		.etags = { 0, 0x40, 0x40 },
+ 		.vids = { 0, 1, 2 },
++	}, {
++		.name = "lwlll",
++		.pvids = { 1, 2, 1, 1, 1, 1, 1 },
++		.members = { 0, 0x7d, 0x42 },
++		.etags = { 0, 0x40, 0x40 },
++		.vids = { 0, 1, 2 },
+ 	},
+ };
  
+@@ -467,6 +479,14 @@ mt7530_set_vid(struct switch_dev *dev, c
+ }
+ 
+ static int
++mt7621_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
++		struct switch_val *val)
++{
++	val->value.i = val->port_vlan;
++	return 0;
++}
++
++static int
+ mt7530_get_vid(struct switch_dev *dev, const struct switch_attr *attr,
+ 		struct switch_val *val)
+ {
+@@ -485,6 +505,52 @@ mt7530_get_vid(struct switch_dev *dev, c
+ 	return 0;
+ }
+ 
++static void
++mt7530_write_vlan_entry(struct mt7530_priv *priv, int vlan, u16 vid,
++	                    u8 ports, u8 etags)
++{
++	int port;
++	u32 val;
++
 +#ifndef CONFIG_SOC_MT7621
- 		/* vid of vlan */
- 		val = mt7530_r32(priv, REG_ESW_VLAN_VTIM(i));
- 		if (i % 2 == 0) {
-@@ -557,7 +558,7 @@ mt7530_apply_config(struct switch_dev *d
- 			val |= (vid << 12);
- 		}
- 		mt7530_w32(priv, REG_ESW_VLAN_VTIM(i), val);
--
++	/* vid of vlan */
++	val = mt7530_r32(priv, REG_ESW_VLAN_VTIM(vlan));
++	if (vlan % 2 == 0) {
++		val &= 0xfff000;
++		val |= vid;
++	} else {
++		val &= 0xfff;
++		val |= (vid << 12);
++	}
++	mt7530_w32(priv, REG_ESW_VLAN_VTIM(vlan), val);
 +#endif
- 		/* vlan port membership */
- 		if (member)
- 			mt7530_w32(priv, REG_ESW_VLAN_VAWD1, REG_ESW_VLAN_VAWD1_IVL_MAC |
-@@ -577,7 +578,11 @@ mt7530_apply_config(struct switch_dev *d
- 		mt7530_w32(priv, REG_ESW_VLAN_VAWD2, val);
- 
- 		/* write to vlan table */
++
++	/* vlan port membership */
++	if (ports)
++		mt7530_w32(priv, REG_ESW_VLAN_VAWD1, REG_ESW_VLAN_VAWD1_IVL_MAC |
++			REG_ESW_VLAN_VAWD1_VTAG_EN | (ports << 16) |
++			REG_ESW_VLAN_VAWD1_VALID);
++	else
++		mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
++
++	/* egress mode */
++	val = 0;
++	for (port = 0; port < MT7530_NUM_PORTS; port++) {
++		if (etags & BIT(port))
++			val |= ETAG_CTRL_TAG << (port * 2);
++		else
++			val |= ETAG_CTRL_UNTAG << (port * 2);
++	}
++	mt7530_w32(priv, REG_ESW_VLAN_VAWD2, val);
++
++	/* write to vlan table */
 +#ifdef CONFIG_SOC_MT7621
-+		mt7530_vtcr(priv, 1, vid);
++	mt7530_vtcr(priv, 1, vid);
 +#else
- 		mt7530_vtcr(priv, 1, i);
++	mt7530_vtcr(priv, 1, vlan);
 +#endif
++}
++
+ static int
+ mt7530_apply_config(struct switch_dev *dev)
+ {
+@@ -541,51 +607,33 @@ mt7530_apply_config(struct switch_dev *d
+ 		mt7530_w32(priv, REG_ESW_PORT_PVC(i), pvc_mode);
+ 	}
+ 
++	/* first clear the swtich vlan table */
++	for (i = 0; i < MT7530_NUM_VLANS; i++)
++		mt7530_write_vlan_entry(priv, i, i, 0, 0);
++
++	/* now program only vlans with members to avoid
++	   clobbering remapped entries in later iterations */
+ 	for (i = 0; i < MT7530_NUM_VLANS; i++) {
+ 		u16 vid = priv->vlan_entries[i].vid;
+ 		u8 member = priv->vlan_entries[i].member;
+ 		u8 etags = priv->vlan_entries[i].etags;
+-		u32 val;
+ 
+-		/* vid of vlan */
+-		val = mt7530_r32(priv, REG_ESW_VLAN_VTIM(i));
+-		if (i % 2 == 0) {
+-			val &= 0xfff000;
+-			val |= vid;
+-		} else {
+-			val &= 0xfff;
+-			val |= (vid << 12);
+-		}
+-		mt7530_w32(priv, REG_ESW_VLAN_VTIM(i), val);
+-
+-		/* vlan port membership */
+ 		if (member)
+-			mt7530_w32(priv, REG_ESW_VLAN_VAWD1, REG_ESW_VLAN_VAWD1_IVL_MAC |
+-				REG_ESW_VLAN_VAWD1_VTAG_EN | (member << 16) |
+-				REG_ESW_VLAN_VAWD1_VALID);
+-		else
+-			mt7530_w32(priv, REG_ESW_VLAN_VAWD1, 0);
+-
+-		/* egress mode */
+-		val = 0;
+-		for (j = 0; j < MT7530_NUM_PORTS; j++) {
+-			if (etags & BIT(j))
+-				val |= ETAG_CTRL_TAG << (j * 2);
+-			else
+-				val |= ETAG_CTRL_UNTAG << (j * 2);
+-		}
+-		mt7530_w32(priv, REG_ESW_VLAN_VAWD2, val);
+-
+-		/* write to vlan table */
+-		mt7530_vtcr(priv, 1, i);
++			mt7530_write_vlan_entry(priv, i, vid, member, etags);
  	}
  
  	/* Port Default PVID */
+ 	for (i = 0; i < MT7530_NUM_PORTS; i++) {
++		int vlan = priv->port_entries[i].pvid;
++		u16 pvid = 0;
+ 		u32 val;
++
++		if (vlan < MT7530_NUM_VLANS && priv->vlan_entries[vlan].member)
++			pvid = priv->vlan_entries[vlan].vid;
++
+ 		val = mt7530_r32(priv, REG_ESW_PORT_PPBV1(i));
+ 		val &= ~0xfff;
+-		val |= priv->port_entries[i].pvid;
++		val |= pvid;
+ 		mt7530_w32(priv, REG_ESW_PORT_PPBV1(i), val);
+ 	}
+ 
+@@ -739,6 +787,34 @@ static int mt7530_sw_get_port_mib(struct
+ 	return 0;
+ }
+ 
++static int mt7530_get_port_stats(struct switch_dev *dev, int port,
++					struct switch_port_stats *stats)
++{
++	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
++
++	if (port < 0 || port >= MT7530_NUM_PORTS)
++		return -EINVAL;
++
++	stats->tx_bytes = get_mib_counter_port_7620(priv, MT7530_PORT_MIB_TXB_ID, port);
++	stats->rx_bytes = get_mib_counter_port_7620(priv, MT7530_PORT_MIB_RXB_ID, port);
++
++	return 0;
++}
++
++static int mt7621_get_port_stats(struct switch_dev *dev, int port,
++					struct switch_port_stats *stats)
++{
++	struct mt7530_priv *priv = container_of(dev, struct mt7530_priv, swdev);
++
++	if (port < 0 || port >= MT7530_NUM_PORTS)
++		return -EINVAL;
++
++	stats->tx_bytes = get_mib_counter(priv, MT7621_PORT_MIB_TXB_ID, port);
++	stats->rx_bytes = get_mib_counter(priv, MT7621_PORT_MIB_RXB_ID, port);
++
++	return 0;
++}
++
+ static const struct switch_attr mt7530_global[] = {
+ 	{
+ 		.type = SWITCH_TYPE_INT,
+@@ -767,6 +843,17 @@ static const struct switch_attr mt7621_p
+ 	},
+ };
+ 
++static const struct switch_attr mt7621_vlan[] = {
++	{
++		.type = SWITCH_TYPE_INT,
++		.name = "vid",
++		.description = "VLAN ID (0-4094)",
++		.set = mt7530_set_vid,
++		.get = mt7621_get_vid,
++		.max = 4094,
++	},
++};
++
+ static const struct switch_attr mt7530_port[] = {
+ 	{
+ 		.type = SWITCH_TYPE_STRING,
+@@ -798,14 +885,15 @@ static const struct switch_dev_ops mt762
+ 		.n_attr = ARRAY_SIZE(mt7621_port),
+ 	},
+ 	.attr_vlan = {
+-		.attr = mt7530_vlan,
+-		.n_attr = ARRAY_SIZE(mt7530_vlan),
++		.attr = mt7621_vlan,
++		.n_attr = ARRAY_SIZE(mt7621_vlan),
+ 	},
+ 	.get_vlan_ports = mt7530_get_vlan_ports,
+ 	.set_vlan_ports = mt7530_set_vlan_ports,
+ 	.get_port_pvid = mt7530_get_port_pvid,
+ 	.set_port_pvid = mt7530_set_port_pvid,
+ 	.get_port_link = mt7530_get_port_link,
++	.get_port_stats = mt7621_get_port_stats,
+ 	.apply_config = mt7530_apply_config,
+ 	.reset_switch = mt7530_reset_switch,
+ };
+@@ -828,6 +916,7 @@ static const struct switch_dev_ops mt753
+ 	.get_port_pvid = mt7530_get_port_pvid,
+ 	.set_port_pvid = mt7530_set_port_pvid,
+ 	.get_port_link = mt7530_get_port_link,
++	.get_port_stats = mt7530_get_port_stats,
+ 	.apply_config = mt7530_apply_config,
+ 	.reset_switch = mt7530_reset_switch,
+ };
+@@ -881,7 +970,7 @@ mt7530_probe(struct device *dev, void __
+ 
+ 	/* magic vodoo */
+ 	if (!IS_ENABLED(CONFIG_SOC_MT7621) && bus && mt7530_r32(mt7530, REG_HWTRAP) !=  0x1117edf) {
+-	        dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n");
++		dev_info(dev, "fixing up MHWTRAP register - bootloader probably played with it\n");
+ 		mt7530_w32(mt7530, REG_HWTRAP, 0x1117edf);
+ 	}
+ 	dev_info(dev, "loaded %s driver\n", swdev->name);



More information about the lede-commits mailing list