diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2021-10-13 03:35:21 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2021-10-13 03:35:22 +0300 |
| commit | 847c6bdba833115e07376584024b2cb43ef7914b (patch) | |
| tree | b9e594210209c145c22a33df4def3dee0268ac42 /include/linux | |
| parent | 3af760e4d3b0a32448decb8ea068a221cbd24fe3 (diff) | |
| parent | 8d5f7954b7c8de54902a8beda141064a7e2e6ee0 (diff) | |
| download | linux-847c6bdba833115e07376584024b2cb43ef7914b.tar.xz | |
Merge branch 'felix-dsa-driver-fixes'
Vladimir Oltean says:
====================
Felix DSA driver fixes
This is an assorted collection of fixes for issues seen on the NXP
LS1028A switch.
- PTP packet drops due to switch congestion result in catastrophic
damage to the driver's state
- loops are not blocked by STP if using the ocelot-8021q tagger
- driver uses the wrong CPU port when two of them are defined in DT
- module autoloading is broken* with both tagging protocol drivers
(ocelot and ocelot-8021q)
Changes in v2:
- Stop printing that we aren't going to take TX timestamps if we don't
have TX timestamping anyway, and we are just carrying PTP frames for a
cascaded DSA switch.
- Shorten the deferred xmit kthread name so that it fits the 16
character limit (TASK_COMM_LEN)
====================
Link: https://lore.kernel.org/r/20211012114044.2526146-1-vladimir.oltean@nxp.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/dsa/ocelot.h | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/include/linux/dsa/ocelot.h b/include/linux/dsa/ocelot.h index 435777a0073c..8ae999f587c4 100644 --- a/include/linux/dsa/ocelot.h +++ b/include/linux/dsa/ocelot.h @@ -5,7 +5,28 @@ #ifndef _NET_DSA_TAG_OCELOT_H #define _NET_DSA_TAG_OCELOT_H +#include <linux/kthread.h> #include <linux/packing.h> +#include <linux/skbuff.h> + +struct ocelot_skb_cb { + struct sk_buff *clone; + unsigned int ptp_class; /* valid only for clones */ + u8 ptp_cmd; + u8 ts_id; +}; + +#define OCELOT_SKB_CB(skb) \ + ((struct ocelot_skb_cb *)((skb)->cb)) + +#define IFH_TAG_TYPE_C 0 +#define IFH_TAG_TYPE_S 1 + +#define IFH_REW_OP_NOOP 0x0 +#define IFH_REW_OP_DSCP 0x1 +#define IFH_REW_OP_ONE_STEP_PTP 0x2 +#define IFH_REW_OP_TWO_STEP_PTP 0x3 +#define IFH_REW_OP_ORIGIN_PTP 0x5 #define OCELOT_TAG_LEN 16 #define OCELOT_SHORT_PREFIX_LEN 4 @@ -140,6 +161,17 @@ * +------+------+------+------+------+------+------+------+ */ +struct felix_deferred_xmit_work { + struct dsa_port *dp; + struct sk_buff *skb; + struct kthread_work work; +}; + +struct felix_port { + void (*xmit_work_fn)(struct kthread_work *work); + struct kthread_worker *xmit_worker; +}; + static inline void ocelot_xfh_get_rew_val(void *extraction, u64 *rew_val) { packing(extraction, rew_val, 116, 85, OCELOT_TAG_LEN, UNPACK, 0); @@ -215,4 +247,21 @@ static inline void ocelot_ifh_set_vid(void *injection, u64 vid) packing(injection, &vid, 11, 0, OCELOT_TAG_LEN, PACK, 0); } +/* Determine the PTP REW_OP to use for injecting the given skb */ +static inline u32 ocelot_ptp_rew_op(struct sk_buff *skb) +{ + struct sk_buff *clone = OCELOT_SKB_CB(skb)->clone; + u8 ptp_cmd = OCELOT_SKB_CB(skb)->ptp_cmd; + u32 rew_op = 0; + + if (ptp_cmd == IFH_REW_OP_TWO_STEP_PTP && clone) { + rew_op = ptp_cmd; + rew_op |= OCELOT_SKB_CB(clone)->ts_id << 3; + } else if (ptp_cmd == IFH_REW_OP_ORIGIN_PTP) { + rew_op = ptp_cmd; + } + + return rew_op; +} + #endif |
