Commit 5565dbd0 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ptp-adjfine'



Jacob Keller says:

====================
ptp: convert drivers to .adjfine

Many drivers implementing PTP have not yet migrated to the new .adjfine
frequency adjustment implementation.

A handful of these drivers use hardware with a simple increment value which
is adjusted by multiplying by the adjustment factor and then dividing by
1 billion. This calculation is very easy to convert to .adjfine, by simply
updating the divisor.

Introduce new helper functions, diff_by_scaled_ppm and adjust_by_scaled_ppm
which perform the most common calculations used by drivers for this purpose.

The adjust_by_scaled_ppm takes the base increment and scaled PPM value, and
calculates the new increment to use.

A few drivers need the difference and direction rather than a raw increment
value. The diff_by_scaled_ppm calculates the difference and returns true if
it should be a subtraction, false otherwise. This most closely aligns with
existing driver implementations.

I previously submitted v1 of this series at [1], and got some feedback only
on a handful of drivers. In the interest of merging the changes which have
received feedback, I've dropped the following drivers out of this send:

 * ptp_phc
 * ptp_ipx46x
 * tg3
 * hclge
 * stmac
 * cpts

I plan to submit those drivers changes again at a later date. As before,
there are some drivers which are not trivial to convert to the new helper
functions. While they may be able to work, their implementation is different
and I lack the hardware or datasheets to determine what the correct
implementation would be.

* drivers/net/ethernet/broadcom/bnx2x
* drivers/net/ethernet/broadcom/bnxt
* drivers/net/ethernet/cavium/liquidio
* drivers/net/ethernet/chelsio/cxgb4
* drivers/net/ethernet/freescale
* drivers/net/ethernet/qlogic/qed
* drivers/net/ethernet/qlogic/qede
* drivers/net/ethernet/sfc
* drivers/net/ethernet/sfc/siena
* drivers/net/ethernet/ti/am65-cpts.c
* drivers/ptp/ptp_dte.c

My end goal is to drop the .adjfreq implementation entirely, and to that end
I plan on modifying these drivers in the future to directly use
scaled_ppm_to_ppb as the simplest method to convert them.

Changes since v2:
* Rebased to allow landing in 6.2
* Added Richard's Acked-by

Cc: "K. Y. Srinivasan" <kys@microsoft.com>
Cc: Haiyang Zhang <haiyangz@microsoft.com>
Cc: Stephen Hemminger <sthemmin@microsoft.com>
Cc: Wei Liu <wei.liu@kernel.org>
Cc: Dexuan Cui <decui@microsoft.com>
Cc: Tom Lendacky <thomas.lendacky@amd.com>
Cc: Shyam Sundar S K <Shyam-sundar.S-k@amd.com>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Siva Reddy Kallam <siva.kallam@broadcom.com>
Cc: Prashant Sreedharan <prashant@broadcom.com>
Cc: Michael Chan <mchan@broadcom.com>
Cc: Yisen Zhuang <yisen.zhuang@huawei.com>
Cc: Salil Mehta <salil.mehta@huawei.com>
Cc: Jesse Brandeburg <jesse.brandeburg@intel.com>
Cc: Tony Nguyen <anthony.l.nguyen@intel.com>
Cc: Tariq Toukan <tariqt@nvidia.com>
Cc: Saeed Mahameed <saeedm@nvidia.com>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Bryan Whitehead <bryan.whitehead@microchip.com>
Cc: Sergey Shtylyov <s.shtylyov@omp.ru>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@foss.st.com>
Cc: Jose Abreu <joabreu@synopsys.com>
Cc: Maxime Coquelin <mcoquelin.stm32@gmail.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Vivek Thampi <vithampi@vmware.com>
Cc: VMware PV-Drivers Reviewers <pv-drivers@vmware.com>
Cc: Jie Wang <wangjie125@huawei.com>
Cc: Jacob Keller <jacob.e.keller@intel.com>
Cc: Guangbin Huang <huangguangbin2@huawei.com>
Cc: Eran Ben Elisha <eranbe@nvidia.com>
Cc: Aya Levin <ayal@nvidia.com>
Cc: Cai Huoqing <cai.huoqing@linux.dev>
Cc: Biju Das <biju.das.jz@bp.renesas.com>
Cc: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
Cc: Phil Edworthy <phil.edworthy@renesas.com>
Cc: Jiasheng Jiang <jiasheng@iscas.ac.cn>
Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Wan Jiabing <wanjiabing@vivo.com>
Cc: Lv Ruyi <lv.ruyi@zte.com.cn>
Cc: Arnd Bergmann <arnd@arndb.de>
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 70479a40 337ffae0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -706,7 +706,7 @@ static int hv_ptp_settime(struct ptp_clock_info *p, const struct timespec64 *ts)
	return -EOPNOTSUPP;
}

static int hv_ptp_adjfreq(struct ptp_clock_info *ptp, s32 delta)
static int hv_ptp_adjfine(struct ptp_clock_info *ptp, long delta)
{
	return -EOPNOTSUPP;
}
@@ -724,7 +724,7 @@ static struct ptp_clock_info ptp_hyperv_info = {
	.name		= "hyperv",
	.enable         = hv_ptp_enable,
	.adjtime        = hv_ptp_adjtime,
	.adjfreq        = hv_ptp_adjfreq,
	.adjfine        = hv_ptp_adjfine,
	.gettime64      = hv_ptp_gettime,
	.settime64      = hv_ptp_settime,
	.owner		= THIS_MODULE,
+4 −16
Original line number Diff line number Diff line
@@ -134,27 +134,15 @@ static u64 xgbe_cc_read(const struct cyclecounter *cc)
	return nsec;
}

