]> git.baikalelectronics.ru Git - kernel.git/commitdiff
bnxt_en: Handle async event when the PHC is updated in RTC mode
authorPavan Chebbi <pavan.chebbi@broadcom.com>
Wed, 26 Jan 2022 04:40:13 +0000 (23:40 -0500)
committerDavid S. Miller <davem@davemloft.net>
Wed, 26 Jan 2022 15:35:20 +0000 (15:35 +0000)
In Multi-host environment, when the PHC is updated by one host,
an async message from firmware will be sent to other hosts.
Re-initialize the timecounter when the driver receives this
async message.

Cc: Richard Cochran <richardcochran@gmail.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/broadcom/bnxt/bnxt.c

index 514798a4f15b6d04f538887f751fe95887afb4bf..c313221348c5cf7b8c3dfb1d499803fa9eb8cdfc 100644 (file)
@@ -233,6 +233,7 @@ static const u16 bnxt_async_events_arr[] = {
        ASYNC_EVENT_CMPL_EVENT_ID_ECHO_REQUEST,
        ASYNC_EVENT_CMPL_EVENT_ID_PPS_TIMESTAMP,
        ASYNC_EVENT_CMPL_EVENT_ID_ERROR_REPORT,
+       ASYNC_EVENT_CMPL_EVENT_ID_PHC_UPDATE,
 };
 
 static struct workqueue_struct *bnxt_pf_wq;
@@ -2079,6 +2080,16 @@ static void bnxt_event_error_report(struct bnxt *bp, u32 data1, u32 data2)
        (BNXT_EVENT_RING_TYPE(data2) == \
         ASYNC_EVENT_CMPL_RING_MONITOR_MSG_EVENT_DATA2_DISABLE_RING_TYPE_RX)
 
+#define BNXT_EVENT_PHC_EVENT_TYPE(data1)       \
+       (((data1) & ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_MASK) >>\
+        ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_SFT)
+
+#define BNXT_EVENT_PHC_RTC_UPDATE(data1)       \
+       (((data1) & ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_PHC_TIME_MSB_MASK) >>\
+        ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_PHC_TIME_MSB_SFT)
+
+#define BNXT_PHC_BITS  48
+
 static int bnxt_async_event_process(struct bnxt *bp,
                                    struct hwrm_async_event_cmpl *cmpl)
 {
@@ -2258,6 +2269,24 @@ static int bnxt_async_event_process(struct bnxt *bp,
                bnxt_event_error_report(bp, data1, data2);
                goto async_event_process_exit;
        }
+       case ASYNC_EVENT_CMPL_EVENT_ID_PHC_UPDATE: {
+               switch (BNXT_EVENT_PHC_EVENT_TYPE(data1)) {
+               case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE:
+                       if (bp->fw_cap & BNXT_FW_CAP_PTP_RTC) {
+                               struct bnxt_ptp_cfg *ptp = bp->ptp_cfg;
+                               u64 ns;
+
+                               spin_lock_bh(&ptp->ptp_lock);
+                               bnxt_ptp_update_current_time(bp);
+                               ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) <<
+                                      BNXT_PHC_BITS) | ptp->current_time);
+                               bnxt_ptp_rtc_timecounter_init(ptp, ns);
+                               spin_unlock_bh(&ptp->ptp_lock);
+                       }
+                       break;
+               }
+               goto async_event_process_exit;
+       }
        case ASYNC_EVENT_CMPL_EVENT_ID_DEFERRED_RESPONSE: {
                u16 seq_id = le32_to_cpu(cmpl->event_data2) & 0xffff;