/*
 *  QLogic FCoE Offload Driver
 *  Copyright (c) 2016 Cavium Inc.
 *
 *  This software is available under the terms of the GNU General Public License
 *  (GPL) Version 2, available from the file COPYING in the main directory of
 *  this source tree.
 */
#include "qedf.h"

/* It's assumed that the lock is held when calling this function. */
static int qedf_initiate_els(struct qedf_rport *fcport, unsigned int op,
	void *data, uint32_t data_len,
	void (*cb_func)(struct qedf_els_cb_arg *cb_arg),
	struct qedf_els_cb_arg *cb_arg, uint32_t timer_msec)
{
	struct qedf_ctx *qedf = fcport->qedf;
	struct fc_lport *lport = qedf->lport;
	struct qedf_ioreq *els_req;
	struct qedf_mp_req *mp_req;
	struct fc_frame_header *fc_hdr;
	struct fcoe_task_context *task;
	int rc = 0;
	uint32_t did, sid;
	uint16_t xid;
	uint32_t start_time = jiffies / HZ;
	uint32_t current_time;

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Sending ELS\n");

	rc = fc_remote_port_chkready(fcport->rport);
	if (rc) {
		QEDF_ERR(&(qedf->dbg_ctx), "els 0x%x: rport not ready\n", op);
		rc = -EAGAIN;
		goto els_err;
	}
	if (lport->state != LPORT_ST_READY || !(lport->link_up)) {
		QEDF_ERR(&(qedf->dbg_ctx), "els 0x%x: link is not ready\n",
			  op);
		rc = -EAGAIN;
		goto els_err;
	}

	if (!(test_bit(QEDF_RPORT_SESSION_READY, &fcport->flags))) {
		QEDF_ERR(&(qedf->dbg_ctx), "els 0x%x: fcport not ready\n", op);
		rc = -EINVAL;
		goto els_err;
	}

retry_els:
	els_req = qedf_alloc_cmd(fcport, QEDF_ELS);
	if (!els_req) {
		current_time = jiffies / HZ;
		if ((current_time - start_time) > 10) {
			QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
				   "els: Failed els 0x%x\n", op);
			rc = -ENOMEM;
			goto els_err;
		}
		mdelay(20 * USEC_PER_MSEC);
		goto retry_els;
	}

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "initiate_els els_req = "
		   "0x%p cb_arg = %p xid = %x\n", els_req, cb_arg,
		   els_req->xid);
	els_req->sc_cmd = NULL;
	els_req->cmd_type = QEDF_ELS;
	els_req->fcport = fcport;
	els_req->cb_func = cb_func;
	cb_arg->io_req = els_req;
	cb_arg->op = op;
	els_req->cb_arg = cb_arg;
	els_req->data_xfer_len = data_len;

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

	mp_req = (struct qedf_mp_req *)&(els_req->mp_req);
	rc = qedf_init_mp_req(els_req);
	if (rc) {
		QEDF_ERR(&(qedf->dbg_ctx), "ELS MP request init failed\n");
		kref_put(&els_req->refcount, qedf_release_cmd);
		goto els_err;
	} else {
		rc = 0;
	}

	/* Fill ELS Payload */
	if ((op >= ELS_LS_RJT) && (op <= ELS_AUTH_ELS)) {
		memcpy(mp_req->req_buf, data, data_len);
	} else {
		QEDF_ERR(&(qedf->dbg_ctx), "Invalid ELS op 0x%x\n", op);
		els_req->cb_func = NULL;
		els_req->cb_arg = NULL;
		kref_put(&els_req->refcount, qedf_release_cmd);
		rc = -EINVAL;
	}

	if (rc)
		goto els_err;

	/* Fill FC header */
	fc_hdr = &(mp_req->req_fc_hdr);

	did = fcport->rdata->ids.port_id;
	sid = fcport->sid;

	__fc_fill_fc_hdr(fc_hdr, FC_RCTL_ELS_REQ, sid, did,
			   FC_TYPE_ELS, FC_FC_FIRST_SEQ | FC_FC_END_SEQ |
			   FC_FC_SEQ_INIT, 0);

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

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

	/* Put timer on original I/O request */
	if (timer_msec)
		qedf_cmd_timer_set(qedf, els_req, timer_msec);

	qedf_add_to_sq(fcport, xid, 0, FCOE_TASK_TYPE_MIDPATH, 0);

	/* Ring doorbell */
	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Ringing doorbell for ELS "
		   "req\n");
	qedf_ring_doorbell(fcport);
