scsi: lpfc: Introduce new attention types for lpfc_sli4_async_fc_evt() handler
authorJustin Tee <justin.tee@broadcom.com>
Mon, 9 Jan 2023 23:33:15 +0000 (15:33 -0800)
committerMartin K. Petersen <martin.petersen@oracle.com>
Thu, 12 Jan 2023 05:03:15 +0000 (00:03 -0500)
Define new FC Link ACQE with new attention types 0x8 (Link Activation
Failure) and 0x9 (Link Reset Protocol Event).

Both attention types are meant to be informational-only type ACQEs with no
action required.

0x8 is reported for diagnostic purposes, while 0x9 is posted during a
normal link up transition when activating BB Credit Recovery feature.

As such, modify lpfc_sli4_async_fc_evt() logic to log the attention types
according to its severity and early return when informational-only
attention types are encountered.

Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/lpfc/lpfc_hw4.h
drivers/scsi/lpfc/lpfc_init.c
drivers/scsi/lpfc/lpfc_sli4.h

index fb3504d..58589eb 100644 (file)
@@ -4201,6 +4201,8 @@ struct lpfc_acqe_fc_la {
 #define LPFC_FC_LA_TYPE_MDS_LOOPBACK   0x5
 #define LPFC_FC_LA_TYPE_UNEXP_WWPN     0x6
 #define LPFC_FC_LA_TYPE_TRUNKING_EVENT  0x7
+#define LPFC_FC_LA_TYPE_ACTIVATE_FAIL          0x8
+#define LPFC_FC_LA_TYPE_LINK_RESET_PRTCL_EVT   0x9
 #define lpfc_acqe_fc_la_port_type_SHIFT                6
 #define lpfc_acqe_fc_la_port_type_MASK         0x00000003
 #define lpfc_acqe_fc_la_port_type_WORD         word0
@@ -4242,6 +4244,9 @@ struct lpfc_acqe_fc_la {
 #define lpfc_acqe_fc_la_fault_SHIFT            0
 #define lpfc_acqe_fc_la_fault_MASK             0x000000FF
 #define lpfc_acqe_fc_la_fault_WORD             word1
+#define lpfc_acqe_fc_la_link_status_SHIFT      8
+#define lpfc_acqe_fc_la_link_status_MASK       0x0000007F
+#define lpfc_acqe_fc_la_link_status_WORD       word1
 #define lpfc_acqe_fc_la_trunk_fault_SHIFT              0
 #define lpfc_acqe_fc_la_trunk_fault_MASK               0x0000000F
 #define lpfc_acqe_fc_la_trunk_fault_WORD               word1
index 4d58373..0fef8cd 100644 (file)
@@ -5189,16 +5189,25 @@ static void
 lpfc_sli4_parse_latt_fault(struct lpfc_hba *phba,
                           struct lpfc_acqe_link *acqe_link)
 {
-       switch (bf_get(lpfc_acqe_link_fault, acqe_link)) {
-       case LPFC_ASYNC_LINK_FAULT_NONE:
-       case LPFC_ASYNC_LINK_FAULT_LOCAL:
-       case LPFC_ASYNC_LINK_FAULT_REMOTE:
-       case LPFC_ASYNC_LINK_FAULT_LR_LRR:
+       switch (bf_get(lpfc_acqe_fc_la_att_type, acqe_link)) {
+       case LPFC_FC_LA_TYPE_LINK_DOWN:
+       case LPFC_FC_LA_TYPE_TRUNKING_EVENT:
+       case LPFC_FC_LA_TYPE_ACTIVATE_FAIL:
+       case LPFC_FC_LA_TYPE_LINK_RESET_PRTCL_EVT:
                break;
        default:
-               lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
-                               "0398 Unknown link fault code: x%x\n",
-                               bf_get(lpfc_acqe_link_fault, acqe_link));
+               switch (bf_get(lpfc_acqe_link_fault, acqe_link)) {
+               case LPFC_ASYNC_LINK_FAULT_NONE:
+               case LPFC_ASYNC_LINK_FAULT_LOCAL:
+               case LPFC_ASYNC_LINK_FAULT_REMOTE:
+               case LPFC_ASYNC_LINK_FAULT_LR_LRR:
+                       break;
+               default:
+                       lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
+                                       "0398 Unknown link fault code: x%x\n",
+                                       bf_get(lpfc_acqe_link_fault, acqe_link));
+                       break;
+               }
                break;
        }
 }
@@ -6281,6 +6290,7 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
        LPFC_MBOXQ_t *pmb;
        MAILBOX_t *mb;
        struct lpfc_mbx_read_top *la;
+       char *log_level;
        int rc;
 
        if (bf_get(lpfc_trailer_type, acqe_fc) !=
@@ -6312,25 +6322,70 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc)
                                bf_get(lpfc_acqe_fc_la_port_number, acqe_fc);
        phba->sli4_hba.link_state.fault =
                                bf_get(lpfc_acqe_link_fault, acqe_fc);
+       phba->sli4_hba.link_state.link_status =
+                               bf_get(lpfc_acqe_fc_la_link_status, acqe_fc);
 
-       if (bf_get(lpfc_acqe_fc_la_att_type, acqe_fc) ==
-           LPFC_FC_LA_TYPE_LINK_DOWN)
-               phba->sli4_hba.link_state.logical_speed = 0;
-       else if (!phba->sli4_hba.conf_trunk)
-               phba->sli4_hba.link_state.logical_speed =
+       /*
+        * Only select attention types need logical speed modification to what
+        * was previously set.
+        */
+       if (phba->sli4_hba.link_state.status >= LPFC_FC_LA_TYPE_LINK_UP &&
+           phba->sli4_hba.link_state.status < LPFC_FC_LA_TYPE_ACTIVATE_FAIL) {
+               if (bf_get(lpfc_acqe_fc_la_att_type, acqe_fc) ==
+                   LPFC_FC_LA_TYPE_LINK_DOWN)
+                       phba->sli4_hba.link_state.logical_speed = 0;
+               else if (!phba->sli4_hba.conf_trunk)
+                       phba->sli4_hba.link_state.logical_speed =
                                bf_get(lpfc_acqe_fc_la_llink_spd, acqe_fc) * 10;
+       }
 
        lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
                        "2896 Async FC event - Speed:%dGBaud Topology:x%x "
                        "LA Type:x%x Port Type:%d Port Number:%d Logical speed:"
-                       "%dMbps Fault:%d\n",
+                       "%dMbps Fault:x%x Link Status:x%x\n",
                        phba->sli4_hba.link_state.speed,
                        phba->sli4_hba.link_state.topology,
                        phba->sli4_hba.link_state.status,
                        phba->sli4_hba.link_state.type,
                        phba->sli4_hba.link_state.number,
                        phba->sli4_hba.link_state.logical_speed,
-                       phba->sli4_hba.link_state.fault);
+                       phba->sli4_hba.link_state.fault,
+                       phba->sli4_hba.link_state.link_status);
+
+       /*
+        * The following attention types are informational only, providing
+        * further details about link status.  Overwrite the value of
+        * link_state.status appropriately.  No further action is required.
+        */
+       if (phba->sli4_hba.link_state.status >= LPFC_FC_LA_TYPE_ACTIVATE_FAIL) {
+               switch (phba->sli4_hba.link_state.status) {
+               case LPFC_FC_LA_TYPE_ACTIVATE_FAIL:
+                       log_level = KERN_WARNING;
+                       phba->sli4_hba.link_state.status =
+                                       LPFC_FC_LA_TYPE_LINK_DOWN;
+                       break;
+               case LPFC_FC_LA_TYPE_LINK_RESET_PRTCL_EVT:
+                       /*
+                        * During bb credit recovery establishment, receiving
+                        * this attention type is normal.  Link Up attention
+                        * type is expected to occur before this informational
+                        * attention type so keep the Link Up status.
+                        */
+                       log_level = KERN_INFO;
+                       phba->sli4_hba.link_state.status =
+                                       LPFC_FC_LA_TYPE_LINK_UP;
+                       break;
+               default:
+                       log_level = KERN_INFO;
+                       break;
+               }
+               lpfc_log_msg(phba, log_level, LOG_SLI,
+                            "2992 Async FC event - Informational Link "
+                            "Attention Type x%x\n",
+                            bf_get(lpfc_acqe_fc_la_att_type, acqe_fc));
+               return;
+       }
+
        pmb = (LPFC_MBOXQ_t *)mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
        if (!pmb) {
                lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
index f927c2a..babdf29 100644 (file)
@@ -291,8 +291,9 @@ struct lpfc_sli4_link {
        uint8_t type;
        uint8_t number;
        uint8_t fault;
-       uint32_t logical_speed;
+       uint8_t link_status;
        uint16_t topology;
+       uint32_t logical_speed;
 };
 
 struct lpfc_fcf_rec {