Skip to content

Commit a372d66

Browse files
vladimirolteandavem330
authored andcommitted
net: dsa: sja1105: always enable the send_meta options
incl_srcpt has the limitation, mentioned in commit b4638af ("net: dsa: sja1105: always enable the INCL_SRCPT option"), that frames with a MAC DA of 01:80:c2:xx:yy:zz will be received as 01:80:c2:00:00:zz unless PTP RX timestamping is enabled. The incl_srcpt option was initially unconditionally enabled, then that changed with commit 4282446 ("net: dsa: sja1105: Limit use of incl_srcpt to bridge+vlan mode"), then again with b4638af ("net: dsa: sja1105: always enable the INCL_SRCPT option"). Bottom line is that it now needs to be always enabled, otherwise the driver does not have a reliable source of information regarding source_port and switch_id for link-local traffic (tag_8021q VLANs may be imprecise since now they identify an entire bridging domain when ports are not standalone). If we accept that PTP RX timestamping (and therefore, meta frame generation) is always enabled in hardware, then that limitation could be avoided and packets with any MAC DA can be properly received, because meta frames do contain the original bytes from the MAC DA of their associated link-local packet. This change enables meta frame generation unconditionally, which also has the nice side effects of simplifying the switch control path (a switch reset is no longer required on hwtstamping settings change) and the tagger data path (it no longer needs to be informed whether to expect meta frames or not - it always does). Fixes: 227d07a ("net: dsa: sja1105: Add support for traffic through standalone ports") Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 1dcf6ef commit a372d66

5 files changed

Lines changed: 7 additions & 97 deletions

File tree

