diff options
| author | Pavan Chebbi <pavan.chebbi@broadcom.com> | 2026-01-08 21:35:17 +0300 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2026-01-11 02:19:50 +0300 |
| commit | c470195b989fe7b9f92297e465c4e8a2363c0bb3 (patch) | |
| tree | d3c3bf8e7d590418d023816f8bb25b2e290232a0 | |
| parent | fdb573d675e3ac50f0b58aaa35bfe7e8c585ba5f (diff) | |
| download | linux-c470195b989fe7b9f92297e465c4e8a2363c0bb3.tar.xz | |
bnxt_en: Add PTP .getcrosststamp() interface to get device/host times
.getcrosststamp() helps the applications to obtain a snapshot of
device and host time almost taken at the same time. This function
will report PCIe PTM device and host times to any application using
the ioctl PTP_SYS_OFFSET_PRECISE. The device time from the HW is
48-bit and needs to be converted to 64-bit.
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Link: https://patch.msgid.link/20260108183521.215610-3-michael.chan@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1 | ||||
| -rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c | 47 |
3 files changed, 50 insertions, 0 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 8419d1eb4035..6aba1967ba00 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -9700,6 +9700,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) bp->fw_cap |= BNXT_FW_CAP_EXT_HW_STATS_SUPPORTED; if (BNXT_PF(bp) && (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_PTP_PPS_SUPPORTED)) bp->fw_cap |= BNXT_FW_CAP_PTP_PPS; + if (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_PTP_PTM_SUPPORTED) + bp->fw_cap |= BNXT_FW_CAP_PTP_PTM; if (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_PTP_64BIT_RTC_SUPPORTED) bp->fw_cap |= BNXT_FW_CAP_PTP_RTC; if (BNXT_PF(bp) && (flags_ext & FUNC_QCAPS_RESP_FLAGS_EXT_HOT_RESET_IF_SUPPORT)) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index f88e7769a838..67e59e61b83c 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -2516,6 +2516,7 @@ struct bnxt { #define BNXT_FW_CAP_SW_MAX_RESOURCE_LIMITS BIT_ULL(41) #define BNXT_FW_CAP_NPAR_1_2 BIT_ULL(42) #define BNXT_FW_CAP_MIRROR_ON_ROCE BIT_ULL(43) + #define BNXT_FW_CAP_PTP_PTM BIT_ULL(44) u32 fw_dbg_cap; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c index a8a74f07bb54..75ad385f5f79 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c @@ -882,6 +882,49 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, } } +static int bnxt_phc_get_syncdevicetime(ktime_t *device, + struct system_counterval_t *system, + void *ctx) +{ + struct bnxt_ptp_cfg *ptp = (struct bnxt_ptp_cfg *)ctx; + struct hwrm_func_ptp_ts_query_output *resp; + struct hwrm_func_ptp_ts_query_input *req; + struct bnxt *bp = ptp->bp; + u64 ptm_local_ts; + int rc; + + rc = hwrm_req_init(bp, req, HWRM_FUNC_PTP_TS_QUERY); + if (rc) + return rc; + req->flags = cpu_to_le32(FUNC_PTP_TS_QUERY_REQ_FLAGS_PTM_TIME); + resp = hwrm_req_hold(bp, req); + rc = hwrm_req_send(bp, req); + if (rc) { + hwrm_req_drop(bp, req); + return rc; + } + ptm_local_ts = le64_to_cpu(resp->ptm_local_ts); + *device = ns_to_ktime(bnxt_timecounter_cyc2time(ptp, ptm_local_ts)); + /* ptm_system_ts is 64-bit */ + system->cycles = le64_to_cpu(resp->ptm_system_ts); + system->cs_id = CSID_X86_ART; + system->use_nsecs = true; + + hwrm_req_drop(bp, req); + + return 0; +} + +static int bnxt_ptp_getcrosststamp(struct ptp_clock_info *ptp_info, + struct system_device_crosststamp *xtstamp) +{ + struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, + ptp_info); + + return get_device_system_crosststamp(bnxt_phc_get_syncdevicetime, + ptp, NULL, xtstamp); +} + static const struct ptp_clock_info bnxt_ptp_caps = { .owner = THIS_MODULE, .name = "bnxt clock", @@ -1094,6 +1137,10 @@ int bnxt_ptp_init(struct bnxt *bp) if (bnxt_ptp_pps_init(bp)) netdev_err(bp->dev, "1pps not initialized, continuing without 1pps support\n"); } + if ((bp->fw_cap & BNXT_FW_CAP_PTP_PTM) && pcie_ptm_enabled(bp->pdev) && + boot_cpu_has(X86_FEATURE_ART)) + ptp->ptp_info.getcrosststamp = bnxt_ptp_getcrosststamp; + ptp->ptp_clock = ptp_clock_register(&ptp->ptp_info, &bp->pdev->dev); if (IS_ERR(ptp->ptp_clock)) { int err = PTR_ERR(ptp->ptp_clock); |
