Commit 2cf7e87f authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ptp-adjfreq-copnvert'



Jacob Keller says:

====================
ptp: convert remaining users of .adjfreq

A handful of drivers remain which still use the .adjfreq interface instead
of the newer .adjfine interface. The new interface is preferred as it has a
more precise adjustment using scaled parts per million.

A handful of the remaining drivers are implemented with a common pattern
that can be refactored to use the adjust_by_scaled_ppm and
diff_by_scaled_ppm helper functions. These include the ptp_phc, ptp_ixp64x,
tg3, hclge, stmac, cpts and bnxt drivers. These are each refactored in a
separate change.

The remaining drivers, bnx2x, liquidio, cxgb4, fec, and qede implement
.adjfreq in a way different from the normal pattern expected by
adjust_by_scaled_ppm. Fixing these drivers to properly use .adjfine requires
specific knowledge of the hardware implementation. Instead I simply refactor
them to use .adjfine and convert scaled_ppm into ppb using the
scaled_ppm_to_ppb function.

Finally, the .adjfreq implementation interface is removed entirely. This
simplifies the interface and ensures that new drivers must implement the new
interface as they no longer have an alternative.

This still leaves parts per billion used as part of the max_adj interface,
and the core PTP stack still converts scaled_ppm to ppb to check this. I
plan to investigate fixing this in the future.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3b738db5 75ab70ec
Loading
Loading
Loading
Loading
+5 −4
Original line number Diff line number Diff line
@@ -13671,19 +13671,20 @@ static int bnx2x_send_update_drift_ramrod(struct bnx2x *bp, int drift_dir,
	return bnx2x_func_state_change(bp, &func_params);
}

static int bnx2x_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
static int bnx2x_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	struct bnx2x *bp = container_of(ptp, struct bnx2x, ptp_clock_info);
	int rc;
	int drift_dir = 1;
	int val, period, period1, period2, dif, dif1, dif2;
	int best_dif = BNX2X_MAX_PHC_DRIFT, best_period = 0, best_val = 0;
	s32 ppb = scaled_ppm_to_ppb(scaled_ppm);

	DP(BNX2X_MSG_PTP, "PTP adjfreq called, ppb = %d\n", ppb);
	DP(BNX2X_MSG_PTP, "PTP adjfine called, ppb = %d\n", ppb);

	if (!netif_running(bp->dev)) {
		DP(BNX2X_MSG_PTP,
		   "PTP adjfreq called while the interface is down\n");
		   "PTP adjfine called while the interface is down\n");
		return -ENETDOWN;
	}

@@ -13818,7 +13819,7 @@ void bnx2x_register_phc(struct bnx2x *bp)
	bp->ptp_clock_info.n_ext_ts = 0;
	bp->ptp_clock_info.n_per_out = 0;
	bp->ptp_clock_info.pps = 0;
	bp->ptp_clock_info.adjfreq = bnx2x_ptp_adjfreq;
	bp->ptp_clock_info.adjfine = bnx2x_ptp_adjfine;
	bp->ptp_clock_info.adjtime = bnx2x_ptp_adjtime;
	bp->ptp_clock_info.gettime64 = bnx2x_ptp_gettime;
	bp->ptp_clock_info.settime64 = bnx2x_ptp_settime;
+6 −16
Original line number Diff line number Diff line
@@ -205,7 +205,7 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
	return 0;
}

static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm)
{
	struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
						ptp_info);
@@ -214,23 +214,13 @@ static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
	int rc = 0;

	if (!(ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)) {
		int neg_adj = 0;
		u32 diff;
		u64 adj;

		if (ppb < 0) {
			neg_adj = 1;
			ppb = -ppb;
		}
		adj = ptp->cmult;
		adj *= ppb;
		diff = div_u64(adj, 1000000000ULL);

		spin_lock_bh(&ptp->ptp_lock);
		timecounter_read(&ptp->tc);
		ptp->cc.mult = neg_adj ? ptp->cmult - diff : ptp->cmult + diff;
		ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm);
		spin_unlock_bh(&ptp->ptp_lock);
	} else {
		s32 ppb = scaled_ppm_to_ppb(scaled_ppm);

		rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
		if (rc)
			return rc;
@@ -240,7 +230,7 @@ static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
		rc = hwrm_req_send(ptp->bp, req);
		if (rc)
			netdev_err(ptp->bp->dev,
				   "ptp adjfreq failed. rc = %d\n", rc);
				   "ptp adjfine failed. rc = %d\n", rc);
	}
	return rc;
}
@@ -769,7 +759,7 @@ static const struct ptp_clock_info bnxt_ptp_caps = {
	.n_per_out	= 0,
	.n_pins		= 0,
	.pps		= 0,
	.adjfreq	= bnxt_ptp_adjfreq,
	.adjfine	= bnxt_ptp_adjfine,
	.adjtime	= bnxt_ptp_adjtime,
	.do_aux_work	= bnxt_ptp_ts_aux_work,
	.gettimex64	= bnxt_ptp_gettimex,
+7 −15
Original line number Diff line number Diff line
@@ -6179,34 +6179,26 @@ static int tg3_get_ts_info(struct net_device *dev, struct ethtool_ts_info *info)
	return 0;
}