els_err:
	return rc;
}

void qedf_process_els_compl(struct qedf_ctx *qedf, struct fcoe_cqe *cqe,
	struct qedf_ioreq *els_req)
{
	struct fcoe_task_context *task_ctx;
	struct scsi_cmnd *sc_cmd;
	uint16_t xid;
	struct fcoe_cqe_midpath_info *mp_info;

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

	/* Kill the ELS timer */
	cancel_delayed_work(&els_req->timeout_work);

	xid = els_req->xid;
	task_ctx = qedf_get_task_mem(&qedf->tasks, xid);
	sc_cmd = els_req->sc_cmd;

	/* Get ELS response length from CQE */
	mp_info = &cqe->cqe_info.midpath_info;
	els_req->mp_req.resp_len = mp_info->data_placement_size;

	/* Parse ELS response */
	if ((els_req->cb_func) && (els_req->cb_arg)) {
		els_req->cb_func(els_req->cb_arg);
		els_req->cb_arg = NULL;
	}

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

static void qedf_rrq_compl(struct qedf_els_cb_arg *cb_arg)
{
	struct qedf_ioreq *orig_io_req;
	struct qedf_ioreq *rrq_req;
	struct qedf_ctx *qedf;
	int refcount;

	rrq_req = cb_arg->io_req;
	qedf = rrq_req->fcport->qedf;

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

	orig_io_req = cb_arg->aborted_io_req;

	if (!orig_io_req)
		goto out_free;

	if (rrq_req->event != QEDF_IOREQ_EV_ELS_TMO &&
	    rrq_req->event != QEDF_IOREQ_EV_ELS_ERR_DETECT)
		cancel_delayed_work_sync(&orig_io_req->timeout_work);

	refcount = kref_read(&orig_io_req->refcount);
	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "rrq_compl: orig io = %p,"
		   " orig xid = 0x%x, rrq_xid = 0x%x, refcount=%d\n",
		   orig_io_req, orig_io_req->xid, rrq_req->xid, refcount);

	/* This should return the aborted io_req to the command pool */
	if (orig_io_req)
		kref_put(&orig_io_req->refcount, qedf_release_cmd);

out_free:
	kfree(cb_arg);
}

