2023-06-27 16:59:44

by Vladimir Oltean

[permalink] [raw]
Subject: [PATCH v2 net 0/3] 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.

Vladimir Oltean (3):
net: mscc: ocelot: don't report that RX timestamping is enabled by
default
net: mscc: ocelot: don't keep PTP configuration of all ports in single
structure
net: dsa: felix: don't drop PTP frames with tag_8021q when RX
timestamping is disabled

drivers/net/dsa/ocelot/felix.c | 12 +++++
drivers/net/ethernet/mscc/ocelot.c | 1 -
drivers/net/ethernet/mscc/ocelot_ptp.c | 66 ++++++++++++++++----------
include/soc/mscc/ocelot.h | 10 ++--
4 files changed, 60 insertions(+), 29 deletions(-)

--
2.34.1



2023-06-27 17:00:29

by Vladimir Oltean

[permalink] [raw]
Subject: [PATCH v2 net 2/3] net: mscc: ocelot: don't keep PTP configuration of all ports in single structure

In a future change, the driver will need to determine whether PTP RX
timestamping is enabled on a port (including whether traps were set up
on that port in particular) and that is currently not possible.

The driver supports different RX filters (L2, L4) and kinds of TX
timestamping (one-step, two-step) on its ports, but it saves all
configuration in a single struct hwtstamp_config that is global to the
switch. So, the latest timestamping configuration on one port
(including a request to disable timestamping) affects what gets reported
for all ports, even though the configuration itself is still individual
to each port.

The port timestamping configurations are only coupled because of the
common structure, so replace the hwtstamp_config with a mask of trapped
protocols saved per port. We also have the ptp_cmd to distinguish
between one-step and two-step PTP timestamping, so with those 2 bits of
information we can fully reconstruct a descriptive struct
hwtstamp_config for each port, during the SIOCGHWTSTAMP ioctl.

Fixes: 4e3b0468e6d7 ("net: mscc: PTP Hardware Clock (PHC) support")
Fixes: 96ca08c05838 ("net: mscc: ocelot: set up traps for PTP packets")
Signed-off-by: Vladimir Oltean <[email protected]>
---
v1->v2: replace the ocelot_port->ptp_rx_filters (bit mask of UAPI enum
hwtstamp_rx_filters) with the hardware-specific trap_proto (bit mask of
enum ocelot_proto). This makes it easier for the next patch to
distinguish between L2 and L4 PTP (not easy when saving the UAPI format).

drivers/net/ethernet/mscc/ocelot.c | 1 -
drivers/net/ethernet/mscc/ocelot_ptp.c | 61 +++++++++++++++++---------
include/soc/mscc/ocelot.h | 10 +++--
3 files changed, 48 insertions(+), 24 deletions(-)

diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c
index 1f5f00b30441..2fa833d041ba 100644
--- a/drivers/net/ethernet/mscc/ocelot.c
+++ b/drivers/net/ethernet/mscc/ocelot.c
@@ -2925,7 +2925,6 @@ int ocelot_init(struct ocelot *ocelot)
}
}

