Skip to content

Commit

Permalink
Merge branch 'ptp-adjfreq-copnvert'
Browse files Browse the repository at this point in the history
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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Nov 11, 2022
2 parents 3b738db + 75ab70e commit 2cf7e87
Show file tree
Hide file tree
Showing 18 changed files with 88 additions and 154 deletions.
9 changes: 5 additions & 4 deletions drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down
22 changes: 6 additions & 16 deletions drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down Expand Up @@ -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,
Expand Down
22 changes: 7 additions & 15 deletions drivers/net/ethernet/broadcom/tg3.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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,
Expand Down
11 changes: 7 additions & 4 deletions drivers/net/ethernet/cavium/liquidio/lio_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
13 changes: 8 additions & 5 deletions drivers/net/ethernet/chelsio/cxgb4/cxgb4_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand Down
13 changes: 8 additions & 5 deletions drivers/net/ethernet/freescale/fec_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,18 +338,21 @@ void fec_ptp_start_cyclecounter(struct net_device *ndev)
}

/**
* fec_ptp_adjfreq - adjust ptp cycle frequency
* fec_ptp_adjfine - adjust ptp cycle frequency
* @ptp: the ptp clock structure
* @ppb: parts per billion adjustment from base
* @scaled_ppm: scaled parts per million adjustment from base
*
* Adjust the frequency of the ptp cycle counter by the
* indicated ppb from the base frequency.
* indicated amount from the base frequency.
*
* Scaled parts per million is ppm with a 16-bit binary fractional field.
*
* Because ENET hardware frequency adjust is complex,
* using software method to do that.
*/
static int fec_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
static int fec_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
unsigned long flags;
int neg_adj = 0;
u32 i, tmp;
Expand Down Expand Up @@ -742,7 +745,7 @@ void fec_ptp_init(struct platform_device *pdev, int irq_idx)
fep->ptp_caps.n_per_out = 1;
fep->ptp_caps.n_pins = 0;
fep->ptp_caps.pps = 1;
fep->ptp_caps.adjfreq = fec_ptp_adjfreq;
fep->ptp_caps.adjfine = fec_ptp_adjfine;
fep->ptp_caps.adjtime = fec_ptp_adjtime;
fep->ptp_caps.gettime64 = fec_ptp_gettime;
fep->ptp_caps.settime64 = fec_ptp_settime;
Expand Down
22 changes: 5 additions & 17 deletions drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,16 @@ static int hclge_ptp_get_cycle(struct hclge_dev *hdev)
return 0;
}

static int hclge_ptp_adjfreq(struct ptp_clock_info *ptp, s32 ppb)
static int hclge_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
struct hclge_dev *hdev = hclge_ptp_get_hdev(ptp);
struct hclge_ptp_cycle *cycle = &hdev->ptp->cycle;
u64 adj_val, adj_base, diff;
u64 adj_val, adj_base;
unsigned long flags;
bool is_neg = false;
u32 quo, numerator;

if (ppb < 0) {
ppb = -ppb;
is_neg = true;
}

adj_base = (u64)cycle->quo * (u64)cycle->den + (u64)cycle->numer;
adj_val = adj_base * ppb;
diff = div_u64(adj_val, 1000000000ULL);

if (is_neg)
adj_val = adj_base - diff;
else
adj_val = adj_base + diff;
adj_val = adjust_by_scaled_ppm(adj_base, scaled_ppm);