/* Assumes kref is already held by caller */
int qedf_send_rrq(struct qedf_ioreq *aborted_io_req)
{

	struct fc_els_rrq rrq;
	struct qedf_rport *fcport;
	struct fc_lport *lport;
	struct qedf_els_cb_arg *cb_arg = NULL;
	struct qedf_ctx *qedf;
	uint32_t sid;
	uint32_t r_a_tov;
	int rc;

	if (!aborted_io_req) {
		QEDF_ERR(NULL, "abort_io_req is NULL.\n");
		return -EINVAL;
	}

	fcport = aborted_io_req->fcport;

	/* 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 -EINVAL;
	}

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

	qedf = fcport->qedf;
	lport = qedf->lport;
	sid = fcport->sid;
	r_a_tov = lport->r_a_tov;

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Sending RRQ orig "
		   "io = %p, orig_xid = 0x%x\n", aborted_io_req,
		   aborted_io_req->xid);
	memset(&rrq, 0, sizeof(rrq));

	cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO);
	if (!cb_arg) {
		QEDF_ERR(&(qedf->dbg_ctx), "Unable to allocate cb_arg for "
			  "RRQ\n");
		rc = -ENOMEM;
		goto rrq_err;
	}

	cb_arg->aborted_io_req = aborted_io_req;

	rrq.rrq_cmd = ELS_RRQ;
	hton24(rrq.rrq_s_id, sid);
	rrq.rrq_ox_id = htons(aborted_io_req->xid);
	rrq.rrq_rx_id =
	    htons(aborted_io_req->task->tstorm_st_context.read_write.rx_id);

	rc = qedf_initiate_els(fcport, ELS_RRQ, &rrq, sizeof(rrq),
	    qedf_rrq_compl, cb_arg, r_a_tov);

rrq_err:
	if (rc) {
		QEDF_ERR(&(qedf->dbg_ctx), "RRQ failed - release orig io "
			  "req 0x%x\n", aborted_io_req->xid);
		kfree(cb_arg);
		kref_put(&aborted_io_req->refcount, qedf_release_cmd);
	}
	return rc;
}

static void qedf_process_l2_frame_compl(struct qedf_rport *fcport,
					struct fc_frame *fp,
					u16 l2_oxid)
{
	struct fc_lport *lport = fcport->qedf->lport;
	struct fc_frame_header *fh;
	u32 crc;

	fh = (struct fc_frame_header *)fc_frame_header_get(fp);

	/* Set the OXID we return to what libfc used */
	if (l2_oxid != FC_XID_UNKNOWN)
		fh->fh_ox_id = htons(l2_oxid);

	/* Setup header fields */
	fh->fh_r_ctl = FC_RCTL_ELS_REP;
	fh->fh_type = FC_TYPE_ELS;
	/* Last sequence, end sequence */
	fh->fh_f_ctl[0] = 0x98;
	hton24(fh->fh_d_id, lport->port_id);
	hton24(fh->fh_s_id, fcport->rdata->ids.port_id);
	fh->fh_rx_id = 0xffff;

	/* Set frame attributes */
	crc = fcoe_fc_crc(fp);
	fc_frame_init(fp);
	fr_dev(fp) = lport;
	fr_sof(fp) = FC_SOF_I3;
	fr_eof(fp) = FC_EOF_T;
	fr_crc(fp) = cpu_to_le32(~crc);

	/* Send completed request to libfc */
	fc_exch_recv(lport, fp);
}

/*
 * In instances where an ELS command times out we may need to restart the
 * rport by logging out and then logging back in.
 */
void qedf_restart_rport(struct qedf_rport *fcport)
{
	struct fc_lport *lport;
	struct fc_rport_priv *rdata;
	u32 port_id;

	if (!fcport)
		return;

	rdata = fcport->rdata;
	if (rdata) {
		lport = fcport->qedf->lport;
		port_id = rdata->ids.port_id;
		QEDF_ERR(&(fcport->qedf->dbg_ctx),
		    "LOGO port_id=%x.\n", port_id);
		fc_rport_logoff(rdata);
		/* Recreate the rport and log back in */
		rdata = fc_rport_create(lport, port_id);
		if (rdata)
			fc_rport_login(rdata);
	}
}