- mutex_init(&ocelot->ptp_lock);
mutex_init(&ocelot->mact_lock);
mutex_init(&ocelot->fwd_domain_lock);
mutex_init(&ocelot->tas_lock);
diff --git a/drivers/net/ethernet/mscc/ocelot_ptp.c b/drivers/net/ethernet/mscc/ocelot_ptp.c
index 673bfd70867a..cb32234a5bf1 100644
--- a/drivers/net/ethernet/mscc/ocelot_ptp.c
+++ b/drivers/net/ethernet/mscc/ocelot_ptp.c
@@ -439,8 +439,12 @@ static int ocelot_ipv6_ptp_trap_del(struct ocelot *ocelot, int port)
static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port,
bool l2, bool l4)
{
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
int err;

+ ocelot_port->trap_proto &= ~(OCELOT_PROTO_PTP_L2 |
+ OCELOT_PROTO_PTP_L4);
+
if (l2)
err = ocelot_l2_ptp_trap_add(ocelot, port);
else
@@ -464,6 +468,11 @@ static int ocelot_setup_ptp_traps(struct ocelot *ocelot, int port,
if (err)
return err;

+ if (l2)
+ ocelot_port->trap_proto |= OCELOT_PROTO_PTP_L2;
+ if (l4)
+ ocelot_port->trap_proto |= OCELOT_PROTO_PTP_L4;
+
return 0;

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

+static int ocelot_traps_to_ptp_rx_filter(unsigned int proto)
+{
+ if ((proto & OCELOT_PROTO_PTP_L2) && (proto & OCELOT_PROTO_PTP_L4))
+ return HWTSTAMP_FILTER_PTP_V2_EVENT;
+ else if (proto & OCELOT_PROTO_PTP_L2)
+ return HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
+ else if (proto & OCELOT_PROTO_PTP_L4)
+ return HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
+
+ return HWTSTAMP_FILTER_NONE;
+}
+
int ocelot_hwstamp_get(struct ocelot *ocelot, int port, struct ifreq *ifr)
{
- return copy_to_user(ifr->ifr_data, &ocelot->hwtstamp_config,
- sizeof(ocelot->hwtstamp_config)) ? -EFAULT : 0;
+ struct ocelot_port *ocelot_port = ocelot->ports[port];
+ struct hwtstamp_config cfg = {};
+
+ switch (ocelot_port->ptp_cmd) {
+ case IFH_REW_OP_TWO_STEP_PTP:
+ cfg.tx_type = HWTSTAMP_TX_ON;
+ break;
+ case IFH_REW_OP_ORIGIN_PTP:
+ cfg.tx_type = HWTSTAMP_TX_ONESTEP_SYNC;
+ break;
+ default:
+ cfg.tx_type = HWTSTAMP_TX_OFF;
+ break;
+ }
+
+ cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto);
+
+ return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
}
EXPORT_SYMBOL(ocelot_hwstamp_get);

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

- mutex_lock(&ocelot->ptp_lock);
-
switch (cfg.rx_filter) {
case HWTSTAMP_FILTER_NONE:
break;
@@ -531,28 +566,14 @@ int ocelot_hwstamp_set(struct ocelot *ocelot, int port, struct ifreq *ifr)
l4 = true;
break;
default:
- mutex_unlock(&ocelot->ptp_lock);
return -ERANGE;
}

err = ocelot_setup_ptp_traps(ocelot, port, l2, l4);
- if (err) {
- mutex_unlock(&ocelot->ptp_lock);
+ if (err)
return err;
- }
-
- if (l2 && l4)
- cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
- else if (l2)
- cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L2_EVENT;
- else if (l4)
- cfg.rx_filter = HWTSTAMP_FILTER_PTP_V2_L4_EVENT;
- else
- cfg.rx_filter = HWTSTAMP_FILTER_NONE;

- /* Commit back the result & save it */
- memcpy(&ocelot->hwtstamp_config, &cfg, sizeof(cfg));
- mutex_unlock(&ocelot->ptp_lock);
+ cfg.rx_filter = ocelot_traps_to_ptp_rx_filter(ocelot_port->trap_proto);

return copy_to_user(ifr->ifr_data, &cfg, sizeof(cfg)) ? -EFAULT : 0;
}
diff --git a/include/soc/mscc/ocelot.h b/include/soc/mscc/ocelot.h
index cb8fbb241879..22aae505c813 100644
--- a/include/soc/mscc/ocelot.h
+++ b/include/soc/mscc/ocelot.h
@@ -730,6 +730,11 @@ enum macaccess_entry_type {
ENTRYTYPE_MACv6,
};

+enum ocelot_proto {
+ OCELOT_PROTO_PTP_L2 = BIT(0),
+ OCELOT_PROTO_PTP_L4 = BIT(1),
+};
+
#define OCELOT_QUIRK_PCS_PERFORMS_RATE_ADAPTATION BIT(0)
#define OCELOT_QUIRK_QSGMII_PORTS_MUST_BE_UP BIT(1)

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

+ unsigned int trap_proto;
+
u16 mrp_ring_id;

u8 ptp_cmd;
@@ -868,12 +875,9 @@ struct ocelot {
u8 mm_supported:1;
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_info;
- struct hwtstamp_config hwtstamp_config;
unsigned int ptp_skbs_in_flight;
/* Protects the 2-step TX timestamp ID logic */
spinlock_t ts_id_lock;
- /* Protects the PTP interface state */
- struct mutex ptp_lock;
/* Protects the PTP clock */
spinlock_t ptp_clock_lock;
struct ptp_pin_desc ptp_pins[OCELOT_PTP_PINS_NUM];
--
2.34.1


2023-06-29 11:43:34

by patchwork-bot+netdevbpf

[permalink] [raw]
Subject: Re: [PATCH v2 net 0/3] Fix PTP packet drops with ocelot-8021q DSA tag protocol

Hello:

This series was applied to netdev/net.git (main)
by Paolo Abeni <[email protected]>:

On Tue, 27 Jun 2023 19:31:11 +0300 you wrote:
> 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.
>
> [...]

Here is the summary with links:
- [v2,net,1/3] net: mscc: ocelot: don't report that RX timestamping is enabled by default
https://git.kernel.org/netdev/net/c/4fd44b82b7ac
- [v2,net,2/3] net: mscc: ocelot: don't keep PTP configuration of all ports in single structure
https://git.kernel.org/netdev/net/c/45d0fcb5bc95
- [v2,net,3/3] net: dsa: felix: don't drop PTP frames with tag_8021q when RX timestamping is disabled
https://git.kernel.org/netdev/net/c/2edcfcbb3c59

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html