// SPDX-License-Identifier: GPL-2.0-only
/*
 *  QLogic FCoE Offload Driver
 *  Copyright (c) 2016-2018 Cavium Inc.
 */
#include <linux/spinlock.h>
#include <linux/vmalloc.h>
#include "qedf.h"
#include <scsi/scsi_tcq.h>

void qedf_cmd_timer_set(struct qedf_ctx *qedf, struct qedf_ioreq *io_req,
	unsigned int timer_msec)
{
	queue_delayed_work(qedf->timer_work_queue, &io_req->timeout_work,
	    msecs_to_jiffies(timer_msec));
}

static void qedf_cmd_timeout(struct work_struct *work)
{

	struct qedf_ioreq *io_req =
	    container_of(work, struct qedf_ioreq, timeout_work.work);
	struct qedf_ctx *qedf;
	struct qedf_rport *fcport;
	u8 op = 0;

	if (io_req == NULL) {
		QEDF_INFO(NULL, QEDF_LOG_IO, "io_req is NULL.\n");
		return;
	}

	fcport = io_req->fcport;
	if (io_req->fcport == NULL) {
		QEDF_INFO(NULL, QEDF_LOG_IO,  "fcport is NULL.\n");
		return;
	}

	qedf = fcport->qedf;

	switch (io_req->cmd_type) {
	case QEDF_ABTS:
		if (qedf == NULL) {
			QEDF_INFO(NULL, QEDF_LOG_IO,
				  "qedf is NULL for ABTS xid=0x%x.\n",
				  io_req->xid);
			return;
		}

		QEDF_ERR((&qedf->dbg_ctx), "ABTS timeout, xid=0x%x.\n",
		    io_req->xid);
		/* Cleanup timed out ABTS */
		qedf_initiate_cleanup(io_req, true);
		complete(&io_req->abts_done);

		/*
		 * Need to call kref_put for reference taken when initiate_abts
		 * was called since abts_compl won't be called now that we've
		 * cleaned up the task.
		 */
		kref_put(&io_req->refcount, qedf_release_cmd);

		/* Clear in abort bit now that we're done with the command */
		clear_bit(QEDF_CMD_IN_ABORT, &io_req->flags);

		/*
		 * Now that the original I/O and the ABTS are complete see
		 * if we need to reconnect to the target.
		 */
		qedf_restart_rport(fcport);
		break;
	case QEDF_ELS:
		if (!qedf) {
			QEDF_INFO(NULL, QEDF_LOG_IO,
				  "qedf is NULL for ELS xid=0x%x.\n",
				  io_req->xid);
			return;
		}
		/* ELS request no longer outstanding since it timed out */
		clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags);

		kref_get(&io_req->refcount);
		/*
		 * Don't attempt to clean an ELS timeout as any subseqeunt
		 * ABTS or cleanup requests just hang.  For now just free
		 * the resources of the original I/O and the RRQ
		 */
		QEDF_ERR(&(qedf->dbg_ctx), "ELS timeout, xid=0x%x.\n",
			  io_req->xid);
		io_req->event = QEDF_IOREQ_EV_ELS_TMO;
		/* Call callback function to complete command */
		if (io_req->cb_func && io_req->cb_arg) {
			op = io_req->cb_arg->op;
			io_req->cb_func(io_req->cb_arg);
			io_req->cb_arg = NULL;
		}
		qedf_initiate_cleanup(io_req, true);
		kref_put(&io_req->refcount, qedf_release_cmd);
		break;
	case QEDF_SEQ_CLEANUP:
		QEDF_ERR(&(qedf->dbg_ctx), "Sequence cleanup timeout, "
		    "xid=0x%x.\n", io_req->xid);
		qedf_initiate_cleanup(io_req, true);
		io_req->event = QEDF_IOREQ_EV_ELS_TMO;
		qedf_process_seq_cleanup_compl(qedf, NULL, io_req);
		break;
	default:
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
			  "Hit default case, xid=0x%x.\n", io_req->xid);
		break;
	}
}

void qedf_cmd_mgr_free(struct qedf_cmd_mgr *cmgr)
{
	struct io_bdt *bdt_info;
	struct qedf_ctx *qedf = cmgr->qedf;
	size_t bd_tbl_sz;
	u16 min_xid = 0;
	u16 max_xid = (FCOE_PARAMS_NUM_TASKS - 1);
	int num_ios;
	int i;
	struct qedf_ioreq *io_req;

	num_ios = max_xid - min_xid + 1;

	/* Free fcoe_bdt_ctx structures */
	if (!cmgr->io_bdt_pool) {
		QEDF_ERR(&qedf->dbg_ctx, "io_bdt_pool is NULL.\n");
		goto free_cmd_pool;
	}

	bd_tbl_sz = QEDF_MAX_BDS_PER_CMD * sizeof(struct scsi_sge);
	for (i = 0; i < num_ios; i++) {
		bdt_info = cmgr->io_bdt_pool[i];
		if (bdt_info->bd_tbl) {
			dma_free_coherent(&qedf->pdev->dev, bd_tbl_sz,
			    bdt_info->bd_tbl, bdt_info->bd_tbl_dma);
			bdt_info->bd_tbl = NULL;
		}
	}

	/* Destroy io_bdt pool */
	for (i = 0; i < num_ios; i++) {
		kfree(cmgr->io_bdt_pool[i]);
		cmgr->io_bdt_pool[i] = NULL;
	}

	kfree(cmgr->io_bdt_pool);
	cmgr->io_bdt_pool = NULL;

free_cmd_pool:

	for (i = 0; i < num_ios; i++) {
		io_req = &cmgr->cmds[i];
		kfree(io_req->sgl_task_params);
		kfree(io_req->task_params);
		/* Make sure we free per command sense buffer */
		if (io_req->sense_buffer)
			dma_free_coherent(&qedf->pdev->dev,
			    QEDF_SCSI_SENSE_BUFFERSIZE, io_req->sense_buffer,
			    io_req->sense_buffer_dma);
		cancel_delayed_work_sync(&io_req->rrq_work);
	}

	/* Free command manager itself */
	vfree(cmgr);
}

static void qedf_handle_rrq(struct work_struct *work)
{
	struct qedf_ioreq *io_req =
	    container_of(work, struct qedf_ioreq, rrq_work.work);

	atomic_set(&io_req->state, QEDFC_CMD_ST_RRQ_ACTIVE);
	qedf_send_rrq(io_req);

}

struct qedf_cmd_mgr *qedf_cmd_mgr_alloc(struct qedf_ctx *qedf)
{
	struct qedf_cmd_mgr *cmgr;
	struct io_bdt *bdt_info;
	struct qedf_ioreq *io_req;
	u16 xid;
	int i;
	int num_ios;
	u16 min_xid = 0;
	u16 max_xid = (FCOE_PARAMS_NUM_TASKS - 1);

	/* Make sure num_queues is already set before calling this function */
	if (!qedf->num_queues) {
		QEDF_ERR(&(qedf->dbg_ctx), "num_queues is not set.\n");
		return NULL;
	}

	if (max_xid <= min_xid || max_xid == FC_XID_UNKNOWN) {
		QEDF_WARN(&(qedf->dbg_ctx), "Invalid min_xid 0x%x and "
			   "max_xid 0x%x.\n", min_xid, max_xid);
		return NULL;
	}

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "min xid 0x%x, max xid "
		   "0x%x.\n", min_xid, max_xid);

	num_ios = max_xid - min_xid + 1;

	cmgr = vzalloc(sizeof(struct qedf_cmd_mgr));
	if (!cmgr) {
		QEDF_WARN(&(qedf->dbg_ctx), "Failed to alloc cmd mgr.\n");
		return NULL;
	}

	cmgr->qedf = qedf;
	spin_lock_init(&cmgr->lock);

	/*
	 * Initialize I/O request fields.
	 */
	xid = 0;

	for (i = 0; i < num_ios; i++) {
		io_req = &cmgr->cmds[i];
		INIT_DELAYED_WORK(&io_req->timeout_work, qedf_cmd_timeout);

		io_req->xid = xid++;

		INIT_DELAYED_WORK(&io_req->rrq_work, qedf_handle_rrq);

		/* Allocate DMA memory to hold sense buffer */
		io_req->sense_buffer = dma_alloc_coherent(&qedf->pdev->dev,
		    QEDF_SCSI_SENSE_BUFFERSIZE, &io_req->sense_buffer_dma,
		    GFP_KERNEL);
		if (!io_req->sense_buffer) {
			QEDF_ERR(&qedf->dbg_ctx,
				 "Failed to alloc sense buffer.\n");
			goto mem_err;
		}

		/* Allocate task parameters to pass to f/w init funcions */
		io_req->task_params = kzalloc(sizeof(*io_req->task_params),
					      GFP_KERNEL);
		if (!io_req->task_params) {
			QEDF_ERR(&(qedf->dbg_ctx),
				 "Failed to allocate task_params for xid=0x%x\n",
				 i);
			goto mem_err;
		}

		/*
		 * Allocate scatter/gather list info to pass to f/w init
		 * functions.
		 */
		io_req->sgl_task_params = kzalloc(
		    sizeof(struct scsi_sgl_task_params), GFP_KERNEL);
		if (!io_req->sgl_task_params) {
			QEDF_ERR(&(qedf->dbg_ctx),
				 "Failed to allocate sgl_task_params for xid=0x%x\n",
				 i);
			goto mem_err;
		}
	}

	/* Allocate pool of io_bdts - one for each qedf_ioreq */
	cmgr->io_bdt_pool = kmalloc_array(num_ios, sizeof(struct io_bdt *),
	    GFP_KERNEL);

	if (!cmgr->io_bdt_pool) {
		QEDF_WARN(&(qedf->dbg_ctx), "Failed to alloc io_bdt_pool.\n");
		goto mem_err;
	}

	for (i = 0; i < num_ios; i++) {
		cmgr->io_bdt_pool[i] = kmalloc(sizeof(struct io_bdt),
		    GFP_KERNEL);
		if (!cmgr->io_bdt_pool[i]) {
			QEDF_WARN(&(qedf->dbg_ctx),
				  "Failed to alloc io_bdt_pool[%d].\n", i);
			goto mem_err;
		}
	}

	for (i = 0; i < num_ios; i++) {
		bdt_info = cmgr->io_bdt_pool[i];
		bdt_info->bd_tbl = dma_alloc_coherent(&qedf->pdev->dev,
		    QEDF_MAX_BDS_PER_CMD * sizeof(struct scsi_sge),
		    &bdt_info->bd_tbl_dma, GFP_KERNEL);
		if (!bdt_info->bd_tbl) {
			QEDF_WARN(&(qedf->dbg_ctx),
				  "Failed to alloc bdt_tbl[%d].\n", i);
			goto mem_err;
		}
	}
	atomic_set(&cmgr->free_list_cnt, num_ios);
	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO,
	    "cmgr->free_list_cnt=%d.\n",
	    atomic_read(&cmgr->free_list_cnt));

	return cmgr;

mem_err:
	qedf_cmd_mgr_free(cmgr);
	return NULL;
}

struct qedf_ioreq *qedf_alloc_cmd(struct qedf_rport *fcport, u8 cmd_type)
{
	struct qedf_ctx *qedf = fcport->qedf;
	struct qedf_cmd_mgr *cmd_mgr = qedf->cmd_mgr;
	struct qedf_ioreq *io_req = NULL;
	struct io_bdt *bd_tbl;
	u16 xid;
	uint32_t free_sqes;
	int i;
	unsigned long flags;

	free_sqes = atomic_read(&fcport->free_sqes);

