// SPDX-License-Identifier: GPL-2.0-only
/*
 * QLogic Fibre Channel HBA Driver
 * Copyright (c)  2003-2017 QLogic Corporation
 */
#include "qla_nvme.h"
#include <linux/scatterlist.h>
#include <linux/delay.h>
#include <linux/nvme.h>
#include <linux/nvme-fc.h>
#include <linux/blk-mq-pci.h>
#include <linux/blk-mq.h>

static struct nvme_fc_port_template qla_nvme_fc_transport;

int qla_nvme_register_remote(struct scsi_qla_host *vha, struct fc_port *fcport)
{
	struct qla_nvme_rport *rport;
	struct nvme_fc_port_info req;
	int ret;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return 0;

	if (!vha->flags.nvme_enabled) {
		ql_log(ql_log_info, vha, 0x2100,
		    "%s: Not registering target since Host NVME is not enabled\n",
		    __func__);
		return 0;
	}

	if (!vha->nvme_local_port && qla_nvme_register_hba(vha))
		return 0;

	if (!(fcport->nvme_prli_service_param &
	    (NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)) ||
		(fcport->nvme_flag & NVME_FLAG_REGISTERED))
		return 0;

	fcport->nvme_flag &= ~NVME_FLAG_RESETTING;

	memset(&req, 0, sizeof(struct nvme_fc_port_info));
	req.port_name = wwn_to_u64(fcport->port_name);
	req.node_name = wwn_to_u64(fcport->node_name);
	req.port_role = 0;
	req.dev_loss_tmo = fcport->dev_loss_tmo;

	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_INITIATOR)
		req.port_role = FC_PORT_ROLE_NVME_INITIATOR;

	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_TARGET)
		req.port_role |= FC_PORT_ROLE_NVME_TARGET;

	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_DISCOVERY)
		req.port_role |= FC_PORT_ROLE_NVME_DISCOVERY;

	req.port_id = fcport->d_id.b24;

	ql_log(ql_log_info, vha, 0x2102,
	    "%s: traddr=nn-0x%016llx:pn-0x%016llx PortID:%06x\n",
	    __func__, req.node_name, req.port_name,
	    req.port_id);

	ret = nvme_fc_register_remoteport(vha->nvme_local_port, &req,
	    &fcport->nvme_remote_port);
	if (ret) {
		ql_log(ql_log_warn, vha, 0x212e,
		    "Failed to register remote port. Transport returned %d\n",
		    ret);
		return ret;
	}

	nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port,
				       fcport->dev_loss_tmo);

	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_SLER)
		ql_log(ql_log_info, vha, 0x212a,
		       "PortID:%06x Supports SLER\n", req.port_id);

	if (fcport->nvme_prli_service_param & NVME_PRLI_SP_PI_CTRL)
		ql_log(ql_log_info, vha, 0x212b,
		       "PortID:%06x Supports PI control\n", req.port_id);

	rport = fcport->nvme_remote_port->private;
	rport->fcport = fcport;

	fcport->nvme_flag |= NVME_FLAG_REGISTERED;
	return 0;
}

/* Allocate a queue for NVMe traffic */
static int qla_nvme_alloc_queue(struct nvme_fc_local_port *lport,
    unsigned int qidx, u16 qsize, void **handle)
{
	struct scsi_qla_host *vha;
	struct qla_hw_data *ha;
	struct qla_qpair *qpair;

	/* Map admin queue and 1st IO queue to index 0 */
	if (qidx)
		qidx--;

	vha = (struct scsi_qla_host *)lport->private;
	ha = vha->hw;

	ql_log(ql_log_info, vha, 0x2104,
	    "%s: handle %p, idx =%d, qsize %d\n",
	    __func__, handle, qidx, qsize);

	if (qidx > qla_nvme_fc_transport.max_hw_queues) {
		ql_log(ql_log_warn, vha, 0x212f,
		    "%s: Illegal qidx=%d. Max=%d\n",
		    __func__, qidx, qla_nvme_fc_transport.max_hw_queues);
		return -EINVAL;
	}

	/* Use base qpair if max_qpairs is 0 */
	if (!ha->max_qpairs) {
		qpair = ha->base_qpair;
	} else {
		if (ha->queue_pair_map[qidx]) {
			*handle = ha->queue_pair_map[qidx];
			ql_log(ql_log_info, vha, 0x2121,
			       "Returning existing qpair of %p for idx=%x\n",
			       *handle, qidx);
			return 0;
		}

		qpair = qla2xxx_create_qpair(vha, 5, vha->vp_idx, true);
		if (!qpair) {
			ql_log(ql_log_warn, vha, 0x2122,
			       "Failed to allocate qpair\n");
			return -EINVAL;
		}
	}
	*handle = qpair;

	return 0;
}