static void qedf_l2_els_compl(struct qedf_els_cb_arg *cb_arg)
{
	struct qedf_ioreq *els_req;
	struct qedf_rport *fcport;
	struct qedf_mp_req *mp_req;
	struct fc_frame *fp;
	struct fc_frame_header *fh, *mp_fc_hdr;
	void *resp_buf, *fc_payload;
	u32 resp_len;
	u16 l2_oxid;

	l2_oxid = cb_arg->l2_oxid;
	els_req = cb_arg->io_req;

	if (!els_req) {
		QEDF_ERR(NULL, "els_req is NULL.\n");
		goto free_arg;
	}

	/*
	 * If we are flushing the command just free the cb_arg as none of the
	 * response data will be valid.
	 */
	if (els_req->event == QEDF_IOREQ_EV_ELS_FLUSH)
		goto free_arg;

	fcport = els_req->fcport;
	mp_req = &(els_req->mp_req);
	mp_fc_hdr = &(mp_req->resp_fc_hdr);
	resp_len = mp_req->resp_len;
	resp_buf = mp_req->resp_buf;

	/*
	 * If a middle path ELS command times out, don't try to return
	 * the command but rather do any internal cleanup and then libfc
	 * timeout the command and clean up its internal resources.
	 */
	if (els_req->event == QEDF_IOREQ_EV_ELS_TMO) {
		/*
		 * If ADISC times out, libfc will timeout the exchange and then
		 * try to send a PLOGI which will timeout since the session is
		 * still offloaded.  Force libfc to logout the session which
		 * will offload the connection and allow the PLOGI response to
		 * flow over the LL2 path.
		 */
		if (cb_arg->op == ELS_ADISC)
			qedf_restart_rport(fcport);
		return;
	}

	if (sizeof(struct fc_frame_header) + resp_len > QEDF_PAGE_SIZE) {
		QEDF_ERR(&(fcport->qedf->dbg_ctx), "resp_len is "
		   "beyond page size.\n");
		goto free_arg;
	}

	fp = fc_frame_alloc(fcport->qedf->lport, resp_len);
	if (!fp) {
		QEDF_ERR(&(fcport->qedf->dbg_ctx),
		    "fc_frame_alloc failure.\n");
		return;
	}

	/* Copy frame header from firmware into fp */
	fh = (struct fc_frame_header *)fc_frame_header_get(fp);
	memcpy(fh, mp_fc_hdr, sizeof(struct fc_frame_header));

	/* Copy payload from firmware into fp */
	fc_payload = fc_frame_payload_get(fp, resp_len);
	memcpy(fc_payload, resp_buf, resp_len);

	QEDF_INFO(&(fcport->qedf->dbg_ctx), QEDF_LOG_ELS,
	    "Completing OX_ID 0x%x back to libfc.\n", l2_oxid);
	qedf_process_l2_frame_compl(fcport, fp, l2_oxid);

free_arg:
	kfree(cb_arg);
}

int qedf_send_adisc(struct qedf_rport *fcport, struct fc_frame *fp)
{
	struct fc_els_adisc *adisc;
	struct fc_frame_header *fh;
	struct fc_lport *lport = fcport->qedf->lport;
	struct qedf_els_cb_arg *cb_arg = NULL;
	struct qedf_ctx *qedf;
	uint32_t r_a_tov = lport->r_a_tov;
	int rc;

	qedf = fcport->qedf;
	fh = fc_frame_header_get(fp);

	cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO);
	if (!cb_arg) {
		QEDF_ERR(&(qedf->dbg_ctx), "Unable to allocate cb_arg for "
			  "ADISC\n");
		rc = -ENOMEM;
		goto adisc_err;
	}
	cb_arg->l2_oxid = ntohs(fh->fh_ox_id);

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
	    "Sending ADISC ox_id=0x%x.\n", cb_arg->l2_oxid);

	adisc = fc_frame_payload_get(fp, sizeof(*adisc));

	rc = qedf_initiate_els(fcport, ELS_ADISC, adisc, sizeof(*adisc),
	    qedf_l2_els_compl, cb_arg, r_a_tov);

adisc_err:
	if (rc) {
		QEDF_ERR(&(qedf->dbg_ctx), "ADISC failed.\n");
		kfree(cb_arg);
	}
	return rc;
}

