Daniel Wagner e124dd
From: Quinn Tran <qutran@marvell.com>
Daniel Wagner e124dd
Date: Mon, 6 Jun 2022 21:46:23 -0700
Daniel Wagner e124dd
Subject: scsi: qla2xxx: edif: Add retry for ELS passthrough
Denis Kirjanov 718367
Patch-mainline: v5.20-rc1
Daniel Wagner e124dd
Git-commit: 0b3f3143d473b489a7aa0779c43bcdb344bd3014
Daniel Wagner e124dd
References: bsc#1201958
Daniel Wagner e124dd
Daniel Wagner e124dd
Relating to EDIF, when sending IKE message, updating key or deleting key,
Daniel Wagner e124dd
driver can encounter IOCB queue full. Add additional retries to reduce
Daniel Wagner e124dd
higher level recovery.
Daniel Wagner e124dd
Daniel Wagner e124dd
Link: https://lore.kernel.org/r/20220607044627.19563-8-njavali@marvell.com
Daniel Wagner e124dd
Fixes: dd30706e73b7 ("scsi: qla2xxx: edif: Add key update")
Daniel Wagner e124dd
Signed-off-by: Quinn Tran <qutran@marvell.com>
Daniel Wagner e124dd
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Daniel Wagner e124dd
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Daniel Wagner e124dd
Acked-by: Daniel Wagner <dwagner@suse.de>
Daniel Wagner e124dd
---
Daniel Wagner e124dd
 drivers/scsi/qla2xxx/qla_edif.c |   52 ++++++++++++++++++++++++++++------------
Daniel Wagner e124dd
 drivers/scsi/qla2xxx/qla_os.c   |    2 -
Daniel Wagner e124dd
 2 files changed, 38 insertions(+), 16 deletions(-)