static void qla_nvme_release_fcp_cmd_kref(struct kref *kref)
{
	struct srb *sp = container_of(kref, struct srb, cmd_kref);
	struct nvme_private *priv = (struct nvme_private *)sp->priv;
	struct nvmefc_fcp_req *fd;
	struct srb_iocb *nvme;
	unsigned long flags;

	if (!priv)
		goto out;

	nvme = &sp->u.iocb_cmd;
	fd = nvme->u.nvme.desc;

	spin_lock_irqsave(&priv->cmd_lock, flags);
	priv->sp = NULL;
	sp->priv = NULL;
	if (priv->comp_status == QLA_SUCCESS) {
		fd->rcv_rsplen = le16_to_cpu(nvme->u.nvme.rsp_pyld_len);
		fd->status = NVME_SC_SUCCESS;
	} else {
		fd->rcv_rsplen = 0;
		fd->transferred_length = 0;
		fd->status = NVME_SC_INTERNAL;
	}
	spin_unlock_irqrestore(&priv->cmd_lock, flags);

	fd->done(fd);
out:
	qla2xxx_rel_qpair_sp(sp->qpair, sp);
}

static void qla_nvme_ls_unmap(struct srb *sp, struct nvmefc_ls_req *fd)
{
	if (sp->flags & SRB_DMA_VALID) {
		struct srb_iocb *nvme = &sp->u.iocb_cmd;
		struct qla_hw_data *ha = sp->fcport->vha->hw;

		dma_unmap_single(&ha->pdev->dev, nvme->u.nvme.cmd_dma,
				 fd->rqstlen, DMA_TO_DEVICE);
		sp->flags &= ~SRB_DMA_VALID;
	}
}

static void qla_nvme_release_ls_cmd_kref(struct kref *kref)
{
	struct srb *sp = container_of(kref, struct srb, cmd_kref);
	struct nvme_private *priv = (struct nvme_private *)sp->priv;
	struct nvmefc_ls_req *fd;
	unsigned long flags;

	if (!priv)
		goto out;

	spin_lock_irqsave(&priv->cmd_lock, flags);
	priv->sp = NULL;
	sp->priv = NULL;
	spin_unlock_irqrestore(&priv->cmd_lock, flags);

	fd = priv->fd;

	qla_nvme_ls_unmap(sp, fd);
	fd->done(fd, priv->comp_status);
out:
	qla2x00_rel_sp(sp);
}

static void qla_nvme_ls_complete(struct work_struct *work)
{
	struct nvme_private *priv =
		container_of(work, struct nvme_private, ls_work);

	kref_put(&priv->sp->cmd_kref, qla_nvme_release_ls_cmd_kref);
}

static void qla_nvme_sp_ls_done(srb_t *sp, int res)
{
	struct nvme_private *priv = sp->priv;

	if (WARN_ON_ONCE(kref_read(&sp->cmd_kref) == 0))
		return;

	if (res)
		res = -EINVAL;

	priv->comp_status = res;
	INIT_WORK(&priv->ls_work, qla_nvme_ls_complete);
	schedule_work(&priv->ls_work);
}

/* it assumed that QPair lock is held. */
static void qla_nvme_sp_done(srb_t *sp, int res)
{
	struct nvme_private *priv = sp->priv;

	priv->comp_status = res;
	kref_put(&sp->cmd_kref, qla_nvme_release_fcp_cmd_kref);

	return;
}

