/*
 * QLogic Fibre Channel HBA Driver
 * Copyright (c)  2003-2017 QLogic Corporation
 *
 * See LICENSE.qla2xxx for copyright and licensing details.
 */
#include "qla_nvme.h"
#include "qla_def.h"
#include <linux/scatterlist.h>
#include <linux/delay.h>
#include <linux/nvme.h>
#include <linux/nvme-fc.h>

static struct nvme_fc_port_template qla_nvme_fc_transport;

static void qla_nvme_unregister_remote_port(struct work_struct *);

int qla_nvme_register_remote(scsi_qla_host_t *vha, fc_port_t *fcport)
{
	struct nvme_rport *rport;
	int ret;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return 0;

	if (fcport->nvme_flag & NVME_FLAG_REGISTERED)
		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 (!(fcport->nvme_prli_service_param &
	    (NVME_PRLI_SP_TARGET | NVME_PRLI_SP_DISCOVERY)))
		return 0;

	INIT_WORK(&fcport->nvme_del_work, qla_nvme_unregister_remote_port);
	rport = kzalloc(sizeof(*rport), GFP_KERNEL);
	if (!rport) {
		ql_log(ql_log_warn, vha, 0x2101,
		    "%s: unable to alloc memory\n", __func__);
		return -ENOMEM;
	}

	rport->req.port_name = wwn_to_u64(fcport->port_name);
	rport->req.node_name = wwn_to_u64(fcport->node_name);
	rport->req.port_role = 0;

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

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

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

	rport->req.port_id = fcport->d_id.b24;

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

	ret = nvme_fc_register_remoteport(vha->nvme_local_port, &rport->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;
	}

	fcport->nvme_remote_port->private = fcport;
	fcport->nvme_flag |= NVME_FLAG_REGISTERED;
	atomic_set(&fcport->nvme_ref_count, 1);
	init_waitqueue_head(&fcport->nvme_waitQ);
	rport->fcport = fcport;
	list_add_tail(&rport->list, &vha->nvme_rport_list);
	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;

	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;
	}

	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;
	}

	ql_log(ql_log_warn, vha, 0xffff,
	    "allocating q for idx=%x w/o cpu mask\n", qidx);
	qpair = qla2xxx_create_qpair(vha, 5, vha->vp_idx, true);
	if (qpair == NULL) {
		ql_log(ql_log_warn, vha, 0x2122,
		    "Failed to allocate qpair\n");
		return -EINVAL;
	}
	*handle = qpair;

	return 0;
}

static void qla_nvme_sp_ls_done(void *ptr, int res)
{
	srb_t *sp = ptr;
	struct srb_iocb *nvme;
	struct nvmefc_ls_req   *fd;
	struct nvme_private *priv;

	if (atomic_read(&sp->ref_count) == 0) {
		ql_log(ql_log_warn, sp->fcport->vha, 0x2123,
		    "SP reference-count to ZERO on LS_done -- sp=%p.\n", sp);
		return;
	}

	if (!atomic_dec_and_test(&sp->ref_count))
		return;

	if (res)
		res = -EINVAL;

	nvme = &sp->u.iocb_cmd;
	fd = nvme->u.nvme.desc;
	priv = fd->private;
	priv->comp_status = res;
	schedule_work(&priv->ls_work);
	/* work schedule doesn't need the sp */
	qla2x00_rel_sp(sp);
}

static void qla_nvme_sp_done(void *ptr, int res)
{
	srb_t *sp = ptr;
	struct srb_iocb *nvme;
	struct nvmefc_fcp_req *fd;

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

	if (!atomic_dec_and_test(&sp->ref_count))
		return;

	if (!(sp->fcport->nvme_flag & NVME_FLAG_REGISTERED))
		goto rel;

	if (unlikely(nvme->u.nvme.comp_status || res))
		fd->status = -EINVAL;
	else
		fd->status = 0;

	fd->rcv_rsplen = nvme->u.nvme.rsp_pyld_len;
	fd->done(fd);
rel:
	qla2xxx_rel_qpair_sp(sp->qpair, sp);
}

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;
	fc_port_t *fcport = rport->private;
	srb_t *sp = priv->sp;
	int rval;
	struct qla_hw_data *ha = fcport->vha->hw;

	rval = ha->isp_ops->abort_command(sp);
	if (rval != QLA_SUCCESS)
		ql_log(ql_log_warn, fcport->vha, 0x2125,
		    "%s: failed to abort LS command for SP:%p rval=%x\n",
		    __func__, sp, rval);

	ql_dbg(ql_dbg_io, fcport->vha, 0x212b,
	    "%s: aborted sp:%p on fcport:%p\n", __func__, sp, fcport);
}

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

	fd->done(fd, priv->comp_status);
}

