Commit 7c571ac5 authored by Jacob Keller's avatar Jacob Keller Committed by Jakub Kicinski
Browse files

net: ptp: introduce .supported_extts_flags to ptp_clock_info



The PTP_EXTTS_REQUEST(2) ioctl has a flags field which specifies how the
external timestamp request should behave. This includes which edge of the
signal to timestamp, as well as a specialized "offset" mode. It is expected
that more flags will be added in the future.

Driver authors routinely do not check the flags, often accepting requests
with flags which they do not support. Even drivers which do check flags may
not be future-proofed to reject flags not yet defined. Thus, any future
flag additions often require manually updating drivers to reject these
flags.

This approach of hoping we catch flag checks during review, or playing
whack-a-mole after the fact is the wrong approach.

Introduce the "supported_extts_flags" field to the ptp_clock_info
structure. This field defines the set of flags the device actually
supports.

Update the core character device logic to check this field and reject
unsupported requests. Getting this right is somewhat tricky. First, to
avoid unnecessary repetition and make basic functionality work when
.supported_extts_flags is 0, the core always accepts the PTP_ENABLE_FEATURE
flag. This flag is used to set the 'on' parameter to the .enable function
and is thus always 'supported' by all drivers.

For backwards compatibility, the PTP_RISING_EDGE and PTP_FALLING_EDGE flags
are merely "hints" when using the old PTP_EXTTS_REQUEST ioctl, and are not
expected to be enforced. If the user issues PTP_EXTTS_REQUEST2, the
PTP_STRICT_FLAGS flag is added which is supposed to inform the driver to
strictly validate the flags and reject unsupported requests. To handle
this, first check if the driver reports PTP_STRICT_FLAGS support. If it
does not, then always allow the PTP_RISING_EDGE and PTP_FALLING_EDGE flags.
This keeps backwards compatibility with the original PTP_EXTTS_REQUEST
ioctl where these flags are not guaranteed to be honored.

This way, drivers which do not set the supported_extts_flags will continue
to accept requests for the original PTP_EXTTS_REQUEST ioctl. The core will
automatically reject requests with new flags, and correctly reject requests
with PTP_STRICT_FLAGS, where the driver is supposed to strictly validate
the flags.

Update the various drivers, refactoring their validation logic into the
.supported_extts_flags field. For consistency and readability,
PTP_ENABLE_FEATURE is not set in the supported flags list, and
PTP_EXTTS_EDGES is expanded to PTP_RISING_EDGE | PTP_FALLING_EDGE in all
cases.

Note the following driver files set n_ext_ts to a non-zero value but did
not check flags at all:

 • drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
 • drivers/net/ethernet/freescale/enetc/enetc_ptp.c
 • drivers/net/ethernet/intel/i40e/i40e_ptp.c
 • drivers/net/ethernet/marvell/octeontx2/nic/otx2_ptp.c
 • drivers/net/ethernet/renesas/ravb_ptp.c
 • drivers/net/ethernet/renesas/rtsn.c
 • drivers/net/ethernet/renesas/rtsn.h
 • drivers/net/ethernet/ti/am65-cpts.c
 • drivers/net/ethernet/ti/cpts.h
 • drivers/net/ethernet/ti/icssg/icss_iep.c
 • drivers/net/ethernet/xscale/ptp_ixp46x.c
 • drivers/net/phy/bcm-phy-ptp.c
 • drivers/ptp/ptp_ocp.c
 • drivers/ptp/ptp_pch.c
 • drivers/ptp/ptp_qoriq.c

These drivers behavior does change slightly: they will now reject the
PTP_EXTTS_REQUEST2 ioctl, because they do not strictly validate their
flags. This also makes them no longer incorrectly accept PTP_EXT_OFFSET.

Also note that the renesas ravb driver does not support PTP_STRICT_FLAGS.
We could leave the .supported_extts_flags as 0, but I added the
PTP_RISING_EDGE | PTP_FALLING_EDGE since the driver previously manually
validated these flags. This is equivalent to 0 because the core will allow
these flags regardless unless PTP_STRICT_FLAGS is also set.

