Skip to content

Commit e5b0a1b

Browse files
committed
Merge branch 'sja1110-dsa-tagging'
Vladimir Oltean says: ==================== DSA tagging driver for NXP SJA1110 This series adds support for tagging data and control packets on the new NXP SJA1110 switch (supported by the sja1105 driver). Up to this point it used the sja1105 driver, which allowed it to send data packets, but not PDUs as those required by STP and PTP. To accommodate this new tagger which has both a header and a trailer, we need to refactor the entire DSA tagging scheme, to replace the "overhead" concept with separate "needed_headroom" and "needed_tailroom" concepts, so that SJA1110 can declare its need for both. There is also some consolidation work for the receive path of tag_8021q and its callers (sja1105 and ocelot-8021q). Changes in v3: Rebase in front of the "Port the SJA1105 DSA driver to XPCS" series which seems to have stalled for now. Changes in v2: Export the dsa_8021q_rcv and sja1110_process_meta_tstamp symbols to avoid build errors as modules. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents f244e25 + 566b18c commit e5b0a1b

31 files changed

+551
-184
lines changed

Documentation/networking/dsa/dsa.rst

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,15 @@ A tagging protocol may tag all packets with switch tags of the same length, or
9393
the tag length might vary (for example packets with PTP timestamps might
9494
require an extended switch tag, or there might be one tag length on TX and a
9595
different one on RX). Either way, the tagging protocol driver must populate the
96-
``struct dsa_device_ops::overhead`` with the length in octets of the longest
97-
switch frame header. The DSA framework will automatically adjust the MTU of the
98-
master interface to accomodate for this extra size in order for DSA user ports
99-
to support the standard MTU (L2 payload length) of 1500 octets. The ``overhead``
100-
is also used to request from the network stack, on a best-effort basis, the
101-
allocation of packets with a ``needed_headroom`` or ``needed_tailroom``
102-
sufficient such that the act of pushing the switch tag on transmission of a
103-
packet does not cause it to reallocate due to lack of memory.
96+
``struct dsa_device_ops::needed_headroom`` and/or ``struct dsa_device_ops::needed_tailroom``
97+
with the length in octets of the longest switch frame header/trailer. The DSA
98+
framework will automatically adjust the MTU of the master interface to
99+
accommodate for this extra size in order for DSA user ports to support the
100+
standard MTU (L2 payload length) of 1500 octets. The ``needed_headroom`` and
101+
``needed_tailroom`` properties are also used to request from the network stack,
102+
on a best-effort basis, the allocation of packets with enough extra space such
103+
that the act of pushing the switch tag on transmission of a packet does not
104+
cause it to reallocate due to lack of memory.
104105

105106
Even though applications are not expected to parse DSA-specific frame headers,
106107
the format on the wire of the tagging protocol represents an Application Binary
@@ -169,8 +170,8 @@ The job of this method is to prepare the skb in a way that the switch will
169170
understand what egress port the packet is for (and not deliver it towards other
170171
ports). Typically this is fulfilled by pushing a frame header. Checking for
171172
insufficient size in the skb headroom or tailroom is unnecessary provided that
172-
the ``overhead`` and ``tail_tag`` properties were filled out properly, because
173-
DSA ensures there is enough space before calling this method.
173+
the ``needed_headroom`` and ``needed_tailroom`` properties were filled out
174+
properly, because DSA ensures there is enough space before calling this method.
174175

175176
The reception of a packet goes through the tagger's ``rcv`` function. The
176177
passed ``struct sk_buff *skb`` has ``skb->data`` pointing at