static int tg3_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
static int tg3_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	struct tg3 *tp = container_of(ptp, struct tg3, ptp_info);
	bool neg_adj = false;
	u32 correction = 0;

	if (ppb < 0) {
		neg_adj = true;
		ppb = -ppb;
	}
	u64 correction;
	bool neg_adj;

	/* Frequency adjustment is performed using hardware with a 24 bit
	 * accumulator and a programmable correction value. On each clk, the
	 * correction value gets added to the accumulator and when it
	 * overflows, the time counter is incremented/decremented.
	 *
	 * So conversion from ppb to correction value is
	 *		ppb * (1 << 24) / 1000000000
	 */
	correction = div_u64((u64)ppb * (1 << 24), 1000000000ULL) &
		     TG3_EAV_REF_CLK_CORRECT_MASK;
	neg_adj = diff_by_scaled_ppm(1 << 24, scaled_ppm, &correction);

	tg3_full_lock(tp, 0);

	if (correction)
		tw32(TG3_EAV_REF_CLK_CORRECT_CTL,
		     TG3_EAV_REF_CLK_CORRECT_EN |
		     (neg_adj ? TG3_EAV_REF_CLK_CORRECT_NEG : 0) | correction);
		     (neg_adj ? TG3_EAV_REF_CLK_CORRECT_NEG : 0) |
		     ((u32)correction & TG3_EAV_REF_CLK_CORRECT_MASK));
	else
		tw32(TG3_EAV_REF_CLK_CORRECT_CTL, 0);

@@ -6330,7 +6322,7 @@ static const struct ptp_clock_info tg3_ptp_caps = {
	.n_per_out	= 1,
	.n_pins		= 0,
	.pps		= 0,
	.adjfreq	= tg3_ptp_adjfreq,
	.adjfine	= tg3_ptp_adjfine,
	.adjtime	= tg3_ptp_adjtime,
	.gettimex64	= tg3_ptp_gettimex,
	.settime64	= tg3_ptp_settime,
+7 −4
Original line number Diff line number Diff line
@@ -1512,14 +1512,17 @@ static void free_netsgbuf_with_resp(void *buf)
}

/**
 * liquidio_ptp_adjfreq - Adjust ptp frequency
 * liquidio_ptp_adjfine - Adjust ptp frequency
 * @ptp: PTP clock info
 * @ppb: how much to adjust by, in parts-per-billion
 * @scaled_ppm: how much to adjust by, in scaled parts-per-million
 *
 * Scaled parts per million is ppm with a 16-bit binary fractional field.
 */
static int liquidio_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
static int liquidio_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	struct lio *lio = container_of(ptp, struct lio, ptp_info);
	struct octeon_device *oct = (struct octeon_device *)lio->oct_dev;
	s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
	u64 comp, delta;
	unsigned long flags;
	bool neg_adj = false;
@@ -1643,7 +1646,7 @@ static void oct_ptp_open(struct net_device *netdev)
	lio->ptp_info.n_ext_ts = 0;
	lio->ptp_info.n_per_out = 0;
	lio->ptp_info.pps = 0;
	lio->ptp_info.adjfreq = liquidio_ptp_adjfreq;
	lio->ptp_info.adjfine = liquidio_ptp_adjfine;
	lio->ptp_info.adjtime = liquidio_ptp_adjtime;
	lio->ptp_info.gettime64 = liquidio_ptp_gettime;
	lio->ptp_info.settime64 = liquidio_ptp_settime;
+8 −5
Original line number Diff line number Diff line
@@ -194,17 +194,20 @@ int cxgb4_ptp_redirect_rx_packet(struct adapter *adapter, struct port_info *pi)
}

/**
 * cxgb4_ptp_adjfreq - Adjust frequency of PHC cycle counter
 * cxgb4_ptp_adjfine - Adjust frequency of PHC cycle counter
 * @ptp: ptp clock structure
 * @ppb: Desired frequency change in parts per billion
 * @scaled_ppm: Desired frequency in scaled parts per billion
 *
 * Adjust the frequency of the PHC cycle counter by the indicated ppb from
 * Adjust the frequency of the PHC cycle counter by the indicated amount from
 * the base frequency.
 *
 * Scaled parts per million is ppm with a 16-bit binary fractional field.
 */
static int cxgb4_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
static int cxgb4_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
	struct adapter *adapter = (struct adapter *)container_of(ptp,
				   struct adapter, ptp_clock_info);
	s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
	struct fw_ptp_cmd c;
	int err;

@@ -404,7 +407,7 @@ static const struct ptp_clock_info cxgb4_ptp_clock_info = {
	.n_ext_ts       = 0,
	.n_per_out      = 0,
	.pps            = 0,
	.adjfreq        = cxgb4_ptp_adjfreq,
	.adjfine        = cxgb4_ptp_adjfine,
	.adjtime        = cxgb4_ptp_adjtime,
	.gettime64      = cxgb4_ptp_gettime,
	.settime64      = cxgb4_ptp_settime,
Loading