static void qla_nvme_abort_work(struct work_struct *work)
{
	struct nvme_private *priv =
		container_of(work, struct nvme_private, abort_work);
	srb_t *sp = priv->sp;
	fc_port_t *fcport = sp->fcport;
	struct qla_hw_data *ha = fcport->vha->hw;
	int rval, abts_done_called = 1;
	bool io_wait_for_abort_done;
	uint32_t handle;

	ql_dbg(ql_dbg_io, fcport->vha, 0xffff,
	       "%s called for sp=%p, hndl=%x on fcport=%p desc=%p deleted=%d\n",
	       __func__, sp, sp->handle, fcport, sp->u.iocb_cmd.u.nvme.desc, fcport->deleted);

	if (!ha->flags.fw_started || fcport->deleted == QLA_SESS_DELETED)
		goto out;

	if (ha->flags.host_shutting_down) {
		ql_log(ql_log_info, sp->fcport->vha, 0xffff,
		    "%s Calling done on sp: %p, type: 0x%x\n",
		    __func__, sp, sp->type);
		sp->done(sp, 0);
		goto out;
	}

	/*
	 * sp may not be valid after abort_command if return code is either
	 * SUCCESS or ERR_FROM_FW codes, so cache the value here.
	 */
	io_wait_for_abort_done = ql2xabts_wait_nvme &&
					QLA_ABTS_WAIT_ENABLED(sp);
	handle = sp->handle;

	rval = ha->isp_ops->abort_command(sp);

	ql_dbg(ql_dbg_io, fcport->vha, 0x212b,
	    "%s: %s command for sp=%p, handle=%x on fcport=%p rval=%x\n",
	    __func__, (rval != QLA_SUCCESS) ? "Failed to abort" : "Aborted",
	    sp, handle, fcport, rval);

	/*
	 * If async tmf is enabled, the abort callback is called only on
	 * return codes QLA_SUCCESS and QLA_ERR_FROM_FW.
	 */
	if (ql2xasynctmfenable &&
	    rval != QLA_SUCCESS && rval != QLA_ERR_FROM_FW)
		abts_done_called = 0;

	/*
	 * Returned before decreasing kref so that I/O requests
	 * are waited until ABTS complete. This kref is decreased
	 * at qla24xx_abort_sp_done function.
	 */
	if (abts_done_called && io_wait_for_abort_done)
		return;
out:
	/* kref_get was done before work was schedule. */
	kref_put(&sp->cmd_kref, sp->put_fn);
}

static void qla_nvme_ls_abort(struct nvme_fc_local_port *lport,
    struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd)
{
	struct nvme_private *priv = fd->private;
	unsigned long flags;

	spin_lock_irqsave(&priv->cmd_lock, flags);
	if (!priv->sp) {
		spin_unlock_irqrestore(&priv->cmd_lock, flags);
		return;
	}

	if (!kref_get_unless_zero(&priv->sp->cmd_kref)) {
		spin_unlock_irqrestore(&priv->cmd_lock, flags);
		return;
	}
	spin_unlock_irqrestore(&priv->cmd_lock, flags);

	INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
	schedule_work(&priv->abort_work);
}

static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
    struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd)
{
	struct qla_nvme_rport *qla_rport = rport->private;
	fc_port_t *fcport = qla_rport->fcport;
	struct srb_iocb   *nvme;
	struct nvme_private *priv = fd->private;
	struct scsi_qla_host *vha;
	int     rval = QLA_FUNCTION_FAILED;
	struct qla_hw_data *ha;
	srb_t           *sp;

	if (!fcport || fcport->deleted)
		return rval;

	vha = fcport->vha;
	ha = vha->hw;

	if (!ha->flags.fw_started)
		return rval;

	/* Alloc SRB structure */
	sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
	if (!sp)
		return rval;

	sp->type = SRB_NVME_LS;
	sp->name = "nvme_ls";
	sp->done = qla_nvme_sp_ls_done;
	sp->put_fn = qla_nvme_release_ls_cmd_kref;
	sp->priv = priv;
	priv->sp = sp;
	kref_init(&sp->cmd_kref);
	spin_lock_init(&priv->cmd_lock);
	nvme = &sp->u.iocb_cmd;
	priv->fd = fd;
	nvme->u.nvme.desc = fd;
	nvme->u.nvme.dir = 0;
	nvme->u.nvme.dl = 0;
	nvme->u.nvme.cmd_len = fd->rqstlen;
	nvme->u.nvme.rsp_len = fd->rsplen;
	nvme->u.nvme.rsp_dma = fd->rspdma;
	nvme->u.nvme.timeout_sec = fd->timeout;
	nvme->u.nvme.cmd_dma = dma_map_single(&ha->pdev->dev, fd->rqstaddr,
	    fd->rqstlen, DMA_TO_DEVICE);
	dma_sync_single_for_device(&ha->pdev->dev, nvme->u.nvme.cmd_dma,
	    fd->rqstlen, DMA_TO_DEVICE);

	sp->flags |= SRB_DMA_VALID;

	rval = qla2x00_start_sp(sp);
	if (rval != QLA_SUCCESS) {
		ql_log(ql_log_warn, vha, 0x700e,
		    "qla2x00_start_sp failed = %d\n", rval);
		wake_up(&sp->nvme_ls_waitq);
		sp->priv = NULL;
		priv->sp = NULL;
		qla_nvme_ls_unmap(sp, fd);
		qla2x00_rel_sp(sp);
		return rval;
	}

	return rval;
}

