Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: dsa: sja1105: always enable the send_meta options

incl_srcpt has the limitation, mentioned in commit b4638af8885a ("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 42824463d38d ("net: dsa: sja1105: Limit use of
incl_srcpt to bridge+vlan mode"), then again with b4638af8885a ("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: 227d07a07ef1 ("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>

authored by

Vladimir Oltean and committed by
David S. Miller
a372d66a 1dcf6efd

+7 -97
+1 -1
drivers/net/dsa/sja1105/sja1105.h
··· 252 252 unsigned long ucast_egress_floods; 253 253 unsigned long bcast_egress_floods; 254 254 unsigned long hwts_tx_en; 255 + unsigned long hwts_rx_en; 255 256 const struct sja1105_info *info; 256 257 size_t max_xfer_len; 257 258 struct spi_device *spidev; ··· 290 289 /* From sja1105_main.c */ 291 290 enum sja1105_reset_reason { 292 291 SJA1105_VLAN_FILTERING = 0, 293 - SJA1105_RX_HWTSTAMPING, 294 292 SJA1105_AGEING_TIME, 295 293 SJA1105_SCHEDULING, 296 294 SJA1105_BEST_EFFORT_POLICING,
+2 -3
drivers/net/dsa/sja1105/sja1105_main.c
··· 867 867 .mac_fltres1 = SJA1105_LINKLOCAL_FILTER_A, 868 868 .mac_flt1 = SJA1105_LINKLOCAL_FILTER_A_MASK, 869 869 .incl_srcpt1 = true, 870 - .send_meta1 = false, 870 + .send_meta1 = true, 871 871 .mac_fltres0 = SJA1105_LINKLOCAL_FILTER_B, 872 872 .mac_flt0 = SJA1105_LINKLOCAL_FILTER_B_MASK, 873 873 .incl_srcpt0 = true, 874 - .send_meta0 = false, 874 + .send_meta0 = true, 875 875 /* Default to an invalid value */ 876 876 .mirr_port = priv->ds->num_ports, 877 877 /* No TTEthernet */ ··· 2215 2215 2216 2216 static const char * const sja1105_reset_reasons[] = { 2217 2217 [SJA1105_VLAN_FILTERING] = "VLAN filtering", 2218 - [SJA1105_RX_HWTSTAMPING] = "RX timestamping", 2219 2218 [SJA1105_AGEING_TIME] = "Ageing time", 2220 2219 [SJA1105_SCHEDULING] = "Time-aware scheduling", 2221 2220 [SJA1105_BEST_EFFORT_POLICING] = "Best-effort policing",
+4 -44
drivers/net/dsa/sja1105/sja1105_ptp.c
··· 58 58 #define ptp_data_to_sja1105(d) \ 59 59 container_of((d), struct sja1105_private, ptp_data) 60 60 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 - 83 61 int sja1105_hwtstamp_set(struct dsa_switch *ds, int port, struct ifreq *ifr) 84 62 { 85 - struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds); 86 63 struct sja1105_private *priv = ds->priv; 87 64 struct hwtstamp_config config; 88 - bool rx_on; 89 - int rc; 90 65 91 66 if (copy_from_user(&config, ifr->ifr_data, sizeof(config))) 92 67 return -EFAULT; ··· 79 104 80 105 switch (config.rx_filter) { 81 106 case HWTSTAMP_FILTER_NONE: 82 - rx_on = false; 107 + priv->hwts_rx_en &= ~BIT(port); 83 108 break; 84 109 default: 85 - rx_on = true; 110 + priv->hwts_rx_en |= BIT(port); 86 111 break; 87 - } 88 - 89 - if (rx_on != tagger_data->rxtstamp_get_state(ds)) { 90 - tagger_data->rxtstamp_set_state(ds, false); 91 - 92 - rc = sja1105_change_rxtstamping(priv, rx_on); 93 - if (rc < 0) { 94 - dev_err(ds->dev, 95 - "Failed to change RX timestamping: %d\n", rc); 96 - return rc; 97 - } 98 - if (rx_on) 99 - tagger_data->rxtstamp_set_state(ds, true); 100 112 } 101 113 102 114 if (copy_to_user(ifr->ifr_data, &config, sizeof(config))) ··· 93 131 94 132 int sja1105_hwtstamp_get(struct dsa_switch *ds, int port, struct ifreq *ifr) 95 133 { 96 - struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds); 97 134 struct sja1105_private *priv = ds->priv; 98 135 struct hwtstamp_config config; 99 136 ··· 101 140 config.tx_type = HWTSTAMP_TX_ON; 102 141 else 103 142 config.tx_type = HWTSTAMP_TX_OFF; 104 - if (tagger_data->rxtstamp_get_state(ds)) 143 + if (priv->hwts_rx_en & BIT(port)) 105 144 config.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT; 106 145 else 107 146 config.rx_filter = HWTSTAMP_FILTER_NONE; ··· 374 413 375 414 bool sja1105_rxtstamp(struct dsa_switch *ds, int port, struct sk_buff *skb) 376 415 { 377 - struct sja1105_tagger_data *tagger_data = sja1105_tagger_data(ds); 378 416 struct sja1105_private *priv = ds->priv; 379 417 struct sja1105_ptp_data *ptp_data = &priv->ptp_data; 380 418 381 - if (!tagger_data->rxtstamp_get_state(ds)) 419 + if (!(priv->hwts_rx_en & BIT(port))) 382 420 return false; 383 421 384 422 /* We need to read the full PTP clock to reconstruct the Rx
-4
include/linux/dsa/sja1105.h
··· 48 48 49 49 /* Global tagger data */ 50 50 struct sja1105_tagger_data { 51 - /* Tagger to switch */ 52 51 void (*xmit_work_fn)(struct kthread_work *work); 53 52 void (*meta_tstamp_handler)(struct dsa_switch *ds, int port, u8 ts_id, 54 53 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); 58 54 }; 59 55 60 56 struct sja1105_skb_cb {
-45
net/dsa/tag_sja1105.c
··· 58 58 #define SJA1110_TX_TRAILER_LEN 4 59 59 #define SJA1110_MAX_PADDING_LEN 15 60 60 61 - #define SJA1105_HWTS_RX_EN 0 62 - 63 61 struct sja1105_tagger_private { 64 62 struct sja1105_tagger_data data; /* Must be first */ 65 - unsigned long state; 66 63 /* Protects concurrent access to the meta state machine 67 64 * from taggers running on multiple ports on SMP systems 68 65 */ ··· 389 392 390 393 priv = sja1105_tagger_private(ds); 391 394 392 - if (!test_bit(SJA1105_HWTS_RX_EN, &priv->state)) 393 - /* Do normal processing. */ 394 - return skb; 395 - 396 395 spin_lock(&priv->meta_lock); 397 396 /* Was this a link-local frame instead of the meta 398 397 * that we were expecting? ··· 424 431 425 432 priv = sja1105_tagger_private(ds); 426 433 427 - /* Drop the meta frame if we're not in the right state 428 - * to process it. 429 - */ 430 - if (!test_bit(SJA1105_HWTS_RX_EN, &priv->state)) 431 - return NULL; 432 - 433 434 spin_lock(&priv->meta_lock); 434 435 435 436 stampable_skb = priv->stampable_skb; ··· 457 470 } 458 471 459 472 return skb; 460 - } 461 - 462 - static bool sja1105_rxtstamp_get_state(struct dsa_switch *ds) 463 - { 464 - struct sja1105_tagger_private *priv = sja1105_tagger_private(ds); 465 - 466 - return test_bit(SJA1105_HWTS_RX_EN, &priv->state); 467 - } 468 - 469 - static void sja1105_rxtstamp_set_state(struct dsa_switch *ds, bool on) 470 - { 471 - struct sja1105_tagger_private *priv = sja1105_tagger_private(ds); 472 - 473 - if (on) 474 - set_bit(SJA1105_HWTS_RX_EN, &priv->state); 475 - else 476 - clear_bit(SJA1105_HWTS_RX_EN, &priv->state); 477 - 478 - /* Initialize the meta state machine to a known state */ 479 - if (!priv->stampable_skb) 480 - return; 481 - 482 - kfree_skb(priv->stampable_skb); 483 - priv->stampable_skb = NULL; 484 473 } 485 474 486 475 static bool sja1105_skb_has_tag_8021q(const struct sk_buff *skb) ··· 515 552 */ 516 553 source_port = hdr->h_dest[3]; 517 554 switch_id = hdr->h_dest[4]; 518 - /* Clear the DMAC bytes that were mangled by the switch */ 519 - hdr->h_dest[3] = 0; 520 - hdr->h_dest[4] = 0; 521 555 } else if (is_meta) { 522 556 sja1105_meta_unpack(skb, &meta); 523 557 source_port = meta.source_port; ··· 745 785 746 786 static int sja1105_connect(struct dsa_switch *ds) 747 787 { 748 - struct sja1105_tagger_data *tagger_data; 749 788 struct sja1105_tagger_private *priv; 750 789 struct kthread_worker *xmit_worker; 751 790 int err; ··· 764 805 } 765 806 766 807 priv->xmit_worker = xmit_worker; 767 - /* Export functions for switch driver use */ 768 - tagger_data = &priv->data; 769 - tagger_data->rxtstamp_get_state = sja1105_rxtstamp_get_state; 770 - tagger_data->rxtstamp_set_state = sja1105_rxtstamp_set_state; 771 808 ds->tagger_data = priv; 772 809 773 810 return 0;