/* This clock cycle is defined by three part: quotient, numerator
* and denominator. For example, 2.5ns, the quotient is 2,
Expand Down Expand Up @@ -446,7 +434,7 @@ static int hclge_ptp_create_clock(struct hclge_dev *hdev)
ptp->info.max_adj = HCLGE_PTP_CYCLE_ADJ_MAX;
ptp->info.n_ext_ts = 0;
ptp->info.pps = 0;
ptp->info.adjfreq = hclge_ptp_adjfreq;
ptp->info.adjfine = hclge_ptp_adjfine;
ptp->info.adjtime = hclge_ptp_adjtime;
ptp->info.gettimex64 = hclge_ptp_gettimex;
ptp->info.settime64 = hclge_ptp_settime;
Expand Down Expand Up @@ -504,7 +492,7 @@ int hclge_ptp_init(struct hclge_dev *hdev)
goto out;

set_bit(HCLGE_PTP_FLAG_EN, &hdev->ptp->flags);
ret = hclge_ptp_adjfreq(&hdev->ptp->info, 0);
ret = hclge_ptp_adjfine(&hdev->ptp->info, 0);
if (ret) {
dev_err(&hdev->pdev->dev,
"failed to init freq, ret = %d\n", ret);
Expand Down
13 changes: 8 additions & 5 deletions drivers/net/ethernet/qlogic/qede/qede_ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,19 @@ struct qede_ptp {
};

/**
* qede_ptp_adjfreq() - Adjust the frequency of the PTP cycle counter.
* qede_ptp_adjfine() - Adjust the frequency of the PTP cycle counter.
*
* @info: The PTP clock info structure.
* @ppb: Parts per billion adjustment from base.
* @scaled_ppm: Scaled parts per million adjustment from base.
*
* Scaled parts per million is ppm with a 16-bit binary fractional field.
*
* Return: Zero on success, negative errno otherwise.
*/
static int qede_ptp_adjfreq(struct ptp_clock_info *info, s32 ppb)
static int qede_ptp_adjfine(struct ptp_clock_info *info, long scaled_ppm)
{
struct qede_ptp *ptp = container_of(info, struct qede_ptp, clock_info);
s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
struct qede_dev *edev = ptp->edev;
int rc;

Expand All @@ -47,7 +50,7 @@ static int qede_ptp_adjfreq(struct ptp_clock_info *info, s32 ppb)
rc = ptp->ops->adjfreq(edev->cdev, ppb);
spin_unlock_bh(&ptp->lock);
} else {
DP_ERR(edev, "PTP adjfreq called while interface is down\n");
DP_ERR(edev, "PTP adjfine called while interface is down\n");
rc = -EFAULT;
}
__qede_unlock(edev);
Expand Down Expand Up @@ -462,7 +465,7 @@ int qede_ptp_enable(struct qede_dev *edev)
ptp->clock_info.n_ext_ts = 0;
ptp->clock_info.n_per_out = 0;
ptp->clock_info.pps = 0;
ptp->clock_info.adjfreq = qede_ptp_adjfreq;
ptp->clock_info.adjfine = qede_ptp_adjfine;
ptp->clock_info.adjtime = qede_ptp_adjtime;
ptp->clock_info.gettime64 = qede_ptp_gettime;
ptp->clock_info.settime64 = qede_ptp_settime;
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/ethernet/sfc/ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ struct efx_ptp_data {
void (*xmit_skb)(struct efx_nic *efx, struct sk_buff *skb);
};

static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta);
static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm);
static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta);
static int efx_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts);
static int efx_phc_settime(struct ptp_clock_info *ptp,
Expand Down Expand Up @@ -1508,7 +1508,7 @@ static const struct ptp_clock_info efx_phc_clock_info = {
.n_per_out = 0,
.n_pins = 0,
.pps = 1,
.adjfreq = efx_phc_adjfreq,
.adjfine = efx_phc_adjfine,
.adjtime = efx_phc_adjtime,
.gettime64 = efx_phc_gettime,
.settime64 = efx_phc_settime,
Expand Down Expand Up @@ -2137,11 +2137,12 @@ void __efx_rx_skb_attach_timestamp(struct efx_channel *channel,
ptp->ts_corrections.general_rx);
}

static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
struct efx_ptp_data *ptp_data = container_of(ptp,
struct efx_ptp_data,
phc_clock_info);
s32 delta = scaled_ppm_to_ppb(scaled_ppm);
struct efx_nic *efx = ptp_data->efx;
MCDI_DECLARE_BUF(inadj, MC_CMD_PTP_IN_ADJUST_LEN);
s64 adjustment_ns;
Expand Down
7 changes: 4 additions & 3 deletions drivers/net/ethernet/sfc/siena/ptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ struct efx_ptp_data {
void (*xmit_skb)(struct efx_nic *efx, struct sk_buff *skb);
};

static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta);
static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm);
static int efx_phc_adjtime(struct ptp_clock_info *ptp, s64 delta);
static int efx_phc_gettime(struct ptp_clock_info *ptp, struct timespec64 *ts);
static int efx_phc_settime(struct ptp_clock_info *ptp,
Expand Down Expand Up @@ -1429,7 +1429,7 @@ static const struct ptp_clock_info efx_phc_clock_info = {
.n_per_out = 0,
.n_pins = 0,
.pps = 1,
.adjfreq = efx_phc_adjfreq,
.adjfine = efx_phc_adjfine,
.adjtime = efx_phc_adjtime,
.gettime64 = efx_phc_gettime,
.settime64 = efx_phc_settime,
Expand Down Expand Up @@ -2044,11 +2044,12 @@ void __efx_siena_rx_skb_attach_timestamp(struct efx_channel *channel,
ptp->ts_corrections.general_rx);
}

static int efx_phc_adjfreq(struct ptp_clock_info *ptp, s32 delta)
static int efx_phc_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
{
struct efx_ptp_data *ptp_data = container_of(ptp,
struct efx_ptp_data,
phc_clock_info);
s32 delta = scaled_ppm_to_ppb(scaled_ppm);
struct efx_nic *efx = ptp_data->efx;
MCDI_DECLARE_BUF(inadj, MC_CMD_PTP_IN_ADJUST_LEN);
s64 adjustment_ns;
Expand Down
Loading

0 comments on commit 2cf7e87

Please sign in to comment.