static void qla_nvme_fcp_abort(struct nvme_fc_local_port *lport,
    struct nvme_fc_remote_port *rport, void *hw_queue_handle,
    struct nvmefc_fcp_req *fd)
{
	struct nvme_private *priv = fd->private;
	unsigned long flags;

	spin_lock_irqsave(&priv->cmd_lock, flags);
	if (!priv->sp) {
		spin_unlock_irqrestore(&priv->cmd_lock, flags);
		return;
	}
	if (!kref_get_unless_zero(&priv->sp->cmd_kref)) {
		spin_unlock_irqrestore(&priv->cmd_lock, flags);
		return;
	}
	spin_unlock_irqrestore(&priv->cmd_lock, flags);

	INIT_WORK(&priv->abort_work, qla_nvme_abort_work);
	schedule_work(&priv->abort_work);
}

static inline int qla2x00_start_nvme_mq(srb_t *sp)
{
	unsigned long   flags;
	uint32_t        *clr_ptr;
	uint32_t        handle;
	struct cmd_nvme *cmd_pkt;
	uint16_t        cnt, i;
	uint16_t        req_cnt;
	uint16_t        tot_dsds;
	uint16_t	avail_dsds;
	struct dsd64	*cur_dsd;
	struct req_que *req = NULL;
	struct rsp_que *rsp = NULL;
	struct scsi_qla_host *vha = sp->fcport->vha;
	struct qla_hw_data *ha = vha->hw;
	struct qla_qpair *qpair = sp->qpair;
	struct srb_iocb *nvme = &sp->u.iocb_cmd;
	struct scatterlist *sgl, *sg;
	struct nvmefc_fcp_req *fd = nvme->u.nvme.desc;
	struct nvme_fc_cmd_iu *cmd = fd->cmdaddr;
	uint32_t        rval = QLA_SUCCESS;

	/* Setup qpair pointers */
	req = qpair->req;
	rsp = qpair->rsp;
	tot_dsds = fd->sg_cnt;

	/* Acquire qpair specific lock */
	spin_lock_irqsave(&qpair->qp_lock, flags);

	handle = qla2xxx_get_next_handle(req);
	if (handle == 0) {
		rval = -EBUSY;
		goto queuing_error;
	}
	req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
	if (req->cnt < (req_cnt + 2)) {
		if (IS_SHADOW_REG_CAPABLE(ha)) {
			cnt = *req->out_ptr;
		} else {
			cnt = rd_reg_dword_relaxed(req->req_q_out);
			if (qla2x00_check_reg16_for_disconnect(vha, cnt))
				goto queuing_error;
		}

		if (req->ring_index < cnt)
			req->cnt = cnt - req->ring_index;
		else
			req->cnt = req->length - (req->ring_index - cnt);

		if (req->cnt < (req_cnt + 2)){
			rval = -EBUSY;
			goto queuing_error;
		}
	}

	if (unlikely(!fd->sqid)) {
		if (cmd->sqe.common.opcode == nvme_admin_async_event) {
			nvme->u.nvme.aen_op = 1;
			atomic_inc(&ha->nvme_active_aen_cnt);
		}
	}

	/* Build command packet. */
	req->current_outstanding_cmd = handle;
	req->outstanding_cmds[handle] = sp;
	sp->handle = handle;
	req->cnt -= req_cnt;

	cmd_pkt = (struct cmd_nvme *)req->ring_ptr;
	cmd_pkt->handle = make_handle(req->id, handle);

	/* Zero out remaining portion of packet. */
	clr_ptr = (uint32_t *)cmd_pkt + 2;
	memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);

	cmd_pkt->entry_status = 0;

	/* Update entry type to indicate Command NVME IOCB */
	cmd_pkt->entry_type = COMMAND_NVME;

	/* No data transfer how do we check buffer len == 0?? */
	if (fd->io_dir == NVMEFC_FCP_READ) {
		cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA);
		qpair->counters.input_bytes += fd->payload_length;
		qpair->counters.input_requests++;
	} else if (fd->io_dir == NVMEFC_FCP_WRITE) {
		cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA);
		if ((vha->flags.nvme_first_burst) &&
		    (sp->fcport->nvme_prli_service_param &
			NVME_PRLI_SP_FIRST_BURST)) {
			if ((fd->payload_length <=
			    sp->fcport->nvme_first_burst_size) ||
				(sp->fcport->nvme_first_burst_size == 0))
				cmd_pkt->control_flags |=
					cpu_to_le16(CF_NVME_FIRST_BURST_ENABLE);
		}
		qpair->counters.output_bytes += fd->payload_length;
		qpair->counters.output_requests++;
	} else if (fd->io_dir == 0) {
		cmd_pkt->control_flags = 0;
	}

	if (sp->fcport->edif.enable && fd->io_dir != 0)
		cmd_pkt->control_flags |= cpu_to_le16(CF_EN_EDIF);

	/* Set BIT_13 of control flags for Async event */
	if (vha->flags.nvme2_enabled &&
	    cmd->sqe.common.opcode == nvme_admin_async_event) {
		cmd_pkt->control_flags |= cpu_to_le16(CF_ADMIN_ASYNC_EVENT);
	}

	/* Set NPORT-ID */
	cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
	cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
	cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
	cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
	cmd_pkt->vp_index = sp->fcport->vha->vp_idx;

	/* NVME RSP IU */
	cmd_pkt->nvme_rsp_dsd_len = cpu_to_le16(fd->rsplen);
	put_unaligned_le64(fd->rspdma, &cmd_pkt->nvme_rsp_dseg_address);

	/* NVME CNMD IU */
	cmd_pkt->nvme_cmnd_dseg_len = cpu_to_le16(fd->cmdlen);
	cmd_pkt->nvme_cmnd_dseg_address = cpu_to_le64(fd->cmddma);

	cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
	cmd_pkt->byte_count = cpu_to_le32(fd->payload_length);

	/* One DSD is available in the Command Type NVME IOCB */
	avail_dsds = 1;
	cur_dsd = &cmd_pkt->nvme_dsd;
	sgl = fd->first_sgl;

	/* Load data segments */
	for_each_sg(sgl, sg, tot_dsds, i) {
		cont_a64_entry_t *cont_pkt;

		/* Allocate additional continuation packets? */
		if (avail_dsds == 0) {
			/*
			 * Five DSDs are available in the Continuation
			 * Type 1 IOCB.
			 */

			/* Adjust ring index */
			req->ring_index++;
			if (req->ring_index == req->length) {
				req->ring_index = 0;
				req->ring_ptr = req->ring;
			} else {
				req->ring_ptr++;
			}
			cont_pkt = (cont_a64_entry_t *)req->ring_ptr;
			put_unaligned_le32(CONTINUE_A64_TYPE,
					   &cont_pkt->entry_type);

			cur_dsd = cont_pkt->dsd;
			avail_dsds = ARRAY_SIZE(cont_pkt->dsd);
		}

		append_dsd64(&cur_dsd, sg);
		avail_dsds--;
	}

	/* Set total entry count. */
	cmd_pkt->entry_count = (uint8_t)req_cnt;
	wmb();

	/* Adjust ring index. */
	req->ring_index++;
	if (req->ring_index == req->length) {
		req->ring_index = 0;
		req->ring_ptr = req->ring;
	} else {
		req->ring_ptr++;
	}

	/* ignore nvme async cmd due to long timeout */
	if (!nvme->u.nvme.aen_op)
		sp->qpair->cmd_cnt++;

	/* Set chip new ring index. */
	wrt_reg_dword(req->req_q_in, req->ring_index);

	if (vha->flags.process_response_queue &&
	    rsp->ring_ptr->signature != RESPONSE_PROCESSED)
		qla24xx_process_response_queue(vha, rsp);