static void qedf_srr_compl(struct qedf_els_cb_arg *cb_arg)
{
	struct qedf_ioreq *orig_io_req;
	struct qedf_ioreq *srr_req;
	struct qedf_mp_req *mp_req;
	struct fc_frame_header *mp_fc_hdr, *fh;
	struct fc_frame *fp;
	void *resp_buf, *fc_payload;
	u32 resp_len;
	struct fc_lport *lport;
	struct qedf_ctx *qedf;
	int refcount;
	u8 opcode;

	srr_req = cb_arg->io_req;
	qedf = srr_req->fcport->qedf;
	lport = qedf->lport;

	orig_io_req = cb_arg->aborted_io_req;

	if (!orig_io_req)
		goto out_free;

	clear_bit(QEDF_CMD_SRR_SENT, &orig_io_req->flags);

	if (srr_req->event != QEDF_IOREQ_EV_ELS_TMO &&
	    srr_req->event != QEDF_IOREQ_EV_ELS_ERR_DETECT)
		cancel_delayed_work_sync(&orig_io_req->timeout_work);

	refcount = kref_read(&orig_io_req->refcount);
	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Entered: orig_io=%p,"
		   " orig_io_xid=0x%x, rec_xid=0x%x, refcount=%d\n",
		   orig_io_req, orig_io_req->xid, srr_req->xid, refcount);

	/* If a SRR times out, simply free resources */
	if (srr_req->event == QEDF_IOREQ_EV_ELS_TMO)
		goto out_free;

	/* Normalize response data into struct fc_frame */
	mp_req = &(srr_req->mp_req);
	mp_fc_hdr = &(mp_req->resp_fc_hdr);
	resp_len = mp_req->resp_len;
	resp_buf = mp_req->resp_buf;

	fp = fc_frame_alloc(lport, resp_len);
	if (!fp) {
		QEDF_ERR(&(qedf->dbg_ctx),
		    "fc_frame_alloc failure.\n");
		goto out_free;
	}

	/* Copy frame header from firmware into fp */
	fh = (struct fc_frame_header *)fc_frame_header_get(fp);
	memcpy(fh, mp_fc_hdr, sizeof(struct fc_frame_header));

	/* Copy payload from firmware into fp */
	fc_payload = fc_frame_payload_get(fp, resp_len);
	memcpy(fc_payload, resp_buf, resp_len);

	opcode = fc_frame_payload_op(fp);
	switch (opcode) {
	case ELS_LS_ACC:
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
		    "SRR success.\n");
		break;
	case ELS_LS_RJT:
		QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_ELS,
		    "SRR rejected.\n");
		qedf_initiate_abts(orig_io_req, true);
		break;
	}

	fc_frame_free(fp);
out_free:
	/* Put reference for original command since SRR completed */
	kref_put(&orig_io_req->refcount, qedf_release_cmd);
	kfree(cb_arg);
}

static int qedf_send_srr(struct qedf_ioreq *orig_io_req, u32 offset, u8 r_ctl)
{
	struct fcp_srr srr;
	struct qedf_ctx *qedf;
	struct qedf_rport *fcport;
	struct fc_lport *lport;
	struct qedf_els_cb_arg *cb_arg = NULL;
	u32 sid, r_a_tov;
	int rc;

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

	fcport = orig_io_req->fcport;

	/* 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 -EINVAL;
	}

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

	/* Take reference until SRR command completion */
	kref_get(&orig_io_req->refcount);

	qedf = fcport->qedf;
	lport = qedf->lport;
	sid = fcport->sid;
	r_a_tov = lport->r_a_tov;

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Sending SRR orig_io=%p, "
		   "orig_xid=0x%x\n", orig_io_req, orig_io_req->xid);
	memset(&srr, 0, sizeof(srr));

	cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO);
	if (!cb_arg) {
		QEDF_ERR(&(qedf->dbg_ctx), "Unable to allocate cb_arg for "
			  "SRR\n");
		rc = -ENOMEM;
		goto srr_err;
	}

	cb_arg->aborted_io_req = orig_io_req;

	srr.srr_op = ELS_SRR;
	srr.srr_ox_id = htons(orig_io_req->xid);
	srr.srr_rx_id = htons(orig_io_req->rx_id);
	srr.srr_rel_off = htonl(offset);
	srr.srr_r_ctl = r_ctl;

	rc = qedf_initiate_els(fcport, ELS_SRR, &srr, sizeof(srr),
	    qedf_srr_compl, cb_arg, r_a_tov);

srr_err:
	if (rc) {
		QEDF_ERR(&(qedf->dbg_ctx), "SRR failed - release orig_io_req"
			  "=0x%x\n", orig_io_req->xid);
		kfree(cb_arg);
		/* If we fail to queue SRR, send ABTS to orig_io */
		qedf_initiate_abts(orig_io_req, true);
		kref_put(&orig_io_req->refcount, qedf_release_cmd);
	} else
		/* Tell other threads that SRR is in progress */
		set_bit(QEDF_CMD_SRR_SENT, &orig_io_req->flags);

	return rc;
}

