Skip to content

Commit e999c89

Browse files
author
Paolo Abeni
committed
Merge branch 'fix-ptp-packet-drops-with-ocelot-8021q-dsa-tag-protocol'
Vladimir Oltean says: ==================== Fix PTP packet drops with ocelot-8021q DSA tag protocol Changes in v2: - Distinguish between L2 and L4 PTP packets v1 at: https://lore.kernel.org/netdev/[email protected]/ Patch 3/3 fixes an issue with the ocelot/felix driver, where it would drop PTP traffic on RX unless hardware timestamping for that packet type was enabled. Fixing that requires the driver to know whether it had previously configured the hardware to timestamp PTP packets on that port. But it cannot correctly determine that today using the existing code structure, so patches 1/3 and 2/3 fix the control path of the code such that ocelot->ports[port]->trap_proto faithfully reflects whether that configuration took place. ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Paolo Abeni <[email protected]>
2 parents 3c4bb45 + 2edcfcb commit e999c89

File tree

4 files changed

+60
-29
lines changed

4 files changed

+60
-29
lines changed

drivers/net/dsa/ocelot/felix.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1725,6 +1725,18 @@ static bool felix_rxtstamp(struct dsa_switch *ds, int port,
17251725
u32 tstamp_hi;
17261726
u64 tstamp;
17271727

1728+
switch (type & PTP_CLASS_PMASK) {
1729+
case PTP_CLASS_L2:
1730+
if (!(ocelot->ports[port]->trap_proto & OCELOT_PROTO_PTP_L2))
1731+
return false;
1732+
break;
1733+
case PTP_CLASS_IPV4:
1734+
case PTP_CLASS_IPV6:
1735+
if (!(ocelot->ports[port]->trap_proto & OCELOT_PROTO_PTP_L4))
1736+
return false;
1737+
break;
1738+
}
1739+
17281740
/* If the "no XTR IRQ" workaround is in use, tell DSA to defer this skb
17291741
* for RX timestamping. Then free it, and poll for its copy through
17301742
* MMIO in the CPU port module, and inject that into the stack from

drivers/net/ethernet/mscc/ocelot.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2925,7 +2925,6 @@ int ocelot_init(struct ocelot *ocelot)
29252925
}
29262926
}
29272927

2928-
mutex_init(&ocelot->ptp_lock);
29292928
mutex_init(&ocelot->mact_lock);
29302929
mutex_init(&ocelot->fwd_domain_lock);
29312930
mutex_init(&ocelot->tas_lock);

drivers/net/ethernet/mscc/ocelot_ptp.c

Lines changed: 41 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -439,8 +439,12 @@ static int ocelot_ipv6_ptp_trap_del(struct ocelot *ocelot, int port)
439439
static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port,
440440
bool l2, bool l4)
441441
{
442+
struct ocelot_port *ocelot_port = ocelot->ports[port];
442443
int err;
443444

445+
ocelot_port->trap_proto &= ~(OCELOT_PROTO_PTP_L2 |
446+
OCELOT_PROTO_PTP_L4);
447+
444448
if (l2)
445449
err = ocelot_l2_ptp_trap_add(ocelot, port);
446450
else
@@ -464,6 +468,11 @@ static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port,
464468
if (err)
465469
return err;
466470

471+
if (l2)
472+
ocelot_port->trap_proto |= OCELOT_PROTO_PTP_L2;
473+
if (l4)
474+
ocelot_port->trap_proto |= OCELOT_PROTO_PTP_L4;
475+
467476
return 0;
468477

469478
err_ipv6:
@@ -474,10 +483,38 @@ static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port,
474483
return err;
475484
}
476485

486+
static int ocelot_traps_to_ptp_rx_filter(unsigned int proto)
487+
{
488+
if ((proto & OCELOT_PROTO_PTP_L2) && (proto & OCELOT_PROTO_PTP_L4))
489+
return HWTSTAMP_FILTER_PTP_V2_EVENT;
490+
else if (proto & OCELOT_PROTO_PTP_L2)
491+
return HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
492+
else if (proto & OCELOT_PROTO_PTP_L4)
493+
return HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
494+
495+
return HWTSTAMP_FILTER_NONE;
496+
}
497+
477498
int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr)
478499
{
479-
return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config,
480-
sizeof(ocelot->hwtstamp_config)) ? -EFAULT : 0;
500+
struct ocelot_port *ocelot_port = ocelot->ports[port];
501+
struct hwtstamp_config cfg = {};
502+
503+
switch (ocelot_port->ptp_cmd) {
504+
case IFH_REW_OP_TWO_STEP_PTP:
505+
cfg.tx_type = HWTSTAMP_TX_ON;
506+
break;
507+
case IFH_REW_OP_ORIGIN_PTP:
508+
cfg.tx_type = HWTSTAMP_TX_ONESTEP_SYNC;
509+
break;
510+
default:
511+
cfg.tx_type = HWTSTAMP_TX_OFF;
512+
break;
513+
}
514+
515+
cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto);
516+
517+
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
481518
}
482519
EXPORT_SYMBOL(ocelot_hwstamp_get);
483520

@@ -509,8 +546,6 @@ int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr)
509546
return -ERANGE;
510547
}
511548

512-
mutex_lock(&ocelot->ptp_lock);
513-
514549
switch (cfg.rx_filter) {
515550
case HWTSTAMP_FILTER_NONE:
516551
break;
@@ -531,28 +566,14 @@ int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr)
531566
l4 = true;
532567
break;
533568
default:
534-
mutex_unlock(&ocelot->ptp_lock);
535569
return -ERANGE;
536570
}
537571

538572
err = ocelot_setup_ptp_traps(ocelot, port, l2, l4);
539-
if (err) {
540-
mutex_unlock(&ocelot->ptp_lock);
573+
if (err)
541574
return err;
542-
}
543575

544-
if (l2 && l4)
545-
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
546-
else if (l2)
547-
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
548-
else if (l4)
549-
cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
550-
else
551-
cfg.rx_filter = HWTSTAMP_FILTER_NONE;
552-
553-
/* Commit back the result & save it */
554-
memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg));
555-
mutex_unlock(&ocelot->ptp_lock);
576+
cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto);
556577