queuing_error:
	spin_unlock_irqrestore(&qpair->qp_lock, flags);

	return rval;
}

/* Post a command */
static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
    struct nvme_fc_remote_port *rport, void *hw_queue_handle,
    struct nvmefc_fcp_req *fd)
{
	fc_port_t *fcport;
	struct srb_iocb *nvme;
	struct scsi_qla_host *vha;
	int rval;
	srb_t *sp;
	struct qla_qpair *qpair = hw_queue_handle;
	struct nvme_private *priv = fd->private;
	struct qla_nvme_rport *qla_rport = rport->private;

	if (!priv) {
		/* nvme association has been torn down */
		return -ENODEV;
	}

	fcport = qla_rport->fcport;

	if (unlikely(!qpair || !fcport || fcport->deleted))
		return -EBUSY;

	if (!(fcport->nvme_flag & NVME_FLAG_REGISTERED))
		return -ENODEV;

	vha = fcport->vha;

	if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
		return -EBUSY;

	/*
	 * If we know the dev is going away while the transport is still sending
	 * IO's return busy back to stall the IO Q.  This happens when the
	 * link goes away and fw hasn't notified us yet, but IO's are being
	 * returned. If the dev comes back quickly we won't exhaust the IO
	 * retry count at the core.
	 */
	if (fcport->nvme_flag & NVME_FLAG_RESETTING)
		return -EBUSY;