static void qedf_initiate_seq_cleanup(struct qedf_ioreq *orig_io_req,
	u32 offset, u8 r_ctl)
{
	struct qedf_rport *fcport;
	unsigned long flags;
	struct qedf_els_cb_arg *cb_arg;

	fcport = orig_io_req->fcport;

	QEDF_INFO(&(fcport->qedf->dbg_ctx), QEDF_LOG_ELS,
	    "Doing sequence cleanup for xid=0x%x offset=%u.\n",
	    orig_io_req->xid, offset);

	cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO);
	if (!cb_arg) {
		QEDF_ERR(&(fcport->qedf->dbg_ctx), "Unable to allocate cb_arg "
			  "for sequence cleanup\n");
		return;
	}

	/* Get reference for cleanup request */
	kref_get(&orig_io_req->refcount);

	orig_io_req->cmd_type = QEDF_SEQ_CLEANUP;
	cb_arg->offset = offset;
	cb_arg->r_ctl = r_ctl;
	orig_io_req->cb_arg = cb_arg;

	qedf_cmd_timer_set(fcport->qedf, orig_io_req,
	    QEDF_CLEANUP_TIMEOUT * HZ);

	spin_lock_irqsave(&fcport->rport_lock, flags);

	qedf_add_to_sq(fcport, orig_io_req->xid, 0,
	    FCOE_TASK_TYPE_SEQUENCE_CLEANUP, offset);
	qedf_ring_doorbell(fcport);

	spin_unlock_irqrestore(&fcport->rport_lock, flags);
}

void qedf_process_seq_cleanup_compl(struct qedf_ctx *qedf,
	struct fcoe_cqe *cqe, struct qedf_ioreq *io_req)
{
	int rc;
	struct qedf_els_cb_arg *cb_arg;

	cb_arg = io_req->cb_arg;

	/* If we timed out just free resources */
	if (io_req->event == QEDF_IOREQ_EV_ELS_TMO || !cqe)
		goto free;

	/* Kill the timer we put on the request */
	cancel_delayed_work_sync(&io_req->timeout_work);

	rc = qedf_send_srr(io_req, cb_arg->offset, cb_arg->r_ctl);
	if (rc)
		QEDF_ERR(&(qedf->dbg_ctx), "Unable to send SRR, I/O will "
		    "abort, xid=0x%x.\n", io_req->xid);
free:
	kfree(cb_arg);
	kref_put(&io_req->refcount, qedf_release_cmd);
}

static bool qedf_requeue_io_req(struct qedf_ioreq *orig_io_req)
{
	struct qedf_rport *fcport;
	struct qedf_ioreq *new_io_req;
	unsigned long flags;
	bool rc = false;

	fcport = orig_io_req->fcport;
	if (!fcport) {
		QEDF_ERR(NULL, "fcport is NULL.\n");
		goto out;
	}

	if (!orig_io_req->sc_cmd) {
		QEDF_ERR(&(fcport->qedf->dbg_ctx), "sc_cmd is NULL for "
		    "xid=0x%x.\n", orig_io_req->xid);
		goto out;
	}

	new_io_req = qedf_alloc_cmd(fcport, QEDF_SCSI_CMD);
	if (!new_io_req) {
		QEDF_ERR(&(fcport->qedf->dbg_ctx), "Could not allocate new "
		    "io_req.\n");
		goto out;
	}

	new_io_req->sc_cmd = orig_io_req->sc_cmd;

	/*
	 * This keeps the sc_cmd struct from being returned to the tape
	 * driver and being requeued twice. We do need to put a reference
	 * for the original I/O request since we will not do a SCSI completion
	 * for it.
	 */
	orig_io_req->sc_cmd = NULL;
	kref_put(&orig_io_req->refcount, qedf_release_cmd);

	spin_lock_irqsave(&fcport->rport_lock, flags);

	/* kref for new command released in qedf_post_io_req on error */
	if (qedf_post_io_req(fcport, new_io_req)) {
		QEDF_ERR(&(fcport->qedf->dbg_ctx), "Unable to post io_req\n");
		/* Return SQE to pool */
		atomic_inc(&fcport->free_sqes);
	} else {
		QEDF_INFO(&(fcport->qedf->dbg_ctx), QEDF_LOG_ELS,
		    "Reissued SCSI command from  orig_xid=0x%x on "
		    "new_xid=0x%x.\n", orig_io_req->xid, new_io_req->xid);
		/*
		 * Abort the original I/O but do not return SCSI command as
		 * it has been reissued on another OX_ID.
		 */
		spin_unlock_irqrestore(&fcport->rport_lock, flags);
		qedf_initiate_abts(orig_io_req, false);
		goto out;
	}

	spin_unlock_irqrestore(&fcport->rport_lock, flags);
out:
	return rc;
}