static int qla_nvme_ls_req(struct nvme_fc_local_port *lport,
    struct nvme_fc_remote_port *rport, struct nvmefc_ls_req *fd)
{
	fc_port_t *fcport = (fc_port_t *)rport->private;
	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->nvme_flag & NVME_FLAG_REGISTERED))
		return rval;

	vha = fcport->vha;
	ha = vha->hw;
	/* 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;
	atomic_set(&sp->ref_count, 1);
	init_waitqueue_head(&sp->nvme_ls_waitQ);
	nvme = &sp->u.iocb_cmd;
	priv->sp = sp;
	priv->fd = fd;
	INIT_WORK(&priv->ls_work, qla_nvme_ls_complete);
	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);

	rval = qla2x00_start_sp(sp);
	if (rval != QLA_SUCCESS) {
		ql_log(ql_log_warn, vha, 0x700e,
		    "qla2x00_start_sp failed = %d\n", rval);
		atomic_dec(&sp->ref_count);
		wake_up(&sp->nvme_ls_waitQ);
		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;
	srb_t *sp = priv->sp;
	int rval;
	fc_port_t *fcport = rport->private;
	struct qla_hw_data *ha = fcport->vha->hw;

	rval = ha->isp_ops->abort_command(sp);
	if (!rval)
		ql_log(ql_log_warn, fcport->vha, 0x2127,
		    "%s: failed to abort command for SP:%p rval=%x\n",
		    __func__, sp, rval);

	ql_dbg(ql_dbg_io, fcport->vha, 0x2126,
	    "%s: aborted sp:%p on fcport:%p\n", __func__, sp, fcport);
}

static void qla_nvme_poll(struct nvme_fc_local_port *lport, void *hw_queue_handle)
{
	struct scsi_qla_host *vha = lport->private;
	unsigned long flags;
	struct qla_qpair *qpair = (struct qla_qpair *)hw_queue_handle;

	/* Acquire ring specific lock */
	spin_lock_irqsave(&qpair->qp_lock, flags);
	qla24xx_process_response_queue(vha, qpair->rsp);
	spin_unlock_irqrestore(&qpair->qp_lock, flags);
}