	/* Alloc SRB structure */
	sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC);
	if (!sp)
		return -EBUSY;

	init_waitqueue_head(&sp->nvme_ls_waitq);
	kref_init(&sp->cmd_kref);
	spin_lock_init(&priv->cmd_lock);
	sp->priv = priv;
	priv->sp = sp;
	sp->type = SRB_NVME_CMD;
	sp->name = "nvme_cmd";
	sp->done = qla_nvme_sp_done;
	sp->put_fn = qla_nvme_release_fcp_cmd_kref;
	sp->qpair = qpair;
	sp->vha = vha;
	sp->cmd_sp = sp;
	nvme = &sp->u.iocb_cmd;
	nvme->u.nvme.desc = fd;

	rval = qla2x00_start_nvme_mq(sp);
	if (rval != QLA_SUCCESS) {
		ql_log(ql_log_warn, vha, 0x212d,
		    "qla2x00_start_nvme_mq failed = %d\n", rval);
		wake_up(&sp->nvme_ls_waitq);
		sp->priv = NULL;
		priv->sp = NULL;
		qla2xxx_rel_qpair_sp(sp->qpair, sp);
	}

	return rval;
}

static void qla_nvme_map_queues(struct nvme_fc_local_port *lport,
		struct blk_mq_queue_map *map)
{
	struct scsi_qla_host *vha = lport->private;
	int rc;

	rc = blk_mq_pci_map_queues(map, vha->hw->pdev, vha->irq_offset);
	if (rc)
		ql_log(ql_log_warn, vha, 0x21de,
		       "pci map queue failed 0x%x", rc);
}

static void qla_nvme_localport_delete(struct nvme_fc_local_port *lport)
{
	struct scsi_qla_host *vha = lport->private;

	ql_log(ql_log_info, vha, 0x210f,
	    "localport delete of %p completed.\n", vha->nvme_local_port);
	vha->nvme_local_port = NULL;
	complete(&vha->nvme_del_done);
}

static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
{
	fc_port_t *fcport;
	struct qla_nvme_rport *qla_rport = rport->private;

	fcport = qla_rport->fcport;
	fcport->nvme_remote_port = NULL;
	fcport->nvme_flag &= ~NVME_FLAG_REGISTERED;
	fcport->nvme_flag &= ~NVME_FLAG_DELETING;
	ql_log(ql_log_info, fcport->vha, 0x2110,
	    "remoteport_delete of %p %8phN completed.\n",
	    fcport, fcport->port_name);
	complete(&fcport->nvme_del_done);
}