	if (!free_sqes) {
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO,
		    "Returning NULL, free_sqes=%d.\n ",
		    free_sqes);
		goto out_failed;
	}

	/* Limit the number of outstanding R/W tasks */
	if ((atomic_read(&fcport->num_active_ios) >=
	    NUM_RW_TASKS_PER_CONNECTION)) {
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO,
		    "Returning NULL, num_active_ios=%d.\n",
		    atomic_read(&fcport->num_active_ios));
		goto out_failed;
	}

	/* Limit global TIDs certain tasks */
	if (atomic_read(&cmd_mgr->free_list_cnt) <= GBL_RSVD_TASKS) {
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO,
		    "Returning NULL, free_list_cnt=%d.\n",
		    atomic_read(&cmd_mgr->free_list_cnt));
		goto out_failed;
	}

	spin_lock_irqsave(&cmd_mgr->lock, flags);
	for (i = 0; i < FCOE_PARAMS_NUM_TASKS; i++) {
		io_req = &cmd_mgr->cmds[cmd_mgr->idx];
		cmd_mgr->idx++;
		if (cmd_mgr->idx == FCOE_PARAMS_NUM_TASKS)
			cmd_mgr->idx = 0;

		/* Check to make sure command was previously freed */
		if (!io_req->alloc)
			break;
	}

	if (i == FCOE_PARAMS_NUM_TASKS) {
		spin_unlock_irqrestore(&cmd_mgr->lock, flags);
		goto out_failed;
	}

	if (test_bit(QEDF_CMD_DIRTY, &io_req->flags))
		QEDF_ERR(&qedf->dbg_ctx,
			 "io_req found to be dirty ox_id = 0x%x.\n",
			 io_req->xid);

	/* Clear any flags now that we've reallocated the xid */
	io_req->flags = 0;
	io_req->alloc = 1;
	spin_unlock_irqrestore(&cmd_mgr->lock, flags);

	atomic_inc(&fcport->num_active_ios);
	atomic_dec(&fcport->free_sqes);
	xid = io_req->xid;
	atomic_dec(&cmd_mgr->free_list_cnt);

	io_req->cmd_mgr = cmd_mgr;
	io_req->fcport = fcport;

	/* Clear any stale sc_cmd back pointer */
	io_req->sc_cmd = NULL;
	io_req->lun = -1;

	/* Hold the io_req against deletion */
	kref_init(&io_req->refcount);	/* ID: 001 */
	atomic_set(&io_req->state, QEDFC_CMD_ST_IO_ACTIVE);

	/* Bind io_bdt for this io_req */
	/* Have a static link between io_req and io_bdt_pool */
	bd_tbl = io_req->bd_tbl = cmd_mgr->io_bdt_pool[xid];
	if (bd_tbl == NULL) {
		QEDF_ERR(&(qedf->dbg_ctx), "bd_tbl is NULL, xid=%x.\n", xid);
		kref_put(&io_req->refcount, qedf_release_cmd);
		goto out_failed;
	}
	bd_tbl->io_req = io_req;
	io_req->cmd_type = cmd_type;
	io_req->tm_flags = 0;

	/* Reset sequence offset data */
	io_req->rx_buf_off = 0;
	io_req->tx_buf_off = 0;
	io_req->rx_id = 0xffff; /* No OX_ID */

	return io_req;

out_failed:
	/* Record failure for stats and return NULL to caller */
	qedf->alloc_failures++;
	return NULL;
}

static void qedf_free_mp_resc(struct qedf_ioreq *io_req)
{
	struct qedf_mp_req *mp_req = &(io_req->mp_req);
	struct qedf_ctx *qedf = io_req->fcport->qedf;
	uint64_t sz = sizeof(struct scsi_sge);

	/* clear tm flags */
	if (mp_req->mp_req_bd) {
		dma_free_coherent(&qedf->pdev->dev, sz,
		    mp_req->mp_req_bd, mp_req->mp_req_bd_dma);
		mp_req->mp_req_bd = NULL;
	}
	if (mp_req->mp_resp_bd) {
		dma_free_coherent(&qedf->pdev->dev, sz,
		    mp_req->mp_resp_bd, mp_req->mp_resp_bd_dma);
		mp_req->mp_resp_bd = NULL;
	}
	if (mp_req->req_buf) {
		dma_free_coherent(&qedf->pdev->dev, QEDF_PAGE_SIZE,
		    mp_req->req_buf, mp_req->req_buf_dma);
		mp_req->req_buf = NULL;
	}
	if (mp_req->resp_buf) {
		dma_free_coherent(&qedf->pdev->dev, QEDF_PAGE_SIZE,
		    mp_req->resp_buf, mp_req->resp_buf_dma);
		mp_req->resp_buf = NULL;
	}
}

void qedf_release_cmd(struct kref *ref)
{
	struct qedf_ioreq *io_req =
	    container_of(ref, struct qedf_ioreq, refcount);
	struct qedf_cmd_mgr *cmd_mgr = io_req->cmd_mgr;
	struct qedf_rport *fcport = io_req->fcport;
	unsigned long flags;

	if (io_req->cmd_type == QEDF_SCSI_CMD) {
		QEDF_WARN(&fcport->qedf->dbg_ctx,
			  "Cmd released called without scsi_done called, io_req %p xid=0x%x.\n",
			  io_req, io_req->xid);
		WARN_ON(io_req->sc_cmd);
	}

	if (io_req->cmd_type == QEDF_ELS ||
	    io_req->cmd_type == QEDF_TASK_MGMT_CMD)
		qedf_free_mp_resc(io_req);

	atomic_inc(&cmd_mgr->free_list_cnt);
	atomic_dec(&fcport->num_active_ios);
	atomic_set(&io_req->state, QEDF_CMD_ST_INACTIVE);
	if (atomic_read(&fcport->num_active_ios) < 0) {
		QEDF_WARN(&(fcport->qedf->dbg_ctx), "active_ios < 0.\n");
		WARN_ON(1);
	}

	/* Increment task retry identifier now that the request is released */
	io_req->task_retry_identifier++;
	io_req->fcport = NULL;

	clear_bit(QEDF_CMD_DIRTY, &io_req->flags);
	io_req->cpu = 0;
	spin_lock_irqsave(&cmd_mgr->lock, flags);
	io_req->fcport = NULL;
	io_req->alloc = 0;
	spin_unlock_irqrestore(&cmd_mgr->lock, flags);
}

static int qedf_map_sg(struct qedf_ioreq *io_req)
{
	struct scsi_cmnd *sc = io_req->sc_cmd;
	struct Scsi_Host *host = sc->device->host;
	struct fc_lport *lport = shost_priv(host);
	struct qedf_ctx *qedf = lport_priv(lport);
	struct scsi_sge *bd = io_req->bd_tbl->bd_tbl;
	struct scatterlist *sg;
	int byte_count = 0;
	int sg_count = 0;
	int bd_count = 0;
	u32 sg_len;
	u64 addr, end_addr;
	int i = 0;

	sg_count = dma_map_sg(&qedf->pdev->dev, scsi_sglist(sc),
	    scsi_sg_count(sc), sc->sc_data_direction);
	sg = scsi_sglist(sc);

	io_req->sge_type = QEDF_IOREQ_UNKNOWN_SGE;

	if (sg_count <= 8 || io_req->io_req_flags == QEDF_READ)
		io_req->sge_type = QEDF_IOREQ_FAST_SGE;

	scsi_for_each_sg(sc, sg, sg_count, i) {
		sg_len = (u32)sg_dma_len(sg);
		addr = (u64)sg_dma_address(sg);
		end_addr = (u64)(addr + sg_len);

		/*
		 * Intermediate s/g element so check if start and end address
		 * is page aligned.  Only required for writes and only if the
		 * number of scatter/gather elements is 8 or more.
		 */
		if (io_req->sge_type == QEDF_IOREQ_UNKNOWN_SGE && (i) &&
		    (i != (sg_count - 1)) && sg_len < QEDF_PAGE_SIZE)
			io_req->sge_type = QEDF_IOREQ_SLOW_SGE;

		bd[bd_count].sge_addr.lo = cpu_to_le32(U64_LO(addr));
		bd[bd_count].sge_addr.hi  = cpu_to_le32(U64_HI(addr));
		bd[bd_count].sge_len = cpu_to_le32(sg_len);

		bd_count++;
		byte_count += sg_len;
	}

	/* To catch a case where FAST and SLOW nothing is set, set FAST */
	if (io_req->sge_type == QEDF_IOREQ_UNKNOWN_SGE)
		io_req->sge_type = QEDF_IOREQ_FAST_SGE;

	if (byte_count != scsi_bufflen(sc))
		QEDF_ERR(&(qedf->dbg_ctx), "byte_count = %d != "
			  "scsi_bufflen = %d, task_id = 0x%x.\n", byte_count,
			   scsi_bufflen(sc), io_req->xid);

	return bd_count;
}

static int qedf_build_bd_list_from_sg(struct qedf_ioreq *io_req)
{
	struct scsi_cmnd *sc = io_req->sc_cmd;
	struct scsi_sge *bd = io_req->bd_tbl->bd_tbl;
	int bd_count;

	if (scsi_sg_count(sc)) {
		bd_count = qedf_map_sg(io_req);
		if (bd_count == 0)
			return -ENOMEM;
	} else {
		bd_count = 0;
		bd[0].sge_addr.lo = bd[0].sge_addr.hi = 0;
		bd[0].sge_len = 0;
	}
	io_req->bd_tbl->bd_valid = bd_count;

	return 0;
}

static void qedf_build_fcp_cmnd(struct qedf_ioreq *io_req,
				  struct fcp_cmnd *fcp_cmnd)
{
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;

	/* fcp_cmnd is 32 bytes */
	memset(fcp_cmnd, 0, FCP_CMND_LEN);

	/* 8 bytes: SCSI LUN info */
	int_to_scsilun(sc_cmd->device->lun,
			(struct scsi_lun *)&fcp_cmnd->fc_lun);

	/* 4 bytes: flag info */
	fcp_cmnd->fc_pri_ta = 0;
	fcp_cmnd->fc_tm_flags = io_req->tm_flags;
	fcp_cmnd->fc_flags = io_req->io_req_flags;
	fcp_cmnd->fc_cmdref = 0;

	/* Populate data direction */
	if (io_req->cmd_type == QEDF_TASK_MGMT_CMD) {
		fcp_cmnd->fc_flags |= FCP_CFL_RDDATA;
	} else {
		if (sc_cmd->sc_data_direction == DMA_TO_DEVICE)
			fcp_cmnd->fc_flags |= FCP_CFL_WRDATA;
		else if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE)
			fcp_cmnd->fc_flags |= FCP_CFL_RDDATA;
	}

	fcp_cmnd->fc_pri_ta = FCP_PTA_SIMPLE;

	/* 16 bytes: CDB information */
	if (io_req->cmd_type != QEDF_TASK_MGMT_CMD)
		memcpy(fcp_cmnd->fc_cdb, sc_cmd->cmnd, sc_cmd->cmd_len);

	/* 4 bytes: FCP data length */
	fcp_cmnd->fc_dl = htonl(io_req->data_xfer_len);
}

static void  qedf_init_task(struct qedf_rport *fcport, struct fc_lport *lport,
	struct qedf_ioreq *io_req, struct e4_fcoe_task_context *task_ctx,
	struct fcoe_wqe *sqe)
{
	enum fcoe_task_type task_type;
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
	struct io_bdt *bd_tbl = io_req->bd_tbl;
	u8 fcp_cmnd[32];
	u32 tmp_fcp_cmnd[8];
	int bd_count = 0;
	struct qedf_ctx *qedf = fcport->qedf;
	uint16_t cq_idx = smp_processor_id() % qedf->num_queues;
	struct regpair sense_data_buffer_phys_addr;
	u32 tx_io_size = 0;
	u32 rx_io_size = 0;
	int i, cnt;

	/* Note init_initiator_rw_fcoe_task memsets the task context */
	io_req->task = task_ctx;
	memset(task_ctx, 0, sizeof(struct e4_fcoe_task_context));
	memset(io_req->task_params, 0, sizeof(struct fcoe_task_params));
	memset(io_req->sgl_task_params, 0, sizeof(struct scsi_sgl_task_params));