static void qedf_rec_compl(struct qedf_els_cb_arg *cb_arg)
{
	struct qedf_ioreq *orig_io_req;
	struct qedf_ioreq *rec_req;
	struct qedf_mp_req *mp_req;
	struct fc_frame_header *mp_fc_hdr, *fh;
	struct fc_frame *fp;
	void *resp_buf, *fc_payload;
	u32 resp_len;
	struct fc_lport *lport;
	struct qedf_ctx *qedf;
	int refcount;
	enum fc_rctl r_ctl;
	struct fc_els_ls_rjt *rjt;
	struct fc_els_rec_acc *acc;
	u8 opcode;
	u32 offset, e_stat;
	struct scsi_cmnd *sc_cmd;
	bool srr_needed = false;

	rec_req = cb_arg->io_req;
	qedf = rec_req->fcport->qedf;
	lport = qedf->lport;

	orig_io_req = cb_arg->aborted_io_req;

	if (!orig_io_req)
		goto out_free;

	if (rec_req->event != QEDF_IOREQ_EV_ELS_TMO &&
	    rec_req->event != QEDF_IOREQ_EV_ELS_ERR_DETECT)
		cancel_delayed_work_sync(&orig_io_req->timeout_work);

	refcount = kref_read(&orig_io_req->refcount);
	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Entered: orig_io=%p,"
		   " orig_io_xid=0x%x, rec_xid=0x%x, refcount=%d\n",
		   orig_io_req, orig_io_req->xid, rec_req->xid, refcount);

	/* If a REC times out, free resources */
	if (rec_req->event == QEDF_IOREQ_EV_ELS_TMO)
		goto out_free;

	/* Normalize response data into struct fc_frame */
	mp_req = &(rec_req->mp_req);
	mp_fc_hdr = &(mp_req->resp_fc_hdr);
	resp_len = mp_req->resp_len;
	acc = resp_buf = mp_req->resp_buf;

	fp = fc_frame_alloc(lport, resp_len);
	if (!fp) {
		QEDF_ERR(&(qedf->dbg_ctx),
		    "fc_frame_alloc failure.\n");
		goto out_free;
	}

	/* Copy frame header from firmware into fp */
	fh = (struct fc_frame_header *)fc_frame_header_get(fp);
	memcpy(fh, mp_fc_hdr, sizeof(struct fc_frame_header));

	/* Copy payload from firmware into fp */
	fc_payload = fc_frame_payload_get(fp, resp_len);
	memcpy(fc_payload, resp_buf, resp_len);

	opcode = fc_frame_payload_op(fp);
	if (opcode == ELS_LS_RJT) {
		rjt = fc_frame_payload_get(fp, sizeof(*rjt));
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
		    "Received LS_RJT for REC: er_reason=0x%x, "
		    "er_explan=0x%x.\n", rjt->er_reason, rjt->er_explan);
		/*
		 * The following response(s) mean that we need to reissue the
		 * request on another exchange.  We need to do this without
		 * informing the upper layers lest it cause an application
		 * error.
		 */
		if ((rjt->er_reason == ELS_RJT_LOGIC ||
		    rjt->er_reason == ELS_RJT_UNAB) &&
		    rjt->er_explan == ELS_EXPL_OXID_RXID) {
			QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
			    "Handle CMD LOST case.\n");
			qedf_requeue_io_req(orig_io_req);
		}
	} else if (opcode == ELS_LS_ACC) {
		offset = ntohl(acc->reca_fc4value);
		e_stat = ntohl(acc->reca_e_stat);
		QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
		    "Received LS_ACC for REC: offset=0x%x, e_stat=0x%x.\n",
		    offset, e_stat);
		if (e_stat & ESB_ST_SEQ_INIT)  {
			QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
			    "Target has the seq init\n");
			goto out_free_frame;
		}
		sc_cmd = orig_io_req->sc_cmd;
		if (!sc_cmd) {
			QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
			    "sc_cmd is NULL for xid=0x%x.\n",
			    orig_io_req->xid);
			goto out_free_frame;
		}
		/* SCSI write case */
		if (sc_cmd->sc_data_direction == DMA_TO_DEVICE) {
			if (offset == orig_io_req->data_xfer_len) {
				QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
				    "WRITE - response lost.\n");
				r_ctl = FC_RCTL_DD_CMD_STATUS;
				srr_needed = true;
				offset = 0;
			} else {
				QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
				    "WRITE - XFER_RDY/DATA lost.\n");
				r_ctl = FC_RCTL_DD_DATA_DESC;
				/* Use data from warning CQE instead of REC */
				offset = orig_io_req->tx_buf_off;
			}
		/* SCSI read case */
		} else {
			if (orig_io_req->rx_buf_off ==
			    orig_io_req->data_xfer_len) {
				QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
				    "READ - response lost.\n");
				srr_needed = true;
				r_ctl = FC_RCTL_DD_CMD_STATUS;
				offset = 0;
			} else {
				QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS,
				    "READ - DATA lost.\n");
				/*
				 * For read case we always set the offset to 0
				 * for sequence recovery task.
				 */
				offset = 0;
				r_ctl = FC_RCTL_DD_SOL_DATA;
			}
		}

		if (srr_needed)
			qedf_send_srr(orig_io_req, offset, r_ctl);
		else
			qedf_initiate_seq_cleanup(orig_io_req, offset, r_ctl);
	}