Daniel Wagner e124dd
Daniel Wagner e124dd
--- a/drivers/scsi/qla2xxx/qla_edif.c
Daniel Wagner e124dd
+++ b/drivers/scsi/qla2xxx/qla_edif.c
Daniel Wagner e124dd
@@ -1467,6 +1467,8 @@ qla24xx_check_sadb_avail_slot(struct bsg
Daniel Wagner e124dd
 
Daniel Wagner e124dd
 #define QLA_SA_UPDATE_FLAGS_RX_KEY      0x0
Daniel Wagner e124dd
 #define QLA_SA_UPDATE_FLAGS_TX_KEY      0x2
Daniel Wagner e124dd
+#define EDIF_MSLEEP_INTERVAL 100
Daniel Wagner e124dd
+#define EDIF_RETRY_COUNT  50
Daniel Wagner e124dd
 
Daniel Wagner e124dd
 int
Daniel Wagner e124dd
 qla24xx_sadb_update(struct bsg_job *bsg_job)
Daniel Wagner e124dd
@@ -1479,7 +1481,7 @@ qla24xx_sadb_update(struct bsg_job *bsg_
Daniel Wagner e124dd
 	struct edif_list_entry *edif_entry = NULL;
Daniel Wagner e124dd
 	int			found = 0;
Daniel Wagner e124dd
 	int			rval = 0;
Daniel Wagner e124dd
-	int result = 0;
Daniel Wagner e124dd
+	int result = 0, cnt;
Daniel Wagner e124dd
 	struct qla_sa_update_frame sa_frame;
Daniel Wagner e124dd
 	struct srb_iocb *iocb_cmd;
Daniel Wagner e124dd
 	port_id_t portid;
Daniel Wagner e124dd
@@ -1720,11 +1722,23 @@ qla24xx_sadb_update(struct bsg_job *bsg_
Daniel Wagner e124dd
 	sp->done = qla2x00_bsg_job_done;
Daniel Wagner e124dd
 	iocb_cmd = &sp->u.iocb_cmd;
Daniel Wagner e124dd
 	iocb_cmd->u.sa_update.sa_frame  = sa_frame;
Daniel Wagner e124dd
-
Daniel Wagner e124dd
+	cnt = 0;
Daniel Wagner e124dd
+retry:
Daniel Wagner e124dd
 	rval = qla2x00_start_sp(sp);
Daniel Wagner e124dd
-	if (rval != QLA_SUCCESS) {
Daniel Wagner e124dd
+	switch (rval) {
Daniel Wagner e124dd
+	case QLA_SUCCESS:
Daniel Wagner e124dd
+		break;
Daniel Wagner e124dd
+	case EAGAIN:
Daniel Wagner e124dd
+		msleep(EDIF_MSLEEP_INTERVAL);
Daniel Wagner e124dd
+		cnt++;
Daniel Wagner e124dd
+		if (cnt < EDIF_RETRY_COUNT)
Daniel Wagner e124dd
+			goto retry;
Daniel Wagner e124dd
+
Daniel Wagner e124dd
+		/* fallthrough */
Daniel Wagner e124dd
+	default:
Daniel Wagner e124dd
 		ql_log(ql_dbg_edif, vha, 0x70e3,
Daniel Wagner e124dd
-		    "qla2x00_start_sp failed=%d.\n", rval);
Daniel Wagner e124dd
+		       "%s qla2x00_start_sp failed=%d.\n",
Daniel Wagner e124dd
+		       __func__, rval);
Daniel Wagner e124dd
 
Daniel Wagner e124dd
 		qla2x00_rel_sp(sp);
Daniel Wagner e124dd
 		rval = -EIO;
Daniel Wagner e124dd
@@ -2398,7 +2412,6 @@ qla24xx_issue_sa_replace_iocb(scsi_qla_h
Daniel Wagner e124dd
 	rval = qla2x00_start_sp(sp);
Daniel Wagner e124dd
 
Daniel Wagner e124dd
 	if (rval != QLA_SUCCESS) {
Daniel Wagner e124dd
-		rval = QLA_FUNCTION_FAILED;
Daniel Wagner e124dd
 		goto done_free_sp;
Daniel Wagner e124dd
 	}
Daniel Wagner e124dd
 
Daniel Wagner e124dd
@@ -3530,7 +3543,7 @@ int qla_edif_process_els(scsi_qla_host_t
Daniel Wagner e124dd
 	fc_port_t *fcport = NULL;
Daniel Wagner e124dd
 	struct qla_hw_data *ha = vha->hw;
Daniel Wagner e124dd
 	srb_t *sp;
Daniel Wagner e124dd
-	int rval =  (DID_ERROR << 16);
Daniel Wagner e124dd
+	int rval =  (DID_ERROR << 16), cnt;
Daniel Wagner e124dd
 	port_id_t d_id;
Daniel Wagner e124dd
 	struct qla_bsg_auth_els_request *p =
Daniel Wagner e124dd
 	    (struct qla_bsg_auth_els_request *)bsg_job->request;
Daniel Wagner e124dd
@@ -3625,17 +3638,26 @@ int qla_edif_process_els(scsi_qla_host_t
Daniel Wagner e124dd
 	sp->free = qla2x00_bsg_sp_free;
Daniel Wagner e124dd
 	sp->done = qla2x00_bsg_job_done;
Daniel Wagner e124dd
 
Daniel Wagner e124dd
+	cnt = 0;
Daniel Wagner e124dd
+retry:
Daniel Wagner e124dd
 	rval = qla2x00_start_sp(sp);
Daniel Wagner e124dd
-
Daniel Wagner e124dd
-	ql_dbg(ql_dbg_edif, vha, 0x700a,
Daniel Wagner e124dd
-	    "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n",
Daniel Wagner e124dd
-	    __func__, sc_to_str(p->e.sub_cmd), fcport->port_name,
Daniel Wagner e124dd
-	    p->e.extra_rx_xchg_address, p->e.extra_control_flags,
Daniel Wagner e124dd
-	    sp->handle, sp->remap.req.len, bsg_job);
Daniel Wagner e124dd
-
Daniel Wagner e124dd
-	if (rval != QLA_SUCCESS) {
Daniel Wagner e124dd
+	switch (rval) {
Daniel Wagner e124dd
+	case QLA_SUCCESS:
Daniel Wagner e124dd
+		ql_dbg(ql_dbg_edif, vha, 0x700a,
Daniel Wagner e124dd
+		       "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n",
Daniel Wagner e124dd
+		       __func__, sc_to_str(p->e.sub_cmd), fcport->port_name,
Daniel Wagner e124dd
+		       p->e.extra_rx_xchg_address, p->e.extra_control_flags,
Daniel Wagner e124dd
+		       sp->handle, sp->remap.req.len, bsg_job);
Daniel Wagner e124dd
+		break;
Daniel Wagner e124dd
+	case EAGAIN:
Daniel Wagner e124dd
+		msleep(EDIF_MSLEEP_INTERVAL);
Daniel Wagner e124dd
+		cnt++;
Daniel Wagner e124dd
+		if (cnt < EDIF_RETRY_COUNT)
Daniel Wagner e124dd
+			goto retry;
Daniel Wagner e124dd
+		/* fallthrough */
Daniel Wagner e124dd
+	default:
Daniel Wagner e124dd
 		ql_log(ql_log_warn, vha, 0x700e,
Daniel Wagner e124dd
-		    "qla2x00_start_sp failed = %d\n", rval);
Daniel Wagner e124dd
+		    "%s qla2x00_start_sp failed = %d\n", __func__, rval);
Daniel Wagner e124dd
 		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
Daniel Wagner e124dd
 		rval = -EIO;
Daniel Wagner e124dd
 		goto done_free_remap_rsp;
Daniel Wagner e124dd
--- a/drivers/scsi/qla2xxx/qla_os.c
Daniel Wagner e124dd
+++ b/drivers/scsi/qla2xxx/qla_os.c
Daniel Wagner e124dd
@@ -5509,7 +5509,7 @@ qla2x00_do_work(struct scsi_qla_host *vh
Daniel Wagner e124dd
 			    e->u.fcport.fcport, false);
Daniel Wagner e124dd
 			break;
Daniel Wagner e124dd
 		case QLA_EVT_SA_REPLACE:
Daniel Wagner e124dd
-			qla24xx_issue_sa_replace_iocb(vha, e);
Daniel Wagner e124dd
+			rc = qla24xx_issue_sa_replace_iocb(vha, e);
Daniel Wagner e124dd
 			break;
Daniel Wagner e124dd
 		}
Daniel Wagner e124dd