mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 14:04:26 -04:00 
			
		
		
		
	Manually rebased: generic/hack-5.4/662-remove_pfifo_fast.patch All other patches automatically rebased. Build system: x86_64 Build-tested: ipq806x/R7800 Run-tested: ipq806x/R7800 No dmesg regressions, everything functional Signed-off-by: John Audia <graysky@archlinux.us> [manual changes to ramips/patches-5.10/835-asoc-add-mt7620-support.patch] Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
		
			
				
	
	
		
			122 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 54a0ed0df49609f4e3f098f8943e38e389dc2e15 Mon Sep 17 00:00:00 2001
 | |
| From: Russell King <rmk+kernel@armlinux.org.uk>
 | |
| Date: Tue, 12 May 2020 20:20:25 +0300
 | |
| Subject: net: dsa: provide an option for drivers to always receive bridge
 | |
|  VLANs
 | |
| 
 | |
| DSA assumes that a bridge which has vlan filtering disabled is not
 | |
| vlan aware, and ignores all vlan configuration. However, the kernel
 | |
| software bridge code allows configuration in this state.
 | |
| 
 | |
| This causes the kernel's idea of the bridge vlan state and the
 | |
| hardware state to disagree, so "bridge vlan show" indicates a correct
 | |
| configuration but the hardware lacks all configuration. Even worse,
 | |
| enabling vlan filtering on a DSA bridge immediately blocks all traffic
 | |
| which, given the output of "bridge vlan show", is very confusing.
 | |
| 
 | |
| Provide an option that drivers can set to indicate they want to receive
 | |
| vlan configuration even when vlan filtering is disabled. At the very
 | |
| least, this is safe for Marvell DSA bridges, which do not look up
 | |
| ingress traffic in the VTU if the port is in 8021Q disabled state. It is
 | |
| also safe for the Ocelot switch family. Whether this change is suitable
 | |
| for all DSA bridges is not known.
 | |
| 
 | |
| Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
 | |
| Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
 | |
| Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
 | |
| Signed-off-by: David S. Miller <davem@davemloft.net>
 | |
| ---
 | |
|  include/net/dsa.h  |  7 +++++++
 | |
|  net/dsa/dsa_priv.h |  1 +
 | |
|  net/dsa/port.c     | 14 ++++++++++++++
 | |
|  net/dsa/slave.c    |  8 ++++----
 | |
|  4 files changed, 26 insertions(+), 4 deletions(-)
 | |
| 
 | |
| --- a/include/net/dsa.h
 | |
| +++ b/include/net/dsa.h
 | |
| @@ -270,6 +270,13 @@ struct dsa_switch {
 | |
|  	 */
 | |
|  	bool			vlan_filtering_is_global;
 | |
|  
 | |
| +	/* Pass .port_vlan_add and .port_vlan_del to drivers even for bridges
 | |
| +	 * that have vlan_filtering=0. All drivers should ideally set this (and
 | |
| +	 * then the option would get removed), but it is unknown whether this
 | |
| +	 * would break things or not.
 | |
| +	 */
 | |
| +	bool			configure_vlan_while_not_filtering;
 | |
| +
 | |
|  	/* In case vlan_filtering_is_global is set, the VLAN awareness state
 | |
|  	 * should be retrieved from here and not from the per-port settings.
 | |
|  	 */
 | |
| --- a/net/dsa/dsa_priv.h
 | |
| +++ b/net/dsa/dsa_priv.h
 | |
| @@ -139,6 +139,7 @@ int dsa_port_bridge_join(struct dsa_port
 | |
|  void dsa_port_bridge_leave(struct dsa_port *dp, struct net_device *br);
 | |
|  int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering,
 | |
|  			    struct switchdev_trans *trans);
 | |
| +bool dsa_port_skip_vlan_configuration(struct dsa_port *dp);
 | |
|  int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
 | |
|  			 struct switchdev_trans *trans);
 | |
|  int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr,
 | |
| --- a/net/dsa/port.c
 | |
| +++ b/net/dsa/port.c
 | |
| @@ -238,6 +238,20 @@ int dsa_port_vlan_filtering(struct dsa_p
 | |
|  	return 0;
 | |
|  }
 | |
|  
 | |
| +/* This enforces legacy behavior for switch drivers which assume they can't
 | |
| + * receive VLAN configuration when enslaved to a bridge with vlan_filtering=0
 | |
| + */
 | |
| +bool dsa_port_skip_vlan_configuration(struct dsa_port *dp)
 | |
| +{
 | |
| +	struct dsa_switch *ds = dp->ds;
 | |
| +
 | |
| +	if (!dp->bridge_dev)
 | |
| +		return false;
 | |
| +
 | |
| +	return (!ds->configure_vlan_while_not_filtering &&
 | |
| +		!br_vlan_enabled(dp->bridge_dev));
 | |
| +}
 | |
| +
 | |
|  int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock,
 | |
|  			 struct switchdev_trans *trans)
 | |
|  {
 | |
| --- a/net/dsa/slave.c
 | |
| +++ b/net/dsa/slave.c
 | |
| @@ -319,7 +319,7 @@ static int dsa_slave_vlan_add(struct net
 | |
|  	if (obj->orig_dev != dev)
 | |
|  		return -EOPNOTSUPP;
 | |
|  
 | |
| -	if (dp->bridge_dev && !br_vlan_enabled(dp->bridge_dev))
 | |
| +	if (dsa_port_skip_vlan_configuration(dp))
 | |
|  		return 0;
 | |
|  
 | |
|  	vlan = *SWITCHDEV_OBJ_PORT_VLAN(obj);
 | |
| @@ -386,7 +386,7 @@ static int dsa_slave_vlan_del(struct net
 | |
|  	if (obj->orig_dev != dev)
 | |
|  		return -EOPNOTSUPP;
 | |
|  
 | |
| -	if (dp->bridge_dev && !br_vlan_enabled(dp->bridge_dev))
 | |
| +	if (dsa_port_skip_vlan_configuration(dp))
 | |
|  		return 0;
 | |
|  
 | |
|  	/* Do not deprogram the CPU port as it may be shared with other user
 | |
| @@ -1120,7 +1120,7 @@ static int dsa_slave_vlan_rx_add_vid(str
 | |
|  	 * need to emulate the switchdev prepare + commit phase.
 | |
|  	 */
 | |
|  	if (dp->bridge_dev) {
 | |
| -		if (!br_vlan_enabled(dp->bridge_dev))
 | |
| +		if (dsa_port_skip_vlan_configuration(dp))
 | |
|  			return 0;
 | |
|  
 | |
|  		/* br_vlan_get_info() returns -EINVAL or -ENOENT if the
 | |
| @@ -1154,7 +1154,7 @@ static int dsa_slave_vlan_rx_kill_vid(st
 | |
|  	 * need to emulate the switchdev prepare + commit phase.
 | |
|  	 */
 | |
|  	if (dp->bridge_dev) {
 | |
| -		if (!br_vlan_enabled(dp->bridge_dev))
 | |
| +		if (dsa_port_skip_vlan_configuration(dp))
 | |
|  			return 0;
 | |
|  
 | |
|  		/* br_vlan_get_info() returns -EINVAL or -ENOENT if the
 |