#define BNXT_PTP_FLAGS_PATH_TX 0x0
#define BNXT_PTP_FLAGS_PATH_RX 0x1
#define BNXT_PTP_FLAGS_CURRENT_TIME 0x2
+#define BNXT_PTP_CURRENT_TIME_MASK 0xFFFF00000000ULL
struct bnxt_ptp_cfg {
#define BNXT_GRCPF_REG_WINDOW_BASE_OUT 0x400
/* On Thor, the Rx timestamp is present in the Rx completion record */
uint64_t rx_timestamp;
+ uint64_t current_time;
};
struct bnxt_coal {
#define BNXT_TRUFLOW_EN(bp) ((bp)->flags & BNXT_FLAG_TRUFLOW_EN)
#define BNXT_GFID_ENABLED(bp) ((bp)->flags & BNXT_FLAG_GFID_ENABLE)
+ uint32_t flags2;
+#define BNXT_FLAGS2_PTP_TIMESYNC_ENABLED BIT(0)
+#define BNXT_FLAGS2_PTP_ALARM_SCHEDULED BIT(1)
+#define BNXT_P5_PTP_TIMESYNC_ENABLED(bp) \
+ ((bp)->flags2 & BNXT_FLAGS2_PTP_TIMESYNC_ENABLED)
+
uint16_t chip_num;
#define CHIP_NUM_58818 0xd818
#define BNXT_CHIP_SR2(bp) ((bp)->chip_num == CHIP_NUM_58818)
}
}
+static void bnxt_ptp_get_current_time(void *arg)
+{
+ struct bnxt *bp = arg;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ int rc;
+
+ rc = is_bnxt_in_error(bp);
+ if (rc)
+ return;
+
+ if (!ptp)
+ return;
+
+ bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,
+ &ptp->current_time);
+
+ rc = rte_eal_alarm_set(US_PER_S, bnxt_ptp_get_current_time, (void *)bp);
+ if (rc != 0) {
+ PMD_DRV_LOG(ERR, "Failed to re-schedule PTP alarm\n");
+ bp->flags2 &= ~BNXT_FLAGS2_PTP_ALARM_SCHEDULED;
+ }
+}
+
+static int bnxt_schedule_ptp_alarm(struct bnxt *bp)
+{
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ int rc;
+
+ if (bp->flags2 & BNXT_FLAGS2_PTP_ALARM_SCHEDULED)
+ return 0;
+
+ bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,
+ &ptp->current_time);
+
+ rc = rte_eal_alarm_set(US_PER_S, bnxt_ptp_get_current_time, (void *)bp);
+ return rc;
+}
+
+static void bnxt_cancel_ptp_alarm(struct bnxt *bp)
+{
+ if (bp->flags2 & BNXT_FLAGS2_PTP_ALARM_SCHEDULED) {
+ rte_eal_alarm_cancel(bnxt_ptp_get_current_time, (void *)bp);
+ bp->flags2 &= ~BNXT_FLAGS2_PTP_ALARM_SCHEDULED;
+ }
+}
+
+static void bnxt_ptp_stop(struct bnxt *bp)
+{
+ bnxt_cancel_ptp_alarm(bp);
+ bp->flags2 &= ~BNXT_FLAGS2_PTP_TIMESYNC_ENABLED;
+}
+
+static int bnxt_ptp_start(struct bnxt *bp)
+{
+ int rc;
+
+ rc = bnxt_schedule_ptp_alarm(bp);
+ if (rc != 0) {
+ PMD_DRV_LOG(ERR, "Failed to schedule PTP alarm\n");
+ } else {
+ bp->flags2 |= BNXT_FLAGS2_PTP_TIMESYNC_ENABLED;
+ bp->flags2 |= BNXT_FLAGS2_PTP_ALARM_SCHEDULED;
+ }
+
+ return rc;
+}
+
static int bnxt_dev_stop(struct rte_eth_dev *eth_dev)
{
struct bnxt *bp = eth_dev->data->dev_private;
bnxt_cancel_fw_health_check(bp);
+ if (BNXT_P5_PTP_TIMESYNC_ENABLED(bp))
+ bnxt_cancel_ptp_alarm(bp);
+
/* Do not bring link down during reset recovery */
if (!is_bnxt_in_error(bp)) {
bnxt_dev_set_link_down_op(eth_dev);
bnxt_schedule_fw_health_check(bp);
+ if (BNXT_P5_PTP_TIMESYNC_ENABLED(bp))
+ bnxt_schedule_ptp_alarm(bp);
+
return 0;
error:
if (!BNXT_CHIP_P5(bp))
bnxt_map_ptp_regs(bp);
+ else
+ rc = bnxt_ptp_start(bp);
- return 0;
+ return rc;
}
static int
if (!BNXT_CHIP_P5(bp))
bnxt_unmap_ptp_regs(bp);
+ else
+ bnxt_ptp_stop(bp);
return 0;
}
static void
bnxt_get_rx_ts_p5(struct bnxt *bp, uint32_t rx_ts_cmpl)
{
- uint64_t systime_cycles = 0;
+ struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+ uint64_t last_hwrm_time;
+ uint64_t pkt_time = 0;
- if (!BNXT_CHIP_P5(bp))
+ if (!BNXT_CHIP_P5(bp) || !ptp)
return;
/* On Thor, Rx timestamps are provided directly in the
* from the HWRM response with the lower 32 bits in the
* Rx completion to produce the 48 bit timestamp for the Rx packet
*/
- bnxt_hwrm_port_ts_query(bp, BNXT_PTP_FLAGS_CURRENT_TIME,
- &systime_cycles);
- bp->ptp_cfg->rx_timestamp = (systime_cycles & 0xFFFF00000000);
- bp->ptp_cfg->rx_timestamp |= rx_ts_cmpl;
+ last_hwrm_time = ptp->current_time;
+ pkt_time = (last_hwrm_time & BNXT_PTP_CURRENT_TIME_MASK) | rx_ts_cmpl;
+ if (rx_ts_cmpl < (uint32_t)last_hwrm_time) {
+ /* timer has rolled over */
+ pkt_time += (1ULL << 32);
+ }
+ ptp->rx_timestamp = pkt_time;
}
#endif