drivers/net/dsa/sja1105/sja1105.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ struct sja1105_info {
109109
int num_cbs_shapers;
110110
int max_frame_mem;
111111
int num_ports;
112+
bool multiple_cascade_ports;
113+
enum dsa_tag_protocol tag_proto;
112114
const struct sja1105_dynamic_table_ops *dyn_ops;
113115
const struct sja1105_table_ops *static_ops;
114116
const struct sja1105_regs *regs;
@@ -128,6 +130,8 @@ struct sja1105_info {
128130
const unsigned char *addr, u16 vid);
129131
void (*ptp_cmd_packing)(u8 *buf, struct sja1105_ptp_cmd *cmd,
130132
enum packing_op op);
133+
bool (*rxtstamp)(struct dsa_switch *ds, int port, struct sk_buff *skb);
134+
void (*txtstamp)(struct dsa_switch *ds, int port, struct sk_buff *skb);
131135
int (*clocking_setup)(struct sja1105_private *priv);
132136
const char *name;
133137
bool supports_mii[SJA1105_MAX_NUM_PORTS];

drivers/net/dsa/sja1105/sja1105_main.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -654,14 +654,6 @@ static int sja1105_init_general_params(struct sja1105_private *priv)
654654
.host_port = priv->ds->num_ports,
655655
/* Default to an invalid value */
656656
.mirr_port = priv->ds->num_ports,
657-
/* Link-local traffic received on casc_port will be forwarded
658-
* to host_port without embedding the source port and device ID
659-
* info in the destination MAC address (presumably because it
660-
* is a cascaded port and a downstream SJA switch already did
661-
* that). Default to an invalid port (to disable the feature)
662-
* and overwrite this if we find any DSA (cascaded) ports.
663-
*/
664-
.casc_port = priv->ds->num_ports,
665657
/* No TTEthernet */
666658
.vllupformat = SJA1105_VL_FORMAT_PSFP,
667659
.vlmarker = 0,
@@ -673,7 +665,12 @@ static int sja1105_init_general_params(struct sja1105_private *priv)
673665
*/
674666
.tpid = ETH_P_SJA1105,
675667
.tpid2 = ETH_P_SJA1105,
668+
/* Enable the TTEthernet engine on SJA1110 */
669+
.tte_en = true,
670+
/* Set up the EtherType for control packets on SJA1110 */
671+
.header_type = ETH_P_SJA1110,
676672
};
673+
struct sja1105_general_params_entry *general_params;
677674
struct dsa_switch *ds = priv->ds;
678675
struct sja1105_table *table;
679676
int port;
@@ -699,12 +696,26 @@ static int sja1105_init_general_params(struct sja1105_private *priv)
699696

700697
table->entry_count = table->ops->max_entry_count;
701698

699+
general_params = table->entries;
700+
702701
/* This table only has a single entry */
703-
((struct sja1105_general_params_entry *)table->entries)[0] =
704-
default_general_params;
702+
general_params[0] = default_general_params;
705703

706704
sja1110_select_tdmaconfigidx(priv);
707705

706+
/* Link-local traffic received on casc_port will be forwarded
707+
* to host_port without embedding the source port and device ID
708+
* info in the destination MAC address, and no RX timestamps will be
709+
* taken either (presumably because it is a cascaded port and a
710+
* downstream SJA switch already did that).
711+
* To disable the feature, we need to do different things depending on
712+
* switch generation. On SJA1105 we need to set an invalid port, while
713+
* on SJA1110 which support multiple cascaded ports, this field is a
714+
* bitmask so it must be left zero.
715+
*/
716+
if (!priv->info->multiple_cascade_ports)
717+
general_params->casc_port = ds->num_ports;
718+
708719
return 0;
709720
}
710721

@@ -2165,7 +2176,9 @@ static enum dsa_tag_protocol
21652176
sja1105_get_tag_protocol(struct dsa_switch *ds, int port,
21662177
enum dsa_tag_protocol mp)
21672178
{
2168-
return DSA_TAG_PROTO_SJA1105;
2179+
struct sja1105_private *priv = ds->priv;
2180+
2181+
return priv->info->tag_proto;
21692182
}
21702183

21712184
static int sja1105_find_free_subvlan(u16 *subvlan_map, bool pvid)

drivers/net/dsa/sja1105/sja1105_ptp.c

