mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-06-17 20:25:19 +00:00
Add support for tag_sja1105 running on non-sja1105 DSA ports, by making sure that every time we dereference dp->priv, we check the switch's dsa_switch_ops (otherwise we access a struct sja1105_port structure that is in fact something else). This adds an unconditional build-time dependency between sja1105 being built as module => tag_sja1105 must also be built as module. This was there only for PTP before. Some sane defaults must also take place when not running on sja1105 hardware. These are: - sja1105_xmit_tpid: the sja1105 driver uses different VLAN protocols depending on VLAN awareness and switch revision (when an encapsulated VLAN must be sent). Default to 0x8100. - sja1105_rcv_meta_state_machine: this aggregates PTP frames with their metadata timestamp frames. When running on non-sja1105 hardware, don't do that and accept all frames unmodified. - sja1105_defer_xmit: calls sja1105_port_deferred_xmit in sja1105_main.c which writes a management route over SPI. When not running on sja1105 hardware, bypass the SPI write and send the frame as-is. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
109 lines
2.9 KiB
C
109 lines
2.9 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) */
|
|
|
|
#if IS_ENABLED(CONFIG_NET_DSA_SJA1105)
|
|
|
|
extern const struct dsa_switch_ops sja1105_switch_ops;
|
|
|
|
static inline bool dsa_port_is_sja1105(struct dsa_port *dp)
|
|
{
|
|
return dp->ds->ops == &sja1105_switch_ops;
|
|
}
|
|
|
|
#else
|
|
|
|
static inline bool dsa_port_is_sja1105(struct dsa_port *dp)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif /* _NET_DSA_SJA1105_H */
|