Simply put, the best-effort VLAN filtering mode relied on VLAN retagging from a bridge VLAN towards a tag_8021q sub-VLAN in order to be able to decode the source port in the tagger, but the VLAN retagging implementation inside the sja1105 chips is not the best and we were relying on marginal operating conditions. The most notable limitation of the best-effort VLAN filtering mode is its incapacity to treat this case properly: ip link add br0 type bridge vlan_filtering 1 ip link set swp2 master br0 ip link set swp4 master br0 bridge vlan del dev swp4 vid 1 bridge vlan add dev swp4 vid 1 pvid When sending an untagged packet through swp2, the expectation is for it to be forwarded to swp4 as egress-tagged (so it will contain VLAN ID 1 on egress). But the switch will send it as egress-untagged. There was an attempt to fix this here: https://patchwork.kernel.org/project/netdevbpf/patch/20210407201452.1703261-2-olteanv@gmail.com/ but it failed miserably because it broke PTP RX timestamping, in a way that cannot be corrected due to hardware issues related to VLAN retagging. So with either PTP broken or pushing VLAN headers on egress for untagged packets being broken, the sad reality is that the best-effort VLAN filtering code is broken. Delete it. Note that this means there will be a temporary loss of functionality in this driver until it is replaced with something better (network stack RX/TX capability for "mode 2" as described in Documentation/networking/dsa/sja1105.rst, the "port under VLAN-aware bridge" case). We simply cannot keep this code until that driver rework is done, it is super bloated and tangled with tag_8021q. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
92 lines
2.6 KiB
C
92 lines
2.6 KiB
C
/* SPDX-License-Identifier: GPL-2.0
|
|
* Copyright (c) 2019, Vladimir Oltean <olteanv@gmail.com>
|
|
*/
|
|
|
|
/* Included by drivers/net/dsa/sja1105/sja1105.h and net/dsa/tag_sja1105.c */
|
|
|
|
#ifndef _NET_DSA_SJA1105_H
|
|
#define _NET_DSA_SJA1105_H
|
|
|
|
#include <linux/skbuff.h>
|
|
#include <linux/etherdevice.h>
|
|
#include <linux/dsa/8021q.h>
|
|
#include <net/dsa.h>
|
|
|
|
#define ETH_P_SJA1105 ETH_P_DSA_8021Q
|
|
#define ETH_P_SJA1105_META 0x0008
|
|
#define ETH_P_SJA1110 0xdadc
|
|
|
|
/* IEEE 802.3 Annex 57A: Slow Protocols PDUs (01:80:C2:xx:xx:xx) */
|
|
#define SJA1105_LINKLOCAL_FILTER_A 0x0180C2000000ull
|
|
#define SJA1105_LINKLOCAL_FILTER_A_MASK 0xFFFFFF000000ull
|
|
/* IEEE 1588 Annex F: Transport of PTP over Ethernet (01:1B:19:xx:xx:xx) */
|
|
#define SJA1105_LINKLOCAL_FILTER_B 0x011B19000000ull
|
|
#define SJA1105_LINKLOCAL_FILTER_B_MASK 0xFFFFFF000000ull
|
|
|
|
/* Source and Destination MAC of follow-up meta frames.
|
|
* Whereas the choice of SMAC only affects the unique identification of the
|
|
* switch as sender of meta frames, the DMAC must be an address that is present
|
|
* in the DSA master port's multicast MAC filter.
|
|
* 01-80-C2-00-00-0E is a good choice for this, as all profiles of IEEE 1588
|
|
* over L2 use this address for some purpose already.
|
|
*/
|
|
#define SJA1105_META_SMAC 0x222222222222ull
|
|
#define SJA1105_META_DMAC 0x0180C200000Eull
|
|
|
|
#define SJA1105_HWTS_RX_EN 0
|
|
|
|
/* Global tagger data: each struct sja1105_port has a reference to
|
|
* the structure defined in struct sja1105_private.
|
|
*/
|
|
struct sja1105_tagger_data {
|
|
struct sk_buff *stampable_skb;
|
|
/* Protects concurrent access to the meta state machine
|
|
* from taggers running on multiple ports on SMP systems
|
|
*/
|
|
spinlock_t meta_lock;
|
|
unsigned long state;
|
|
u8 ts_id;
|
|
};
|
|
|
|
struct sja1105_skb_cb {
|
|
struct sk_buff *clone;
|
|
u64 tstamp;
|
|
/* Only valid for packets cloned for 2-step TX timestamping */
|
|
u8 ts_id;
|
|
};
|
|
|
|
#define SJA1105_SKB_CB(skb) \
|
|
((struct sja1105_skb_cb *)((skb)->cb))
|
|
|
|
struct sja1105_port {
|
|
struct kthread_worker *xmit_worker;
|
|
struct kthread_work xmit_work;
|
|
struct sk_buff_head xmit_queue;
|
|
struct sja1105_tagger_data *data;
|
|
struct dsa_port *dp;
|
|
bool hwts_tx_en;
|
|
u16 xmit_tpid;
|
|
};
|
|
|
|
enum sja1110_meta_tstamp {
|
|
SJA1110_META_TSTAMP_TX = 0,
|
|
SJA1110_META_TSTAMP_RX = 1,
|
|
};
|
|
|
|
#if IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP)
|
|
|
|
void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, u8 ts_id,
|
|
enum sja1110_meta_tstamp dir, u64 tstamp);
|
|
|
|
#else
|
|
|
|
static inline void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port,
|
|
u8 ts_id, enum sja1110_meta_tstamp dir,
|
|
u64 tstamp)
|
|
{
|
|
}
|
|
|
|
#endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */
|
|
|
|
#endif /* _NET_DSA_SJA1105_H */
|