	/* Set task type bassed on DMA directio of command */
	if (io_req->cmd_type == QEDF_TASK_MGMT_CMD) {
		task_type = FCOE_TASK_TYPE_READ_INITIATOR;
	} else {
		if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) {
			task_type = FCOE_TASK_TYPE_WRITE_INITIATOR;
			tx_io_size = io_req->data_xfer_len;
		} else {
			task_type = FCOE_TASK_TYPE_READ_INITIATOR;
			rx_io_size = io_req->data_xfer_len;
		}
	}

	/* Setup the fields for fcoe_task_params */
	io_req->task_params->context = task_ctx;
	io_req->task_params->sqe = sqe;
	io_req->task_params->task_type = task_type;
	io_req->task_params->tx_io_size = tx_io_size;
	io_req->task_params->rx_io_size = rx_io_size;
	io_req->task_params->conn_cid = fcport->fw_cid;
	io_req->task_params->itid = io_req->xid;
	io_req->task_params->cq_rss_number = cq_idx;
	io_req->task_params->is_tape_device = fcport->dev_type;

	/* Fill in information for scatter/gather list */
	if (io_req->cmd_type != QEDF_TASK_MGMT_CMD) {
		bd_count = bd_tbl->bd_valid;
		io_req->sgl_task_params->sgl = bd_tbl->bd_tbl;
		io_req->sgl_task_params->sgl_phys_addr.lo =
			U64_LO(bd_tbl->bd_tbl_dma);
		io_req->sgl_task_params->sgl_phys_addr.hi =
			U64_HI(bd_tbl->bd_tbl_dma);
		io_req->sgl_task_params->num_sges = bd_count;
		io_req->sgl_task_params->total_buffer_size =
		    scsi_bufflen(io_req->sc_cmd);
		if (io_req->sge_type == QEDF_IOREQ_SLOW_SGE)
			io_req->sgl_task_params->small_mid_sge = 1;
		else
			io_req->sgl_task_params->small_mid_sge = 0;
	}

	/* Fill in physical address of sense buffer */
	sense_data_buffer_phys_addr.lo = U64_LO(io_req->sense_buffer_dma);
	sense_data_buffer_phys_addr.hi = U64_HI(io_req->sense_buffer_dma);

	/* fill FCP_CMND IU */
	qedf_build_fcp_cmnd(io_req, (struct fcp_cmnd *)tmp_fcp_cmnd);

	/* Swap fcp_cmnd since FC is big endian */
	cnt = sizeof(struct fcp_cmnd) / sizeof(u32);
	for (i = 0; i < cnt; i++) {
		tmp_fcp_cmnd[i] = cpu_to_be32(tmp_fcp_cmnd[i]);
	}
	memcpy(fcp_cmnd, tmp_fcp_cmnd, sizeof(struct fcp_cmnd));

	init_initiator_rw_fcoe_task(io_req->task_params,
				    io_req->sgl_task_params,
				    sense_data_buffer_phys_addr,
				    io_req->task_retry_identifier, fcp_cmnd);

	/* Increment SGL type counters */
	if (io_req->sge_type == QEDF_IOREQ_SLOW_SGE)
		qedf->slow_sge_ios++;
	else
		qedf->fast_sge_ios++;
}

void qedf_init_mp_task(struct qedf_ioreq *io_req,
	struct e4_fcoe_task_context *task_ctx, struct fcoe_wqe *sqe)
{
	struct qedf_mp_req *mp_req = &(io_req->mp_req);
	struct qedf_rport *fcport = io_req->fcport;
	struct qedf_ctx *qedf = io_req->fcport->qedf;
	struct fc_frame_header *fc_hdr;
	struct fcoe_tx_mid_path_params task_fc_hdr;
	struct scsi_sgl_task_params tx_sgl_task_params;
	struct scsi_sgl_task_params rx_sgl_task_params;

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC,
		  "Initializing MP task for cmd_type=%d\n",
		  io_req->cmd_type);

	qedf->control_requests++;

	memset(&tx_sgl_task_params, 0, sizeof(struct scsi_sgl_task_params));
	memset(&rx_sgl_task_params, 0, sizeof(struct scsi_sgl_task_params));
	memset(task_ctx, 0, sizeof(struct e4_fcoe_task_context));
	memset(&task_fc_hdr, 0, sizeof(struct fcoe_tx_mid_path_params));

	/* Setup the task from io_req for easy reference */
	io_req->task = task_ctx;

	/* Setup the fields for fcoe_task_params */
	io_req->task_params->context = task_ctx;
	io_req->task_params->sqe = sqe;
	io_req->task_params->task_type = FCOE_TASK_TYPE_MIDPATH;
	io_req->task_params->tx_io_size = io_req->data_xfer_len;
	/* rx_io_size tells the f/w how large a response buffer we have */
	io_req->task_params->rx_io_size = PAGE_SIZE;
	io_req->task_params->conn_cid = fcport->fw_cid;
	io_req->task_params->itid = io_req->xid;
	/* Return middle path commands on CQ 0 */
	io_req->task_params->cq_rss_number = 0;
	io_req->task_params->is_tape_device = fcport->dev_type;

	fc_hdr = &(mp_req->req_fc_hdr);
	/* Set OX_ID and RX_ID based on driver task id */
	fc_hdr->fh_ox_id = io_req->xid;
	fc_hdr->fh_rx_id = htons(0xffff);

	/* Set up FC header information */
	task_fc_hdr.parameter = fc_hdr->fh_parm_offset;
	task_fc_hdr.r_ctl = fc_hdr->fh_r_ctl;
	task_fc_hdr.type = fc_hdr->fh_type;
	task_fc_hdr.cs_ctl = fc_hdr->fh_cs_ctl;
	task_fc_hdr.df_ctl = fc_hdr->fh_df_ctl;
	task_fc_hdr.rx_id = fc_hdr->fh_rx_id;
	task_fc_hdr.ox_id = fc_hdr->fh_ox_id;

	/* Set up s/g list parameters for request buffer */
	tx_sgl_task_params.sgl = mp_req->mp_req_bd;
	tx_sgl_task_params.sgl_phys_addr.lo = U64_LO(mp_req->mp_req_bd_dma);
	tx_sgl_task_params.sgl_phys_addr.hi = U64_HI(mp_req->mp_req_bd_dma);
	tx_sgl_task_params.num_sges = 1;
	/* Set PAGE_SIZE for now since sg element is that size ??? */
	tx_sgl_task_params.total_buffer_size = io_req->data_xfer_len;
	tx_sgl_task_params.small_mid_sge = 0;

	/* Set up s/g list parameters for request buffer */
	rx_sgl_task_params.sgl = mp_req->mp_resp_bd;
	rx_sgl_task_params.sgl_phys_addr.lo = U64_LO(mp_req->mp_resp_bd_dma);
	rx_sgl_task_params.sgl_phys_addr.hi = U64_HI(mp_req->mp_resp_bd_dma);
	rx_sgl_task_params.num_sges = 1;
	/* Set PAGE_SIZE for now since sg element is that size ??? */
	rx_sgl_task_params.total_buffer_size = PAGE_SIZE;
	rx_sgl_task_params.small_mid_sge = 0;


	/*
	 * Last arg is 0 as previous code did not set that we wanted the
	 * fc header information.
	 */
	init_initiator_midpath_unsolicited_fcoe_task(io_req->task_params,
						     &task_fc_hdr,
						     &tx_sgl_task_params,
						     &rx_sgl_task_params, 0);
}

/* Presumed that fcport->rport_lock is held */
u16 qedf_get_sqe_idx(struct qedf_rport *fcport)
{
	uint16_t total_sqe = (fcport->sq_mem_size)/(sizeof(struct fcoe_wqe));
	u16 rval;

	rval = fcport->sq_prod_idx;

	/* Adjust ring index */
	fcport->sq_prod_idx++;
	fcport->fw_sq_prod_idx++;
	if (fcport->sq_prod_idx == total_sqe)
		fcport->sq_prod_idx = 0;

	return rval;
}

void qedf_ring_doorbell(struct qedf_rport *fcport)
{
	struct fcoe_db_data dbell = { 0 };

	dbell.agg_flags = 0;

	dbell.params |= DB_DEST_XCM << FCOE_DB_DATA_DEST_SHIFT;
	dbell.params |= DB_AGG_CMD_SET << FCOE_DB_DATA_AGG_CMD_SHIFT;
	dbell.params |= DQ_XCM_FCOE_SQ_PROD_CMD <<
	    FCOE_DB_DATA_AGG_VAL_SEL_SHIFT;

	dbell.sq_prod = fcport->fw_sq_prod_idx;
	/* wmb makes sure that the BDs data is updated before updating the
	 * producer, otherwise FW may read old data from the BDs.
	 */
	wmb();
	barrier();
	writel(*(u32 *)&dbell, fcport->p_doorbell);
	/*
	 * Fence required to flush the write combined buffer, since another
	 * CPU may write to the same doorbell address and data may be lost
	 * due to relaxed order nature of write combined bar.
	 */
	wmb();
}

static void qedf_trace_io(struct qedf_rport *fcport, struct qedf_ioreq *io_req,
			  int8_t direction)
{
	struct qedf_ctx *qedf = fcport->qedf;
	struct qedf_io_log *io_log;
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
	unsigned long flags;
	uint8_t op;

	spin_lock_irqsave(&qedf->io_trace_lock, flags);

	io_log = &qedf->io_trace_buf[qedf->io_trace_idx];
	io_log->direction = direction;
	io_log->task_id = io_req->xid;
	io_log->port_id = fcport->rdata->ids.port_id;
	io_log->lun = sc_cmd->device->lun;
	io_log->op = op = sc_cmd->cmnd[0];
	io_log->lba[0] = sc_cmd->cmnd[2];
	io_log->lba[1] = sc_cmd->cmnd[3];
	io_log->lba[2] = sc_cmd->cmnd[4];
	io_log->lba[3] = sc_cmd->cmnd[5];
	io_log->bufflen = scsi_bufflen(sc_cmd);
	io_log->sg_count = scsi_sg_count(sc_cmd);
	io_log->result = sc_cmd->result;
	io_log->jiffies = jiffies;
	io_log->refcount = kref_read(&io_req->refcount);

	if (direction == QEDF_IO_TRACE_REQ) {
		/* For requests we only care abot the submission CPU */
		io_log->req_cpu = io_req->cpu;
		io_log->int_cpu = 0;
		io_log->rsp_cpu = 0;
	} else if (direction == QEDF_IO_TRACE_RSP) {
		io_log->req_cpu = io_req->cpu;
		io_log->int_cpu = io_req->int_cpu;
		io_log->rsp_cpu = smp_processor_id();
	}

	io_log->sge_type = io_req->sge_type;

	qedf->io_trace_idx++;
	if (qedf->io_trace_idx == QEDF_IO_TRACE_SIZE)
		qedf->io_trace_idx = 0;

	spin_unlock_irqrestore(&qedf->io_trace_lock, flags);
}

int qedf_post_io_req(struct qedf_rport *fcport, struct qedf_ioreq *io_req)
{
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
	struct Scsi_Host *host = sc_cmd->device->host;
	struct fc_lport *lport = shost_priv(host);
	struct qedf_ctx *qedf = lport_priv(lport);
	struct e4_fcoe_task_context *task_ctx;
	u16 xid;
	enum fcoe_task_type req_type = 0;
	struct fcoe_wqe *sqe;
	u16 sqe_idx;

	/* Initialize rest of io_req fileds */
	io_req->data_xfer_len = scsi_bufflen(sc_cmd);
	sc_cmd->SCp.ptr = (char *)io_req;
	io_req->sge_type = QEDF_IOREQ_FAST_SGE; /* Assume fast SGL by default */

	/* Record which cpu this request is associated with */
	io_req->cpu = smp_processor_id();

	if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {
		req_type = FCOE_TASK_TYPE_READ_INITIATOR;
		io_req->io_req_flags = QEDF_READ;
		qedf->input_requests++;
	} else if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) {
		req_type = FCOE_TASK_TYPE_WRITE_INITIATOR;
		io_req->io_req_flags = QEDF_WRITE;
		qedf->output_requests++;
	} else {
		io_req->io_req_flags = 0;
		qedf->control_requests++;
	}

	xid = io_req->xid;

	/* Build buffer descriptor list for firmware from sg list */
	if (qedf_build_bd_list_from_sg(io_req)) {
		QEDF_ERR(&(qedf->dbg_ctx), "BD list creation failed.\n");
		/* Release cmd will release io_req, but sc_cmd is assigned */
		io_req->sc_cmd = NULL;
		kref_put(&io_req->refcount, qedf_release_cmd);
		return -EAGAIN;
	}

	if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags) ||
	    test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) {
		QEDF_ERR(&(qedf->dbg_ctx), "Session not offloaded yet.\n");
		/* Release cmd will release io_req, but sc_cmd is assigned */
		io_req->sc_cmd = NULL;
		kref_put(&io_req->refcount, qedf_release_cmd);
		return -EINVAL;
	}

	/* Record LUN number for later use if we neeed them */
	io_req->lun = (int)sc_cmd->device->lun;

	/* Obtain free SQE */
	sqe_idx = qedf_get_sqe_idx(fcport);
	sqe = &fcport->sq[sqe_idx];
	memset(sqe, 0, sizeof(struct fcoe_wqe));

	/* Get the task context */
	task_ctx = qedf_get_task_mem(&qedf->tasks, xid);
	if (!task_ctx) {
		QEDF_WARN(&(qedf->dbg_ctx), "task_ctx is NULL, xid=%d.\n",
			   xid);
		/* Release cmd will release io_req, but sc_cmd is assigned */
		io_req->sc_cmd = NULL;
		kref_put(&io_req->refcount, qedf_release_cmd);
		return -EINVAL;
	}

	qedf_init_task(fcport, lport, io_req, task_ctx, sqe);

	/* Ring doorbell */
	qedf_ring_doorbell(fcport);

	/* Set that command is with the firmware now */
	set_bit(QEDF_CMD_OUTSTANDING, &io_req->flags);

	if (qedf_io_tracing && io_req->sc_cmd)
		qedf_trace_io(fcport, io_req, QEDF_IO_TRACE_REQ);

	return false;
}