static struct nvme_fc_port_template qla_nvme_fc_transport = {
	.localport_delete = qla_nvme_localport_delete,
	.remoteport_delete = qla_nvme_remoteport_delete,
	.create_queue   = qla_nvme_alloc_queue,
	.delete_queue 	= NULL,
	.ls_req		= qla_nvme_ls_req,
	.ls_abort	= qla_nvme_ls_abort,
	.fcp_io		= qla_nvme_post_cmd,
	.fcp_abort	= qla_nvme_fcp_abort,
	.map_queues	= qla_nvme_map_queues,
	.max_hw_queues  = DEF_NVME_HW_QUEUES,
	.max_sgl_segments = 1024,
	.max_dif_sgl_segments = 64,
	.dma_boundary = 0xFFFFFFFF,
	.local_priv_sz  = 8,
	.remote_priv_sz = sizeof(struct qla_nvme_rport),
	.lsrqst_priv_sz = sizeof(struct nvme_private),
	.fcprqst_priv_sz = sizeof(struct nvme_private),
};

void qla_nvme_unregister_remote_port(struct fc_port *fcport)
{
	int ret;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return;

	ql_log(ql_log_warn, fcport->vha, 0x2112,
	    "%s: unregister remoteport on %p %8phN\n",
	    __func__, fcport, fcport->port_name);

	if (test_bit(PFLG_DRIVER_REMOVING, &fcport->vha->pci_flags))
		nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0);

	init_completion(&fcport->nvme_del_done);
	ret = nvme_fc_unregister_remoteport(fcport->nvme_remote_port);
	if (ret)
		ql_log(ql_log_info, fcport->vha, 0x2114,
			"%s: Failed to unregister nvme_remote_port (%d)\n",
			    __func__, ret);
	wait_for_completion(&fcport->nvme_del_done);
}

void qla_nvme_delete(struct scsi_qla_host *vha)
{
	int nv_ret;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return;

	if (vha->nvme_local_port) {
		init_completion(&vha->nvme_del_done);
		ql_log(ql_log_info, vha, 0x2116,
			"unregister localport=%p\n",
			vha->nvme_local_port);
		nv_ret = nvme_fc_unregister_localport(vha->nvme_local_port);
		if (nv_ret)
			ql_log(ql_log_info, vha, 0x2115,
			    "Unregister of localport failed\n");
		else
			wait_for_completion(&vha->nvme_del_done);
	}
}

int qla_nvme_register_hba(struct scsi_qla_host *vha)
{
	struct nvme_fc_port_template *tmpl;
	struct qla_hw_data *ha;
	struct nvme_fc_port_info pinfo;
	int ret = -EINVAL;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return ret;

	ha = vha->hw;
	tmpl = &qla_nvme_fc_transport;

	if (ql2xnvme_queues < MIN_NVME_HW_QUEUES) {
		ql_log(ql_log_warn, vha, 0xfffd,
		    "ql2xnvme_queues=%d is lower than minimum queues: %d. Resetting ql2xnvme_queues to:%d\n",
		    ql2xnvme_queues, MIN_NVME_HW_QUEUES, DEF_NVME_HW_QUEUES);
		ql2xnvme_queues = DEF_NVME_HW_QUEUES;
	} else if (ql2xnvme_queues > (ha->max_qpairs - 1)) {
		ql_log(ql_log_warn, vha, 0xfffd,
		       "ql2xnvme_queues=%d is greater than available IRQs: %d. Resetting ql2xnvme_queues to: %d\n",
		       ql2xnvme_queues, (ha->max_qpairs - 1),
		       (ha->max_qpairs - 1));
		ql2xnvme_queues = ((ha->max_qpairs - 1));
	}

	qla_nvme_fc_transport.max_hw_queues =
	    min((uint8_t)(ql2xnvme_queues),
		(uint8_t)((ha->max_qpairs - 1) ? (ha->max_qpairs - 1) : 1));

	ql_log(ql_log_info, vha, 0xfffb,
	       "Number of NVME queues used for this port: %d\n",
	    qla_nvme_fc_transport.max_hw_queues);

	pinfo.node_name = wwn_to_u64(vha->node_name);
	pinfo.port_name = wwn_to_u64(vha->port_name);
	pinfo.port_role = FC_PORT_ROLE_NVME_INITIATOR;
	pinfo.port_id = vha->d_id.b24;

	mutex_lock(&ha->vport_lock);
	/*
	 * Check again for nvme_local_port to see if any other thread raced
	 * with this one and finished registration.
	 */
	if (!vha->nvme_local_port) {
		ql_log(ql_log_info, vha, 0xffff,
		    "register_localport: host-traddr=nn-0x%llx:pn-0x%llx on portID:%x\n",
		    pinfo.node_name, pinfo.port_name, pinfo.port_id);
		qla_nvme_fc_transport.dma_boundary = vha->host->dma_boundary;

		ret = nvme_fc_register_localport(&pinfo, tmpl,
						 get_device(&ha->pdev->dev),
						 &vha->nvme_local_port);
		mutex_unlock(&ha->vport_lock);
	} else {
		mutex_unlock(&ha->vport_lock);
		return 0;
	}
	if (ret) {
		ql_log(ql_log_warn, vha, 0xffff,
		    "register_localport failed: ret=%x\n", ret);
	} else {
		vha->nvme_local_port->private = vha;
	}

	return ret;
}

