Commit 131db499 authored by Vadim Fedorenko's avatar Vadim Fedorenko Committed by Jakub Kicinski

bnxt_en: reset PHC frequency in free-running mode

When using a PHC in shared between multiple hosts, the previous
frequency value may not be reset and could lead to host being unable to
compensate the offset with timecounter adjustments. To avoid such state
reset the hardware frequency of PHC to zero on init. Some refactoring is
needed to make code readable.

Fixes: 85036aee ("bnxt_en: Add a non-real time mode to access NIC clock")
Signed-off-by: default avatarVadim Fedorenko <vadfed@meta.com>
Reviewed-by: default avatarPavan Chebbi <pavan.chebbi@broadcom.com>
Link: https://lore.kernel.org/r/20230310151356.678059-1-vadfed@meta.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 064d7052
...@@ -6990,11 +6990,9 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp) ...@@ -6990,11 +6990,9 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
if (flags & FUNC_QCFG_RESP_FLAGS_FW_DCBX_AGENT_ENABLED) if (flags & FUNC_QCFG_RESP_FLAGS_FW_DCBX_AGENT_ENABLED)
bp->fw_cap |= BNXT_FW_CAP_DCBX_AGENT; bp->fw_cap |= BNXT_FW_CAP_DCBX_AGENT;
} }
if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST)) { if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST))
bp->flags |= BNXT_FLAG_MULTI_HOST; bp->flags |= BNXT_FLAG_MULTI_HOST;
if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
bp->fw_cap &= ~BNXT_FW_CAP_PTP_RTC;
}
if (flags & FUNC_QCFG_RESP_FLAGS_RING_MONITOR_ENABLED) if (flags & FUNC_QCFG_RESP_FLAGS_RING_MONITOR_ENABLED)
bp->fw_cap |= BNXT_FW_CAP_RING_MONITOR; bp->fw_cap |= BNXT_FW_CAP_RING_MONITOR;
......
...@@ -2000,6 +2000,8 @@ struct bnxt { ...@@ -2000,6 +2000,8 @@ struct bnxt {
u32 fw_dbg_cap; u32 fw_dbg_cap;
#define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM) #define BNXT_NEW_RM(bp) ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
#define BNXT_PTP_USE_RTC(bp) (!BNXT_MH(bp) && \
((bp)->fw_cap & BNXT_FW_CAP_PTP_RTC))
u32 hwrm_spec_code; u32 hwrm_spec_code;
u16 hwrm_cmd_seq; u16 hwrm_cmd_seq;
u16 hwrm_cmd_kong_seq; u16 hwrm_cmd_kong_seq;
......
...@@ -63,7 +63,7 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info, ...@@ -63,7 +63,7 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info,
ptp_info); ptp_info);
u64 ns = timespec64_to_ns(ts); u64 ns = timespec64_to_ns(ts);
if (ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC) if (BNXT_PTP_USE_RTC(ptp->bp))
return bnxt_ptp_cfg_settime(ptp->bp, ns); return bnxt_ptp_cfg_settime(ptp->bp, ns);
spin_lock_bh(&ptp->ptp_lock); spin_lock_bh(&ptp->ptp_lock);
...@@ -196,7 +196,7 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) ...@@ -196,7 +196,7 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
ptp_info); ptp_info);
if (ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC) if (BNXT_PTP_USE_RTC(ptp->bp))
return bnxt_ptp_adjphc(ptp, delta); return bnxt_ptp_adjphc(ptp, delta);
spin_lock_bh(&ptp->ptp_lock); spin_lock_bh(&ptp->ptp_lock);
...@@ -205,21 +205,11 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) ...@@ -205,21 +205,11 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
return 0; return 0;
} }
static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) static int bnxt_ptp_adjfine_rtc(struct bnxt *bp, long scaled_ppm)
{ {
struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg,
ptp_info);
struct hwrm_port_mac_cfg_input *req;
struct bnxt *bp = ptp->bp;
int rc = 0;
if (!(ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)) {
spin_lock_bh(&ptp->ptp_lock);
timecounter_read(&ptp->tc);
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); s32 ppb = scaled_ppm_to_ppb(scaled_ppm);
struct hwrm_port_mac_cfg_input *req;
int rc;
rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG); rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
if (rc) if (rc)
...@@ -227,14 +217,29 @@ static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) ...@@ -227,14 +217,29 @@ static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm)
req->ptp_freq_adj_ppb = cpu_to_le32(ppb); req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB); req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
rc = hwrm_req_send(ptp->bp, req); rc = hwrm_req_send(bp, req);
if (rc) if (rc)
netdev_err(ptp->bp->dev, netdev_err(bp->dev,
"ptp adjfine failed. rc = %d\n", rc); "ptp adjfine failed. rc = %d\n", rc);
}
return rc; return rc;
} }
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);
struct bnxt *bp = ptp->bp;
if (BNXT_PTP_USE_RTC(bp))
return bnxt_ptp_adjfine_rtc(bp, scaled_ppm);
spin_lock_bh(&ptp->ptp_lock);
timecounter_read(&ptp->tc);
ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm);
spin_unlock_bh(&ptp->ptp_lock);
return 0;
}
void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2) void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2)
{ {
struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
...@@ -879,7 +884,7 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) ...@@ -879,7 +884,7 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
u64 ns; u64 ns;
int rc; int rc;
if (!bp->ptp_cfg || !(bp->fw_cap & BNXT_FW_CAP_PTP_RTC)) if (!bp->ptp_cfg || !BNXT_PTP_USE_RTC(bp))
return -ENODEV; return -ENODEV;
if (!phc_cfg) { if (!phc_cfg) {
...@@ -932,13 +937,14 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg) ...@@ -932,13 +937,14 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg)
atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS); atomic_set(&ptp->tx_avail, BNXT_MAX_TX_TS);
spin_lock_init(&ptp->ptp_lock); spin_lock_init(&ptp->ptp_lock);
if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC) { if (BNXT_PTP_USE_RTC(bp)) {
bnxt_ptp_timecounter_init(bp, false); bnxt_ptp_timecounter_init(bp, false);
rc = bnxt_ptp_init_rtc(bp, phc_cfg); rc = bnxt_ptp_init_rtc(bp, phc_cfg);
if (rc) if (rc)
goto out; goto out;
} else { } else {
bnxt_ptp_timecounter_init(bp, true); bnxt_ptp_timecounter_init(bp, true);
bnxt_ptp_adjfine_rtc(bp, 0);
} }
ptp->ptp_info = bnxt_ptp_caps; ptp->ptp_info = bnxt_ptp_caps;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment