scsi: lpfc: Add SET_HOST_DATA mbox cmd to pass date/time info to firmware
authorJames Smart <jsmart2021@gmail.com>
Mon, 16 Aug 2021 16:28:47 +0000 (09:28 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Wed, 25 Aug 2021 02:56:33 +0000 (22:56 -0400)
Implement the SET_HOST_DATA mbox command to set date / time during
initialization.  It is used by the firmware for various purposes including
congestion management and firmware dumps.

Link: https://lore.kernel.org/r/20210816162901.121235-3-jsmart2021@gmail.com
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc_hw4.h
drivers/scsi/lpfc/lpfc_sli.c

index aadbb0de629d9edea6b13d3e08a6805968d43184..658b9c55823794aa02c26e09e6a1dc8a3aa1760f 100644 (file)
@@ -3427,12 +3427,40 @@ struct lpfc_mbx_set_feature {
 
 
 #define LPFC_SET_HOST_OS_DRIVER_VERSION    0x2
+#define LPFC_SET_HOST_DATE_TIME                   0x4
+
+struct lpfc_mbx_set_host_date_time {
+       uint32_t word6;
+#define lpfc_mbx_set_host_month_WORD   word6
+#define lpfc_mbx_set_host_month_SHIFT  16
+#define lpfc_mbx_set_host_month_MASK   0xFF
+#define lpfc_mbx_set_host_day_WORD     word6
+#define lpfc_mbx_set_host_day_SHIFT    8
+#define lpfc_mbx_set_host_day_MASK     0xFF
+#define lpfc_mbx_set_host_year_WORD    word6
+#define lpfc_mbx_set_host_year_SHIFT   0
+#define lpfc_mbx_set_host_year_MASK    0xFF
+       uint32_t word7;
+#define lpfc_mbx_set_host_hour_WORD    word7
+#define lpfc_mbx_set_host_hour_SHIFT   16
+#define lpfc_mbx_set_host_hour_MASK    0xFF
+#define lpfc_mbx_set_host_min_WORD     word7
+#define lpfc_mbx_set_host_min_SHIFT    8
+#define lpfc_mbx_set_host_min_MASK     0xFF
+#define lpfc_mbx_set_host_sec_WORD     word7
+#define lpfc_mbx_set_host_sec_SHIFT     0
+#define lpfc_mbx_set_host_sec_MASK      0xFF
+};
+
 struct lpfc_mbx_set_host_data {
 #define LPFC_HOST_OS_DRIVER_VERSION_SIZE   48
        struct mbox_header header;
        uint32_t param_id;
        uint32_t param_len;
-       uint8_t  data[LPFC_HOST_OS_DRIVER_VERSION_SIZE];
+       union {
+               uint8_t data[LPFC_HOST_OS_DRIVER_VERSION_SIZE];
+               struct  lpfc_mbx_set_host_date_time tm;
+       } un;
 };
 
 struct lpfc_mbx_set_trunk_mode {
index 47dd13719901471b31dffbbbca923eb06b8eed59..9ff4abb966af791e1ff31ed622c87477a977140b 100644 (file)
@@ -7369,7 +7369,7 @@ lpfc_set_host_data(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
        mbox->u.mqe.un.set_host_data.param_id = LPFC_SET_HOST_OS_DRIVER_VERSION;
        mbox->u.mqe.un.set_host_data.param_len =
                                        LPFC_HOST_OS_DRIVER_VERSION_SIZE;
-       snprintf(mbox->u.mqe.un.set_host_data.data,
+       snprintf(mbox->u.mqe.un.set_host_data.un.data,
                 LPFC_HOST_OS_DRIVER_VERSION_SIZE,
                 "Linux %s v"LPFC_DRIVER_VERSION,
                 (phba->hba_flag & HBA_FCOE_MODE) ? "FCoE" : "FC");
@@ -7499,6 +7499,51 @@ static void lpfc_sli4_dip(struct lpfc_hba *phba)
        }
 }
 
+static int
+lpfc_set_host_tm(struct lpfc_hba *phba)
+{
+       LPFC_MBOXQ_t *mboxq;
+       uint32_t len, rc;
+       struct timespec64 cur_time;
+       struct tm broken;
+       uint32_t month, day, year;
+       uint32_t hour, minute, second;
+       struct lpfc_mbx_set_host_date_time *tm;
+
+       mboxq = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
+       if (!mboxq)
+               return -ENOMEM;
+
+       len = sizeof(struct lpfc_mbx_set_host_data) -
+               sizeof(struct lpfc_sli4_cfg_mhdr);
+       lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
+                        LPFC_MBOX_OPCODE_SET_HOST_DATA, len,
+                        LPFC_SLI4_MBX_EMBED);
+
+       mboxq->u.mqe.un.set_host_data.param_id = LPFC_SET_HOST_DATE_TIME;
+       mboxq->u.mqe.un.set_host_data.param_len =
+                       sizeof(struct lpfc_mbx_set_host_date_time);
+       tm = &mboxq->u.mqe.un.set_host_data.un.tm;
+       ktime_get_real_ts64(&cur_time);
+       time64_to_tm(cur_time.tv_sec, 0, &broken);
+       month = broken.tm_mon + 1;
+       day = broken.tm_mday;
+       year = broken.tm_year - 100;
+       hour = broken.tm_hour;
+       minute = broken.tm_min;
+       second = broken.tm_sec;
+       bf_set(lpfc_mbx_set_host_month, tm, month);
+       bf_set(lpfc_mbx_set_host_day, tm, day);
+       bf_set(lpfc_mbx_set_host_year, tm, year);
+       bf_set(lpfc_mbx_set_host_hour, tm, hour);
+       bf_set(lpfc_mbx_set_host_min, tm, minute);
+       bf_set(lpfc_mbx_set_host_sec, tm, second);
+
+       rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
+       mempool_free(mboxq, phba->mbox_mem_pool);
+       return rc;
+}
+
 /**
  * lpfc_sli4_hba_setup - SLI4 device initialization PCI function
  * @phba: Pointer to HBA context object.
@@ -7588,6 +7633,10 @@ lpfc_sli4_hba_setup(struct lpfc_hba *phba)
                goto out_free_mbox;
        }
 
+       rc = lpfc_set_host_tm(phba);
+       lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_INIT,
+                       "6468 Set host date / time: Status x%x:\n", rc);
+
        /*
         * Continue initialization with default values even if driver failed
         * to read FCoE param config regions, only read parameters if the