]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bnxt_en: Add PTP .getcrosststamp() interface to get device/host times
authorPavan Chebbi <pavan.chebbi@broadcom.com>
Thu, 8 Jan 2026 18:35:17 +0000 (10:35 -0800)
committerJakub Kicinski <kuba@kernel.org>
Sat, 10 Jan 2026 23:19:50 +0000 (15:19 -0800)
.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>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c

index 8419d1eb4035dc1faef32f7fec6e7d440016adaf..6aba1967ba00d099892f399db415620ac8d38a93 100644 (file)
@@ -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))
index f88e7769a838a1c4b3e60377dc10df2909f98ba5..67e59e61b83c2ea737a49120c742bc95e0027fba 100644 (file)
@@ -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;
 
index a8a74f07bb547539edd28a03aada5c3d5a52adfc..75ad385f5f79ecce9dbc0a98a604682c4d090e8a 100644 (file)
@@ -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);