int
qedf_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *sc_cmd)
{
	struct fc_lport *lport = shost_priv(host);
	struct qedf_ctx *qedf = lport_priv(lport);
	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
	struct fc_rport_libfc_priv *rp = rport->dd_data;
	struct qedf_rport *fcport;
	struct qedf_ioreq *io_req;
	int rc = 0;
	int rval;
	unsigned long flags = 0;
	int num_sgs = 0;

	num_sgs = scsi_sg_count(sc_cmd);
	if (scsi_sg_count(sc_cmd) > QEDF_MAX_BDS_PER_CMD) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "Number of SG elements %d exceeds what hardware limitation of %d.\n",
			 num_sgs, QEDF_MAX_BDS_PER_CMD);
		sc_cmd->result = DID_ERROR;
		sc_cmd->scsi_done(sc_cmd);
		return 0;
	}

	if (test_bit(QEDF_UNLOADING, &qedf->flags) ||
	    test_bit(QEDF_DBG_STOP_IO, &qedf->flags)) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
			  "Returning DNC as unloading or stop io, flags 0x%lx.\n",
			  qedf->flags);
		sc_cmd->result = DID_NO_CONNECT << 16;
		sc_cmd->scsi_done(sc_cmd);
		return 0;
	}

	if (!qedf->pdev->msix_enabled) {
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO,
		    "Completing sc_cmd=%p DID_NO_CONNECT as MSI-X is not enabled.\n",
		    sc_cmd);
		sc_cmd->result = DID_NO_CONNECT << 16;
		sc_cmd->scsi_done(sc_cmd);
		return 0;
	}

	rval = fc_remote_port_chkready(rport);
	if (rval) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
			  "fc_remote_port_chkready failed=0x%x for port_id=0x%06x.\n",
			  rval, rport->port_id);
		sc_cmd->result = rval;
		sc_cmd->scsi_done(sc_cmd);
		return 0;
	}

	/* Retry command if we are doing a qed drain operation */
	if (test_bit(QEDF_DRAIN_ACTIVE, &qedf->flags)) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, "Drain active.\n");
		rc = SCSI_MLQUEUE_HOST_BUSY;
		goto exit_qcmd;
	}

	if (lport->state != LPORT_ST_READY ||
	    atomic_read(&qedf->link_state) != QEDF_LINK_UP) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, "Link down.\n");
		rc = SCSI_MLQUEUE_HOST_BUSY;
		goto exit_qcmd;
	}

	/* rport and tgt are allocated together, so tgt should be non-NULL */
	fcport = (struct qedf_rport *)&rp[1];

	if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags) ||
	    test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) {
		/*
		 * Session is not offloaded yet. Let SCSI-ml retry
		 * the command.
		 */
		rc = SCSI_MLQUEUE_TARGET_BUSY;
		goto exit_qcmd;
	}

	atomic_inc(&fcport->ios_to_queue);

	if (fcport->retry_delay_timestamp) {
		if (time_after(jiffies, fcport->retry_delay_timestamp)) {
			fcport->retry_delay_timestamp = 0;
		} else {
			/* If retry_delay timer is active, flow off the ML */
			rc = SCSI_MLQUEUE_TARGET_BUSY;
			atomic_dec(&fcport->ios_to_queue);
			goto exit_qcmd;
		}
	}

	io_req = qedf_alloc_cmd(fcport, QEDF_SCSI_CMD);
	if (!io_req) {
		rc = SCSI_MLQUEUE_HOST_BUSY;
		atomic_dec(&fcport->ios_to_queue);
		goto exit_qcmd;
	}

	io_req->sc_cmd = sc_cmd;

	/* Take fcport->rport_lock for posting to fcport send queue */
	spin_lock_irqsave(&fcport->rport_lock, flags);
	if (qedf_post_io_req(fcport, io_req)) {
		QEDF_WARN(&(qedf->dbg_ctx), "Unable to post io_req\n");
		/* Return SQE to pool */
		atomic_inc(&fcport->free_sqes);
		rc = SCSI_MLQUEUE_HOST_BUSY;
	}
	spin_unlock_irqrestore(&fcport->rport_lock, flags);
	atomic_dec(&fcport->ios_to_queue);

exit_qcmd:
	return rc;
}

static void qedf_parse_fcp_rsp(struct qedf_ioreq *io_req,
				 struct fcoe_cqe_rsp_info *fcp_rsp)
{
	struct scsi_cmnd *sc_cmd = io_req->sc_cmd;
	struct qedf_ctx *qedf = io_req->fcport->qedf;
	u8 rsp_flags = fcp_rsp->rsp_flags.flags;
	int fcp_sns_len = 0;
	int fcp_rsp_len = 0;
	uint8_t *rsp_info, *sense_data;

	io_req->fcp_status = FC_GOOD;
	io_req->fcp_resid = 0;
	if (rsp_flags & (FCOE_FCP_RSP_FLAGS_FCP_RESID_OVER |
	    FCOE_FCP_RSP_FLAGS_FCP_RESID_UNDER))
		io_req->fcp_resid = fcp_rsp->fcp_resid;

	io_req->scsi_comp_flags = rsp_flags;
	CMD_SCSI_STATUS(sc_cmd) = io_req->cdb_status =
	    fcp_rsp->scsi_status_code;

	if (rsp_flags &
	    FCOE_FCP_RSP_FLAGS_FCP_RSP_LEN_VALID)
		fcp_rsp_len = fcp_rsp->fcp_rsp_len;

	if (rsp_flags &
	    FCOE_FCP_RSP_FLAGS_FCP_SNS_LEN_VALID)
		fcp_sns_len = fcp_rsp->fcp_sns_len;

	io_req->fcp_rsp_len = fcp_rsp_len;
	io_req->fcp_sns_len = fcp_sns_len;
	rsp_info = sense_data = io_req->sense_buffer;

	/* fetch fcp_rsp_code */
	if ((fcp_rsp_len == 4) || (fcp_rsp_len == 8)) {
		/* Only for task management function */
		io_req->fcp_rsp_code = rsp_info[3];
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO,
		    "fcp_rsp_code = %d\n", io_req->fcp_rsp_code);
		/* Adjust sense-data location. */
		sense_data += fcp_rsp_len;
	}

	if (fcp_sns_len > SCSI_SENSE_BUFFERSIZE) {
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO,
		    "Truncating sense buffer\n");
		fcp_sns_len = SCSI_SENSE_BUFFERSIZE;
	}

	/* The sense buffer can be NULL for TMF commands */
	if (sc_cmd->sense_buffer) {
		memset(sc_cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
		if (fcp_sns_len)
			memcpy(sc_cmd->sense_buffer, sense_data,
			    fcp_sns_len);
	}
}

static void qedf_unmap_sg_list(struct qedf_ctx *qedf, struct qedf_ioreq *io_req)
{
	struct scsi_cmnd *sc = io_req->sc_cmd;

	if (io_req->bd_tbl->bd_valid && sc && scsi_sg_count(sc)) {
		dma_unmap_sg(&qedf->pdev->dev, scsi_sglist(sc),
		    scsi_sg_count(sc), sc->sc_data_direction);
		io_req->bd_tbl->bd_valid = 0;
	}
}

void qedf_scsi_completion(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
	struct qedf_ioreq *io_req)
{
	u16 xid;
	struct e4_fcoe_task_context *task_ctx;
	struct scsi_cmnd *sc_cmd;
	struct fcoe_cqe_rsp_info *fcp_rsp;
	struct qedf_rport *fcport;
	int refcount;
	u16 scope, qualifier = 0;
	u8 fw_residual_flag = 0;

	if (!io_req)
		return;
	if (!cqe)
		return;

	if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) ||
	    test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) ||
	    test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "io_req xid=0x%x already in cleanup or abort processing or already completed.\n",
			 io_req->xid);
		return;
	}

	xid = io_req->xid;
	task_ctx = qedf_get_task_mem(&qedf->tasks, xid);
	sc_cmd = io_req->sc_cmd;
	fcp_rsp = &cqe->cqe_info.rsp_info;

	if (!sc_cmd) {
		QEDF_WARN(&(qedf->dbg_ctx), "sc_cmd is NULL!\n");
		return;
	}

	if (!sc_cmd->SCp.ptr) {
		QEDF_WARN(&(qedf->dbg_ctx), "SCp.ptr is NULL, returned in "
		    "another context.\n");
		return;
	}

	if (!sc_cmd->device) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "Device for sc_cmd %p is NULL.\n", sc_cmd);
		return;
	}

	if (!sc_cmd->request) {
		QEDF_WARN(&(qedf->dbg_ctx), "sc_cmd->request is NULL, "
		    "sc_cmd=%p.\n", sc_cmd);
		return;
	}

	if (!sc_cmd->request->q) {
		QEDF_WARN(&(qedf->dbg_ctx), "request->q is NULL so request "
		   "is not valid, sc_cmd=%p.\n", sc_cmd);
		return;
	}

	fcport = io_req->fcport;

	/*
	 * When flush is active, let the cmds be completed from the cleanup
	 * context
	 */
	if (test_bit(QEDF_RPORT_IN_TARGET_RESET, &fcport->flags) ||
	    (test_bit(QEDF_RPORT_IN_LUN_RESET, &fcport->flags) &&
	     sc_cmd->device->lun == (u64)fcport->lun_reset_lun)) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
			  "Dropping good completion xid=0x%x as fcport is flushing",
			  io_req->xid);
		return;
	}

	qedf_parse_fcp_rsp(io_req, fcp_rsp);

	qedf_unmap_sg_list(qedf, io_req);

	/* Check for FCP transport error */
	if (io_req->fcp_rsp_len > 3 && io_req->fcp_rsp_code) {
		QEDF_ERR(&(qedf->dbg_ctx),
		    "FCP I/O protocol failure xid=0x%x fcp_rsp_len=%d "
		    "fcp_rsp_code=%d.\n", io_req->xid, io_req->fcp_rsp_len,
		    io_req->fcp_rsp_code);
		sc_cmd->result = DID_BUS_BUSY << 16;
		goto out;
	}

	fw_residual_flag = GET_FIELD(cqe->cqe_info.rsp_info.fw_error_flags,
	    FCOE_CQE_RSP_INFO_FW_UNDERRUN);
	if (fw_residual_flag) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "Firmware detected underrun: xid=0x%x fcp_rsp.flags=0x%02x fcp_resid=%d fw_residual=0x%x lba=%02x%02x%02x%02x.\n",
			 io_req->xid, fcp_rsp->rsp_flags.flags,
			 io_req->fcp_resid,
			 cqe->cqe_info.rsp_info.fw_residual, sc_cmd->cmnd[2],
			 sc_cmd->cmnd[3], sc_cmd->cmnd[4], sc_cmd->cmnd[5]);

		if (io_req->cdb_status == 0)
			sc_cmd->result = (DID_ERROR << 16) | io_req->cdb_status;
		else
			sc_cmd->result = (DID_OK << 16) | io_req->cdb_status;

		/*
		 * Set resid to the whole buffer length so we won't try to resue
		 * any previously data.
		 */
		scsi_set_resid(sc_cmd, scsi_bufflen(sc_cmd));
		goto out;
	}

	switch (io_req->fcp_status) {
	case FC_GOOD:
		if (io_req->cdb_status == 0) {
			/* Good I/O completion */
			sc_cmd->result = DID_OK << 16;
		} else {
			refcount = kref_read(&io_req->refcount);
			QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO,
			    "%d:0:%d:%lld xid=0x%0x op=0x%02x "
			    "lba=%02x%02x%02x%02x cdb_status=%d "
			    "fcp_resid=0x%x refcount=%d.\n",
			    qedf->lport->host->host_no, sc_cmd->device->id,
			    sc_cmd->device->lun, io_req->xid,
			    sc_cmd->cmnd[0], sc_cmd->cmnd[2], sc_cmd->cmnd[3],
			    sc_cmd->cmnd[4], sc_cmd->cmnd[5],
			    io_req->cdb_status, io_req->fcp_resid,
			    refcount);
			sc_cmd->result = (DID_OK << 16) | io_req->cdb_status;

			if (io_req->cdb_status == SAM_STAT_TASK_SET_FULL ||
			    io_req->cdb_status == SAM_STAT_BUSY) {
				/*
				 * Check whether we need to set retry_delay at
				 * all based on retry_delay module parameter
				 * and the status qualifier.
				 */

				/* Upper 2 bits */
				scope = fcp_rsp->retry_delay_timer & 0xC000;
				/* Lower 14 bits */
				qualifier = fcp_rsp->retry_delay_timer & 0x3FFF;

				if (qedf_retry_delay &&
				    scope > 0 && qualifier > 0 &&
				    qualifier <= 0x3FEF) {
					/* Check we don't go over the max */
					if (qualifier > QEDF_RETRY_DELAY_MAX)
						qualifier =
						    QEDF_RETRY_DELAY_MAX;
					fcport->retry_delay_timestamp =
					    jiffies + (qualifier * HZ / 10);
				}
				/* Record stats */
				if (io_req->cdb_status ==
				    SAM_STAT_TASK_SET_FULL)
					qedf->task_set_fulls++;
				else
					qedf->busy++;
			}
		}
		if (io_req->fcp_resid)
			scsi_set_resid(sc_cmd, io_req->fcp_resid);
		break;
	default:
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, "fcp_status=%d.\n",
			   io_req->fcp_status);
		break;
	}