drivers/net/dsa/sja1105/sja1105.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ struct sja1105_private {
252252
unsigned long ucast_egress_floods;
253253
unsigned long bcast_egress_floods;
254254
unsigned long hwts_tx_en;
255+
unsigned long hwts_rx_en;
255256
const struct sja1105_info *info;
256257
size_t max_xfer_len;
257258
struct spi_device *spidev;
@@ -289,7 +290,6 @@ struct sja1105_spi_message {
289290
/* From sja1105_main.c */
290291
enum sja1105_reset_reason {
291292
SJA1105_VLAN_FILTERING = 0,
292-
SJA1105_RX_HWTSTAMPING,
293293
SJA1105_AGEING_TIME,
294294
SJA1105_SCHEDULING,
295295
SJA1105_BEST_EFFORT_POLICING,

drivers/net/dsa/sja1105/sja1105_main.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -867,11 +867,11 @@ static int sja1105_init_general_params(struct sja1105_private *priv)
867867
.mac_fltres1 = SJA1105_LINKLOCAL_FILTER_A,
868868
.mac_flt1 = SJA1105_LINKLOCAL_FILTER_A_MASK,
869869
.incl_srcpt1 = true,
870-
.send_meta1 = false,
870+
.send_meta1 = true,
871871
.mac_fltres0 = SJA1105_LINKLOCAL_FILTER_B,
872872
.mac_flt0 = SJA1105_LINKLOCAL_FILTER_B_MASK,
873873
.incl_srcpt0 = true,
874-
.send_meta0 = false,
874+
.send_meta0 = true,
875875
/* Default to an invalid value */
876876
.mirr_port = priv->ds->num_ports,
877877
/* No TTEthernet */
@@ -2215,7 +2215,6 @@ static int sja1105_reload_cbs(struct sja1105_private *priv)
22152215

22162216
static const char * const sja1105_reset_reasons[] = {
22172217
[SJA1105_VLAN_FILTERING] = "VLAN filtering",
2218-
[SJA1105_RX_HWTSTAMPING] = "RX timestamping",
22192218
[SJA1105_AGEING_TIME] = "Ageing time",
22202219
[SJA1105_SCHEDULING] = "Time-aware scheduling",
22212220
[SJA1105_BEST_EFFORT_POLICING] = "Best-effort policing",

drivers/net/dsa/sja1105/sja1105_ptp.c

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -58,35 +58,10 @@ enum sja1105_ptp_clk_mode {
5858
#define ptp_data_to_sja1105(d) \
5959
container_of((d), struct sja1105_private, ptp_data)
6060

61-
/* Must be called only while the RX timestamping state of the tagger
62-
* is turned off
63-
*/
64-
static int sja1105_change_rxtstamping(struct sja1105_private *priv,
65-
bool on)
66-
{
67-
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
68-
struct sja1105_general_params_entry *general_params;
69-
struct sja1105_table *table;
70-
71-
table = &priv->static_config.tables[BLK_IDX_GENERAL_PARAMS];
72-
general_params = table->entries;
73-
general_params->send_meta1 = on;
74-
general_params->send_meta0 = on;
75-
76-
ptp_cancel_worker_sync(ptp_data->clock);
77-
skb_queue_purge(&ptp_data->skb_txtstamp_queue);
78-
skb_queue_purge(&ptp_data->skb_rxtstamp_queue);
79-
80-
return sja1105_static_config_reload(priv, SJA1105_RX_HWTSTAMPING);
81-
}
82-
8361
int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr)
8462
{
85-
struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds);
8663
struct sja1105_private *priv = ds->priv;
8764
struct hwtstamp_config config;
88-
bool rx_on;
89-
int rc;
9065

9166
if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
9267
return -EFAULT;
@@ -104,34 +79,20 @@ int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr)
10479

10580
switch (config.rx_filter) {
10681
case HWTSTAMP_FILTER_NONE:
107-
rx_on = false;
82+
priv->hwts_rx_en &= ~BIT(port);
10883
break;
10984
default:
110-
rx_on = true;
85+
priv->hwts_rx_en |= BIT(port);
11186
break;
11287
}
11388

114-
if (rx_on != tagger_data->rxtstamp_get_state(ds)) {
115-
tagger_data->rxtstamp_set_state(ds, false);
116-
117-
rc = sja1105_change_rxtstamping(priv, rx_on);
118-
if (rc < 0) {
119-
dev_err(ds->dev,
120-
"Failed to change RX timestamping: %d\n", rc);
121-
return rc;
122-
}
123-
if (rx_on)
124-
tagger_data->rxtstamp_set_state(ds, true);
125-
}
126-
12789
if (copy_to_user(ifr->ifr_data, &config, sizeof(config)))
12890
return -EFAULT;
12991
return 0;
13092
}
13193

13294
int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr)
13395
{
134-
struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds);
13596
struct sja1105_private *priv = ds->priv;
13697
struct hwtstamp_config config;
13798

@@ -140,7 +101,7 @@ int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr)
140101
config.tx_type = HWTSTAMP_TX_ON;
141102
else
142103
config.tx_type = HWTSTAMP_TX_OFF;
143-
if (tagger_data->rxtstamp_get_state(ds))
104+
if (priv->hwts_rx_en & BIT(port))
144105
config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
145106
else
146107
config.rx_filter = HWTSTAMP_FILTER_NONE;
@@ -413,11 +374,10 @@ static long sja1105_rxtstamp_work(struct ptp_clock_info *ptp)
413374

414375
bool sja1105_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb)
415376
{
416-
struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds);
417377
struct sja1105_private *priv = ds->priv;
418378
struct sja1105_ptp_data *ptp_data = &priv->ptp_data;
419379

420-
if (!tagger_data->rxtstamp_get_state(ds))
380+
if (!(priv->hwts_rx_en & BIT(port)))
421381
return false;
422382

423383
/* We need to read the full PTP clock to reconstruct the Rx

include/linux/dsa/sja1105.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,9 @@ struct sja1105_deferred_xmit_work {
4848

4949
/* Global tagger data */
5050
struct sja1105_tagger_data {
51-
/* Tagger to switch */
5251
void (*xmit_work_fn)(struct kthread_work *work);
5352
void (*meta_tstamp_handler)(struct dsa_switch *ds, int port, u8 ts_id,
5453
enum sja1110_meta_tstamp dir, u64 tstamp);
55-
/* Switch to tagger */
56-
bool (*rxtstamp_get_state)(struct dsa_switch *ds);
57-
void (*rxtstamp_set_state)(struct dsa_switch *ds, bool on);
5854
};
5955