Lines changed: 93 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ static int sja1105_change_rxtstamping(struct sja1105_private *priv,
7979
priv->tagger_data.stampable_skb = NULL;
8080
}
8181
ptp_cancel_worker_sync(ptp_data->clock);
82+
skb_queue_purge(&ptp_data->skb_txtstamp_queue);
8283
skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
8384

8485
return sja1105_static_config_reload(priv, SJA1105_RX_HWTSTAMPING);
@@ -397,7 +398,7 @@ static long sja1105_rxtstamp_work(struct ptp_clock_info *ptp)
397398

398399
*shwt = (struct skb_shared_hwtstamps) {0};
399400

400-
ts = SJA1105_SKB_CB(skb)->meta_tstamp;
401+
ts = SJA1105_SKB_CB(skb)->tstamp;
401402
ts = sja1105_tstamp_reconstruct(ds, ticks, ts);
402403

403404
shwt->hwtstamp = ns_to_ktime(sja1105_ticks_to_ns(ts));
@@ -413,9 +414,7 @@ static long sja1105_rxtstamp_work(struct ptp_clock_info *ptp)
413414
return -1;
414415
}
415416

416-
/* Called from dsa_skb_defer_rx_timestamp */
417-
bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
418-
struct sk_buff *skb, unsigned int type)
417+
bool sja1105_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
419418
{
420419
struct sja1105_private *priv = ds->priv;
421420
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
@@ -431,6 +430,89 @@ bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
431430
return true;
432431
}
433432

433+
bool sja1110_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
434+
{
435+
struct skb_shared_hwtstamps *shwt = skb_hwtstamps(skb);
436+
u64 ts = SJA1105_SKB_CB(skb)->tstamp;
437+
438+
*shwt = (struct skb_shared_hwtstamps) {0};
439+
440+
shwt->hwtstamp = ns_to_ktime(sja1105_ticks_to_ns(ts));
441+
442+
/* Don't defer */
443+
return false;
444+
}
445+
446+
/* Called from dsa_skb_defer_rx_timestamp */
447+
bool sja1105_port_rxtstamp(struct dsa_switch *ds, int port,
448+
struct sk_buff *skb, unsigned int type)
449+
{
450+
struct sja1105_private *priv = ds->priv;
451+
452+
return priv->info->rxtstamp(ds, port, skb);
453+
}
454+
455+
void sja1110_process_meta_tstamp(struct dsa_switch *ds, int port, u8 ts_id,
456+
enum sja1110_meta_tstamp dir, u64 tstamp)
457+
{
458+
struct sja1105_private *priv = ds->priv;
459+
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
460+
struct sk_buff *skb, *skb_tmp, *skb_match = NULL;
461+
struct skb_shared_hwtstamps shwt = {0};
462+
463+
/* We don't care about RX timestamps on the CPU port */
464+
if (dir == SJA1110_META_TSTAMP_RX)
465+
return;
466+
467+
spin_lock(&ptp_data->skb_txtstamp_queue.lock);
468+
469+
skb_queue_walk_safe(&ptp_data->skb_txtstamp_queue, skb, skb_tmp) {
470+
if (SJA1105_SKB_CB(skb)->ts_id != ts_id)
471+
continue;
472+
473+
__skb_unlink(skb, &ptp_data->skb_txtstamp_queue);
474+
skb_match = skb;
475+
476+
break;
477+
}
478+
479+
spin_unlock(&ptp_data->skb_txtstamp_queue.lock);
480+
481+
if (WARN_ON(!skb_match))
482+
return;
483+
484+
shwt.hwtstamp = ns_to_ktime(sja1105_ticks_to_ns(tstamp));
485+
skb_complete_tx_timestamp(skb_match, &shwt);
486+
}
487+
EXPORT_SYMBOL_GPL(sja1110_process_meta_tstamp);
488+
489+
/* In addition to cloning the skb which is done by the common
490+
* sja1105_port_txtstamp, we need to generate a timestamp ID and save the
491+
* packet to the TX timestamping queue.
492+
*/
493+
void sja1110_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
494+
{
495+
struct sk_buff *clone = SJA1105_SKB_CB(skb)->clone;
496+
struct sja1105_private *priv = ds->priv;
497+
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
498+
struct sja1105_port *sp = &priv->ports[port];
499+
u8 ts_id;
500+
501+
skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
502+
503+
spin_lock(&sp->data->meta_lock);
504+
505+
ts_id = sp->data->ts_id;
506+
/* Deal automatically with 8-bit wraparound */
507+
sp->data->ts_id++;
508+
509+
SJA1105_SKB_CB(clone)->ts_id = ts_id;
510+
511+
spin_unlock(&sp->data->meta_lock);
512+
513+
skb_queue_tail(&ptp_data->skb_txtstamp_queue, clone);
514+
}
515+
434516
/* Called from dsa_skb_tx_timestamp. This callback is just to clone
435517
* the skb and have it available in SJA1105_SKB_CB in the .port_deferred_xmit
436518
* callback, where we will timestamp it synchronously.
@@ -449,6 +531,9 @@ void sja1105_port_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
449531
return;
450532

451533
SJA1105_SKB_CB(skb)->clone = clone;
534+
535+
if (priv->info->txtstamp)
536+
priv->info->txtstamp(ds, port, skb);
452537
}
453538

454539
static int sja1105_ptp_reset(struct dsa_switch *ds)
@@ -865,7 +950,10 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds)
865950
.n_per_out = 1,
866951
};
867952

953+
/* Only used on SJA1105 */
868954
skb_queue_head_init(&ptp_data->skb_rxtstamp_queue);
955+
/* Only used on SJA1110 */
956+
skb_queue_head_init(&ptp_data->skb_txtstamp_queue);
869957
spin_lock_init(&tagger_data->meta_lock);
870958