Signed-off-by: default avatarJacob Keller <jacob.e.keller@intel.com>
Reviewed-by: default avatarKory Maincent <kory.maincent@bootlin.com>
Link: https://patch.msgid.link/20250414-jk-supported-perout-flags-v2-1-f6b17d15475c@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent a496d2f0
Loading
Loading
Loading
Loading
+4 −7
Original line number Diff line number Diff line
@@ -332,13 +332,6 @@ static int mv88e6352_ptp_enable_extts(struct mv88e6xxx_chip *chip,
	int pin;
	int err;

	/* Reject requests with unsupported flags */
	if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |
				PTP_RISING_EDGE |
				PTP_FALLING_EDGE |
				PTP_STRICT_FLAGS))
		return -EOPNOTSUPP;

	/* Reject requests to enable time stamping on both edges. */
	if ((rq->extts.flags & PTP_STRICT_FLAGS) &&
	    (rq->extts.flags & PTP_ENABLE_FEATURE) &&
@@ -566,6 +559,10 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
	chip->ptp_clock_info.verify	= ptp_ops->ptp_verify;
	chip->ptp_clock_info.do_aux_work = mv88e6xxx_hwtstamp_work;

	chip->ptp_clock_info.supported_extts_flags = PTP_RISING_EDGE |
						     PTP_FALLING_EDGE |
						     PTP_STRICT_FLAGS;

	if (ptp_ops->set_ptp_cpu_port) {
		struct dsa_port *dp;
		int upstream = 0;
+3 −7
Original line number Diff line number Diff line
@@ -820,13 +820,6 @@ static int sja1105_extts_enable(struct sja1105_private *priv,
	if (extts->index != 0)
		return -EOPNOTSUPP;

	/* Reject requests with unsupported flags */
	if (extts->flags & ~(PTP_ENABLE_FEATURE |
			     PTP_RISING_EDGE |
			     PTP_FALLING_EDGE |
			     PTP_STRICT_FLAGS))
		return -EOPNOTSUPP;

	/* We can only enable time stamping on both edges, sadly. */
	if ((extts->flags & PTP_STRICT_FLAGS) &&
	    (extts->flags & PTP_ENABLE_FEATURE) &&
@@ -912,6 +905,9 @@ int sja1105_ptp_clock_register(struct dsa_switch *ds)
		.n_pins		= 1,
		.n_ext_ts	= 1,
		.n_per_out	= 1,
		.supported_extts_flags = PTP_RISING_EDGE |
					 PTP_FALLING_EDGE |
					 PTP_STRICT_FLAGS,
	};

	/* Only used on SJA1105 */
+4 −8
Original line number Diff line number Diff line
@@ -1627,14 +1627,6 @@ static int ice_ptp_cfg_extts(struct ice_pf *pf, struct ptp_extts_request *rq,
	int pin_desc_idx;
	u8 tmr_idx;

	/* Reject requests with unsupported flags */

	if (rq->flags & ~(PTP_ENABLE_FEATURE |
			  PTP_RISING_EDGE |
			  PTP_FALLING_EDGE |
			  PTP_STRICT_FLAGS))
		return -EOPNOTSUPP;

	tmr_idx = hw->func_caps.ts_func_info.tmr_index_owned;
	chan = rq->index;

@@ -2740,6 +2732,10 @@ static void ice_ptp_set_caps(struct ice_pf *pf)
	info->enable = ice_ptp_gpio_enable;
	info->verify = ice_verify_pin;

	info->supported_extts_flags = PTP_RISING_EDGE |
				      PTP_FALLING_EDGE |
				      PTP_STRICT_FLAGS;

	switch (pf->hw.mac_type) {
	case ICE_MAC_E810:
		ice_ptp_set_funcs_e810(pf);
+6 −14
Original line number Diff line number Diff line
@@ -502,13 +502,6 @@ static int igb_ptp_feature_enable_82580(struct ptp_clock_info *ptp,

	switch (rq->type) {
	case PTP_CLK_REQ_EXTTS:
		/* Reject requests with unsupported flags */
		if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |
					PTP_RISING_EDGE |
					PTP_FALLING_EDGE |
					PTP_STRICT_FLAGS))
			return -EOPNOTSUPP;

		/* Both the rising and falling edge are timestamped */
		if (rq->extts.flags & PTP_STRICT_FLAGS &&
		    (rq->extts.flags & PTP_ENABLE_FEATURE) &&
@@ -658,13 +651,6 @@ static int igb_ptp_feature_enable_i210(struct ptp_clock_info *ptp,

	switch (rq->type) {
	case PTP_CLK_REQ_EXTTS:
		/* Reject requests with unsupported flags */
		if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |
					PTP_RISING_EDGE |
					PTP_FALLING_EDGE |
					PTP_STRICT_FLAGS))
			return -EOPNOTSUPP;

		/* Reject requests failing to enable both edges. */
		if ((rq->extts.flags & PTP_STRICT_FLAGS) &&
		    (rq->extts.flags & PTP_ENABLE_FEATURE) &&
@@ -1356,6 +1342,9 @@ void igb_ptp_init(struct igb_adapter *adapter)
		adapter->ptp_caps.n_per_out = IGB_N_PEROUT;
		adapter->ptp_caps.n_pins = IGB_N_SDP;
		adapter->ptp_caps.pps = 0;
		adapter->ptp_caps.supported_extts_flags = PTP_RISING_EDGE |
							  PTP_FALLING_EDGE |
							  PTP_STRICT_FLAGS;
		adapter->ptp_caps.pin_config = adapter->sdp_config;
		adapter->ptp_caps.adjfine = igb_ptp_adjfine_82580;
		adapter->ptp_caps.adjtime = igb_ptp_adjtime_82576;
@@ -1378,6 +1367,9 @@ void igb_ptp_init(struct igb_adapter *adapter)
		adapter->ptp_caps.n_ext_ts = IGB_N_EXTTS;
		adapter->ptp_caps.n_per_out = IGB_N_PEROUT;
		adapter->ptp_caps.n_pins = IGB_N_SDP;
		adapter->ptp_caps.supported_extts_flags = PTP_RISING_EDGE |
							  PTP_FALLING_EDGE |
							  PTP_STRICT_FLAGS;
		adapter->ptp_caps.pps = 1;
		adapter->ptp_caps.pin_config = adapter->sdp_config;
		adapter->ptp_caps.adjfine = igb_ptp_adjfine_82580;
+3 −7
Original line number Diff line number Diff line
@@ -257,13 +257,6 @@ static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp,

	switch (rq->type) {
	case PTP_CLK_REQ_EXTTS:
		/* Reject requests with unsupported flags */
		if (rq->extts.flags & ~(PTP_ENABLE_FEATURE |
					PTP_RISING_EDGE |
					PTP_FALLING_EDGE |
					PTP_STRICT_FLAGS))
			return -EOPNOTSUPP;

		/* Reject requests failing to enable both edges. */
		if ((rq->extts.flags & PTP_STRICT_FLAGS) &&
		    (rq->extts.flags & PTP_ENABLE_FEATURE) &&
@@ -1146,6 +1139,9 @@ void igc_ptp_init(struct igc_adapter *adapter)
		adapter->ptp_caps.pin_config = adapter->sdp_config;
		adapter->ptp_caps.n_ext_ts = IGC_N_EXTTS;
		adapter->ptp_caps.n_per_out = IGC_N_PEROUT;
		adapter->ptp_caps.supported_extts_flags = PTP_RISING_EDGE |
							  PTP_FALLING_EDGE |
							  PTP_STRICT_FLAGS;
		adapter->ptp_caps.n_pins = IGC_N_SDP;
		adapter->ptp_caps.verify = igc_ptp_verify_pin;

Loading