6056
struct sja1105_skb_cb {

net/dsa/tag_sja1105.c

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,8 @@
5858
#define SJA1110_TX_TRAILER_LEN 4
5959
#define SJA1110_MAX_PADDING_LEN 15
6060

61-
#define SJA1105_HWTS_RX_EN 0
62-
6361
struct sja1105_tagger_private {
6462
struct sja1105_tagger_data data; /* Must be first */
65-
unsigned long state;
6663
/* Protects concurrent access to the meta state machine
6764
* from taggers running on multiple ports on SMP systems
6865
*/
@@ -392,10 +389,6 @@ static struct sk_buff
392389

393390
priv = sja1105_tagger_private(ds);
394391

395-
if (!test_bit(SJA1105_HWTS_RX_EN, &priv->state))
396-
/* Do normal processing. */
397-
return skb;
398-
399392
spin_lock(&priv->meta_lock);
400393
/* Was this a link-local frame instead of the meta
401394
* that we were expecting?
@@ -431,12 +424,6 @@ static struct sk_buff
431424

432425
priv = sja1105_tagger_private(ds);
433426

434-
/* Drop the meta frame if we're not in the right state
435-
* to process it.
436-
*/
437-
if (!test_bit(SJA1105_HWTS_RX_EN, &priv->state))
438-
return NULL;
439-
440427
spin_lock(&priv->meta_lock);
441428

442429
stampable_skb = priv->stampable_skb;
@@ -472,30 +459,6 @@ static struct sk_buff
472459
return skb;
473460
}
474461

475-
static bool sja1105_rxtstamp_get_state(struct dsa_switch *ds)
476-
{
477-
struct sja1105_tagger_private *priv = sja1105_tagger_private(ds);
478-
479-
return test_bit(SJA1105_HWTS_RX_EN, &priv->state);
480-
}
481-
482-
static void sja1105_rxtstamp_set_state(struct dsa_switch *ds, bool on)
483-
{
484-
struct sja1105_tagger_private *priv = sja1105_tagger_private(ds);
485-
486-
if (on)
487-
set_bit(SJA1105_HWTS_RX_EN, &priv->state);
488-
else
489-
clear_bit(SJA1105_HWTS_RX_EN, &priv->state);
490-
491-
/* Initialize the meta state machine to a known state */
492-
if (!priv->stampable_skb)
493-
return;
494-
495-
kfree_skb(priv->stampable_skb);
496-
priv->stampable_skb = NULL;
497-
}
498-
499462
static bool sja1105_skb_has_tag_8021q(const struct sk_buff *skb)
500463
{
501464
u16 tpid = ntohs(eth_hdr(skb)->h_proto);
@@ -552,9 +515,6 @@ static struct sk_buff *sja1105_rcv(struct sk_buff *skb,
552515
*/
553516
source_port = hdr->h_dest[3];
554517
switch_id = hdr->h_dest[4];
555-
/* Clear the DMAC bytes that were mangled by the switch */
556-
hdr->h_dest[3] = 0;
557-
hdr->h_dest[4] = 0;
558518
} else if (is_meta) {
559519
sja1105_meta_unpack(skb, &meta);
560520
source_port = meta.source_port;
@@ -785,7 +745,6 @@ static void sja1105_disconnect(struct dsa_switch *ds)
785745

786746
static int sja1105_connect(struct dsa_switch *ds)
787747
{
788-
struct sja1105_tagger_data *tagger_data;
789748
struct sja1105_tagger_private *priv;
790749
struct kthread_worker *xmit_worker;
791750
int err;
@@ -805,10 +764,6 @@ static int sja1105_connect(struct dsa_switch *ds)
805764
}
806765

807766
priv->xmit_worker = xmit_worker;
808-
/* Export functions for switch driver use */
809-
tagger_data = &priv->data;
810-
tagger_data->rxtstamp_get_state = sja1105_rxtstamp_get_state;
811-
tagger_data->rxtstamp_set_state = sja1105_rxtstamp_set_state;
812767
ds->tagger_data = priv;
813768

814769
return 0;

0 commit comments

Comments
 (0)