static int qla2x00_start_nvme_mq(srb_t *sp)
{
	unsigned long   flags;
	uint32_t        *clr_ptr;
	uint32_t        index;
	uint32_t        handle;
	struct cmd_nvme *cmd_pkt;
	uint16_t        cnt, i;
	uint16_t        req_cnt;
	uint16_t        tot_dsds;
	uint16_t	avail_dsds;
	uint32_t	*cur_dsd;
	struct req_que *req = 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;
	uint32_t        rval = QLA_SUCCESS;

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

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

	/* Check for room in outstanding command list. */
	handle = req->current_outstanding_cmd;
	for (index = 1; index < req->num_outstanding_cmds; index++) {
		handle++;
		if (handle == req->num_outstanding_cmds)
			handle = 1;
		if (!req->outstanding_cmds[handle])
			break;
	}

	if (index == req->num_outstanding_cmds) {
		rval = -1;
		goto queuing_error;
	}
	req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
	if (req->cnt < (req_cnt + 2)) {
		cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
		    RD_REG_DWORD_RELAXED(req->req_q_out);

		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 = -1;
			goto queuing_error;
		}
	}

	if (unlikely(!fd->sqid)) {
		struct nvme_fc_cmd_iu *cmd = fd->cmdaddr;
		if (cmd->sqe.common.opcode == nvme_admin_async_event) {
			nvme->u.nvme.aen_op = 1;
			atomic_inc(&vha->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 | CF_NVME_ENABLE);
		vha->qla_stats.input_bytes += fd->payload_length;
		vha->qla_stats.input_requests++;
	} else if (fd->io_dir == NVMEFC_FCP_WRITE) {
		cmd_pkt->control_flags =
		    cpu_to_le16(CF_WRITE_DATA | CF_NVME_ENABLE);
		vha->qla_stats.output_bytes += fd->payload_length;
		vha->qla_stats.output_requests++;
	} else if (fd->io_dir == 0) {
		cmd_pkt->control_flags = cpu_to_le16(CF_NVME_ENABLE);
	}

	/* 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);
	cmd_pkt->nvme_rsp_dseg_address[0] = cpu_to_le32(LSD(fd->rspdma));
	cmd_pkt->nvme_rsp_dseg_address[1] = cpu_to_le32(MSD(fd->rspdma));

	/* NVME CNMD IU */
	cmd_pkt->nvme_cmnd_dseg_len = cpu_to_le16(fd->cmdlen);
	cmd_pkt->nvme_cmnd_dseg_address[0] = cpu_to_le32(LSD(fd->cmddma));
	cmd_pkt->nvme_cmnd_dseg_address[1] = cpu_to_le32(MSD(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 = (uint32_t *)&cmd_pkt->nvme_data_dseg_address[0];
	sgl = fd->first_sgl;

	/* Load data segments */
	for_each_sg(sgl, sg, tot_dsds, i) {
		dma_addr_t      sle_dma;
		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;
			*((uint32_t *)(&cont_pkt->entry_type)) =
			    cpu_to_le32(CONTINUE_A64_TYPE);

			cur_dsd = (uint32_t *)cont_pkt->dseg_0_address;
			avail_dsds = 5;
		}

		sle_dma = sg_dma_address(sg);
		*cur_dsd++ = cpu_to_le32(LSD(sle_dma));
		*cur_dsd++ = cpu_to_le32(MSD(sle_dma));
		*cur_dsd++ = cpu_to_le32(sg_dma_len(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++;
	}

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

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 = QLA_FUNCTION_FAILED;
	srb_t *sp;
	struct qla_qpair *qpair = (struct qla_qpair *)hw_queue_handle;
	struct nvme_private *priv;

	if (!fd) {
		ql_log(ql_log_warn, NULL, 0x2134, "NO NVMe FCP request\n");
		return rval;
	}

	priv = fd->private;
	fcport = (fc_port_t *)rport->private;
	if (!fcport) {
		ql_log(ql_log_warn, NULL, 0x210e, "No fcport ptr\n");
		return rval;
	}

	vha = fcport->vha;
	if ((!qpair) || (!(fcport->nvme_flag & NVME_FLAG_REGISTERED)))
		return -EBUSY;

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

	atomic_set(&sp->ref_count, 1);
	init_waitqueue_head(&sp->nvme_ls_waitQ);
	priv->sp = sp;
	sp->type = SRB_NVME_CMD;
	sp->name = "nvme_cmd";
	sp->done = qla_nvme_sp_done;
	sp->qpair = qpair;
	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);
		atomic_dec(&sp->ref_count);
		wake_up(&sp->nvme_ls_waitQ);
		return -EIO;
	}

	return rval;
}

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

	atomic_dec(&vha->nvme_ref_count);
	wake_up_all(&vha->nvme_waitQ);

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

static void qla_nvme_remoteport_delete(struct nvme_fc_remote_port *rport)
{
	fc_port_t *fcport;
	struct nvme_rport *r_port, *trport;

	fcport = (fc_port_t *)rport->private;
	fcport->nvme_remote_port = NULL;
	fcport->nvme_flag &= ~NVME_FLAG_REGISTERED;
	atomic_dec(&fcport->nvme_ref_count);
	wake_up_all(&fcport->nvme_waitQ);

	list_for_each_entry_safe(r_port, trport,
	    &fcport->vha->nvme_rport_list, list) {
		if (r_port->fcport == fcport) {
			list_del(&r_port->list);
			break;
		}
	}
	kfree(r_port);

	ql_log(ql_log_info, fcport->vha, 0x2110,
	    "remoteport_delete of %p completed.\n", fcport);
}

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,
	.poll_queue	= qla_nvme_poll,
	.max_hw_queues  = 8,
	.max_sgl_segments = 128,
	.max_dif_sgl_segments = 64,
	.dma_boundary = 0xFFFFFFFF,
	.local_priv_sz  = 8,
	.remote_priv_sz = 0,
	.lsrqst_priv_sz = sizeof(struct nvme_private),
	.fcprqst_priv_sz = sizeof(struct nvme_private),
};

#define NVME_ABORT_POLLING_PERIOD    2
static int qla_nvme_wait_on_command(srb_t *sp)
{
	int ret = QLA_SUCCESS;

	wait_event_timeout(sp->nvme_ls_waitQ, (atomic_read(&sp->ref_count) > 1),
	    NVME_ABORT_POLLING_PERIOD*HZ);

	if (atomic_read(&sp->ref_count) > 1)
		ret = QLA_FUNCTION_FAILED;

	return ret;
}

