]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
bnxt_en: reset PHC frequency in free-running mode
authorVadim Fedorenko <vadfed@meta.com>
Fri, 10 Mar 2023 15:13:56 +0000 (07:13 -0800)
committerRoxana Nicolescu <roxana.nicolescu@canonical.com>
Wed, 17 May 2023 11:33:15 +0000 (13:33 +0200)
BugLink: https://bugs.launchpad.net/bugs/2016876
[ Upstream commit 131db499162274858bdbd7b5323a639da4aab86c ]

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: 85036aee1938 ("bnxt_en: Add a non-real time mode to access NIC clock")
Signed-off-by: Vadim Fedorenko <vadfed@meta.com>
Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Link: https://lore.kernel.org/r/20230310151356.678059-1-vadfed@meta.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt.h
drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c

index 25d1642c10c3b18c2c2899ff5cfd89228bfad59b..b44b2ec5e61a235b1a03c8149dd8ff6ae055ef43 100644 (file)
@@ -6991,11 +6991,9 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
                if (flags & FUNC_QCFG_RESP_FLAGS_FW_DCBX_AGENT_ENABLED)
                        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;
-               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)
                bp->fw_cap |= BNXT_FW_CAP_RING_MONITOR;
 
index 5163ef4a49ea35e49e6a1cbe9fb50079a06a3aa8..56355e64815e2d77c6a0e98fc9d1387c6de6450c 100644 (file)
@@ -1992,6 +1992,8 @@ struct bnxt {
        u32                     fw_dbg_cap;
 
 #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;
        u16                     hwrm_cmd_seq;
        u16                     hwrm_cmd_kong_seq;
index 4ec8bba18cdd2c8abd58fc4649d1516f2507669a..a3a3978a4d1c257d343b425b1350dbef66c318ae 100644 (file)
@@ -63,7 +63,7 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info,
                                                ptp_info);
        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);
 
        spin_lock_bh(&ptp->ptp_lock);
@@ -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,
                                                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);
 
        spin_lock_bh(&ptp->ptp_lock);
@@ -205,34 +205,39 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta)
        return 0;
 }
 
+static int bnxt_ptp_adjfine_rtc(struct bnxt *bp, long 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);
+       if (rc)
+               return rc;
+
+       req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
+       req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
+       rc = hwrm_req_send(bp, req);
+       if (rc)
+               netdev_err(bp->dev,
+                          "ptp adjfine failed. rc = %d\n", 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 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);
-
-               rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
-               if (rc)
-                       return rc;
+       if (BNXT_PTP_USE_RTC(bp))
+               return bnxt_ptp_adjfine_rtc(bp, scaled_ppm);
 
-               req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
-               req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
-               rc = hwrm_req_send(ptp->bp, req);
-               if (rc)
-                       netdev_err(ptp->bp->dev,
-                                  "ptp adjfine failed. rc = %d\n", rc);
-       }
-       return rc;
+       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)
@@ -879,7 +884,7 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg)
        u64 ns;
        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;
 
        if (!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);
        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);
                rc = bnxt_ptp_init_rtc(bp, phc_cfg);
                if (rc)
                        goto out;
        } else {
                bnxt_ptp_timecounter_init(bp, true);
+               bnxt_ptp_adjfine_rtc(bp, 0);
        }
 
        ptp->ptp_info = bnxt_ptp_caps;