out:
	if (qedf_io_tracing)
		qedf_trace_io(fcport, io_req, QEDF_IO_TRACE_RSP);

	/*
	 * We wait till the end of the function to clear the
	 * outstanding bit in case we need to send an abort
	 */
	clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags);

	io_req->sc_cmd = NULL;
	sc_cmd->SCp.ptr =  NULL;
	sc_cmd->scsi_done(sc_cmd);
	kref_put(&io_req->refcount, qedf_release_cmd);
}

/* Return a SCSI command in some other context besides a normal completion */
void qedf_scsi_done(struct qedf_ctx *qedf, struct qedf_ioreq *io_req,
	int result)
{
	u16 xid;
	struct scsi_cmnd *sc_cmd;
	int refcount;

	if (!io_req) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, "io_req is NULL\n");
		return;
	}

	if (test_and_set_bit(QEDF_CMD_ERR_SCSI_DONE, &io_req->flags)) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
			  "io_req:%p scsi_done handling already done\n",
			  io_req);
		return;
	}

	/*
	 * We will be done with this command after this call so clear the
	 * outstanding bit.
	 */
	clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags);

	xid = io_req->xid;
	sc_cmd = io_req->sc_cmd;

	if (!sc_cmd) {
		QEDF_WARN(&(qedf->dbg_ctx), "sc_cmd is NULL!\n");
		return;
	}

	if (!virt_addr_valid(sc_cmd)) {
		QEDF_ERR(&qedf->dbg_ctx, "sc_cmd=%p is not valid.", sc_cmd);
		goto bad_scsi_ptr;
	}

	if (!sc_cmd->SCp.ptr) {
		QEDF_WARN(&(qedf->dbg_ctx), "SCp.ptr is NULL, returned in "
		    "another context.\n");
		return;
	}

	if (!sc_cmd->device) {
		QEDF_ERR(&qedf->dbg_ctx, "Device for sc_cmd %p is NULL.\n",
			 sc_cmd);
		goto bad_scsi_ptr;
	}

	if (!virt_addr_valid(sc_cmd->device)) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "Device pointer for sc_cmd %p is bad.\n", sc_cmd);
		goto bad_scsi_ptr;
	}

	if (!sc_cmd->sense_buffer) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "sc_cmd->sense_buffer for sc_cmd %p is NULL.\n",
			 sc_cmd);
		goto bad_scsi_ptr;
	}

	if (!virt_addr_valid(sc_cmd->sense_buffer)) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "sc_cmd->sense_buffer for sc_cmd %p is bad.\n",
			 sc_cmd);
		goto bad_scsi_ptr;
	}

	if (!sc_cmd->scsi_done) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "sc_cmd->scsi_done for sc_cmd %p is NULL.\n",
			 sc_cmd);
		goto bad_scsi_ptr;
	}

	qedf_unmap_sg_list(qedf, io_req);

	sc_cmd->result = result << 16;
	refcount = kref_read(&io_req->refcount);
	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, "%d:0:%d:%lld: Completing "
	    "sc_cmd=%p result=0x%08x op=0x%02x lba=0x%02x%02x%02x%02x, "
	    "allowed=%d retries=%d refcount=%d.\n",
	    qedf->lport->host->host_no, sc_cmd->device->id,
	    sc_cmd->device->lun, sc_cmd, sc_cmd->result, sc_cmd->cmnd[0],
	    sc_cmd->cmnd[2], sc_cmd->cmnd[3], sc_cmd->cmnd[4],
	    sc_cmd->cmnd[5], sc_cmd->allowed, sc_cmd->retries,
	    refcount);

	/*
	 * Set resid to the whole buffer length so we won't try to resue any
	 * previously read data
	 */
	scsi_set_resid(sc_cmd, scsi_bufflen(sc_cmd));

	if (qedf_io_tracing)
		qedf_trace_io(io_req->fcport, io_req, QEDF_IO_TRACE_RSP);

	io_req->sc_cmd = NULL;
	sc_cmd->SCp.ptr = NULL;
	sc_cmd->scsi_done(sc_cmd);
	kref_put(&io_req->refcount, qedf_release_cmd);
	return;

bad_scsi_ptr:
	/*
	 * Clear the io_req->sc_cmd backpointer so we don't try to process
	 * this again
	 */
	io_req->sc_cmd = NULL;
	kref_put(&io_req->refcount, qedf_release_cmd);  /* ID: 001 */
}

/*
 * Handle warning type CQE completions. This is mainly used for REC timer
 * popping.
 */
void qedf_process_warning_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
	struct qedf_ioreq *io_req)
{
	int rval, i;
	struct qedf_rport *fcport = io_req->fcport;
	u64 err_warn_bit_map;
	u8 err_warn = 0xff;

	if (!cqe) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
			  "cqe is NULL for io_req %p xid=0x%x\n",
			  io_req, io_req->xid);
		return;
	}

	QEDF_ERR(&(io_req->fcport->qedf->dbg_ctx), "Warning CQE, "
		  "xid=0x%x\n", io_req->xid);
	QEDF_ERR(&(io_req->fcport->qedf->dbg_ctx),
		  "err_warn_bitmap=%08x:%08x\n",
		  le32_to_cpu(cqe->cqe_info.err_info.err_warn_bitmap_hi),
		  le32_to_cpu(cqe->cqe_info.err_info.err_warn_bitmap_lo));
	QEDF_ERR(&(io_req->fcport->qedf->dbg_ctx), "tx_buff_off=%08x, "
		  "rx_buff_off=%08x, rx_id=%04x\n",
		  le32_to_cpu(cqe->cqe_info.err_info.tx_buf_off),
		  le32_to_cpu(cqe->cqe_info.err_info.rx_buf_off),
		  le32_to_cpu(cqe->cqe_info.err_info.rx_id));

	/* Normalize the error bitmap value to an just an unsigned int */
	err_warn_bit_map = (u64)
	    ((u64)cqe->cqe_info.err_info.err_warn_bitmap_hi << 32) |
	    (u64)cqe->cqe_info.err_info.err_warn_bitmap_lo;
	for (i = 0; i < 64; i++) {
		if (err_warn_bit_map & (u64)((u64)1 << i)) {
			err_warn = i;
			break;
		}
	}

	/* Check if REC TOV expired if this is a tape device */
	if (fcport->dev_type == QEDF_RPORT_TYPE_TAPE) {
		if (err_warn ==
		    FCOE_WARNING_CODE_REC_TOV_TIMER_EXPIRATION) {
			QEDF_ERR(&(qedf->dbg_ctx), "REC timer expired.\n");
			if (!test_bit(QEDF_CMD_SRR_SENT, &io_req->flags)) {
				io_req->rx_buf_off =
				    cqe->cqe_info.err_info.rx_buf_off;
				io_req->tx_buf_off =
				    cqe->cqe_info.err_info.tx_buf_off;
				io_req->rx_id = cqe->cqe_info.err_info.rx_id;
				rval = qedf_send_rec(io_req);
				/*
				 * We only want to abort the io_req if we
				 * can't queue the REC command as we want to
				 * keep the exchange open for recovery.
				 */
				if (rval)
					goto send_abort;
			}
			return;
		}
	}

send_abort:
	init_completion(&io_req->abts_done);
	rval = qedf_initiate_abts(io_req, true);
	if (rval)
		QEDF_ERR(&(qedf->dbg_ctx), "Failed to queue ABTS.\n");
}

/* Cleanup a command when we receive an error detection completion */
void qedf_process_error_detect(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
	struct qedf_ioreq *io_req)
{
	int rval;

	if (!cqe) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
			  "cqe is NULL for io_req %p\n", io_req);
		return;
	}

	QEDF_ERR(&(io_req->fcport->qedf->dbg_ctx), "Error detection CQE, "
		  "xid=0x%x\n", io_req->xid);
	QEDF_ERR(&(io_req->fcport->qedf->dbg_ctx),
		  "err_warn_bitmap=%08x:%08x\n",
		  le32_to_cpu(cqe->cqe_info.err_info.err_warn_bitmap_hi),
		  le32_to_cpu(cqe->cqe_info.err_info.err_warn_bitmap_lo));
	QEDF_ERR(&(io_req->fcport->qedf->dbg_ctx), "tx_buff_off=%08x, "
		  "rx_buff_off=%08x, rx_id=%04x\n",
		  le32_to_cpu(cqe->cqe_info.err_info.tx_buf_off),
		  le32_to_cpu(cqe->cqe_info.err_info.rx_buf_off),
		  le32_to_cpu(cqe->cqe_info.err_info.rx_id));

	if (qedf->stop_io_on_error) {
		qedf_stop_all_io(qedf);
		return;
	}

	init_completion(&io_req->abts_done);
	rval = qedf_initiate_abts(io_req, true);
	if (rval)
		QEDF_ERR(&(qedf->dbg_ctx), "Failed to queue ABTS.\n");
}

static void qedf_flush_els_req(struct qedf_ctx *qedf,
	struct qedf_ioreq *els_req)
{
	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO,
	    "Flushing ELS request xid=0x%x refcount=%d.\n", els_req->xid,
	    kref_read(&els_req->refcount));

	/*
	 * Need to distinguish this from a timeout when calling the
	 * els_req->cb_func.
	 */
	els_req->event = QEDF_IOREQ_EV_ELS_FLUSH;

	/* Cancel the timer */
	cancel_delayed_work_sync(&els_req->timeout_work);

	/* Call callback function to complete command */
	if (els_req->cb_func && els_req->cb_arg) {
		els_req->cb_func(els_req->cb_arg);
		els_req->cb_arg = NULL;
	}

	/* Release kref for original initiate_els */
	kref_put(&els_req->refcount, qedf_release_cmd);
}

/* A value of -1 for lun is a wild card that means flush all
 * active SCSI I/Os for the target.
 */
