scsi: qla2xxx: Fix N2N and NVMe connect retry failure
authorQuinn Tran <qutran@marvell.com>
Wed, 2 Dec 2020 13:23:06 +0000 (05:23 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 30 Dec 2020 10:53:45 +0000 (11:53 +0100)
[ Upstream commit 07a5f69248e3486e387c40af64793466371c7d91 ]

FC-NVMe target discovery failed when initiator wwpn < target wwpn in an N2N
(Direct Attach) config, where the driver was stuck on FCP PRLI mode and
failed to retry with NVMe PRLI.

Link: https://lore.kernel.org/r/20201202132312.19966-10-njavali@marvell.com
Fixes: 84ed362ac40c ("scsi: qla2xxx: Dual FCP-NVMe target port support”)
Fixes: 983f127603fa ("scsi: qla2xxx: Retry PLOGI on FC-NVMe PRLI failure”)
Signed-off-by: Quinn Tran <qutran@marvell.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/scsi/qla2xxx/qla_init.c
drivers/scsi/qla2xxx/qla_mbx.c

index 898c70b..52e8b55 100644 (file)
@@ -1268,9 +1268,10 @@ qla24xx_async_prli(struct scsi_qla_host *vha, fc_port_t *fcport)
                lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
 
        ql_dbg(ql_dbg_disc, vha, 0x211b,
-           "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n",
+           "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d fc4type %x priority %x %s.\n",
            fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
-           fcport->login_retry, NVME_TARGET(vha->hw, fcport) ? "nvme" : "fc");
+           fcport->login_retry, fcport->fc4_type, vha->hw->fc4_type_priority,
+           NVME_TARGET(vha->hw, fcport) ? "nvme" : "fcp");
 
        rval = qla2x00_start_sp(sp);
        if (rval != QLA_SUCCESS) {
@@ -1932,26 +1933,58 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
                        break;
                }
 
-               /*
-                * Retry PRLI with other FC-4 type if failure occurred on dual
-                * FCP/NVMe port
-                */
-               if (NVME_FCP_TARGET(ea->fcport)) {
-                       ql_dbg(ql_dbg_disc, vha, 0x2118,
-                               "%s %d %8phC post %s prli\n",
-                               __func__, __LINE__, ea->fcport->port_name,
-                               (ea->fcport->fc4_type & FS_FC4TYPE_NVME) ?
-                               "NVMe" : "FCP");
-                       if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
+               ql_dbg(ql_dbg_disc, vha, 0x2118,
+                      "%s %d %8phC priority %s, fc4type %x\n",
+                      __func__, __LINE__, ea->fcport->port_name,
+                      vha->hw->fc4_type_priority == FC4_PRIORITY_FCP ?
+                      "FCP" : "NVMe", ea->fcport->fc4_type);
+
+               if (N2N_TOPO(vha->hw)) {
+                       if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME) {
                                ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
-                       else
+                               ea->fcport->fc4_type |= FS_FC4TYPE_FCP;
+                       } else {
                                ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
-               }
+                               ea->fcport->fc4_type |= FS_FC4TYPE_NVME;
+                       }
 
-               ea->fcport->flags &= ~FCF_ASYNC_SENT;
-               ea->fcport->keep_nport_handle = 0;
-               ea->fcport->logout_on_delete = 1;
-               qlt_schedule_sess_for_deletion(ea->fcport);
+                       if (ea->fcport->n2n_link_reset_cnt < 3) {
+                               ea->fcport->n2n_link_reset_cnt++;
+                               vha->relogin_jif = jiffies + 2 * HZ;
+                               /*
+                                * PRLI failed. Reset link to kick start
+                                * state machine
+                                */
+                               set_bit(N2N_LINK_RESET, &vha->dpc_flags);
+                       } else {
+                               ql_log(ql_log_warn, vha, 0x2119,
+                                      "%s %d %8phC Unable to reconnect\n",
+                                      __func__, __LINE__,
+                                      ea->fcport->port_name);
+                       }
+               } else {
+                       /*
+                        * switch connect. login failed. Take connection down
+                        * and allow relogin to retrigger
+                        */
+                       if (NVME_FCP_TARGET(ea->fcport)) {
+                               ql_dbg(ql_dbg_disc, vha, 0x2118,
+                                      "%s %d %8phC post %s prli\n",
+                                      __func__, __LINE__,
+                                      ea->fcport->port_name,
+                                      (ea->fcport->fc4_type & FS_FC4TYPE_NVME)
+                                      ? "NVMe" : "FCP");
+                               if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
+                                       ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
+                               else
+                                       ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
+                       }
+
+                       ea->fcport->flags &= ~FCF_ASYNC_SENT;
+                       ea->fcport->keep_nport_handle = 0;
+                       ea->fcport->logout_on_delete = 1;
+                       qlt_schedule_sess_for_deletion(ea->fcport);
+               }
                break;
        }
 }
index bef871a..d6325fb 100644 (file)
@@ -3998,9 +3998,6 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
                                fcport->scan_state = QLA_FCPORT_FOUND;
                                fcport->n2n_flag = 1;
                                fcport->keep_nport_handle = 1;
-                               fcport->fc4_type = FS_FC4TYPE_FCP;
-                               if (vha->flags.nvme_enabled)
-                                       fcport->fc4_type |= FS_FC4TYPE_NVME;
 
                                if (wwn_to_u64(vha->port_name) >
                                    wwn_to_u64(fcport->port_name)) {