static int xgbe_adjfreq(struct ptp_clock_info *info, s32 delta)
static int xgbe_adjfine(struct ptp_clock_info *info, long scaled_ppm)
{
	struct xgbe_prv_data *pdata = container_of(info,
						   struct xgbe_prv_data,
						   ptp_clock_info);
	unsigned long flags;
	u64 adjust;
	u32 addend, diff;
	unsigned int neg_adjust = 0;
	u64 addend;

	if (delta < 0) {
		neg_adjust = 1;
		delta = -delta;
	}

	adjust = pdata->tstamp_addend;
	adjust *= delta;
	diff = div_u64(adjust, 1000000000UL);

	addend = (neg_adjust) ? pdata->tstamp_addend - diff :
				pdata->tstamp_addend + diff;
	addend = adjust_by_scaled_ppm(pdata->tstamp_addend, scaled_ppm);

	spin_lock_irqsave(&pdata->tstamp_lock, flags);

@@ -235,7 +223,7 @@ void xgbe_ptp_register(struct xgbe_prv_data *pdata)
		 netdev_name(pdata->netdev));
	info->owner = THIS_MODULE;
	info->max_adj = pdata->ptpclk_rate;
	info->adjfreq = xgbe_adjfreq;
	info->adjfine = xgbe_adjfine;
	info->adjtime = xgbe_adjtime;
	info->gettime64 = xgbe_gettime;
	info->settime64 = xgbe_settime;
+3 −13
Original line number Diff line number Diff line
@@ -29,17 +29,11 @@ static int e1000e_phc_adjfine(struct ptp_clock_info *ptp, long delta)
	struct e1000_adapter *adapter = container_of(ptp, struct e1000_adapter,
						     ptp_clock_info);
	struct e1000_hw *hw = &adapter->hw;
	bool neg_adj = false;
	unsigned long flags;
	u64 adjustment;
	u32 timinca, incvalue;
	u64 incvalue;
	u32 timinca;
	s32 ret_val;

	if (delta < 0) {
		neg_adj = true;
		delta = -delta;
	}

	/* Get the System Time Register SYSTIM base frequency */
	ret_val = e1000e_get_base_timinca(adapter, &timinca);
	if (ret_val)
@@ -48,11 +42,7 @@ static int e1000e_phc_adjfine(struct ptp_clock_info *ptp, long delta)
	spin_lock_irqsave(&adapter->systim_lock, flags);

	incvalue = timinca & E1000_TIMINCA_INCVALUE_MASK;

	adjustment = mul_u64_u64_div_u64(incvalue, (u64)delta,
					 1000000ULL << 16);

	incvalue = neg_adj ? (incvalue - adjustment) : (incvalue + adjustment);
	incvalue = adjust_by_scaled_ppm(incvalue, delta);

	timinca &= ~E1000_TIMINCA_INCVALUE_MASK;
	timinca |= incvalue;
+3 −14
Original line number Diff line number Diff line
@@ -347,23 +347,12 @@ static int i40e_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	struct i40e_pf *pf = container_of(ptp, struct i40e_pf, ptp_caps);
	struct i40e_hw *hw = &pf->hw;
	u64 adj, freq, diff;
	int neg_adj = 0;

	if (scaled_ppm < 0) {
		neg_adj = 1;
		scaled_ppm = -scaled_ppm;
	}
	u64 adj, base_adj;

	smp_mb(); /* Force any pending update before accessing. */
	freq = I40E_PTP_40GB_INCVAL * READ_ONCE(pf->ptp_adj_mult);
	diff = mul_u64_u64_div_u64(freq, (u64)scaled_ppm,
				   1000000ULL << 16);
	base_adj = I40E_PTP_40GB_INCVAL * READ_ONCE(pf->ptp_adj_mult);

	if (neg_adj)
		adj = I40E_PTP_40GB_INCVAL - diff;
	else
		adj = I40E_PTP_40GB_INCVAL + diff;
	adj = adjust_by_scaled_ppm(base_adj, scaled_ppm);

	wr32(hw, I40E_PRTTSYN_INC_L, adj & 0xFFFFFFFF);
	wr32(hw, I40E_PRTTSYN_INC_H, adj >> 32);
+2 −16
Original line number Diff line number Diff line
@@ -1444,24 +1444,10 @@ static int ice_ptp_adjfine(struct ptp_clock_info *info, long scaled_ppm)
{
	struct ice_pf *pf = ptp_info_to_pf(info);
	struct ice_hw *hw = &pf->hw;
	u64 incval, diff;
	int neg_adj = 0;
	u64 incval;
	int err;

	incval = ice_base_incval(pf);

	if (scaled_ppm < 0) {
		neg_adj = 1;
		scaled_ppm = -scaled_ppm;
	}

	diff = mul_u64_u64_div_u64(incval, (u64)scaled_ppm,
				   1000000ULL << 16);
	if (neg_adj)
		incval -= diff;
	else
		incval += diff;

	incval = adjust_by_scaled_ppm(ice_base_incval(pf), scaled_ppm);
	err = ice_ptp_write_incval_locked(hw, incval);
	if (err) {
		dev_err(ice_pf_to_dev(pf), "PTP failed to set incval, err %d\n",
Loading