void qedf_flush_active_ios(struct qedf_rport *fcport, int lun)
{
	struct qedf_ioreq *io_req;
	struct qedf_ctx *qedf;
	struct qedf_cmd_mgr *cmd_mgr;
	int i, rc;
	unsigned long flags;
	int flush_cnt = 0;
	int wait_cnt = 100;
	int refcount = 0;

	if (!fcport) {
		QEDF_ERR(NULL, "fcport is NULL\n");
		return;
	}

	/* Check that fcport is still offloaded */
	if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
		QEDF_ERR(NULL, "fcport is no longer offloaded.\n");
		return;
	}

	qedf = fcport->qedf;

	if (!qedf) {
		QEDF_ERR(NULL, "qedf is NULL.\n");
		return;
	}

	/* Only wait for all commands to be queued in the Upload context */
	if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags) &&
	    (lun == -1)) {
		while (atomic_read(&fcport->ios_to_queue)) {
			QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
				  "Waiting for %d I/Os to be queued\n",
				  atomic_read(&fcport->ios_to_queue));
			if (wait_cnt == 0) {
				QEDF_ERR(NULL,
					 "%d IOs request could not be queued\n",
					 atomic_read(&fcport->ios_to_queue));
			}
			msleep(20);
			wait_cnt--;
		}
	}

	cmd_mgr = qedf->cmd_mgr;

	QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
		  "Flush active i/o's num=0x%x fcport=0x%p port_id=0x%06x scsi_id=%d.\n",
		  atomic_read(&fcport->num_active_ios), fcport,
		  fcport->rdata->ids.port_id, fcport->rport->scsi_target_id);
	QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, "Locking flush mutex.\n");

	mutex_lock(&qedf->flush_mutex);
	if (lun == -1) {
		set_bit(QEDF_RPORT_IN_TARGET_RESET, &fcport->flags);
	} else {
		set_bit(QEDF_RPORT_IN_LUN_RESET, &fcport->flags);
		fcport->lun_reset_lun = lun;
	}

	for (i = 0; i < FCOE_PARAMS_NUM_TASKS; i++) {
		io_req = &cmd_mgr->cmds[i];

		if (!io_req)
			continue;
		if (!io_req->fcport)
			continue;

		spin_lock_irqsave(&cmd_mgr->lock, flags);

		if (io_req->alloc) {
			if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags)) {
				if (io_req->cmd_type == QEDF_SCSI_CMD)
					QEDF_ERR(&qedf->dbg_ctx,
						 "Allocated but not queued, xid=0x%x\n",
						 io_req->xid);
			}
			spin_unlock_irqrestore(&cmd_mgr->lock, flags);
		} else {
			spin_unlock_irqrestore(&cmd_mgr->lock, flags);
			continue;
		}

		if (io_req->fcport != fcport)
			continue;

		/* In case of ABTS, CMD_OUTSTANDING is cleared on ABTS response,
		 * but RRQ is still pending.
		 * Workaround: Within qedf_send_rrq, we check if the fcport is
		 * NULL, and we drop the ref on the io_req to clean it up.
		 */
		if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags)) {
			refcount = kref_read(&io_req->refcount);
			QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
				  "Not outstanding, xid=0x%x, cmd_type=%d refcount=%d.\n",
				  io_req->xid, io_req->cmd_type, refcount);
			/* If RRQ work has been queue, try to cancel it and
			 * free the io_req
			 */
			if (atomic_read(&io_req->state) ==
			    QEDFC_CMD_ST_RRQ_WAIT) {
				if (cancel_delayed_work_sync
				    (&io_req->rrq_work)) {
					QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
						  "Putting reference for pending RRQ work xid=0x%x.\n",
						  io_req->xid);
					/* ID: 003 */
					kref_put(&io_req->refcount,
						 qedf_release_cmd);
				}
			}
			continue;
		}

		/* Only consider flushing ELS during target reset */
		if (io_req->cmd_type == QEDF_ELS &&
		    lun == -1) {
			rc = kref_get_unless_zero(&io_req->refcount);
			if (!rc) {
				QEDF_ERR(&(qedf->dbg_ctx),
				    "Could not get kref for ELS io_req=0x%p xid=0x%x.\n",
				    io_req, io_req->xid);
				continue;
			}
			flush_cnt++;
			qedf_flush_els_req(qedf, io_req);
			/*
			 * Release the kref and go back to the top of the
			 * loop.
			 */
			goto free_cmd;
		}

		if (io_req->cmd_type == QEDF_ABTS) {
			/* ID: 004 */
			rc = kref_get_unless_zero(&io_req->refcount);
			if (!rc) {
				QEDF_ERR(&(qedf->dbg_ctx),
				    "Could not get kref for abort io_req=0x%p xid=0x%x.\n",
				    io_req, io_req->xid);
				continue;
			}
			if (lun != -1 && io_req->lun != lun)
				goto free_cmd;

			QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
			    "Flushing abort xid=0x%x.\n", io_req->xid);

			if (cancel_delayed_work_sync(&io_req->rrq_work)) {
				QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
					  "Putting ref for cancelled RRQ work xid=0x%x.\n",
					  io_req->xid);
				kref_put(&io_req->refcount, qedf_release_cmd);
			}

			if (cancel_delayed_work_sync(&io_req->timeout_work)) {
				QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
					  "Putting ref for cancelled tmo work xid=0x%x.\n",
					  io_req->xid);
				qedf_initiate_cleanup(io_req, true);
				/* Notify eh_abort handler that ABTS is
				 * complete
				 */
				complete(&io_req->abts_done);
				clear_bit(QEDF_CMD_IN_ABORT, &io_req->flags);
				/* ID: 002 */
				kref_put(&io_req->refcount, qedf_release_cmd);
			}
			flush_cnt++;
			goto free_cmd;
		}

		if (!io_req->sc_cmd)
			continue;
		if (!io_req->sc_cmd->device) {
			QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
				  "Device backpointer NULL for sc_cmd=%p.\n",
				  io_req->sc_cmd);
			/* Put reference for non-existent scsi_cmnd */
			io_req->sc_cmd = NULL;
			qedf_initiate_cleanup(io_req, false);
			kref_put(&io_req->refcount, qedf_release_cmd);
			continue;
		}
		if (lun > -1) {
			if (io_req->lun != lun)
				continue;
		}

		/*
		 * Use kref_get_unless_zero in the unlikely case the command
		 * we're about to flush was completed in the normal SCSI path
		 */
		rc = kref_get_unless_zero(&io_req->refcount);
		if (!rc) {
			QEDF_ERR(&(qedf->dbg_ctx), "Could not get kref for "
			    "io_req=0x%p xid=0x%x\n", io_req, io_req->xid);
			continue;
		}

		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO,
		    "Cleanup xid=0x%x.\n", io_req->xid);
		flush_cnt++;

		/* Cleanup task and return I/O mid-layer */
		qedf_initiate_cleanup(io_req, true);

free_cmd:
		kref_put(&io_req->refcount, qedf_release_cmd);	/* ID: 004 */
	}

	wait_cnt = 60;
	QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
		  "Flushed 0x%x I/Os, active=0x%x.\n",
		  flush_cnt, atomic_read(&fcport->num_active_ios));
	/* Only wait for all commands to complete in the Upload context */
	if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags) &&
	    (lun == -1)) {
		while (atomic_read(&fcport->num_active_ios)) {
			QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
				  "Flushed 0x%x I/Os, active=0x%x cnt=%d.\n",
				  flush_cnt,
				  atomic_read(&fcport->num_active_ios),
				  wait_cnt);
			if (wait_cnt == 0) {
				QEDF_ERR(&qedf->dbg_ctx,
					 "Flushed %d I/Os, active=%d.\n",
					 flush_cnt,
					 atomic_read(&fcport->num_active_ios));
				for (i = 0; i < FCOE_PARAMS_NUM_TASKS; i++) {
					io_req = &cmd_mgr->cmds[i];
					if (io_req->fcport &&
					    io_req->fcport == fcport) {
						refcount =
						kref_read(&io_req->refcount);
						set_bit(QEDF_CMD_DIRTY,
							&io_req->flags);
						QEDF_ERR(&qedf->dbg_ctx,
							 "Outstanding io_req =%p xid=0x%x flags=0x%lx, sc_cmd=%p refcount=%d cmd_type=%d.\n",
							 io_req, io_req->xid,
							 io_req->flags,
							 io_req->sc_cmd,
							 refcount,
							 io_req->cmd_type);
					}
				}
				WARN_ON(1);
				break;
			}
			msleep(500);
			wait_cnt--;
		}
	}

	clear_bit(QEDF_RPORT_IN_LUN_RESET, &fcport->flags);
	clear_bit(QEDF_RPORT_IN_TARGET_RESET, &fcport->flags);
	QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO, "Unlocking flush mutex.\n");
	mutex_unlock(&qedf->flush_mutex);
}

/*
 * Initiate a ABTS middle path command. Note that we don't have to initialize
 * the task context for an ABTS task.
 */
int qedf_initiate_abts(struct qedf_ioreq *io_req, bool return_scsi_cmd_on_abts)
{
	struct fc_lport *lport;
	struct qedf_rport *fcport = io_req->fcport;
	struct fc_rport_priv *rdata;
	struct qedf_ctx *qedf;
	u16 xid;
	u32 r_a_tov = 0;
	int rc = 0;
	unsigned long flags;
	struct fcoe_wqe *sqe;
	u16 sqe_idx;
	int refcount = 0;

	/* Sanity check qedf_rport before dereferencing any pointers */
	if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
		QEDF_ERR(NULL, "tgt not offloaded\n");
		rc = 1;
		goto out;
	}

	qedf = fcport->qedf;
	rdata = fcport->rdata;

	if (!rdata || !kref_get_unless_zero(&rdata->kref)) {
		QEDF_ERR(&qedf->dbg_ctx, "stale rport\n");
		rc = 1;
		goto out;
	}

	r_a_tov = rdata->r_a_tov;
	lport = qedf->lport;

	if (lport->state != LPORT_ST_READY || !(lport->link_up)) {
		QEDF_ERR(&(qedf->dbg_ctx), "link is not ready\n");
		rc = 1;
		goto drop_rdata_kref;
	}

	if (atomic_read(&qedf->link_down_tmo_valid) > 0) {
		QEDF_ERR(&(qedf->dbg_ctx), "link_down_tmo active.\n");
		rc = 1;
		goto drop_rdata_kref;
	}

	/* Ensure room on SQ */
	if (!atomic_read(&fcport->free_sqes)) {
		QEDF_ERR(&(qedf->dbg_ctx), "No SQ entries available\n");
		rc = 1;
		goto drop_rdata_kref;
	}

	if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) {
		QEDF_ERR(&qedf->dbg_ctx, "fcport is uploading.\n");
		rc = 1;
		goto drop_rdata_kref;
	}

	if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) ||
	    test_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags) ||
	    test_bit(QEDF_CMD_IN_ABORT, &io_req->flags)) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "io_req xid=0x%x sc_cmd=%p already in cleanup or abort processing or already completed.\n",
			 io_req->xid, io_req->sc_cmd);
		rc = 1;
		goto drop_rdata_kref;
	}

	kref_get(&io_req->refcount);

	xid = io_req->xid;
	qedf->control_requests++;
	qedf->packet_aborts++;

	/* Set the command type to abort */
	io_req->cmd_type = QEDF_ABTS;
	io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts;

	set_bit(QEDF_CMD_IN_ABORT, &io_req->flags);
	refcount = kref_read(&io_req->refcount);
	QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_SCSI_TM,
		  "ABTS io_req xid = 0x%x refcount=%d\n",
		  xid, refcount);

	qedf_cmd_timer_set(qedf, io_req, QEDF_ABORT_TIMEOUT);

	spin_lock_irqsave(&fcport->rport_lock, flags);

	sqe_idx = qedf_get_sqe_idx(fcport);
	sqe = &fcport->sq[sqe_idx];
	memset(sqe, 0, sizeof(struct fcoe_wqe));
	io_req->task_params->sqe = sqe;

	init_initiator_abort_fcoe_task(io_req->task_params);
	qedf_ring_doorbell(fcport);

	spin_unlock_irqrestore(&fcport->rport_lock, flags);

drop_rdata_kref:
	kref_put(&rdata->kref, fc_rport_destroy);
out:
	return rc;
}