void qla_nvme_abort_set_option(struct abort_entry_24xx *abt, srb_t *orig_sp)
{
	struct qla_hw_data *ha;

	if (!(ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(orig_sp)))
		return;

	ha = orig_sp->fcport->vha->hw;

	WARN_ON_ONCE(abt->options & cpu_to_le16(BIT_0));
	/* Use Driver Specified Retry Count */
	abt->options |= cpu_to_le16(AOF_ABTS_RTY_CNT);
	abt->drv.abts_rty_cnt = cpu_to_le16(2);
	/* Use specified response timeout */
	abt->options |= cpu_to_le16(AOF_RSP_TIMEOUT);
	/* set it to 2 * r_a_tov in secs */
	abt->drv.rsp_timeout = cpu_to_le16(2 * (ha->r_a_tov / 10));
}

void qla_nvme_abort_process_comp_status(struct abort_entry_24xx *abt, srb_t *orig_sp)
{
	u16	comp_status;
	struct scsi_qla_host *vha;

	if (!(ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(orig_sp)))
		return;

	vha = orig_sp->fcport->vha;

	comp_status = le16_to_cpu(abt->comp_status);
	switch (comp_status) {
	case CS_RESET:		/* reset event aborted */
	case CS_ABORTED:	/* IOCB was cleaned */
	/* N_Port handle is not currently logged in */
	case CS_TIMEOUT:
	/* N_Port handle was logged out while waiting for ABTS to complete */
	case CS_PORT_UNAVAILABLE:
	/* Firmware found that the port name changed */
	case CS_PORT_LOGGED_OUT:
	/* BA_RJT was received for the ABTS */
	case CS_PORT_CONFIG_CHG:
		ql_dbg(ql_dbg_async, vha, 0xf09d,
		       "Abort I/O IOCB completed with error, comp_status=%x\n",
		comp_status);
		break;

	/* BA_RJT was received for the ABTS */
	case CS_REJECT_RECEIVED:
		ql_dbg(ql_dbg_async, vha, 0xf09e,
		       "BA_RJT was received for the ABTS rjt_vendorUnique = %u",
			abt->fw.ba_rjt_vendorUnique);
		ql_dbg(ql_dbg_async + ql_dbg_mbx, vha, 0xf09e,
		       "ba_rjt_reasonCodeExpl = %u, ba_rjt_reasonCode = %u\n",
		       abt->fw.ba_rjt_reasonCodeExpl, abt->fw.ba_rjt_reasonCode);
		break;

	case CS_COMPLETE:
		ql_dbg(ql_dbg_async + ql_dbg_verbose, vha, 0xf09f,
		       "IOCB request is completed successfully comp_status=%x\n",
		comp_status);
		break;

	case CS_IOCB_ERROR:
		ql_dbg(ql_dbg_async, vha, 0xf0a0,
		       "IOCB request is failed, comp_status=%x\n", comp_status);
		break;

	default:
		ql_dbg(ql_dbg_async, vha, 0xf0a1,
		       "Invalid Abort IO IOCB Completion Status %x\n",
		comp_status);
		break;
	}
}

inline void qla_wait_nvme_release_cmd_kref(srb_t *orig_sp)
{
	if (!(ql2xabts_wait_nvme && QLA_ABTS_WAIT_ENABLED(orig_sp)))
		return;
	kref_put(&orig_sp->cmd_kref, orig_sp->put_fn);
}
