Index: sys/dev/bnxt/bnxt_en/bnxt.h =================================================================== --- sys/dev/bnxt/bnxt_en/bnxt.h +++ sys/dev/bnxt/bnxt_en/bnxt.h @@ -1333,6 +1333,10 @@ unsigned long fw_reset_timestamp; struct bnxt_fw_health *fw_health; +#define BOOTTIME_TS_RETRIES 600 +#define MIN_VALID_TIMESTAMP 946684800 /* 2000-01-01 */ + struct callout time_sync_callout; + uint16_t ts_retry_count; }; struct bnxt_filter_info { @@ -1380,6 +1384,7 @@ int bnxt_dcb_ieee_getets(struct bnxt_softc *softc, struct bnxt_ieee_ets *ets); int bnxt_dcb_ieee_setets(struct bnxt_softc *softc, struct bnxt_ieee_ets *ets); uint8_t get_phy_type(struct bnxt_softc *softc); +int bnxt_host_fw_ts_sync(struct bnxt_softc *softc); int bnxt_dcb_ieee_getpfc(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc); int bnxt_dcb_ieee_setpfc(struct bnxt_softc *softc, struct bnxt_ieee_pfc *pfc); int bnxt_dcb_ieee_setapp(struct bnxt_softc *softc, struct bnxt_dcb_app *app); Index: sys/dev/bnxt/bnxt_en/if_bnxt.c =================================================================== --- sys/dev/bnxt/bnxt_en/if_bnxt.c +++ sys/dev/bnxt/bnxt_en/if_bnxt.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -1442,10 +1443,8 @@ struct bnxt_bar_info *db_bar = &ring->softc->doorbell_bar; uint64_t db_val; - if (idx >= ring->ring_size) { - device_printf(ring->softc->dev, "%s: BRCM DBG: idx: %d crossed boundary\n", __func__, idx); + if (idx >= ring->ring_size) return; - } db_val = ((DBR_PATH_L2 | DBR_TYPE_SRQ | DBR_VALID | idx) | ((uint64_t)ring->phys_id << DBR_XID_SFT)); @@ -1466,10 +1465,8 @@ struct bnxt_bar_info *db_bar = &ring->softc->doorbell_bar; uint64_t db_val; - if (idx >= ring->ring_size) { - device_printf(ring->softc->dev, "%s: BRCM DBG: idx: %d crossed boundary\n", __func__, idx); + if (idx >= ring->ring_size) return; - } db_val = ((DBR_PATH_L2 | DBR_TYPE_SQ | DBR_VALID | idx) | ((uint64_t)ring->phys_id << DBR_XID_SFT)); @@ -1700,6 +1697,8 @@ } bnxt_fw_fatal_close(bp); } + if (BNXT_CHIP_P5_PLUS(bp)) + callout_drain(&bp->time_sync_callout); iflib_request_reset(bp->ctx); bnxt_stop(bp->ctx); @@ -2070,6 +2069,9 @@ bnxt_init(bp->ctx); bnxt_intr_enable(bp->ctx); + if (BNXT_CHIP_P5_PLUS(bp)) + bnxt_host_fw_ts_sync(bp); + if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) { if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) { bnxt_ulp_start(bp, 0); @@ -2288,6 +2290,61 @@ clear_bit(BNXT_STATE_IN_SP_TASK, &bp->state); } +static void inline bnxt_host_fw_ts_sync_callout(void *arg) +{ + struct bnxt_softc *softc = (struct bnxt_softc *)arg; + + bnxt_host_fw_ts_sync(softc); + + return; +} + +int bnxt_host_fw_ts_sync(struct bnxt_softc *softc) +{ + struct hwrm_fw_set_time_input req = {0}; + struct timespec ts; + struct clocktime ct; + int rc = 0; + + getnanotime(&ts); + if (ts.tv_sec < MIN_VALID_TIMESTAMP) { + softc->ts_retry_count++; + if (softc->ts_retry_count > BOOTTIME_TS_RETRIES) { + device_printf(softc->dev, "OS real time clock is not ready after %d retries. " + "Aborting host firware timestamp synchronization\n", BOOTTIME_TS_RETRIES); + softc->ts_retry_count = 0; + return -1; + } + callout_reset(&softc->time_sync_callout, hz, bnxt_host_fw_ts_sync_callout, softc); + return 0; + } + + softc->ts_retry_count = 0; + clock_ts_to_ct(&ts, &ct); + + bnxt_hwrm_cmd_hdr_init(softc, &req, HWRM_FW_SET_TIME); + + /* Populate the request structure with the current time */ + req.year = cpu_to_le16(ct.year); + req.month = ct.mon; + req.day = ct.day; + req.hour = ct.hour; + req.minute = ct.min; + req.second = ct.sec; + + rc = hwrm_send_message(softc, &req, sizeof(req)); + if (rc) { + device_printf(softc->dev, "%s hwrm command failed, rc %d\n", __func__, rc); + return rc; + } + + /* Schedule the fw timestamp sync to run after 4 hours */ + callout_reset(&softc->time_sync_callout, 4 * 3600 * hz, bnxt_host_fw_ts_sync_callout, softc); + + return rc; +} + + /* Device setup and teardown */ static int bnxt_attach_pre(if_ctx_t ctx) @@ -2658,6 +2715,11 @@ if (rc) goto failed; + if (BNXT_CHIP_P5_PLUS(softc)) { + callout_init(&softc->time_sync_callout, 1); + bnxt_host_fw_ts_sync(softc); + } + set_bit(BNXT_STATE_OPEN, &softc->state); INIT_WORK(&softc->sp_task, bnxt_sp_task); INIT_DELAYED_WORK(&softc->fw_reset_task, bnxt_fw_reset_task); @@ -2737,6 +2799,10 @@ struct bnxt_vlan_tag *tmp; int i; + /* Stop the timesync callout if it is scheduled */ + if (BNXT_CHIP_P5_PLUS(softc)) + callout_drain(&softc->time_sync_callout); + bnxt_rdma_aux_device_uninit(softc); cancel_delayed_work_sync(&softc->fw_reset_task); cancel_work_sync(&softc->sp_task);