void qedf_process_abts_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
	struct qedf_ioreq *io_req)
{
	uint32_t r_ctl;
	uint16_t xid;
	int rc;
	struct qedf_rport *fcport = io_req->fcport;

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM, "Entered with xid = "
		   "0x%x cmd_type = %d\n", io_req->xid, io_req->cmd_type);

	xid = io_req->xid;
	r_ctl = cqe->cqe_info.abts_info.r_ctl;

	/* This was added at a point when we were scheduling abts_compl &
	 * cleanup_compl on different CPUs and there was a possibility of
	 * the io_req to be freed from the other context before we got here.
	 */
	if (!fcport) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
			  "Dropping ABTS completion xid=0x%x as fcport is NULL",
			  io_req->xid);
		return;
	}

	/*
	 * When flush is active, let the cmds be completed from the cleanup
	 * context
	 */
	if (test_bit(QEDF_RPORT_IN_TARGET_RESET, &fcport->flags) ||
	    test_bit(QEDF_RPORT_IN_LUN_RESET, &fcport->flags)) {
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
			  "Dropping ABTS completion xid=0x%x as fcport is flushing",
			  io_req->xid);
		return;
	}

	if (!cancel_delayed_work(&io_req->timeout_work)) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "Wasn't able to cancel abts timeout work.\n");
	}

	switch (r_ctl) {
	case FC_RCTL_BA_ACC:
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM,
		    "ABTS response - ACC Send RRQ after R_A_TOV\n");
		io_req->event = QEDF_IOREQ_EV_ABORT_SUCCESS;
		rc = kref_get_unless_zero(&io_req->refcount);	/* ID: 003 */
		if (!rc) {
			QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_SCSI_TM,
				  "kref is already zero so ABTS was already completed or flushed xid=0x%x.\n",
				  io_req->xid);
			return;
		}
		/*
		 * Dont release this cmd yet. It will be relesed
		 * after we get RRQ response
		 */
		queue_delayed_work(qedf->dpc_wq, &io_req->rrq_work,
		    msecs_to_jiffies(qedf->lport->r_a_tov));
		atomic_set(&io_req->state, QEDFC_CMD_ST_RRQ_WAIT);
		break;
	/* For error cases let the cleanup return the command */
	case FC_RCTL_BA_RJT:
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM,
		   "ABTS response - RJT\n");
		io_req->event = QEDF_IOREQ_EV_ABORT_FAILED;
		break;
	default:
		QEDF_ERR(&(qedf->dbg_ctx), "Unknown ABTS response\n");
		break;
	}

	clear_bit(QEDF_CMD_IN_ABORT, &io_req->flags);

	if (io_req->sc_cmd) {
		if (!io_req->return_scsi_cmd_on_abts)
			QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_SCSI_TM,
				  "Not call scsi_done for xid=0x%x.\n",
				  io_req->xid);
		if (io_req->return_scsi_cmd_on_abts)
			qedf_scsi_done(qedf, io_req, DID_ERROR);
	}

	/* Notify eh_abort handler that ABTS is complete */
	complete(&io_req->abts_done);

	kref_put(&io_req->refcount, qedf_release_cmd);
}

int qedf_init_mp_req(struct qedf_ioreq *io_req)
{
	struct qedf_mp_req *mp_req;
	struct scsi_sge *mp_req_bd;
	struct scsi_sge *mp_resp_bd;
	struct qedf_ctx *qedf = io_req->fcport->qedf;
	dma_addr_t addr;
	uint64_t sz;

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_MP_REQ, "Entered.\n");

	mp_req = (struct qedf_mp_req *)&(io_req->mp_req);
	memset(mp_req, 0, sizeof(struct qedf_mp_req));

	if (io_req->cmd_type != QEDF_ELS) {
		mp_req->req_len = sizeof(struct fcp_cmnd);
		io_req->data_xfer_len = mp_req->req_len;
	} else
		mp_req->req_len = io_req->data_xfer_len;

	mp_req->req_buf = dma_alloc_coherent(&qedf->pdev->dev, QEDF_PAGE_SIZE,
	    &mp_req->req_buf_dma, GFP_KERNEL);
	if (!mp_req->req_buf) {
		QEDF_ERR(&(qedf->dbg_ctx), "Unable to alloc MP req buffer\n");
		qedf_free_mp_resc(io_req);
		return -ENOMEM;
	}

	mp_req->resp_buf = dma_alloc_coherent(&qedf->pdev->dev,
	    QEDF_PAGE_SIZE, &mp_req->resp_buf_dma, GFP_KERNEL);
	if (!mp_req->resp_buf) {
		QEDF_ERR(&(qedf->dbg_ctx), "Unable to alloc TM resp "
			  "buffer\n");
		qedf_free_mp_resc(io_req);
		return -ENOMEM;
	}

	/* Allocate and map mp_req_bd and mp_resp_bd */
	sz = sizeof(struct scsi_sge);
	mp_req->mp_req_bd = dma_alloc_coherent(&qedf->pdev->dev, sz,
	    &mp_req->mp_req_bd_dma, GFP_KERNEL);
	if (!mp_req->mp_req_bd) {
		QEDF_ERR(&(qedf->dbg_ctx), "Unable to alloc MP req bd\n");
		qedf_free_mp_resc(io_req);
		return -ENOMEM;
	}

	mp_req->mp_resp_bd = dma_alloc_coherent(&qedf->pdev->dev, sz,
	    &mp_req->mp_resp_bd_dma, GFP_KERNEL);
	if (!mp_req->mp_resp_bd) {
		QEDF_ERR(&(qedf->dbg_ctx), "Unable to alloc MP resp bd\n");
		qedf_free_mp_resc(io_req);
		return -ENOMEM;
	}

	/* Fill bd table */
	addr = mp_req->req_buf_dma;
	mp_req_bd = mp_req->mp_req_bd;
	mp_req_bd->sge_addr.lo = U64_LO(addr);
	mp_req_bd->sge_addr.hi = U64_HI(addr);
	mp_req_bd->sge_len = QEDF_PAGE_SIZE;

	/*
	 * MP buffer is either a task mgmt command or an ELS.
	 * So the assumption is that it consumes a single bd
	 * entry in the bd table
	 */
	mp_resp_bd = mp_req->mp_resp_bd;
	addr = mp_req->resp_buf_dma;
	mp_resp_bd->sge_addr.lo = U64_LO(addr);
	mp_resp_bd->sge_addr.hi = U64_HI(addr);
	mp_resp_bd->sge_len = QEDF_PAGE_SIZE;

	return 0;
}

/*
 * Last ditch effort to clear the port if it's stuck. Used only after a
 * cleanup task times out.
 */
static void qedf_drain_request(struct qedf_ctx *qedf)
{
	if (test_bit(QEDF_DRAIN_ACTIVE, &qedf->flags)) {
		QEDF_ERR(&(qedf->dbg_ctx), "MCP drain already active.\n");
		return;
	}

	/* Set bit to return all queuecommand requests as busy */
	set_bit(QEDF_DRAIN_ACTIVE, &qedf->flags);

	/* Call qed drain request for function. Should be synchronous */
	qed_ops->common->drain(qedf->cdev);

	/* Settle time for CQEs to be returned */
	msleep(100);

	/* Unplug and continue */
	clear_bit(QEDF_DRAIN_ACTIVE, &qedf->flags);
}

/*
 * Returns SUCCESS if the cleanup task does not timeout, otherwise return
 * FAILURE.
 */
int qedf_initiate_cleanup(struct qedf_ioreq *io_req,
	bool return_scsi_cmd_on_abts)
{
	struct qedf_rport *fcport;
	struct qedf_ctx *qedf;
	uint16_t xid;
	struct e4_fcoe_task_context *task;
	int tmo = 0;
	int rc = SUCCESS;
	unsigned long flags;
	struct fcoe_wqe *sqe;
	u16 sqe_idx;
	int refcount = 0;

	fcport = io_req->fcport;
	if (!fcport) {
		QEDF_ERR(NULL, "fcport is NULL.\n");
		return SUCCESS;
	}

	/* Sanity check qedf_rport before dereferencing any pointers */
	if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
		QEDF_ERR(NULL, "tgt not offloaded\n");
		rc = 1;
		return SUCCESS;
	}

	qedf = fcport->qedf;
	if (!qedf) {
		QEDF_ERR(NULL, "qedf is NULL.\n");
		return SUCCESS;
	}

	if (!test_bit(QEDF_CMD_OUTSTANDING, &io_req->flags) ||
	    test_and_set_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags)) {
		QEDF_ERR(&(qedf->dbg_ctx), "io_req xid=0x%x already in "
			  "cleanup processing or already completed.\n",
			  io_req->xid);
		return SUCCESS;
	}
	set_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags);

	/* Ensure room on SQ */
	if (!atomic_read(&fcport->free_sqes)) {
		QEDF_ERR(&(qedf->dbg_ctx), "No SQ entries available\n");
		/* Need to make sure we clear the flag since it was set */
		clear_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags);
		return FAILED;
	}

	if (io_req->cmd_type == QEDF_CLEANUP) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "io_req=0x%x is already a cleanup command cmd_type=%d.\n",
			 io_req->xid, io_req->cmd_type);
		clear_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags);
		return SUCCESS;
	}

	refcount = kref_read(&io_req->refcount);

	QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_IO,
		  "Entered xid=0x%x sc_cmd=%p cmd_type=%d flags=0x%lx refcount=%d fcport=%p port_id=0x%06x\n",
		  io_req->xid, io_req->sc_cmd, io_req->cmd_type, io_req->flags,
		  refcount, fcport, fcport->rdata->ids.port_id);

	/* Cleanup cmds re-use the same TID as the original I/O */
	xid = io_req->xid;
	io_req->cmd_type = QEDF_CLEANUP;
	io_req->return_scsi_cmd_on_abts = return_scsi_cmd_on_abts;

	task = qedf_get_task_mem(&qedf->tasks, xid);

	init_completion(&io_req->cleanup_done);

	spin_lock_irqsave(&fcport->rport_lock, flags);

	sqe_idx = qedf_get_sqe_idx(fcport);
	sqe = &fcport->sq[sqe_idx];
	memset(sqe, 0, sizeof(struct fcoe_wqe));
	io_req->task_params->sqe = sqe;

	init_initiator_cleanup_fcoe_task(io_req->task_params);
	qedf_ring_doorbell(fcport);

	spin_unlock_irqrestore(&fcport->rport_lock, flags);

	tmo = wait_for_completion_timeout(&io_req->cleanup_done,
					  QEDF_CLEANUP_TIMEOUT * HZ);

	if (!tmo) {
		rc = FAILED;
		/* Timeout case */
		QEDF_ERR(&(qedf->dbg_ctx), "Cleanup command timeout, "
			  "xid=%x.\n", io_req->xid);
		clear_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags);
		/* Issue a drain request if cleanup task times out */
		QEDF_ERR(&(qedf->dbg_ctx), "Issuing MCP drain request.\n");
		qedf_drain_request(qedf);
	}

	/* If it TASK MGMT handle it, reference will be decreased
	 * in qedf_execute_tmf
	 */
	if (io_req->tm_flags  == FCP_TMF_LUN_RESET ||
	    io_req->tm_flags == FCP_TMF_TGT_RESET) {
		clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags);
		io_req->sc_cmd = NULL;
		complete(&io_req->tm_done);
	}

	if (io_req->sc_cmd) {
		if (!io_req->return_scsi_cmd_on_abts)
			QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_SCSI_TM,
				  "Not call scsi_done for xid=0x%x.\n",
				  io_req->xid);
		if (io_req->return_scsi_cmd_on_abts)
			qedf_scsi_done(qedf, io_req, DID_ERROR);
	}

	if (rc == SUCCESS)
		io_req->event = QEDF_IOREQ_EV_CLEANUP_SUCCESS;
	else
		io_req->event = QEDF_IOREQ_EV_CLEANUP_FAILED;

	return rc;
}

void qedf_process_cleanup_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
	struct qedf_ioreq *io_req)
{
	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_IO, "Entered xid = 0x%x\n",
		   io_req->xid);

	clear_bit(QEDF_CMD_IN_CLEANUP, &io_req->flags);

	/* Complete so we can finish cleaning up the I/O */
	complete(&io_req->cleanup_done);
}

