Skip to content

Commit 85036ae

Browse files
pavanchebbiPaolo Abeni
authored andcommitted
bnxt_en: Add a non-real time mode to access NIC clock
When using a PHC that is shared between multiple hosts, in order to achieve consistent timestamps across all hosts, we need to isolate the PHC from any host making frequency adjustments. This patch adds a non-real time mode for this purpose. The implementation is based on a free running NIC hardware timer which is used as the timestamper time-base. Each host implements individual adjustments to a local timecounter based on the NIC free running timer. Cc: Richard Cochran <richardcochran@gmail.com> Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com> Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Reviewed-by: Leon Romanovsky <leonro@nvidia.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
1 parent 98a4322 commit 85036ae

File tree

3 files changed

+42
-15
lines changed

3 files changed

+42
-15
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6985,8 +6985,11 @@ static int bnxt_hwrm_func_qcfg(struct bnxt *bp)
69856985
if (flags & FUNC_QCFG_RESP_FLAGS_FW_DCBX_AGENT_ENABLED)
69866986
bp->fw_cap |= BNXT_FW_CAP_DCBX_AGENT;
69876987
}
6988-
if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST))
6988+
if (BNXT_PF(bp) && (flags & FUNC_QCFG_RESP_FLAGS_MULTI_HOST)) {
69896989
bp->flags |= BNXT_FLAG_MULTI_HOST;
6990+
if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC)
6991+
bp->fw_cap &= ~BNXT_FW_CAP_PTP_RTC;
6992+
}
69906993
if (flags & FUNC_QCFG_RESP_FLAGS_RING_MONITOR_ENABLED)
69916994
bp->fw_cap |= BNXT_FW_CAP_RING_MONITOR;
69926995

drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.c

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <linux/net_tstamp.h>
1515
#include <linux/timekeeping.h>
1616
#include <linux/ptp_classify.h>
17+
#include <linux/clocksource.h>
1718
#include "bnxt_hsi.h"
1819
#include "bnxt.h"
1920
#include "bnxt_hwrm.h"
@@ -210,18 +211,37 @@ static int bnxt_ptp_adjfreq(struct ptp_clock_info *ptp_info, s32 ppb)
210211
ptp_info);
211212
struct hwrm_port_mac_cfg_input *req;
212213
struct bnxt *bp = ptp->bp;
213-
int rc;
214+
int rc = 0;
214215

215-
rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
216-
if (rc)
217-
return rc;
216+
if (!(ptp->bp->fw_cap & BNXT_FW_CAP_PTP_RTC)) {
217+
int neg_adj = 0;
218+
u32 diff;
219+
u64 adj;
218220

219-
req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
220-
req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
221-
rc = hwrm_req_send(ptp->bp, req);
222-
if (rc)
223-
netdev_err(ptp->bp->dev,
224-
"ptp adjfreq failed. rc = %d\n", rc);
221+
if (ppb < 0) {
222+
neg_adj = 1;
223+
ppb = -ppb;
224+
}
225+
adj = ptp->cmult;
226+
adj *= ppb;
227+
diff = div_u64(adj, 1000000000ULL);
228+
229+
spin_lock_bh(&ptp->ptp_lock);
230+
timecounter_read(&ptp->tc);
231+
ptp->cc.mult = neg_adj ? ptp->cmult - diff : ptp->cmult + diff;
232+
spin_unlock_bh(&ptp->ptp_lock);
233+
} else {
234+
rc = hwrm_req_init(bp, req, HWRM_PORT_MAC_CFG);
235+
if (rc)
236+
return rc;
237+
238+
req->ptp_freq_adj_ppb = cpu_to_le32(ppb);
239+
req->enables = cpu_to_le32(PORT_MAC_CFG_REQ_ENABLES_PTP_FREQ_ADJ_PPB);
240+
rc = hwrm_req_send(ptp->bp, req);
241+
if (rc)
242+
netdev_err(ptp->bp->dev,
243+
"ptp adjfreq failed. rc = %d\n", rc);
244+
}
225245
return rc;
226246
}
227247

@@ -846,8 +866,9 @@ static void bnxt_ptp_timecounter_init(struct bnxt *bp, bool init_tc)
846866
memset(&ptp->cc, 0, sizeof(ptp->cc));
847867
ptp->cc.read = bnxt_cc_read;
848868
ptp->cc.mask = CYCLECOUNTER_MASK(48);
849-
ptp->cc.shift = 0;
850-
ptp->cc.mult = 1;
869+
ptp->cc.shift = BNXT_CYCLES_SHIFT;
870+
ptp->cc.mult = clocksource_khz2mult(BNXT_DEVCLK_FREQ, ptp->cc.shift);
871+
ptp->cmult = ptp->cc.mult;
851872
ptp->next_overflow_check = jiffies + BNXT_PHC_OVERFLOW_PERIOD;
852873
}
853874
if (init_tc)

drivers/net/ethernet/broadcom/bnxt/bnxt_ptp.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
#define BNXT_PTP_GRC_WIN_BASE 0x6000
1818

1919
#define BNXT_MAX_PHC_DRIFT 31000000
20+
#define BNXT_CYCLES_SHIFT 23
21+
#define BNXT_DEVCLK_FREQ 1000000
2022
#define BNXT_LO_TIMER_MASK 0x0000ffffffffUL
2123
#define BNXT_HI_TIMER_MASK 0xffff00000000UL
2224

@@ -88,8 +90,9 @@ struct bnxt_ptp_cfg {
8890
u64 old_time;
8991
unsigned long next_period;
9092
unsigned long next_overflow_check;
91-
/* 48-bit PHC overflows in 78 hours. Check overflow every 19 hours. */
92-
#define BNXT_PHC_OVERFLOW_PERIOD (19 * 3600 * HZ)
93+
u32 cmult;
94+
/* a 23b shift cyclecounter will overflow in ~36 mins. Check overflow every 18 mins. */
95+
#define BNXT_PHC_OVERFLOW_PERIOD (18 * 60 * HZ)
9396

9497
u16 tx_seqid;
9598
u16 tx_hdr_off;

0 commit comments

Comments
 (0)