557578
return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
558579
}
@@ -824,11 +845,6 @@ int ocelot_init_timestamp(struct ocelot *ocelot,
824845

825846
ocelot_write(ocelot, PTP_CFG_MISC_PTP_EN, PTP_CFG_MISC);
826847

827-
/* There is no device reconfiguration, PTP Rx stamping is always
828-
* enabled.
829-
*/
830-
ocelot->hwtstamp_config.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
831-
832848
return 0;
833849
}
834850
EXPORT_SYMBOL(ocelot_init_timestamp);

include/soc/mscc/ocelot.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,11 @@ enum macaccess_entry_type {
730730
ENTRYTYPE_MACv6,
731731
};
732732

733+
enum ocelot_proto {
734+
OCELOT_PROTO_PTP_L2 = BIT(0),
735+
OCELOT_PROTO_PTP_L4 = BIT(1),
736+
};
737+
733738
#define OCELOT_QUIRK_PCS_PERFORMS_RATE_ADAPTATION BIT(0)
734739
#define OCELOT_QUIRK_QSGMII_PORTS_MUST_BE_UP BIT(1)
735740

@@ -775,6 +780,8 @@ struct ocelot_port {
775780
unsigned int ptp_skbs_in_flight;
776781
struct sk_buff_head tx_skbs;
777782

783+
unsigned int trap_proto;
784+
778785
u16 mrp_ring_id;
779786

780787
u8 ptp_cmd;
@@ -868,12 +875,9 @@ struct ocelot {
868875
u8 mm_supported:1;
869876
struct ptp_clock *ptp_clock;
870877
struct ptp_clock_info ptp_info;
871-
struct hwtstamp_config hwtstamp_config;
872878
unsigned int ptp_skbs_in_flight;
873879
/* Protects the 2-step TX timestamp ID logic */
874880
spinlock_t ts_id_lock;
875-
/* Protects the PTP interface state */
876-
struct mutex ptp_lock;
877881
/* Protects the PTP clock */
878882
spinlock_t ptp_clock_lock;
879883
struct ptp_pin_desc ptp_pins[OCELOT_PTP_PINS_NUM];

0 commit comments

Comments
 (0)