static int qedf_execute_tmf(struct qedf_rport *fcport, struct scsi_cmnd *sc_cmd,
	uint8_t tm_flags)
{
	struct qedf_ioreq *io_req;
	struct e4_fcoe_task_context *task;
	struct qedf_ctx *qedf = fcport->qedf;
	struct fc_lport *lport = qedf->lport;
	int rc = 0;
	uint16_t xid;
	int tmo = 0;
	int lun = 0;
	unsigned long flags;
	struct fcoe_wqe *sqe;
	u16 sqe_idx;

	if (!sc_cmd) {
		QEDF_ERR(&qedf->dbg_ctx, "sc_cmd is NULL\n");
		return FAILED;
	}

	lun = (int)sc_cmd->device->lun;
	if (!test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags)) {
		QEDF_ERR(&(qedf->dbg_ctx), "fcport not offloaded\n");
		rc = FAILED;
		goto no_flush;
	}

	io_req = qedf_alloc_cmd(fcport, QEDF_TASK_MGMT_CMD);
	if (!io_req) {
		QEDF_ERR(&(qedf->dbg_ctx), "Failed TMF");
		rc = -EAGAIN;
		goto no_flush;
	}

	if (tm_flags == FCP_TMF_LUN_RESET)
		qedf->lun_resets++;
	else if (tm_flags == FCP_TMF_TGT_RESET)
		qedf->target_resets++;

	/* Initialize rest of io_req fields */
	io_req->sc_cmd = sc_cmd;
	io_req->fcport = fcport;
	io_req->cmd_type = QEDF_TASK_MGMT_CMD;

	/* Record which cpu this request is associated with */
	io_req->cpu = smp_processor_id();

	/* Set TM flags */
	io_req->io_req_flags = QEDF_READ;
	io_req->data_xfer_len = 0;
	io_req->tm_flags = tm_flags;

	/* Default is to return a SCSI command when an error occurs */
	io_req->return_scsi_cmd_on_abts = false;

	/* Obtain exchange id */
	xid = io_req->xid;

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_SCSI_TM, "TMF io_req xid = "
		   "0x%x\n", xid);

	/* Initialize task context for this IO request */
	task = qedf_get_task_mem(&qedf->tasks, xid);

	init_completion(&io_req->tm_done);

	spin_lock_irqsave(&fcport->rport_lock, flags);

	sqe_idx = qedf_get_sqe_idx(fcport);
	sqe = &fcport->sq[sqe_idx];
	memset(sqe, 0, sizeof(struct fcoe_wqe));

	qedf_init_task(fcport, lport, io_req, task, sqe);
	qedf_ring_doorbell(fcport);

	spin_unlock_irqrestore(&fcport->rport_lock, flags);

	set_bit(QEDF_CMD_OUTSTANDING, &io_req->flags);
	tmo = wait_for_completion_timeout(&io_req->tm_done,
	    QEDF_TM_TIMEOUT * HZ);

	if (!tmo) {
		rc = FAILED;
		QEDF_ERR(&(qedf->dbg_ctx), "wait for tm_cmpl timeout!\n");
		/* Clear outstanding bit since command timed out */
		clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags);
		io_req->sc_cmd = NULL;
	} else {
		/* Check TMF response code */
		if (io_req->fcp_rsp_code == 0)
			rc = SUCCESS;
		else
			rc = FAILED;
	}
	/*
	 * Double check that fcport has not gone into an uploading state before
	 * executing the command flush for the LUN/target.
	 */
	if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) {
		QEDF_ERR(&qedf->dbg_ctx,
			 "fcport is uploading, not executing flush.\n");
		goto no_flush;
	}
	/* We do not need this io_req any more */
	kref_put(&io_req->refcount, qedf_release_cmd);


	if (tm_flags == FCP_TMF_LUN_RESET)
		qedf_flush_active_ios(fcport, lun);
	else
		qedf_flush_active_ios(fcport, -1);

no_flush:
	if (rc != SUCCESS) {
		QEDF_ERR(&(qedf->dbg_ctx), "task mgmt command failed...\n");
		rc = FAILED;
	} else {
		QEDF_ERR(&(qedf->dbg_ctx), "task mgmt command success...\n");
		rc = SUCCESS;
	}
	return rc;
}

int qedf_initiate_tmf(struct scsi_cmnd *sc_cmd, u8 tm_flags)
{
	struct fc_rport *rport = starget_to_rport(scsi_target(sc_cmd->device));
	struct fc_rport_libfc_priv *rp = rport->dd_data;
	struct qedf_rport *fcport = (struct qedf_rport *)&rp[1];
	struct qedf_ctx *qedf;
	struct fc_lport *lport = shost_priv(sc_cmd->device->host);
	int rc = SUCCESS;
	int rval;
	struct qedf_ioreq *io_req = NULL;
	int ref_cnt = 0;
	struct fc_rport_priv *rdata = fcport->rdata;

	QEDF_ERR(NULL,
		 "tm_flags 0x%x sc_cmd %p op = 0x%02x target_id = 0x%x lun=%d\n",
		 tm_flags, sc_cmd, sc_cmd->cmd_len ? sc_cmd->cmnd[0] : 0xff,
		 rport->scsi_target_id, (int)sc_cmd->device->lun);

	if (!rdata || !kref_get_unless_zero(&rdata->kref)) {
		QEDF_ERR(NULL, "stale rport\n");
		return FAILED;
	}

	QEDF_ERR(NULL, "portid=%06x tm_flags =%s\n", rdata->ids.port_id,
		 (tm_flags == FCP_TMF_TGT_RESET) ? "TARGET RESET" :
		 "LUN RESET");

	if (sc_cmd->SCp.ptr) {
		io_req = (struct qedf_ioreq *)sc_cmd->SCp.ptr;
		ref_cnt = kref_read(&io_req->refcount);
		QEDF_ERR(NULL,
			 "orig io_req = %p xid = 0x%x ref_cnt = %d.\n",
			 io_req, io_req->xid, ref_cnt);
	}

	rval = fc_remote_port_chkready(rport);
	if (rval) {
		QEDF_ERR(NULL, "device_reset rport not ready\n");
		rc = FAILED;
		goto tmf_err;
	}

	rc = fc_block_scsi_eh(sc_cmd);
	if (rc)
		goto tmf_err;

	if (!fcport) {
		QEDF_ERR(NULL, "device_reset: rport is NULL\n");
		rc = FAILED;
		goto tmf_err;
	}

	qedf = fcport->qedf;

	if (!qedf) {
		QEDF_ERR(NULL, "qedf is NULL.\n");
		rc = FAILED;
		goto tmf_err;
	}

	if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) {
		QEDF_ERR(&qedf->dbg_ctx, "Connection is getting uploaded.\n");
		rc = SUCCESS;
		goto tmf_err;
	}

	if (test_bit(QEDF_UNLOADING, &qedf->flags) ||
	    test_bit(QEDF_DBG_STOP_IO, &qedf->flags)) {
		rc = SUCCESS;
		goto tmf_err;
	}

	if (lport->state != LPORT_ST_READY || !(lport->link_up)) {
		QEDF_ERR(&(qedf->dbg_ctx), "link is not ready\n");
		rc = FAILED;
		goto tmf_err;
	}

	if (test_bit(QEDF_RPORT_UPLOADING_CONNECTION, &fcport->flags)) {
		if (!fcport->rdata)
			QEDF_ERR(&qedf->dbg_ctx, "fcport %p is uploading.\n",
				 fcport);
		else
			QEDF_ERR(&qedf->dbg_ctx,
				 "fcport %p port_id=%06x is uploading.\n",
				 fcport, fcport->rdata->ids.port_id);
		rc = FAILED;
		goto tmf_err;
	}

	rc = qedf_execute_tmf(fcport, sc_cmd, tm_flags);

tmf_err:
	kref_put(&rdata->kref, fc_rport_destroy);
	return rc;
}

void qedf_process_tmf_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
	struct qedf_ioreq *io_req)
{
	struct fcoe_cqe_rsp_info *fcp_rsp;

	clear_bit(QEDF_CMD_OUTSTANDING, &io_req->flags);

	fcp_rsp = &cqe->cqe_info.rsp_info;
	qedf_parse_fcp_rsp(io_req, fcp_rsp);

	io_req->sc_cmd = NULL;
	complete(&io_req->tm_done);
}

void qedf_process_unsol_compl(struct qedf_ctx *qedf, uint16_t que_idx,
	struct fcoe_cqe *cqe)
{
	unsigned long flags;
	uint16_t tmp;
	uint16_t pktlen = cqe->cqe_info.unsolic_info.pkt_len;
	u32 payload_len, crc;
	struct fc_frame_header *fh;
	struct fc_frame *fp;
	struct qedf_io_work *io_work;
	u32 bdq_idx;
	void *bdq_addr;
	struct scsi_bd *p_bd_info;

	p_bd_info = &cqe->cqe_info.unsolic_info.bd_info;
	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_UNSOL,
		  "address.hi=%x, address.lo=%x, opaque_data.hi=%x, opaque_data.lo=%x, bdq_prod_idx=%u, len=%u\n",
		  le32_to_cpu(p_bd_info->address.hi),
		  le32_to_cpu(p_bd_info->address.lo),
		  le32_to_cpu(p_bd_info->opaque.fcoe_opaque.hi),
		  le32_to_cpu(p_bd_info->opaque.fcoe_opaque.lo),
		  qedf->bdq_prod_idx, pktlen);

	bdq_idx = le32_to_cpu(p_bd_info->opaque.fcoe_opaque.lo);
	if (bdq_idx >= QEDF_BDQ_SIZE) {
		QEDF_ERR(&(qedf->dbg_ctx), "bdq_idx is out of range %d.\n",
		    bdq_idx);
		goto increment_prod;
	}

	bdq_addr = qedf->bdq[bdq_idx].buf_addr;
	if (!bdq_addr) {
		QEDF_ERR(&(qedf->dbg_ctx), "bdq_addr is NULL, dropping "
		    "unsolicited packet.\n");
		goto increment_prod;
	}

	if (qedf_dump_frames) {
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_UNSOL,
		    "BDQ frame is at addr=%p.\n", bdq_addr);
		print_hex_dump(KERN_WARNING, "bdq ", DUMP_PREFIX_OFFSET, 16, 1,
		    (void *)bdq_addr, pktlen, false);
	}

	/* Allocate frame */
	payload_len = pktlen - sizeof(struct fc_frame_header);
	fp = fc_frame_alloc(qedf->lport, payload_len);
	if (!fp) {
		QEDF_ERR(&(qedf->dbg_ctx), "Could not allocate fp.\n");
		goto increment_prod;
	}

	/* Copy data from BDQ buffer into fc_frame struct */
	fh = (struct fc_frame_header *)fc_frame_header_get(fp);
	memcpy(fh, (void *)bdq_addr, pktlen);

	QEDF_WARN(&qedf->dbg_ctx,
		  "Processing Unsolicated frame, src=%06x dest=%06x r_ctl=0x%x type=0x%x cmd=%02x\n",
		  ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id), fh->fh_r_ctl,
		  fh->fh_type, fc_frame_payload_op(fp));

	/* Initialize the frame so libfc sees it as a valid frame */
	crc = fcoe_fc_crc(fp);
	fc_frame_init(fp);
	fr_dev(fp) = qedf->lport;
	fr_sof(fp) = FC_SOF_I3;
	fr_eof(fp) = FC_EOF_T;
	fr_crc(fp) = cpu_to_le32(~crc);

	/*
	 * We need to return the frame back up to libfc in a non-atomic
	 * context
	 */
	io_work = mempool_alloc(qedf->io_mempool, GFP_ATOMIC);
	if (!io_work) {
		QEDF_WARN(&(qedf->dbg_ctx), "Could not allocate "
			   "work for I/O completion.\n");
		fc_frame_free(fp);
		goto increment_prod;
	}
	memset(io_work, 0, sizeof(struct qedf_io_work));

	INIT_WORK(&io_work->work, qedf_fp_io_handler);

	/* Copy contents of CQE for deferred processing */
	memcpy(&io_work->cqe, cqe, sizeof(struct fcoe_cqe));

	io_work->qedf = qedf;
	io_work->fp = fp;

	queue_work_on(smp_processor_id(), qedf_io_wq, &io_work->work);
increment_prod:
	spin_lock_irqsave(&qedf->hba_lock, flags);

	/* Increment producer to let f/w know we've handled the frame */
	qedf->bdq_prod_idx++;

	/* Producer index wraps at uint16_t boundary */
	if (qedf->bdq_prod_idx == 0xffff)
		qedf->bdq_prod_idx = 0;

	writew(qedf->bdq_prod_idx, qedf->bdq_primary_prod);
	tmp = readw(qedf->bdq_primary_prod);
	writew(qedf->bdq_prod_idx, qedf->bdq_secondary_prod);
	tmp = readw(qedf->bdq_secondary_prod);

	spin_unlock_irqrestore(&qedf->hba_lock, flags);
}
