diff options
Diffstat (limited to 'drivers/net/ethernet/intel/ice/ice_ptp.c')
| -rw-r--r-- | drivers/net/ethernet/intel/ice/ice_ptp.c | 68 | 
1 files changed, 55 insertions, 13 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_ptp.c b/drivers/net/ethernet/intel/ice/ice_ptp.c index 5d5207b56ca9..05cc5870e4ef 100644 --- a/drivers/net/ethernet/intel/ice/ice_ptp.c +++ b/drivers/net/ethernet/intel/ice/ice_ptp.c @@ -22,7 +22,7 @@ static void ice_set_tx_tstamp(struct ice_pf *pf, bool on)  		return;  	/* Set the timestamp enable flag for all the Tx rings */ -	ice_for_each_rxq(vsi, i) { +	ice_for_each_txq(vsi, i) {  		if (!vsi->tx_rings[i])  			continue;  		vsi->tx_rings[i]->ptp_tx = on; @@ -656,7 +656,7 @@ static int ice_ptp_cfg_clkout(struct ice_pf *pf, unsigned int chan,  	 * maintaining phase  	 */  	if (start_time < current_time) -		start_time = div64_u64(current_time + NSEC_PER_MSEC - 1, +		start_time = div64_u64(current_time + NSEC_PER_SEC - 1,  				       NSEC_PER_SEC) * NSEC_PER_SEC + phase;  	start_time -= E810_OUT_PROP_DELAY_NS; @@ -689,6 +689,41 @@ err:  }  /** + * ice_ptp_disable_all_clkout - Disable all currently configured outputs + * @pf: pointer to the PF structure + * + * Disable all currently configured clock outputs. This is necessary before + * certain changes to the PTP hardware clock. Use ice_ptp_enable_all_clkout to + * re-enable the clocks again. + */ +static void ice_ptp_disable_all_clkout(struct ice_pf *pf) +{ +	uint i; + +	for (i = 0; i < pf->ptp.info.n_per_out; i++) +		if (pf->ptp.perout_channels[i].ena) +			ice_ptp_cfg_clkout(pf, i, NULL, false); +} + +/** + * ice_ptp_enable_all_clkout - Enable all configured periodic clock outputs + * @pf: pointer to the PF structure + * + * Enable all currently configured clock outputs. Use this after + * ice_ptp_disable_all_clkout to reconfigure the output signals according to + * their configuration. + */ +static void ice_ptp_enable_all_clkout(struct ice_pf *pf) +{ +	uint i; + +	for (i = 0; i < pf->ptp.info.n_per_out; i++) +		if (pf->ptp.perout_channels[i].ena) +			ice_ptp_cfg_clkout(pf, i, &pf->ptp.perout_channels[i], +					   false); +} + +/**   * ice_ptp_gpio_enable_e810 - Enable/disable ancillary features of PHC   * @info: the driver's PTP info structure   * @rq: The requested feature to change @@ -783,12 +818,17 @@ ice_ptp_settime64(struct ptp_clock_info *info, const struct timespec64 *ts)  		goto exit;  	} +	/* Disable periodic outputs */ +	ice_ptp_disable_all_clkout(pf); +  	err = ice_ptp_write_init(pf, &ts64);  	ice_ptp_unlock(hw);  	if (!err)  		ice_ptp_update_cached_phctime(pf); +	/* Reenable periodic outputs */ +	ice_ptp_enable_all_clkout(pf);  exit:  	if (err) {  		dev_err(ice_pf_to_dev(pf), "PTP failed to set time %d\n", err); @@ -842,8 +882,14 @@ static int ice_ptp_adjtime(struct ptp_clock_info *info, s64 delta)  		return -EBUSY;  	} +	/* Disable periodic outputs */ +	ice_ptp_disable_all_clkout(pf); +  	err = ice_ptp_write_adj(pf, delta); +	/* Reenable periodic outputs */ +	ice_ptp_enable_all_clkout(pf); +  	ice_ptp_unlock(hw);  	if (err) { @@ -1064,17 +1110,6 @@ static long ice_ptp_create_clock(struct ice_pf *pf)  	info = &pf->ptp.info;  	dev = ice_pf_to_dev(pf); -	/* Allocate memory for kernel pins interface */ -	if (info->n_pins) { -		info->pin_config = devm_kcalloc(dev, info->n_pins, -						sizeof(*info->pin_config), -						GFP_KERNEL); -		if (!info->pin_config) { -			info->n_pins = 0; -			return -ENOMEM; -		} -	} -  	/* Attempt to register the clock before enabling the hardware. */  	clock = ptp_clock_register(info, dev);  	if (IS_ERR(clock)) @@ -1278,6 +1313,8 @@ ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)  {  	u8 idx; +	spin_lock(&tx->lock); +  	for (idx = 0; idx < tx->len; idx++) {  		u8 phy_idx = idx + tx->quad_offset; @@ -1290,6 +1327,8 @@ ice_ptp_flush_tx_tracker(struct ice_pf *pf, struct ice_ptp_tx *tx)  			tx->tstamps[idx].skb = NULL;  		}  	} + +	spin_unlock(&tx->lock);  }  /** @@ -1550,6 +1589,9 @@ void ice_ptp_release(struct ice_pf *pf)  	if (!pf->ptp.clock)  		return; +	/* Disable periodic outputs */ +	ice_ptp_disable_all_clkout(pf); +  	ice_clear_ptp_clock_index(pf);  	ptp_clock_unregister(pf->ptp.clock);  	pf->ptp.clock = NULL;  | 