871959
ptp_data->clock = ptp_clock_register(&ptp_data->caps, ds->dev);
@@ -890,6 +978,7 @@ void sja1105_ptp_clock_unregister(struct dsa_switch *ds)
890978

891979
del_timer_sync(&ptp_data->extts_timer);
892980
ptp_cancel_worker_sync(ptp_data->clock);
981+
skb_queue_purge(&ptp_data->skb_txtstamp_queue);
893982
skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
894983
ptp_clock_unregister(ptp_data->clock);
895984
ptp_data->clock = NULL;

drivers/net/dsa/sja1105/sja1105_ptp.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,12 @@ struct sja1105_ptp_cmd {
7575

7676
struct sja1105_ptp_data {
7777
struct timer_list extts_timer;
78+
/* Used only on SJA1105 to reconstruct partial timestamps */
7879
struct sk_buff_head skb_rxtstamp_queue;
80+
/* Used on SJA1110 where meta frames are generated only for
81+
* 2-step TX timestamps
82+
*/
83+
struct sk_buff_head skb_txtstamp_queue;
7984
struct ptp_clock_info caps;
8085
struct ptp_clock *clock;
8186
struct sja1105_ptp_cmd cmd;
@@ -122,6 +127,10 @@ int __sja1105_ptp_adjtime(struct dsa_switch *ds, s64 delta);
122127
int sja1105_ptp_commit(struct dsa_switch *ds, struct sja1105_ptp_cmd *cmd,
123128
sja1105_spi_rw_mode_t rw);
124129

130+
bool sja1105_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb);
131+
bool sja1110_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb);
132+
void sja1110_txtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb);
133+
125134
#else
126135

127136
struct sja1105_ptp_cmd;
@@ -184,6 +193,10 @@ static inline int sja1105_ptp_commit(struct dsa_switch *ds,
184193

185194
#define sja1105_hwtstamp_set NULL
186195

196+
#define sja1105_rxtstamp NULL
197+
#define sja1110_rxtstamp NULL
198+
#define sja1110_txtstamp NULL
199+
187200
#endif /* IS_ENABLED(CONFIG_NET_DSA_SJA1105_PTP) */
188201

189202
#endif /* _SJA1105_PTP_H */

0 commit comments

Comments
 (0)