static int qla_nvme_wait_on_rport_del(fc_port_t *fcport)
{
	int ret = QLA_SUCCESS;

	wait_event_timeout(fcport->nvme_waitQ,
	    atomic_read(&fcport->nvme_ref_count),
	    NVME_ABORT_POLLING_PERIOD*HZ);

	if (atomic_read(&fcport->nvme_ref_count)) {
		ret = QLA_FUNCTION_FAILED;
		ql_log(ql_log_info, fcport->vha, 0x2111,
		    "timed out waiting for fcport=%p to delete\n", fcport);
	}

	return ret;
}

void qla_nvme_abort(struct qla_hw_data *ha, srb_t *sp)
{
	int rval;

	rval = ha->isp_ops->abort_command(sp);
	if (!rval) {
		if (!qla_nvme_wait_on_command(sp))
			ql_log(ql_log_warn, NULL, 0x2112,
			    "nvme_wait_on_command timed out waiting on sp=%p\n",
			    sp);
	}
}

static void qla_nvme_abort_all(fc_port_t *fcport)
{
	int que, cnt;
	unsigned long flags;
	srb_t *sp;
	struct qla_hw_data *ha = fcport->vha->hw;
	struct req_que *req;

	spin_lock_irqsave(&ha->hardware_lock, flags);
	for (que = 0; que < ha->max_req_queues; que++) {
		req = ha->req_q_map[que];
		if (!req)
			continue;
		if (!req->outstanding_cmds)
			continue;
		for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
			sp = req->outstanding_cmds[cnt];
			if ((sp) && ((sp->type == SRB_NVME_CMD) ||
			    (sp->type == SRB_NVME_LS)) &&
				(sp->fcport == fcport)) {
				atomic_inc(&sp->ref_count);
				spin_unlock_irqrestore(&ha->hardware_lock,
				    flags);
				qla_nvme_abort(ha, sp);
				spin_lock_irqsave(&ha->hardware_lock, flags);
				req->outstanding_cmds[cnt] = NULL;
				sp->done(sp, 1);
			}
		}
	}
	spin_unlock_irqrestore(&ha->hardware_lock, flags);
}

static void qla_nvme_unregister_remote_port(struct work_struct *work)
{
	struct fc_port *fcport = container_of(work, struct fc_port,
	    nvme_del_work);
	struct nvme_rport *rport, *trport;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return;

	list_for_each_entry_safe(rport, trport,
	    &fcport->vha->nvme_rport_list, list) {
		if (rport->fcport == fcport) {
			ql_log(ql_log_info, fcport->vha, 0x2113,
			    "%s: fcport=%p\n", __func__, fcport);
			nvme_fc_unregister_remoteport(
			    fcport->nvme_remote_port);
		}
	}
}

void qla_nvme_delete(scsi_qla_host_t *vha)
{
	struct nvme_rport *rport, *trport;
	fc_port_t *fcport;
	int nv_ret;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return;

	list_for_each_entry_safe(rport, trport, &vha->nvme_rport_list, list) {
		fcport = rport->fcport;

		ql_log(ql_log_info, fcport->vha, 0x2114, "%s: fcport=%p\n",
		    __func__, fcport);

		nvme_fc_unregister_remoteport(fcport->nvme_remote_port);
		qla_nvme_wait_on_rport_del(fcport);
		qla_nvme_abort_all(fcport);
	}

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

void qla_nvme_register_hba(scsi_qla_host_t *vha)
{
	struct nvme_fc_port_template *tmpl;
	struct qla_hw_data *ha;
	struct nvme_fc_port_info pinfo;
	int ret;

	if (!IS_ENABLED(CONFIG_NVME_FC))
		return;

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

	WARN_ON(vha->nvme_local_port);
	WARN_ON(ha->max_req_queues < 3);

	qla_nvme_fc_transport.max_hw_queues =
	    min((uint8_t)(qla_nvme_fc_transport.max_hw_queues),
		(uint8_t)(ha->max_req_queues - 2));

	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;

	ql_log(ql_log_info, vha, 0xffff,
	    "register_localport: host-traddr=pn-0x%llx:nn-0x%llx on portID:%x\n",
	    pinfo.port_name, pinfo.node_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);
	if (ret) {
		ql_log(ql_log_warn, vha, 0xffff,
		    "register_localport failed: ret=%x\n", ret);
		return;
	}
	atomic_set(&vha->nvme_ref_count, 1);
	vha->nvme_local_port->private = vha;
	init_waitqueue_head(&vha->nvme_waitQ);
}
