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

net: ptp: introduce .supported_perout_flags to ptp_clock_info



The PTP_PEROUT_REQUEST2 ioctl has gained support for flags specifying
specific output behavior including PTP_PEROUT_ONE_SHOT,
PTP_PEROUT_DUTY_CYCLE, PTP_PEROUT_PHASE.

Driver authors are notorious for not checking the flags of the request.
This results in misinterpreting the request, generating an output signal
that does not match the requested value. It is anticipated that even more
flags will be added in the future, resulting in even more broken requests.

Expecting these issues to be caught during review or playing whack-a-mole
after the fact is not a great solution.

Instead, introduce the supported_perout_flags field in the ptp_clock_info
structure. Update the core character device logic to explicitly reject any
request which has a flag not on this list.

This ensures that drivers must 'opt in' to the flags they support. Drivers
which don't set the .supported_perout_flags field will not need to check
that unsupported flags aren't passed, as the core takes care of this.

Update the drivers which do support flags to set this new field.

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

 • drivers/ptp/ptp_clockmatrix.c
 • drivers/ptp/ptp_idt82p33.c
 • drivers/ptp/ptp_fc3.c
 • drivers/net/ethernet/ti/am65-cpts.c
 • drivers/net/ethernet/aquantia/atlantic/aq_ptp.c
 • drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
 • drivers/net/dsa/sja1105/sja1105_ptp.c
 • drivers/net/ethernet/freescale/dpaa2/dpaa2-ptp.c
 • drivers/net/ethernet/mscc/ocelot_vsc7514.c
 • drivers/net/ethernet/intel/i40e/i40e_ptp.c

Reviewed-by: default avatarVadim Fedorenko <vadim.fedorenko@linux.dev>
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-2-f6b17d15475c@intel.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 7c571ac5
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -737,10 +737,6 @@ static int sja1105_per_out_enable(struct sja1105_private *priv,
	if (perout->index != 0)
		return -EOPNOTSUPP;

	/* Reject requests with unsupported flags */
	if (perout->flags)
		return -EOPNOTSUPP;

	mutex_lock(&ptp_data->lock);

	rc = sja1105_change_ptp_clk_pin_func(priv, PTP_PF_PEROUT);
+1 −3
Original line number Diff line number Diff line
@@ -1797,9 +1797,6 @@ static int ice_ptp_cfg_perout(struct ice_pf *pf, struct ptp_perout_request *rq,
	struct ice_hw *hw = &pf->hw;
	int pin_desc_idx;

	if (rq->flags & ~PTP_PEROUT_PHASE)
		return -EOPNOTSUPP;

	pin_desc_idx = ice_ptp_find_pin_idx(pf, PTP_PF_PEROUT, rq->index);
	if (pin_desc_idx < 0)
		return -EIO;
@@ -2735,6 +2732,7 @@ static void ice_ptp_set_caps(struct ice_pf *pf)
	info->supported_extts_flags = PTP_RISING_EDGE |
				      PTP_FALLING_EDGE |
				      PTP_STRICT_FLAGS;
	info->supported_perout_flags = PTP_PEROUT_PHASE;

	switch (pf->hw.mac_type) {
	case ICE_MAC_E810:
+0 −4
Original line number Diff line number Diff line
@@ -293,10 +293,6 @@ static int igc_ptp_feature_enable_i225(struct ptp_clock_info *ptp,
		return 0;

	case PTP_CLK_REQ_PEROUT:
		/* Reject requests with unsupported flags */
		if (rq->perout.flags)
			return -EOPNOTSUPP;

		if (on) {
			pin = ptp_find_pin(igc->ptp_clock, PTP_PF_PEROUT,
					   rq->perout.index);
+3 −12
Original line number Diff line number Diff line
@@ -813,12 +813,6 @@ static int perout_conf_npps_real_time(struct mlx5_core_dev *mdev, struct ptp_clo
	return 0;
}

static bool mlx5_perout_verify_flags(struct mlx5_core_dev *mdev, unsigned int flags)
{
	return ((!mlx5_npps_real_time_supported(mdev) && flags) ||
		(mlx5_npps_real_time_supported(mdev) && flags & ~PTP_PEROUT_DUTY_CYCLE));
}

static int mlx5_perout_configure(struct ptp_clock_info *ptp,
				 struct ptp_clock_request *rq,
				 int on)
@@ -854,12 +848,6 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
		goto unlock;
	}

	/* Reject requests with unsupported flags */
	if (mlx5_perout_verify_flags(mdev, rq->perout.flags)) {
		err = -EOPNOTSUPP;
		goto unlock;
	}

	if (on) {
		pin_mode = MLX5_PIN_MODE_OUT;
		pattern = MLX5_OUT_PATTERN_PERIODIC;
@@ -1031,6 +1019,9 @@ static void mlx5_init_pin_config(struct mlx5_core_dev *mdev)
						PTP_FALLING_EDGE |
						PTP_STRICT_FLAGS;

	if (mlx5_npps_real_time_supported(mdev))
		clock->ptp_info.supported_perout_flags = PTP_PEROUT_DUTY_CYCLE;

	for (i = 0; i < clock->ptp_info.n_pins; i++) {
		snprintf(clock->ptp_info.pin_config[i].name,
			 sizeof(clock->ptp_info.pin_config[i].name),
+1 −4
Original line number Diff line number Diff line
@@ -463,10 +463,6 @@ static int lan743x_ptp_perout(struct lan743x_adapter *adapter, int on,
	struct lan743x_ptp_perout *perout = &ptp->perout[index];
	int ret = 0;

	/* Reject requests with unsupported flags */
	if (perout_request->flags & ~PTP_PEROUT_DUTY_CYCLE)
		return -EOPNOTSUPP;

	if (on) {
		perout_pin = ptp_find_pin(ptp->ptp_clock, PTP_PF_PEROUT,
					  perout_request->index);
@@ -1540,6 +1536,7 @@ int lan743x_ptp_open(struct lan743x_adapter *adapter)
	ptp->ptp_clock_info.supported_extts_flags = PTP_RISING_EDGE |
						    PTP_FALLING_EDGE |
						    PTP_STRICT_FLAGS;
	ptp->ptp_clock_info.supported_perout_flags = PTP_PEROUT_DUTY_CYCLE;
	ptp->ptp_clock_info.pin_config = ptp->pin_config;
	ptp->ptp_clock_info.adjfine = lan743x_ptpci_adjfine;
	ptp->ptp_clock_info.adjtime = lan743x_ptpci_adjtime;
Loading