out_free_frame:
	fc_frame_free(fp);
out_free:
	/* Put reference for original command since REC completed */
	kref_put(&orig_io_req->refcount, qedf_release_cmd);
	kfree(cb_arg);
}

/* Assumes kref is already held by caller */
int qedf_send_rec(struct qedf_ioreq *orig_io_req)
{

	struct fc_els_rec rec;
	struct qedf_rport *fcport;
	struct fc_lport *lport;
	struct qedf_els_cb_arg *cb_arg = NULL;
	struct qedf_ctx *qedf;
	uint32_t sid;
	uint32_t r_a_tov;
	int rc;

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

	fcport = orig_io_req->fcport;

	/* 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 -EINVAL;
	}

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

	/* Take reference until REC command completion */
	kref_get(&orig_io_req->refcount);

	qedf = fcport->qedf;
	lport = qedf->lport;
	sid = fcport->sid;
	r_a_tov = lport->r_a_tov;

	memset(&rec, 0, sizeof(rec));

	cb_arg = kzalloc(sizeof(struct qedf_els_cb_arg), GFP_NOIO);
	if (!cb_arg) {
		QEDF_ERR(&(qedf->dbg_ctx), "Unable to allocate cb_arg for "
			  "REC\n");
		rc = -ENOMEM;
		goto rec_err;
	}

	cb_arg->aborted_io_req = orig_io_req;

	rec.rec_cmd = ELS_REC;
	hton24(rec.rec_s_id, sid);
	rec.rec_ox_id = htons(orig_io_req->xid);
	rec.rec_rx_id =
	    htons(orig_io_req->task->tstorm_st_context.read_write.rx_id);

	QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_ELS, "Sending REC orig_io=%p, "
	   "orig_xid=0x%x rx_id=0x%x\n", orig_io_req,
	   orig_io_req->xid, rec.rec_rx_id);
	rc = qedf_initiate_els(fcport, ELS_REC, &rec, sizeof(rec),
	    qedf_rec_compl, cb_arg, r_a_tov);

rec_err:
	if (rc) {
		QEDF_ERR(&(qedf->dbg_ctx), "REC failed - release orig_io_req"
			  "=0x%x\n", orig_io_req->xid);
		kfree(cb_arg);
		kref_put(&orig_io_req->refcount, qedf_release_cmd);
	}
	return rc;
}
