Commit c019cd65 authored by Quinn Tran's avatar Quinn Tran Committed by Martin K. Petersen
Browse files

scsi: qla2xxx: edif: Fix dropped IKE message

This patch fixes IKE message being dropped due to error in processing Purex
IOCB and Continuation IOCBs.

Link: https://lore.kernel.org/r/20220713052045.10683-6-njavali@marvell.com


Fixes: fac28079 ("scsi: qla2xxx: edif: Add extraction of auth_els from the wire")
Cc: stable@vger.kernel.org
Reviewed-by: default avatarHimanshu Madhani <himanshu.madhani@oracle.com>
Signed-off-by: default avatarQuinn Tran <qutran@marvell.com>
Signed-off-by: default avatarNilesh Javali <njavali@marvell.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent b1f70714
Loading
Loading
Loading
Loading
+24 −30
Original line number Diff line number Diff line
@@ -3720,12 +3720,11 @@ void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *vha,
 * Return: 0 all iocbs has arrived, xx- all iocbs have not arrived.
 */
static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha,
	struct rsp_que *rsp, response_t *pkt)
	struct rsp_que *rsp, response_t *pkt, u32 rsp_q_in)
{
	int start_pkt_ring_index, end_pkt_ring_index, n_ring_index;
	response_t *end_pkt;
	int start_pkt_ring_index;
	u32 iocb_cnt = 0;
	int rc = 0;
	u32 rsp_q_in;

	if (pkt->entry_count == 1)
		return rc;
@@ -3736,34 +3735,18 @@ static int qla_chk_cont_iocb_avail(struct scsi_qla_host *vha,
	else
		start_pkt_ring_index = rsp->ring_index - 1;

	if ((start_pkt_ring_index + pkt->entry_count) >= rsp->length)
		end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count -
			rsp->length - 1;
	if (rsp_q_in < start_pkt_ring_index)
		/* q in ptr is wrapped */
		iocb_cnt = rsp->length - start_pkt_ring_index + rsp_q_in;
	else
		end_pkt_ring_index = start_pkt_ring_index + pkt->entry_count - 1;
		iocb_cnt = rsp_q_in - start_pkt_ring_index;

	end_pkt = rsp->ring + end_pkt_ring_index;

	/*  next pkt = end_pkt + 1 */
	n_ring_index = end_pkt_ring_index + 1;
	if (n_ring_index >= rsp->length)
		n_ring_index = 0;

	rsp_q_in = rsp->qpair->use_shadow_reg ? *rsp->in_ptr :
		rd_reg_dword(rsp->rsp_q_in);

	/* rsp_q_in is either wrapped or pointing beyond endpkt */
	if ((rsp_q_in < start_pkt_ring_index && rsp_q_in < n_ring_index) ||
			rsp_q_in >= n_ring_index)
		/* all IOCBs arrived. */
		rc = 0;
	else
	if (iocb_cnt < pkt->entry_count)
		rc = -EIO;

	ql_dbg(ql_dbg_init + ql_dbg_verbose, vha, 0x5091,
	    "%s - ring %p pkt %p end pkt %p entry count %#x rsp_q_in %d rc %d\n",
	    __func__, rsp->ring, pkt, end_pkt, pkt->entry_count,
	    rsp_q_in, rc);
	ql_dbg(ql_dbg_init, vha, 0x5091,
	       "%s - ring %p pkt %p entry count %d iocb_cnt %d rsp_q_in %d rc %d\n",
	       __func__, rsp->ring, pkt, pkt->entry_count, iocb_cnt, rsp_q_in, rc);

	return rc;
}
@@ -3780,7 +3763,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
	struct qla_hw_data *ha = vha->hw;
	struct purex_entry_24xx *purex_entry;
	struct purex_item *pure_item;
	u16 rsp_in = 0;
	u16 rsp_in = 0, cur_ring_index;
	int follow_inptr, is_shadow_hba;

	if (!ha->flags.fw_started)
@@ -3811,6 +3794,7 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
		       (!follow_inptr &&
			rsp->ring_ptr->signature != RESPONSE_PROCESSED)) {
		pkt = (struct sts_entry_24xx *)rsp->ring_ptr;
		cur_ring_index = rsp->ring_index;

		rsp->ring_index++;
		if (rsp->ring_index == rsp->length) {
@@ -3931,7 +3915,17 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
				break;

			case ELS_AUTH_ELS:
				if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt)) {
				if (qla_chk_cont_iocb_avail(vha, rsp, (response_t *)pkt, rsp_in)) {
					/*
					 * ring_ptr and ring_index were
					 * pre-incremented above. Reset them
					 * back to current. Wait for next
					 * interrupt with all IOCBs to arrive
					 * and re-process.
					 */
					rsp->ring_ptr = (response_t *)pkt;
					rsp->ring_index = cur_ring_index;

					ql_dbg(ql_dbg_init, vha, 0x5091,
					    "Defer processing ELS opcode %#x...\n",
					    purex_entry->els_frame_payload[3]);