// SPDX-License-Identifier: GPL-2.0-only
/*
 * Marvell Fibre Channel HBA Driver
 * Copyright (c)  2021     Marvell
 */
#include "qla_def.h"
#include "qla_edif.h"

#include <linux/kthread.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <scsi/scsi_tcq.h>

static struct edif_sa_index_entry *qla_edif_sadb_find_sa_index_entry(uint16_t nport_handle,
		struct list_head *sa_list);
static uint16_t qla_edif_sadb_get_sa_index(fc_port_t *fcport,
		struct qla_sa_update_frame *sa_frame);
static int qla_edif_sadb_delete_sa_index(fc_port_t *fcport, uint16_t nport_handle,
		uint16_t sa_index);
static int qla_pur_get_pending(scsi_qla_host_t *, fc_port_t *, struct bsg_job *);

struct edb_node {
	struct  list_head	list;
	uint32_t		ntype;
	union {
		port_id_t	plogi_did;
		uint32_t	async;
		port_id_t	els_sid;
		struct edif_sa_update_aen	sa_aen;
	} u;
};

static struct els_sub_cmd {
	uint16_t cmd;
	const char *str;
} sc_str[] = {
	{SEND_ELS, "send ELS"},
	{SEND_ELS_REPLY, "send ELS Reply"},
	{PULL_ELS, "retrieve ELS"},
};

const char *sc_to_str(uint16_t cmd)
{
	int i;
	struct els_sub_cmd *e;

	for (i = 0; i < ARRAY_SIZE(sc_str); i++) {
		e = sc_str + i;
		if (cmd == e->cmd)
			return e->str;
	}
	return "unknown";
}

static struct edb_node *qla_edb_getnext(scsi_qla_host_t *vha)
{
	unsigned long   flags;
	struct edb_node *edbnode = NULL;

	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);

	/* db nodes are fifo - no qualifications done */
	if (!list_empty(&vha->e_dbell.head)) {
		edbnode = list_first_entry(&vha->e_dbell.head,
					   struct edb_node, list);
		list_del_init(&edbnode->list);
	}

	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);

	return edbnode;
}

static void qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node)
{
	list_del_init(&node->list);
	kfree(node);
}

static struct edif_list_entry *qla_edif_list_find_sa_index(fc_port_t *fcport,
		uint16_t handle)
{
	struct edif_list_entry *entry;
	struct edif_list_entry *tentry;
	struct list_head *indx_list = &fcport->edif.edif_indx_list;

	list_for_each_entry_safe(entry, tentry, indx_list, next) {
		if (entry->handle == handle)
			return entry;
	}
	return NULL;
}

/* timeout called when no traffic and delayed rx sa_index delete */
static void qla2x00_sa_replace_iocb_timeout(struct timer_list *t)
{
	struct edif_list_entry *edif_entry = from_timer(edif_entry, t, timer);
	fc_port_t *fcport = edif_entry->fcport;
	struct scsi_qla_host *vha = fcport->vha;
	struct  edif_sa_ctl *sa_ctl;
	uint16_t nport_handle;
	unsigned long flags = 0;

	ql_dbg(ql_dbg_edif, vha, 0x3069,
	    "%s:  nport_handle 0x%x,  SA REPL Delay Timeout, %8phC portid=%06x\n",
	    __func__, edif_entry->handle, fcport->port_name, fcport->d_id.b24);

	/*
	 * if delete_sa_index is valid then no one has serviced this
	 * delayed delete
	 */
	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);

	/*
	 * delete_sa_index is invalidated when we find the new sa_index in
	 * the incoming data stream.  If it is not invalidated then we are
	 * still looking for the new sa_index because there is no I/O and we
	 * need to just force the rx delete and move on.  Otherwise
	 * we could get another rekey which will result in an error 66.
	 */
	if (edif_entry->delete_sa_index != INVALID_EDIF_SA_INDEX) {
		uint16_t delete_sa_index = edif_entry->delete_sa_index;

		edif_entry->delete_sa_index = INVALID_EDIF_SA_INDEX;
		nport_handle = edif_entry->handle;
		spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);

		sa_ctl = qla_edif_find_sa_ctl_by_index(fcport,
		    delete_sa_index, 0);

		if (sa_ctl) {
			ql_dbg(ql_dbg_edif, vha, 0x3063,
			    "%s: sa_ctl: %p, delete index %d, update index: %d, lid: 0x%x\n",
			    __func__, sa_ctl, delete_sa_index, edif_entry->update_sa_index,
			    nport_handle);

			sa_ctl->flags = EDIF_SA_CTL_FLG_DEL;
			set_bit(EDIF_SA_CTL_REPL, &sa_ctl->state);
			qla_post_sa_replace_work(fcport->vha, fcport,
			    nport_handle, sa_ctl);

		} else {
			ql_dbg(ql_dbg_edif, vha, 0x3063,
			    "%s: sa_ctl not found for delete_sa_index: %d\n",
			    __func__, edif_entry->delete_sa_index);
		}
	} else {
		spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
	}
}

/*
 * create a new list entry for this nport handle and
 * add an sa_update index to the list - called for sa_update
 */
static int qla_edif_list_add_sa_update_index(fc_port_t *fcport,
		uint16_t sa_index, uint16_t handle)
{
	struct edif_list_entry *entry;
	unsigned long flags = 0;

	/* if the entry exists, then just update the sa_index */
	entry = qla_edif_list_find_sa_index(fcport, handle);
	if (entry) {
		entry->update_sa_index = sa_index;
		entry->count = 0;
		return 0;
	}

	/*
	 * This is the normal path - there should be no existing entry
	 * when update is called.  The exception is at startup
	 * when update is called for the first two sa_indexes
	 * followed by a delete of the first sa_index
	 */
	entry = kzalloc((sizeof(struct edif_list_entry)), GFP_ATOMIC);
	if (!entry)
		return -ENOMEM;

	INIT_LIST_HEAD(&entry->next);
	entry->handle = handle;
	entry->update_sa_index = sa_index;
	entry->delete_sa_index = INVALID_EDIF_SA_INDEX;
	entry->count = 0;
	entry->flags = 0;
	timer_setup(&entry->timer, qla2x00_sa_replace_iocb_timeout, 0);
	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);
	list_add_tail(&entry->next, &fcport->edif.edif_indx_list);
	spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
	return 0;
}

/* remove an entry from the list */
static void qla_edif_list_delete_sa_index(fc_port_t *fcport, struct edif_list_entry *entry)
{
	unsigned long flags = 0;

	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);
	list_del(&entry->next);
	spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
}

int qla_post_sa_replace_work(struct scsi_qla_host *vha,
	 fc_port_t *fcport, uint16_t nport_handle, struct edif_sa_ctl *sa_ctl)
{
	struct qla_work_evt *e;

	e = qla2x00_alloc_work(vha, QLA_EVT_SA_REPLACE);
	if (!e)
		return QLA_FUNCTION_FAILED;

	e->u.sa_update.fcport = fcport;
	e->u.sa_update.sa_ctl = sa_ctl;
	e->u.sa_update.nport_handle = nport_handle;
	fcport->flags |= FCF_ASYNC_ACTIVE;
	return qla2x00_post_work(vha, e);
}

static void
qla_edif_sa_ctl_init(scsi_qla_host_t *vha, struct fc_port  *fcport)
{
	ql_dbg(ql_dbg_edif, vha, 0x2058,
	    "Init SA_CTL List for fcport - nn %8phN pn %8phN portid=%06x.\n",
	    fcport->node_name, fcport->port_name, fcport->d_id.b24);

	fcport->edif.tx_rekey_cnt = 0;
	fcport->edif.rx_rekey_cnt = 0;

	fcport->edif.tx_bytes = 0;
	fcport->edif.rx_bytes = 0;
}

static int qla_bsg_check(scsi_qla_host_t *vha, struct bsg_job *bsg_job,
fc_port_t *fcport)
{
	struct extra_auth_els *p;
	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
	struct qla_bsg_auth_els_request *req =
	    (struct qla_bsg_auth_els_request *)bsg_job->request;

	if (!vha->hw->flags.edif_enabled) {
		ql_dbg(ql_dbg_edif, vha, 0x9105,
		    "%s edif not enabled\n", __func__);
		goto done;
	}
	if (DBELL_INACTIVE(vha)) {
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "%s doorbell not enabled\n", __func__);
		goto done;
	}

	p = &req->e;

	/* Get response */
	if (p->sub_cmd == PULL_ELS) {
		struct qla_bsg_auth_els_reply *rpl =
			(struct qla_bsg_auth_els_reply *)bsg_job->reply;

		qla_pur_get_pending(vha, fcport, bsg_job);

		ql_dbg(ql_dbg_edif, vha, 0x911d,
			"%s %s %8phN sid=%x. xchg %x, nb=%xh bsg ptr %p\n",
			__func__, sc_to_str(p->sub_cmd), fcport->port_name,
			fcport->d_id.b24, rpl->rx_xchg_address,
			rpl->r.reply_payload_rcv_len, bsg_job);

		goto done;
	}
	return 0;

done:

	bsg_job_done(bsg_job, bsg_reply->result,
			bsg_reply->reply_payload_rcv_len);
	return -EIO;
}

fc_port_t *
qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id)
{
	fc_port_t *f, *tf;

	f = NULL;
	list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) {
		if (f->d_id.b24 == id->b24)
			return f;
	}
	return NULL;
}

/**
 * qla_edif_app_check(): check for valid application id.
 * @vha: host adapter pointer
 * @appid: application id
 * Return: false = fail, true = pass
 */
static bool
qla_edif_app_check(scsi_qla_host_t *vha, struct app_id appid)
{
	/* check that the app is allow/known to the driver */

	if (appid.app_vid != EDIF_APP_ID) {
		ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app id not ok (%x)",
		    __func__, appid.app_vid);
		return false;
	}

	if (appid.version != EDIF_VERSION1) {
		ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app version is not ok (%x)",
		    __func__, appid.version);
		return false;
	}

	return true;
}

static void
qla_edif_free_sa_ctl(fc_port_t *fcport, struct edif_sa_ctl *sa_ctl,
	int index)
{
	unsigned long flags = 0;

	spin_lock_irqsave(&fcport->edif.sa_list_lock, flags);
	list_del(&sa_ctl->next);
	spin_unlock_irqrestore(&fcport->edif.sa_list_lock, flags);
	if (index >= 512)
		fcport->edif.tx_rekey_cnt--;
	else
		fcport->edif.rx_rekey_cnt--;
	kfree(sa_ctl);
}

/* return an index to the freepool */
static void qla_edif_add_sa_index_to_freepool(fc_port_t *fcport, int dir,
		uint16_t sa_index)
{
	void *sa_id_map;
	struct scsi_qla_host *vha = fcport->vha;
	struct qla_hw_data *ha = vha->hw;
	unsigned long flags = 0;
	u16 lsa_index = sa_index;

	ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063,
	    "%s: entry\n", __func__);

	if (dir) {
		sa_id_map = ha->edif_tx_sa_id_map;
		lsa_index -= EDIF_TX_SA_INDEX_BASE;
	} else {
		sa_id_map = ha->edif_rx_sa_id_map;
	}

	spin_lock_irqsave(&ha->sadb_fp_lock, flags);
	clear_bit(lsa_index, sa_id_map);
	spin_unlock_irqrestore(&ha->sadb_fp_lock, flags);
	ql_dbg(ql_dbg_edif, vha, 0x3063,
	    "%s: index %d added to free pool\n", __func__, sa_index);
}

static void __qla2x00_release_all_sadb(struct scsi_qla_host *vha,
	struct fc_port *fcport, struct edif_sa_index_entry *entry,
	int pdir)
{
	struct edif_list_entry *edif_entry;
	struct  edif_sa_ctl *sa_ctl;
	int i, dir;
	int key_cnt = 0;

	for (i = 0; i < 2; i++) {
		if (entry->sa_pair[i].sa_index == INVALID_EDIF_SA_INDEX)
			continue;

		if (fcport->loop_id != entry->handle) {
			ql_dbg(ql_dbg_edif, vha, 0x3063,
			    "%s: ** WARNING %d** entry handle: 0x%x, lid: 0x%x, sa_index: %d\n",
			    __func__, i, entry->handle, fcport->loop_id,
			    entry->sa_pair[i].sa_index);
		}

		/* release the sa_ctl */
		sa_ctl = qla_edif_find_sa_ctl_by_index(fcport,
				entry->sa_pair[i].sa_index, pdir);
		if (sa_ctl &&
		    qla_edif_find_sa_ctl_by_index(fcport, sa_ctl->index, pdir)) {
			ql_dbg(ql_dbg_edif, vha, 0x3063,
			    "%s: freeing sa_ctl for index %d\n", __func__, sa_ctl->index);
			qla_edif_free_sa_ctl(fcport, sa_ctl, sa_ctl->index);
		} else {
			ql_dbg(ql_dbg_edif, vha, 0x3063,
			    "%s: sa_ctl NOT freed, sa_ctl: %p\n", __func__, sa_ctl);
		}

		/* Release the index */
		ql_dbg(ql_dbg_edif, vha, 0x3063,
			"%s: freeing sa_index %d, nph: 0x%x\n",
			__func__, entry->sa_pair[i].sa_index, entry->handle);

		dir = (entry->sa_pair[i].sa_index <
			EDIF_TX_SA_INDEX_BASE) ? 0 : 1;
		qla_edif_add_sa_index_to_freepool(fcport, dir,
			entry->sa_pair[i].sa_index);

		/* Delete timer on RX */
		if (pdir != SAU_FLG_TX) {
			edif_entry =
				qla_edif_list_find_sa_index(fcport, entry->handle);
			if (edif_entry) {
				ql_dbg(ql_dbg_edif, vha, 0x5033,
				    "%s: remove edif_entry %p, update_sa_index: 0x%x, delete_sa_index: 0x%x\n",
				    __func__, edif_entry, edif_entry->update_sa_index,
				    edif_entry->delete_sa_index);
				qla_edif_list_delete_sa_index(fcport, edif_entry);
				/*
				 * valid delete_sa_index indicates there is a rx
				 * delayed delete queued
				 */
				if (edif_entry->delete_sa_index !=
						INVALID_EDIF_SA_INDEX) {
					del_timer(&edif_entry->timer);

					/* build and send the aen */
					fcport->edif.rx_sa_set = 1;
					fcport->edif.rx_sa_pending = 0;
					qla_edb_eventcreate(vha,
							VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
							QL_VND_SA_STAT_SUCCESS,
							QL_VND_RX_SA_KEY, fcport);
				}
				ql_dbg(ql_dbg_edif, vha, 0x5033,
				    "%s: release edif_entry %p, update_sa_index: 0x%x, delete_sa_index: 0x%x\n",
				    __func__, edif_entry, edif_entry->update_sa_index,
				    edif_entry->delete_sa_index);

				kfree(edif_entry);
			}
		}
		key_cnt++;
	}
	ql_dbg(ql_dbg_edif, vha, 0x3063,
	    "%s: %d %s keys released\n",
	    __func__, key_cnt, pdir ? "tx" : "rx");
}

/* find an release all outstanding sadb sa_indicies */
void qla2x00_release_all_sadb(struct scsi_qla_host *vha, struct fc_port *fcport)
{
	struct edif_sa_index_entry *entry, *tmp;
	struct qla_hw_data *ha = vha->hw;
	unsigned long flags;

	ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063,
	    "%s: Starting...\n", __func__);

	spin_lock_irqsave(&ha->sadb_lock, flags);

	list_for_each_entry_safe(entry, tmp, &ha->sadb_rx_index_list, next) {
		if (entry->fcport == fcport) {
			list_del(&entry->next);
			spin_unlock_irqrestore(&ha->sadb_lock, flags);
			__qla2x00_release_all_sadb(vha, fcport, entry, 0);
			kfree(entry);
			spin_lock_irqsave(&ha->sadb_lock, flags);
			break;
		}
	}

	list_for_each_entry_safe(entry, tmp, &ha->sadb_tx_index_list, next) {
		if (entry->fcport == fcport) {
			list_del(&entry->next);
			spin_unlock_irqrestore(&ha->sadb_lock, flags);

			__qla2x00_release_all_sadb(vha, fcport, entry, SAU_FLG_TX);

			kfree(entry);
			spin_lock_irqsave(&ha->sadb_lock, flags);
			break;
		}
	}
	spin_unlock_irqrestore(&ha->sadb_lock, flags);
}

/**
 * qla_edif_app_start:  application has announce its present
 * @vha: host adapter pointer
 * @bsg_job: user request
 *
 * Set/activate doorbell.  Reset current sessions and re-login with
 * secure flag.
 */
static int
qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	int32_t			rval = 0;
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	struct app_start	appstart;
	struct app_start_reply	appreply;
	struct fc_port  *fcport, *tf;

	ql_log(ql_log_info, vha, 0x1313,
	       "EDIF application registration with driver, FC device connections will be re-established.\n");

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &appstart,
	    sizeof(struct app_start));

	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app_vid=%x app_start_flags %x\n",
	     __func__, appstart.app_info.app_vid, appstart.app_start_flags);

	if (DBELL_INACTIVE(vha)) {
		/* mark doorbell as active since an app is now present */
		vha->e_dbell.db_flags |= EDB_ACTIVE;
	} else {
		goto out;
	}

	if (N2N_TOPO(vha->hw)) {
		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list)
			fcport->n2n_link_reset_cnt = 0;

		if (vha->hw->flags.n2n_fw_acc_sec) {
			list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list)
				qla_edif_sa_ctl_init(vha, fcport);

			/*
			 * While authentication app was not running, remote device
			 * could still try to login with this local port.  Let's
			 * clear the state and try again.
			 */
			qla2x00_wait_for_sess_deletion(vha);

			/* bounce the link to get the other guy to relogin */
			if (!vha->hw->flags.n2n_bigger) {
				set_bit(N2N_LINK_RESET, &vha->dpc_flags);
				qla2xxx_wake_dpc(vha);
			}
		} else {
			qla2x00_wait_for_hba_online(vha);
			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
			qla2xxx_wake_dpc(vha);
			qla2x00_wait_for_hba_online(vha);
		}
	} else {
		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
			ql_dbg(ql_dbg_edif, vha, 0x2058,
			       "FCSP - nn %8phN pn %8phN portid=%06x.\n",
			       fcport->node_name, fcport->port_name,
			       fcport->d_id.b24);
			ql_dbg(ql_dbg_edif, vha, 0xf084,
			       "%s: se_sess %p / sess %p from port %8phC "
			       "loop_id %#04x s_id %06x logout %d "
			       "keep %d els_logo %d disc state %d auth state %d"
			       "stop state %d\n",
			       __func__, fcport->se_sess, fcport,
			       fcport->port_name, fcport->loop_id,
			       fcport->d_id.b24, fcport->logout_on_delete,
			       fcport->keep_nport_handle, fcport->send_els_logo,
			       fcport->disc_state, fcport->edif.auth_state,
			       fcport->edif.app_stop);

			if (atomic_read(&vha->loop_state) == LOOP_DOWN)
				break;

			fcport->login_retry = vha->hw->login_retry_count;

			fcport->edif.app_stop = 0;
			fcport->edif.app_sess_online = 0;

			if (fcport->scan_state != QLA_FCPORT_FOUND)
				continue;

			if (fcport->port_type == FCT_UNKNOWN &&
			    !fcport->fc4_features)
				rval = qla24xx_async_gffid(vha, fcport, true);

			if (!rval && !(fcport->fc4_features & FC4_FF_TARGET ||
			    fcport->port_type & (FCT_TARGET|FCT_NVME_TARGET)))
				continue;

			rval = 0;

			ql_dbg(ql_dbg_edif, vha, 0x911e,
			       "%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
			       __func__, fcport->port_name);
			qlt_schedule_sess_for_deletion(fcport);
			qla_edif_sa_ctl_init(vha, fcport);
		}
		set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
	}

	if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
		/* mark as active since an app is now present */
		vha->pur_cinfo.enode_flags = ENODE_ACTIVE;
	} else {
		ql_dbg(ql_dbg_edif, vha, 0x911f, "%s enode already active\n",
		     __func__);
	}

out:
	appreply.host_support_edif = vha->hw->flags.edif_enabled;
	appreply.edif_enode_active = vha->pur_cinfo.enode_flags;
	appreply.edif_edb_active = vha->e_dbell.db_flags;
	appreply.version = EDIF_VERSION1;

	bsg_job->reply_len = sizeof(struct fc_bsg_reply);

	SET_DID_STATUS(bsg_reply->result, DID_OK);

	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
							       bsg_job->reply_payload.sg_cnt,
							       &appreply,
							       sizeof(struct app_start_reply));

	ql_dbg(ql_dbg_edif, vha, 0x911d,
	    "%s app start completed with 0x%x\n",
	    __func__, rval);

	return rval;
}

/**
 * qla_edif_app_stop - app has announced it's exiting.
 * @vha: host adapter pointer
 * @bsg_job: user space command pointer
 *
 * Free any in flight messages, clear all doorbell events
 * to application. Reject any message relate to security.
 */
static int
qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	struct app_stop         appstop;
	struct fc_bsg_reply     *bsg_reply = bsg_job->reply;
	struct fc_port  *fcport, *tf;

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &appstop,
	    sizeof(struct app_stop));

	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s Stopping APP: app_vid=%x\n",
	    __func__, appstop.app_info.app_vid);

	/* Call db stop and enode stop functions */

	/* if we leave this running short waits are operational < 16 secs */
	qla_enode_stop(vha);        /* stop enode */
	qla_edb_stop(vha);          /* stop db */

	list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
		if (!(fcport->flags & FCF_FCSP_DEVICE))
			continue;

		if (fcport->flags & FCF_FCSP_DEVICE) {
			ql_dbg(ql_dbg_edif, vha, 0xf084,
			    "%s: sess %p from port %8phC lid %#04x s_id %06x logout %d keep %d els_logo %d\n",
			    __func__, fcport,
			    fcport->port_name, fcport->loop_id, fcport->d_id.b24,
			    fcport->logout_on_delete, fcport->keep_nport_handle,
			    fcport->send_els_logo);

			if (atomic_read(&vha->loop_state) == LOOP_DOWN)
				break;

			fcport->edif.app_stop = 1;
			ql_dbg(ql_dbg_edif, vha, 0x911e,
				"%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
				__func__, fcport->port_name);

			fcport->send_els_logo = 1;
			qlt_schedule_sess_for_deletion(fcport);
		}
	}

	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	SET_DID_STATUS(bsg_reply->result, DID_OK);

	/* no return interface to app - it assumes we cleaned up ok */

	return 0;
}

static int
qla_edif_app_chk_sa_update(scsi_qla_host_t *vha, fc_port_t *fcport,
		struct app_plogi_reply *appplogireply)
{
	int	ret = 0;

	if (!(fcport->edif.rx_sa_set && fcport->edif.tx_sa_set)) {
		ql_dbg(ql_dbg_edif, vha, 0x911e,
		    "%s: wwpn %8phC Both SA indexes has not been SET TX %d, RX %d.\n",
		    __func__, fcport->port_name, fcport->edif.tx_sa_set,
		    fcport->edif.rx_sa_set);
		appplogireply->prli_status = 0;
		ret = 1;
	} else  {
		ql_dbg(ql_dbg_edif, vha, 0x911e,
		    "%s wwpn %8phC Both SA(s) updated.\n", __func__,
		    fcport->port_name);
		fcport->edif.rx_sa_set = fcport->edif.tx_sa_set = 0;
		fcport->edif.rx_sa_pending = fcport->edif.tx_sa_pending = 0;
		appplogireply->prli_status = 1;
	}
	return ret;
}

/**
 * qla_edif_app_authok - authentication by app succeeded.  Driver can proceed
 *   with prli
 * @vha: host adapter pointer
 * @bsg_job: user request
 */
static int
qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	struct auth_complete_cmd appplogiok;
	struct app_plogi_reply	appplogireply = {0};
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	fc_port_t		*fcport = NULL;
	port_id_t		portid = {0};

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &appplogiok,
	    sizeof(struct auth_complete_cmd));

	/* silent unaligned access warning */
	portid.b.domain = appplogiok.u.d_id.b.domain;
	portid.b.area   = appplogiok.u.d_id.b.area;
	portid.b.al_pa  = appplogiok.u.d_id.b.al_pa;

	appplogireply.version = EDIF_VERSION1;
	switch (appplogiok.type) {
	case PL_TYPE_WWPN:
		fcport = qla2x00_find_fcport_by_wwpn(vha,
		    appplogiok.u.wwpn, 0);
		if (!fcport)
			ql_dbg(ql_dbg_edif, vha, 0x911d,
			    "%s wwpn lookup failed: %8phC\n",
			    __func__, appplogiok.u.wwpn);
		break;
	case PL_TYPE_DID:
		fcport = qla2x00_find_fcport_by_pid(vha, &portid);
		if (!fcport)
			ql_dbg(ql_dbg_edif, vha, 0x911d,
			    "%s d_id lookup failed: %x\n", __func__,
			    portid.b24);
		break;
	default:
		ql_dbg(ql_dbg_edif, vha, 0x911d,
		    "%s undefined type: %x\n", __func__,
		    appplogiok.type);
		break;
	}

	if (!fcport) {
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		goto errstate_exit;
	}

	/*
	 * if port is online then this is a REKEY operation
	 * Only do sa update checking
	 */
	if (atomic_read(&fcport->state) == FCS_ONLINE) {
		ql_dbg(ql_dbg_edif, vha, 0x911d,
		    "%s Skipping PRLI complete based on rekey\n", __func__);
		appplogireply.prli_status = 1;
		SET_DID_STATUS(bsg_reply->result, DID_OK);
		qla_edif_app_chk_sa_update(vha, fcport, &appplogireply);
		goto errstate_exit;
	}

	/* make sure in AUTH_PENDING or else reject */
	if (fcport->disc_state != DSC_LOGIN_AUTH_PEND) {
		ql_dbg(ql_dbg_edif, vha, 0x911e,
		    "%s wwpn %8phC is not in auth pending state (%x)\n",
		    __func__, fcport->port_name, fcport->disc_state);
		SET_DID_STATUS(bsg_reply->result, DID_OK);
		appplogireply.prli_status = 0;
		goto errstate_exit;
	}

	SET_DID_STATUS(bsg_reply->result, DID_OK);
	appplogireply.prli_status = 1;
	fcport->edif.authok = 1;
	if (!(fcport->edif.rx_sa_set && fcport->edif.tx_sa_set)) {
		ql_dbg(ql_dbg_edif, vha, 0x911e,
		    "%s: wwpn %8phC Both SA indexes has not been SET TX %d, RX %d.\n",
		    __func__, fcport->port_name, fcport->edif.tx_sa_set,
		    fcport->edif.rx_sa_set);
		SET_DID_STATUS(bsg_reply->result, DID_OK);
		appplogireply.prli_status = 0;
		goto errstate_exit;

	} else {
		ql_dbg(ql_dbg_edif, vha, 0x911e,
		    "%s wwpn %8phC Both SA(s) updated.\n", __func__,
		    fcport->port_name);
		fcport->edif.rx_sa_set = fcport->edif.tx_sa_set = 0;
		fcport->edif.rx_sa_pending = fcport->edif.tx_sa_pending = 0;
	}

	if (qla_ini_mode_enabled(vha)) {
		ql_dbg(ql_dbg_edif, vha, 0x911e,
		    "%s AUTH complete - RESUME with prli for wwpn %8phC\n",
		    __func__, fcport->port_name);
		qla24xx_post_prli_work(vha, fcport);
	}

errstate_exit:
	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
							       bsg_job->reply_payload.sg_cnt,
							       &appplogireply,
							       sizeof(struct app_plogi_reply));

	return 0;
}

/**
 * qla_edif_app_authfail - authentication by app has failed.  Driver is given
 *   notice to tear down current session.
 * @vha: host adapter pointer
 * @bsg_job: user request
 */
static int
qla_edif_app_authfail(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	int32_t			rval = 0;
	struct auth_complete_cmd appplogifail;
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	fc_port_t		*fcport = NULL;
	port_id_t		portid = {0};

	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app auth fail\n", __func__);

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &appplogifail,
	    sizeof(struct auth_complete_cmd));

	/* silent unaligned access warning */
	portid.b.domain = appplogifail.u.d_id.b.domain;
	portid.b.area   = appplogifail.u.d_id.b.area;
	portid.b.al_pa  = appplogifail.u.d_id.b.al_pa;

	/*
	 * TODO: edif: app has failed this plogi. Inform driver to
	 * take any action (if any).
	 */
	switch (appplogifail.type) {
	case PL_TYPE_WWPN:
		fcport = qla2x00_find_fcport_by_wwpn(vha,
		    appplogifail.u.wwpn, 0);
		SET_DID_STATUS(bsg_reply->result, DID_OK);
		break;
	case PL_TYPE_DID:
		fcport = qla2x00_find_fcport_by_pid(vha, &portid);
		if (!fcport)
			ql_dbg(ql_dbg_edif, vha, 0x911d,
			    "%s d_id lookup failed: %x\n", __func__,
			    portid.b24);
		SET_DID_STATUS(bsg_reply->result, DID_OK);
		break;
	default:
		ql_dbg(ql_dbg_edif, vha, 0x911e,
		    "%s undefined type: %x\n", __func__,
		    appplogifail.type);
		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		rval = -1;
		break;
	}

	ql_dbg(ql_dbg_edif, vha, 0x911d,
	    "%s fcport is 0x%p\n", __func__, fcport);

	if (fcport) {
		/* set/reset edif values and flags */
		ql_dbg(ql_dbg_edif, vha, 0x911e,
		    "%s reset the auth process - %8phC, loopid=%x portid=%06x.\n",
		    __func__, fcport->port_name, fcport->loop_id, fcport->d_id.b24);

		if (qla_ini_mode_enabled(fcport->vha)) {
			fcport->send_els_logo = 1;
			qlt_schedule_sess_for_deletion(fcport);
		}
	}

	return rval;
}

/**
 * qla_edif_app_getfcinfo - app would like to read session info (wwpn, nportid,
 *   [initiator|target] mode.  It can specific session with specific nport id or
 *   all sessions.
 * @vha: host adapter pointer
 * @bsg_job: user request pointer
 */
static int
qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	int32_t			rval = 0;
	int32_t			pcnt = 0;
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	struct app_pinfo_req	app_req;
	struct app_pinfo_reply	*app_reply;
	port_id_t		tdid;

	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app get fcinfo\n", __func__);

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &app_req,
	    sizeof(struct app_pinfo_req));

	app_reply = kzalloc((sizeof(struct app_pinfo_reply) +
	    sizeof(struct app_pinfo) * app_req.num_ports), GFP_KERNEL);

	if (!app_reply) {
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		rval = -1;
	} else {
		struct fc_port	*fcport = NULL, *tf;

		app_reply->version = EDIF_VERSION1;

		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
			if (!(fcport->flags & FCF_FCSP_DEVICE))
				continue;

			tdid = app_req.remote_pid;

			ql_dbg(ql_dbg_edif, vha, 0x2058,
			    "APP request entry - portid=%06x.\n", tdid.b24);

			/* Ran out of space */
			if (pcnt >= app_req.num_ports)
				break;

			if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24)
				continue;

			if (!N2N_TOPO(vha->hw)) {
				if (fcport->scan_state != QLA_FCPORT_FOUND)
					continue;

				if (fcport->port_type == FCT_UNKNOWN &&
				    !fcport->fc4_features)
					rval = qla24xx_async_gffid(vha, fcport,
								   true);

				if (!rval &&
				    !(fcport->fc4_features & FC4_FF_TARGET ||
				      fcport->port_type &
				      (FCT_TARGET | FCT_NVME_TARGET)))
					continue;
			}

			rval = 0;

			app_reply->ports[pcnt].version = EDIF_VERSION1;
			app_reply->ports[pcnt].remote_type =
				VND_CMD_RTYPE_UNKNOWN;
			if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET))
				app_reply->ports[pcnt].remote_type |=
					VND_CMD_RTYPE_TARGET;
			if (fcport->port_type & (FCT_NVME_INITIATOR | FCT_INITIATOR))
				app_reply->ports[pcnt].remote_type |=
					VND_CMD_RTYPE_INITIATOR;

			app_reply->ports[pcnt].remote_pid = fcport->d_id;

			ql_dbg(ql_dbg_edif, vha, 0x2058,
			    "Found FC_SP fcport - nn %8phN pn %8phN pcnt %d portid=%06x secure %d.\n",
			    fcport->node_name, fcport->port_name, pcnt,
			    fcport->d_id.b24, fcport->flags & FCF_FCSP_DEVICE);

			switch (fcport->edif.auth_state) {
			case VND_CMD_AUTH_STATE_ELS_RCVD:
				if (fcport->disc_state == DSC_LOGIN_AUTH_PEND) {
					fcport->edif.auth_state = VND_CMD_AUTH_STATE_NEEDED;
					app_reply->ports[pcnt].auth_state =
						VND_CMD_AUTH_STATE_NEEDED;
				} else {
					app_reply->ports[pcnt].auth_state =
						VND_CMD_AUTH_STATE_ELS_RCVD;
				}
				break;
			default:
				app_reply->ports[pcnt].auth_state = fcport->edif.auth_state;
				break;
			}

			memcpy(app_reply->ports[pcnt].remote_wwpn,
			    fcport->port_name, 8);

			app_reply->ports[pcnt].remote_state =
				(atomic_read(&fcport->state) ==
				    FCS_ONLINE ? 1 : 0);

			pcnt++;

			if (tdid.b24 != 0)
				break;
		}
		app_reply->port_count = pcnt;
		SET_DID_STATUS(bsg_reply->result, DID_OK);
	}

	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
							       bsg_job->reply_payload.sg_cnt,
							       app_reply,
							       sizeof(struct app_pinfo_reply) + sizeof(struct app_pinfo) * pcnt);

	kfree(app_reply);

	return rval;
}

/**
 * qla_edif_app_getstats - app would like to read various statistics info
 * @vha: host adapter pointer
 * @bsg_job: user request
 */
static int32_t
qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	int32_t			rval = 0;
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	uint32_t size;

	struct app_sinfo_req	app_req;
	struct app_stats_reply	*app_reply;
	uint32_t pcnt = 0;

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &app_req,
	    sizeof(struct app_sinfo_req));
	if (app_req.num_ports == 0) {
		ql_dbg(ql_dbg_async, vha, 0x911d,
		   "%s app did not indicate number of ports to return\n",
		    __func__);
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		rval = -1;
	}

	size = sizeof(struct app_stats_reply) +
	    (sizeof(struct app_sinfo) * app_req.num_ports);

	app_reply = kzalloc(size, GFP_KERNEL);
	if (!app_reply) {
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		rval = -1;
	} else {
		struct fc_port	*fcport = NULL, *tf;

		app_reply->version = EDIF_VERSION1;

		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
			if (fcport->edif.enable) {
				if (pcnt > app_req.num_ports)
					break;

				app_reply->elem[pcnt].rekey_count =
				    fcport->edif.rekey_cnt;
				app_reply->elem[pcnt].tx_bytes =
				    fcport->edif.tx_bytes;
				app_reply->elem[pcnt].rx_bytes =
				    fcport->edif.rx_bytes;

				memcpy(app_reply->elem[pcnt].remote_wwpn,
				    fcport->port_name, 8);

				pcnt++;
			}
		}
		app_reply->elem_count = pcnt;
		SET_DID_STATUS(bsg_reply->result, DID_OK);
	}

	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	bsg_reply->reply_payload_rcv_len =
	    sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
	       bsg_job->reply_payload.sg_cnt, app_reply,
	       sizeof(struct app_stats_reply) + (sizeof(struct app_sinfo) * pcnt));

	kfree(app_reply);

	return rval;
}

static int32_t
qla_edif_ack(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	struct fc_port *fcport;
	struct aen_complete_cmd ack;
	struct fc_bsg_reply     *bsg_reply = bsg_job->reply;

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
			  bsg_job->request_payload.sg_cnt, &ack, sizeof(ack));

	ql_dbg(ql_dbg_edif, vha, 0x70cf,
	       "%s: %06x event_code %x\n",
	       __func__, ack.port_id.b24, ack.event_code);

	fcport = qla2x00_find_fcport_by_pid(vha, &ack.port_id);
	SET_DID_STATUS(bsg_reply->result, DID_OK);

	if (!fcport) {
		ql_dbg(ql_dbg_edif, vha, 0x70cf,
		       "%s: unable to find fcport %06x \n",
		       __func__, ack.port_id.b24);
		return 0;
	}

	switch (ack.event_code) {
	case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
		fcport->edif.sess_down_acked = 1;
		break;
	default:
		break;
	}
	return 0;
}

static int qla_edif_consume_dbell(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	u32 sg_skip, reply_payload_len;
	bool keep;
	struct edb_node *dbnode = NULL;
	struct edif_app_dbell ap;
	int dat_size = 0;

	sg_skip = 0;
	reply_payload_len = bsg_job->reply_payload.payload_len;

	while ((reply_payload_len - sg_skip) >= sizeof(struct edb_node)) {
		dbnode = qla_edb_getnext(vha);
		if (dbnode) {
			keep = true;
			dat_size = 0;
			ap.event_code = dbnode->ntype;
			switch (dbnode->ntype) {
			case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
			case VND_CMD_AUTH_STATE_NEEDED:
				ap.port_id = dbnode->u.plogi_did;
				dat_size += sizeof(ap.port_id);
				break;
			case VND_CMD_AUTH_STATE_ELS_RCVD:
				ap.port_id = dbnode->u.els_sid;
				dat_size += sizeof(ap.port_id);
				break;
			case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
				ap.port_id = dbnode->u.sa_aen.port_id;
				memcpy(&ap.event_data, &dbnode->u,
				    sizeof(struct edif_sa_update_aen));
				dat_size += sizeof(struct edif_sa_update_aen);
				break;
			default:
				keep = false;
				ql_log(ql_log_warn, vha, 0x09102,
					"%s unknown DB type=%d %p\n",
					__func__, dbnode->ntype, dbnode);
				break;
			}
			ap.event_data_size = dat_size;
			/* 8 = sizeof(ap.event_code + ap.event_data_size) */
			dat_size += 8;
			if (keep)
				sg_skip += sg_copy_buffer(bsg_job->reply_payload.sg_list,
						bsg_job->reply_payload.sg_cnt,
						&ap, dat_size, sg_skip, false);

			ql_dbg(ql_dbg_edif, vha, 0x09102,
				"%s Doorbell consumed : type=%d %p\n",
				__func__, dbnode->ntype, dbnode);

			kfree(dbnode);
		} else {
			break;
		}
	}

	SET_DID_STATUS(bsg_reply->result, DID_OK);
	bsg_reply->reply_payload_rcv_len = sg_skip;
	bsg_job->reply_len = sizeof(struct fc_bsg_reply);

	return 0;
}

static void __qla_edif_dbell_bsg_done(scsi_qla_host_t *vha, struct bsg_job *bsg_job,
	u32 delay)
{
	struct fc_bsg_reply *bsg_reply = bsg_job->reply;

	/* small sleep for doorbell events to accumulate */
	if (delay)
		msleep(delay);

	qla_edif_consume_dbell(vha, bsg_job);

	bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len);
}

static void qla_edif_dbell_bsg_done(scsi_qla_host_t *vha)
{
	unsigned long flags;
	struct bsg_job *prev_bsg_job = NULL;

	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
	if (vha->e_dbell.dbell_bsg_job) {
		prev_bsg_job = vha->e_dbell.dbell_bsg_job;
		vha->e_dbell.dbell_bsg_job = NULL;
	}
	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);

	if (prev_bsg_job)
		__qla_edif_dbell_bsg_done(vha, prev_bsg_job, 0);
}

static int
qla_edif_dbell_bsg(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	unsigned long flags;
	bool return_bsg = false;

	/* flush previous dbell bsg */
	qla_edif_dbell_bsg_done(vha);

	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
	if (list_empty(&vha->e_dbell.head) && DBELL_ACTIVE(vha)) {
		/*
		 * when the next db event happens, bsg_job will return.
		 * Otherwise, timer will return it.
		 */
		vha->e_dbell.dbell_bsg_job = bsg_job;
		vha->e_dbell.bsg_expire = jiffies + 10 * HZ;
	} else {
		return_bsg = true;
	}
	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);

	if (return_bsg)
		__qla_edif_dbell_bsg_done(vha, bsg_job, 1);

	return 0;
}

int32_t
qla_edif_app_mgmt(struct bsg_job *bsg_job)
{
	struct fc_bsg_request	*bsg_request = bsg_job->request;
	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
	scsi_qla_host_t		*vha = shost_priv(host);
	struct app_id		appcheck;
	bool done = true;
	int32_t         rval = 0;
	uint32_t	vnd_sc = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
	u32 level = ql_dbg_edif;

	/* doorbell is high traffic */
	if (vnd_sc == QL_VND_SC_READ_DBELL)
		level = 0;

	ql_dbg(level, vha, 0x911d, "%s vnd subcmd=%x\n",
	    __func__, vnd_sc);

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &appcheck,
	    sizeof(struct app_id));

	if (!vha->hw->flags.edif_enabled ||
		test_bit(VPORT_DELETE, &vha->dpc_flags)) {
		ql_dbg(level, vha, 0x911d,
		    "%s edif not enabled or vp delete. bsg ptr done %p. dpc_flags %lx\n",
		    __func__, bsg_job, vha->dpc_flags);

		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		goto done;
	}

	if (!qla_edif_app_check(vha, appcheck)) {
		ql_dbg(level, vha, 0x911d,
		    "%s app checked failed.\n",
		    __func__);

		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		goto done;
	}

	switch (vnd_sc) {
	case QL_VND_SC_SA_UPDATE:
		done = false;
		rval = qla24xx_sadb_update(bsg_job);
		break;
	case QL_VND_SC_APP_START:
		rval = qla_edif_app_start(vha, bsg_job);
		break;
	case QL_VND_SC_APP_STOP:
		rval = qla_edif_app_stop(vha, bsg_job);
		break;
	case QL_VND_SC_AUTH_OK:
		rval = qla_edif_app_authok(vha, bsg_job);
		break;
	case QL_VND_SC_AUTH_FAIL:
		rval = qla_edif_app_authfail(vha, bsg_job);
		break;
	case QL_VND_SC_GET_FCINFO:
		rval = qla_edif_app_getfcinfo(vha, bsg_job);
		break;
	case QL_VND_SC_GET_STATS:
		rval = qla_edif_app_getstats(vha, bsg_job);
		break;
	case QL_VND_SC_AEN_COMPLETE:
		rval = qla_edif_ack(vha, bsg_job);
		break;
	case QL_VND_SC_READ_DBELL:
		rval = qla_edif_dbell_bsg(vha, bsg_job);
		done = false;
		break;
	default:
		ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n",
		    __func__,
		    bsg_request->rqst_data.h_vendor.vendor_cmd[1]);
		rval = EXT_STATUS_INVALID_PARAM;
		done = false;
		break;
	}

done:
	if (done) {
		ql_dbg(level, vha, 0x7009,
		    "%s: %d  bsg ptr done %p\n", __func__, __LINE__, bsg_job);
		bsg_job_done(bsg_job, bsg_reply->result,
		    bsg_reply->reply_payload_rcv_len);
	}

	return rval;
}

static struct edif_sa_ctl *
qla_edif_add_sa_ctl(fc_port_t *fcport, struct qla_sa_update_frame *sa_frame,
	int dir)
{
	struct	edif_sa_ctl *sa_ctl;
	struct qla_sa_update_frame *sap;
	int	index = sa_frame->fast_sa_index;
	unsigned long flags = 0;

	sa_ctl = kzalloc(sizeof(*sa_ctl), GFP_KERNEL);
	if (!sa_ctl) {
		/* couldn't get space */
		ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
		    "unable to allocate SA CTL\n");
		return NULL;
	}

	/*
	 * need to allocate sa_index here and save it
	 * in both sa_ctl->index and sa_frame->fast_sa_index;
	 * If alloc fails then delete sa_ctl and return NULL
	 */
	INIT_LIST_HEAD(&sa_ctl->next);
	sap = &sa_ctl->sa_frame;
	*sap = *sa_frame;
	sa_ctl->index = index;
	sa_ctl->fcport = fcport;
	sa_ctl->flags = 0;
	sa_ctl->state = 0L;
	ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
	    "%s: Added sa_ctl %p, index %d, state 0x%lx\n",
	    __func__, sa_ctl, sa_ctl->index, sa_ctl->state);
	spin_lock_irqsave(&fcport->edif.sa_list_lock, flags);
	if (dir == SAU_FLG_TX)
		list_add_tail(&sa_ctl->next, &fcport->edif.tx_sa_list);
	else
		list_add_tail(&sa_ctl->next, &fcport->edif.rx_sa_list);
	spin_unlock_irqrestore(&fcport->edif.sa_list_lock, flags);

	return sa_ctl;
}

void
qla_edif_flush_sa_ctl_lists(fc_port_t *fcport)
{
	struct edif_sa_ctl *sa_ctl, *tsa_ctl;
	unsigned long flags = 0;

	spin_lock_irqsave(&fcport->edif.sa_list_lock, flags);

	list_for_each_entry_safe(sa_ctl, tsa_ctl, &fcport->edif.tx_sa_list,
	    next) {
		list_del(&sa_ctl->next);
		kfree(sa_ctl);
	}

	list_for_each_entry_safe(sa_ctl, tsa_ctl, &fcport->edif.rx_sa_list,
	    next) {
		list_del(&sa_ctl->next);
		kfree(sa_ctl);
	}

	spin_unlock_irqrestore(&fcport->edif.sa_list_lock, flags);
}

struct edif_sa_ctl *
qla_edif_find_sa_ctl_by_index(fc_port_t *fcport, int index, int dir)
{
	struct edif_sa_ctl *sa_ctl, *tsa_ctl;
	struct list_head *sa_list;

	if (dir == SAU_FLG_TX)
		sa_list = &fcport->edif.tx_sa_list;
	else
		sa_list = &fcport->edif.rx_sa_list;

	list_for_each_entry_safe(sa_ctl, tsa_ctl, sa_list, next) {
		if (test_bit(EDIF_SA_CTL_USED, &sa_ctl->state) &&
		    sa_ctl->index == index)
			return sa_ctl;
	}
	return NULL;
}

/* add the sa to the correct list */
static int
qla24xx_check_sadb_avail_slot(struct bsg_job *bsg_job, fc_port_t *fcport,
	struct qla_sa_update_frame *sa_frame)
{
	struct edif_sa_ctl *sa_ctl = NULL;
	int dir;
	uint16_t sa_index;

	dir = (sa_frame->flags & SAU_FLG_TX);

	/* map the spi to an sa_index */
	sa_index = qla_edif_sadb_get_sa_index(fcport, sa_frame);
	if (sa_index == RX_DELETE_NO_EDIF_SA_INDEX) {
		/* process rx delete */
		ql_dbg(ql_dbg_edif, fcport->vha, 0x3063,
		    "%s: rx delete for lid 0x%x, spi 0x%x, no entry found\n",
		    __func__, fcport->loop_id, sa_frame->spi);

		/* build and send the aen */
		fcport->edif.rx_sa_set = 1;
		fcport->edif.rx_sa_pending = 0;
		qla_edb_eventcreate(fcport->vha,
		    VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
		    QL_VND_SA_STAT_SUCCESS,
		    QL_VND_RX_SA_KEY, fcport);

		/* force a return of good bsg status; */
		return RX_DELETE_NO_EDIF_SA_INDEX;
	} else if (sa_index == INVALID_EDIF_SA_INDEX) {
		ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
		    "%s: Failed to get sa_index for spi 0x%x, dir: %d\n",
		    __func__, sa_frame->spi, dir);
		return INVALID_EDIF_SA_INDEX;
	}

	ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
	    "%s: index %d allocated to spi 0x%x, dir: %d, nport_handle: 0x%x\n",
	    __func__, sa_index, sa_frame->spi, dir, fcport->loop_id);

	/* This is a local copy of sa_frame. */
	sa_frame->fast_sa_index = sa_index;
	/* create the sa_ctl */
	sa_ctl = qla_edif_add_sa_ctl(fcport, sa_frame, dir);
	if (!sa_ctl) {
		ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
		    "%s: Failed to add sa_ctl for spi 0x%x, dir: %d, sa_index: %d\n",
		    __func__, sa_frame->spi, dir, sa_index);
		return -1;
	}

	set_bit(EDIF_SA_CTL_USED, &sa_ctl->state);

	if (dir == SAU_FLG_TX)
		fcport->edif.tx_rekey_cnt++;
	else
		fcport->edif.rx_rekey_cnt++;

	ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
	    "%s: Found sa_ctl %p, index %d, state 0x%lx, tx_cnt %d, rx_cnt %d, nport_handle: 0x%x\n",
	    __func__, sa_ctl, sa_ctl->index, sa_ctl->state,
	    fcport->edif.tx_rekey_cnt,
	    fcport->edif.rx_rekey_cnt, fcport->loop_id);

	return 0;
}

#define QLA_SA_UPDATE_FLAGS_RX_KEY      0x0
#define QLA_SA_UPDATE_FLAGS_TX_KEY      0x2
#define EDIF_MSLEEP_INTERVAL 100
#define EDIF_RETRY_COUNT  50

int
qla24xx_sadb_update(struct bsg_job *bsg_job)
{
	struct	fc_bsg_reply	*bsg_reply = bsg_job->reply;
	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
	scsi_qla_host_t *vha = shost_priv(host);
	fc_port_t		*fcport = NULL;
	srb_t			*sp = NULL;
	struct edif_list_entry *edif_entry = NULL;
	int			found = 0;
	int			rval = 0;
	int result = 0, cnt;
	struct qla_sa_update_frame sa_frame;
	struct srb_iocb *iocb_cmd;
	port_id_t portid;

	ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x911d,
	    "%s entered, vha: 0x%p\n", __func__, vha);

	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, &sa_frame,
	    sizeof(struct qla_sa_update_frame));

	/* Check if host is online */
	if (!vha->flags.online) {
		ql_log(ql_log_warn, vha, 0x70a1, "Host is not online\n");
		rval = -EIO;
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		goto done;
	}

	if (DBELL_INACTIVE(vha)) {
		ql_log(ql_log_warn, vha, 0x70a1, "App not started\n");
		rval = -EIO;
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		goto done;
	}

	/* silent unaligned access warning */
	portid.b.domain = sa_frame.port_id.b.domain;
	portid.b.area   = sa_frame.port_id.b.area;
	portid.b.al_pa  = sa_frame.port_id.b.al_pa;

	fcport = qla2x00_find_fcport_by_pid(vha, &portid);
	if (fcport) {
		found = 1;
		if (sa_frame.flags == QLA_SA_UPDATE_FLAGS_TX_KEY)
			fcport->edif.tx_bytes = 0;
		if (sa_frame.flags == QLA_SA_UPDATE_FLAGS_RX_KEY)
			fcport->edif.rx_bytes = 0;
	}

	if (!found) {
		ql_dbg(ql_dbg_edif, vha, 0x70a3, "Failed to find port= %06x\n",
		    sa_frame.port_id.b24);
		rval = -EINVAL;
		SET_DID_STATUS(bsg_reply->result, DID_TARGET_FAILURE);
		goto done;
	}

	/* make sure the nport_handle is valid */
	if (fcport->loop_id == FC_NO_LOOP_ID) {
		ql_dbg(ql_dbg_edif, vha, 0x70e1,
		    "%s: %8phN lid=FC_NO_LOOP_ID, spi: 0x%x, DS %d, returning NO_CONNECT\n",
		    __func__, fcport->port_name, sa_frame.spi,
		    fcport->disc_state);
		rval = -EINVAL;
		SET_DID_STATUS(bsg_reply->result, DID_NO_CONNECT);
		goto done;
	}

	/* allocate and queue an sa_ctl */
	result = qla24xx_check_sadb_avail_slot(bsg_job, fcport, &sa_frame);

	/* failure of bsg */
	if (result == INVALID_EDIF_SA_INDEX) {
		ql_dbg(ql_dbg_edif, vha, 0x70e1,
		    "%s: %8phN, skipping update.\n",
		    __func__, fcport->port_name);
		rval = -EINVAL;
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		goto done;

	/* rx delete failure */
	} else if (result == RX_DELETE_NO_EDIF_SA_INDEX) {
		ql_dbg(ql_dbg_edif, vha, 0x70e1,
		    "%s: %8phN, skipping rx delete.\n",
		    __func__, fcport->port_name);
		SET_DID_STATUS(bsg_reply->result, DID_OK);
		goto done;
	}

	ql_dbg(ql_dbg_edif, vha, 0x70e1,
	    "%s: %8phN, sa_index in sa_frame: %d flags %xh\n",
	    __func__, fcport->port_name, sa_frame.fast_sa_index,
	    sa_frame.flags);

	/* looking for rx index and delete */
	if (((sa_frame.flags & SAU_FLG_TX) == 0) &&
	    (sa_frame.flags & SAU_FLG_INV)) {
		uint16_t nport_handle = fcport->loop_id;
		uint16_t sa_index = sa_frame.fast_sa_index;

		/*
		 * make sure we have an existing rx key, otherwise just process
		 * this as a straight delete just like TX
		 * This is NOT a normal case, it indicates an error recovery or key cleanup
		 * by the ipsec code above us.
		 */
		edif_entry = qla_edif_list_find_sa_index(fcport, fcport->loop_id);
		if (!edif_entry) {
			ql_dbg(ql_dbg_edif, vha, 0x911d,
			    "%s: WARNING: no active sa_index for nport_handle 0x%x, forcing delete for sa_index 0x%x\n",
			    __func__, fcport->loop_id, sa_index);
			goto force_rx_delete;
		}

		/*
		 * if we have a forced delete for rx, remove the sa_index from the edif list
		 * and proceed with normal delete.  The rx delay timer should not be running
		 */
		if ((sa_frame.flags & SAU_FLG_FORCE_DELETE) == SAU_FLG_FORCE_DELETE) {
			qla_edif_list_delete_sa_index(fcport, edif_entry);
			ql_dbg(ql_dbg_edif, vha, 0x911d,
			    "%s: FORCE DELETE flag found for nport_handle 0x%x, sa_index 0x%x, forcing DELETE\n",
			    __func__, fcport->loop_id, sa_index);
			kfree(edif_entry);
			goto force_rx_delete;
		}

		/*
		 * delayed rx delete
		 *
		 * if delete_sa_index is not invalid then there is already
		 * a delayed index in progress, return bsg bad status
		 */
		if (edif_entry->delete_sa_index != INVALID_EDIF_SA_INDEX) {
			struct edif_sa_ctl *sa_ctl;

			ql_dbg(ql_dbg_edif, vha, 0x911d,
			    "%s: delete for lid 0x%x, delete_sa_index %d is pending\n",
			    __func__, edif_entry->handle, edif_entry->delete_sa_index);

			/* free up the sa_ctl that was allocated with the sa_index */
			sa_ctl = qla_edif_find_sa_ctl_by_index(fcport, sa_index,
			    (sa_frame.flags & SAU_FLG_TX));
			if (sa_ctl) {
				ql_dbg(ql_dbg_edif, vha, 0x3063,
				    "%s: freeing sa_ctl for index %d\n",
				    __func__, sa_ctl->index);
				qla_edif_free_sa_ctl(fcport, sa_ctl, sa_ctl->index);
			}

			/* release the sa_index */
			ql_dbg(ql_dbg_edif, vha, 0x3063,
			    "%s: freeing sa_index %d, nph: 0x%x\n",
			    __func__, sa_index, nport_handle);
			qla_edif_sadb_delete_sa_index(fcport, nport_handle, sa_index);

			rval = -EINVAL;
			SET_DID_STATUS(bsg_reply->result, DID_ERROR);
			goto done;
		}

		fcport->edif.rekey_cnt++;

		/* configure and start the rx delay timer */
		edif_entry->fcport = fcport;
		edif_entry->timer.expires = jiffies + RX_DELAY_DELETE_TIMEOUT * HZ;

		ql_dbg(ql_dbg_edif, vha, 0x911d,
		    "%s: adding timer, entry: %p, delete sa_index %d, lid 0x%x to edif_list\n",
		    __func__, edif_entry, sa_index, nport_handle);

		/*
		 * Start the timer when we queue the delayed rx delete.
		 * This is an activity timer that goes off if we have not
		 * received packets with the new sa_index
		 */
		add_timer(&edif_entry->timer);

		/*
		 * sa_delete for rx key with an active rx key including this one
		 * add the delete rx sa index to the hash so we can look for it
		 * in the rsp queue.  Do this after making any changes to the
		 * edif_entry as part of the rx delete.
		 */

		ql_dbg(ql_dbg_edif, vha, 0x911d,
		    "%s: delete sa_index %d, lid 0x%x to edif_list. bsg done ptr %p\n",
		    __func__, sa_index, nport_handle, bsg_job);

		edif_entry->delete_sa_index = sa_index;

		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
		bsg_reply->result = DID_OK << 16;

		goto done;

	/*
	 * rx index and update
	 * add the index to the list and continue with normal update
	 */
	} else if (((sa_frame.flags & SAU_FLG_TX) == 0) &&
	    ((sa_frame.flags & SAU_FLG_INV) == 0)) {
		/* sa_update for rx key */
		uint32_t nport_handle = fcport->loop_id;
		uint16_t sa_index = sa_frame.fast_sa_index;
		int result;

		/*
		 * add the update rx sa index to the hash so we can look for it
		 * in the rsp queue and continue normally
		 */

		ql_dbg(ql_dbg_edif, vha, 0x911d,
		    "%s:  adding update sa_index %d, lid 0x%x to edif_list\n",
		    __func__, sa_index, nport_handle);

		result = qla_edif_list_add_sa_update_index(fcport, sa_index,
		    nport_handle);
		if (result) {
			ql_dbg(ql_dbg_edif, vha, 0x911d,
			    "%s: SA_UPDATE failed to add new sa index %d to list for lid 0x%x\n",
			    __func__, sa_index, nport_handle);
		}
	}
	if (sa_frame.flags & SAU_FLG_GMAC_MODE)
		fcport->edif.aes_gmac = 1;
	else
		fcport->edif.aes_gmac = 0;

force_rx_delete:
	/*
	 * sa_update for both rx and tx keys, sa_delete for tx key
	 * immediately process the request
	 */
	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
	if (!sp) {
		rval = -ENOMEM;
		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
		goto done;
	}

	sp->type = SRB_SA_UPDATE;
	sp->name = "bsg_sa_update";
	sp->u.bsg_job = bsg_job;
	/* sp->free = qla2x00_bsg_sp_free; */
	sp->free = qla2x00_rel_sp;
	sp->done = qla2x00_bsg_job_done;
	iocb_cmd = &sp->u.iocb_cmd;
	iocb_cmd->u.sa_update.sa_frame  = sa_frame;
	cnt = 0;
retry:
	rval = qla2x00_start_sp(sp);
	switch (rval) {
	case QLA_SUCCESS:
		break;
	case EAGAIN:
		msleep(EDIF_MSLEEP_INTERVAL);
		cnt++;
		if (cnt < EDIF_RETRY_COUNT)
			goto retry;

		fallthrough;
	default:
		ql_log(ql_dbg_edif, vha, 0x70e3,
		       "%s qla2x00_start_sp failed=%d.\n",
		       __func__, rval);

		qla2x00_rel_sp(sp);
		rval = -EIO;
		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
		goto done;
	}

	ql_dbg(ql_dbg_edif, vha, 0x911d,
	    "%s:  %s sent, hdl=%x, portid=%06x.\n",
	    __func__, sp->name, sp->handle, fcport->d_id.b24);

	fcport->edif.rekey_cnt++;
	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	SET_DID_STATUS(bsg_reply->result, DID_OK);

	return 0;

/*
 * send back error status
 */
done:
	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
	ql_dbg(ql_dbg_edif, vha, 0x911d,
	    "%s:status: FAIL, result: 0x%x, bsg ptr done %p\n",
	    __func__, bsg_reply->result, bsg_job);
	bsg_job_done(bsg_job, bsg_reply->result,
	    bsg_reply->reply_payload_rcv_len);

	return 0;
}

static void
qla_enode_free(scsi_qla_host_t *vha, struct enode *node)
{
	node->ntype = N_UNDEF;
	kfree(node);
}

/**
 * qla_enode_init - initialize enode structs & lock
 * @vha: host adapter pointer
 *
 * should only be called when driver attaching
 */
void
qla_enode_init(scsi_qla_host_t *vha)
{
	struct	qla_hw_data *ha = vha->hw;
	char	name[32];

	if (vha->pur_cinfo.enode_flags == ENODE_ACTIVE) {
		/* list still active - error */
		ql_dbg(ql_dbg_edif, vha, 0x09102, "%s enode still active\n",
		    __func__);
		return;
	}

	/* initialize lock which protects pur_core & init list */
	spin_lock_init(&vha->pur_cinfo.pur_lock);
	INIT_LIST_HEAD(&vha->pur_cinfo.head);

	snprintf(name, sizeof(name), "%s_%d_purex", QLA2XXX_DRIVER_NAME,
	    ha->pdev->device);
}

/**
 * qla_enode_stop - stop and clear and enode data
 * @vha: host adapter pointer
 *
 * called when app notified it is exiting
 */
void
qla_enode_stop(scsi_qla_host_t *vha)
{
	unsigned long flags;
	struct enode *node, *q;

	if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
		/* doorbell list not enabled */
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "%s enode not active\n", __func__);
		return;
	}

	/* grab lock so list doesn't move */
	spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);

	vha->pur_cinfo.enode_flags &= ~ENODE_ACTIVE; /* mark it not active */

	/* hopefully this is a null list at this point */
	list_for_each_entry_safe(node, q, &vha->pur_cinfo.head, list) {
		ql_dbg(ql_dbg_edif, vha, 0x910f,
		    "%s freeing enode type=%x, cnt=%x\n", __func__, node->ntype,
		    node->dinfo.nodecnt);
		list_del_init(&node->list);
		qla_enode_free(vha, node);
	}
	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);
}

static void qla_enode_clear(scsi_qla_host_t *vha, port_id_t portid)
{
	unsigned    long flags;
	struct enode    *e, *tmp;
	struct purexevent   *purex;
	LIST_HEAD(enode_list);

	if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		       "%s enode not active\n", __func__);
		return;
	}
	spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);
	list_for_each_entry_safe(e, tmp, &vha->pur_cinfo.head, list) {
		purex = &e->u.purexinfo;
		if (purex->pur_info.pur_sid.b24 == portid.b24) {
			ql_dbg(ql_dbg_edif, vha, 0x911d,
			    "%s free ELS sid=%06x. xchg %x, nb=%xh\n",
			    __func__, portid.b24,
			    purex->pur_info.pur_rx_xchg_address,
			    purex->pur_info.pur_bytes_rcvd);

			list_del_init(&e->list);
			list_add_tail(&e->list, &enode_list);
		}
	}
	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);

	list_for_each_entry_safe(e, tmp, &enode_list, list) {
		list_del_init(&e->list);
		qla_enode_free(vha, e);
	}
}

/*
 *  allocate enode struct and populate buffer
 *  returns: enode pointer with buffers
 *           NULL on error
 */
static struct enode *
qla_enode_alloc(scsi_qla_host_t *vha, uint32_t ntype)
{
	struct enode		*node;
	struct purexevent	*purex;

	node = kzalloc(RX_ELS_SIZE, GFP_ATOMIC);
	if (!node)
		return NULL;

	purex = &node->u.purexinfo;
	purex->msgp = (u8 *)(node + 1);
	purex->msgp_len = ELS_MAX_PAYLOAD;

	node->ntype = ntype;
	INIT_LIST_HEAD(&node->list);
	return node;
}

static void
qla_enode_add(scsi_qla_host_t *vha, struct enode *ptr)
{
	unsigned long flags;

	ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x9109,
	    "%s add enode for type=%x, cnt=%x\n",
	    __func__, ptr->ntype, ptr->dinfo.nodecnt);

	spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);
	list_add_tail(&ptr->list, &vha->pur_cinfo.head);
	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);

	return;
}

static struct enode *
qla_enode_find(scsi_qla_host_t *vha, uint32_t ntype, uint32_t p1, uint32_t p2)
{
	struct enode		*node_rtn = NULL;
	struct enode		*list_node, *q;
	unsigned long		flags;
	uint32_t		sid;
	struct purexevent	*purex;

	/* secure the list from moving under us */
	spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);

	list_for_each_entry_safe(list_node, q, &vha->pur_cinfo.head, list) {

		/* node type determines what p1 and p2 are */
		purex = &list_node->u.purexinfo;
		sid = p1;

		if (purex->pur_info.pur_sid.b24 == sid) {
			/* found it and its complete */
			node_rtn = list_node;
			list_del(&list_node->list);
			break;
		}
	}

	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);

	return node_rtn;
}

/**
 * qla_pur_get_pending - read/return authentication message sent
 *  from remote port
 * @vha: host adapter pointer
 * @fcport: session pointer
 * @bsg_job: user request where the message is copy to.
 */
static int
qla_pur_get_pending(scsi_qla_host_t *vha, fc_port_t *fcport,
	struct bsg_job *bsg_job)
{
	struct enode		*ptr;
	struct purexevent	*purex;
	struct qla_bsg_auth_els_reply *rpl =
	    (struct qla_bsg_auth_els_reply *)bsg_job->reply;

	bsg_job->reply_len = sizeof(*rpl);

	ptr = qla_enode_find(vha, N_PUREX, fcport->d_id.b24, PUR_GET);
	if (!ptr) {
		ql_dbg(ql_dbg_edif, vha, 0x9111,
		    "%s no enode data found for %8phN sid=%06x\n",
		    __func__, fcport->port_name, fcport->d_id.b24);
		SET_DID_STATUS(rpl->r.result, DID_IMM_RETRY);
		return -EIO;
	}

	/*
	 * enode is now off the linked list and is ours to deal with
	 */
	purex = &ptr->u.purexinfo;

	/* Copy info back to caller */
	rpl->rx_xchg_address = purex->pur_info.pur_rx_xchg_address;

	SET_DID_STATUS(rpl->r.result, DID_OK);
	rpl->r.reply_payload_rcv_len =
	    sg_pcopy_from_buffer(bsg_job->reply_payload.sg_list,
		bsg_job->reply_payload.sg_cnt, purex->msgp,
		purex->pur_info.pur_bytes_rcvd, 0);

	/* data copy / passback completed - destroy enode */
	qla_enode_free(vha, ptr);

	return 0;
}

/* it is assume qpair lock is held */
static int
qla_els_reject_iocb(scsi_qla_host_t *vha, struct qla_qpair *qp,
	struct qla_els_pt_arg *a)
{
	struct els_entry_24xx *els_iocb;

	els_iocb = __qla2x00_alloc_iocbs(qp, NULL);
	if (!els_iocb) {
		ql_log(ql_log_warn, vha, 0x700c,
		    "qla2x00_alloc_iocbs failed.\n");
		return QLA_FUNCTION_FAILED;
	}

	qla_els_pt_iocb(vha, els_iocb, a);

	ql_dbg(ql_dbg_edif, vha, 0x0183,
	    "Sending ELS reject ox_id %04x s:%06x -> d:%06x\n",
	    a->ox_id, a->sid.b24, a->did.b24);
	ql_dump_buffer(ql_dbg_edif + ql_dbg_verbose, vha, 0x0185,
	    vha->hw->elsrej.c, sizeof(*vha->hw->elsrej.c));
	/* flush iocb to mem before notifying hw doorbell */
	wmb();
	qla2x00_start_iocbs(vha, qp->req);
	return 0;
}

void
qla_edb_init(scsi_qla_host_t *vha)
{
	if (DBELL_ACTIVE(vha)) {
		/* list already init'd - error */
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "edif db already initialized, cannot reinit\n");
		return;
	}

	/* initialize lock which protects doorbell & init list */
	spin_lock_init(&vha->e_dbell.db_lock);
	INIT_LIST_HEAD(&vha->e_dbell.head);
}

static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid)
{
	unsigned long flags;
	struct edb_node *e, *tmp;
	port_id_t sid;
	LIST_HEAD(edb_list);

	if (DBELL_INACTIVE(vha)) {
		/* doorbell list not enabled */
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		       "%s doorbell not enabled\n", __func__);
		return;
	}

	/* grab lock so list doesn't move */
	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
	list_for_each_entry_safe(e, tmp, &vha->e_dbell.head, list) {
		switch (e->ntype) {
		case VND_CMD_AUTH_STATE_NEEDED:
		case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
			sid = e->u.plogi_did;
			break;
		case VND_CMD_AUTH_STATE_ELS_RCVD:
			sid = e->u.els_sid;
			break;
		case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
			/* app wants to see this  */
			continue;
		default:
			ql_log(ql_log_warn, vha, 0x09102,
			       "%s unknown node type: %x\n", __func__, e->ntype);
			sid.b24 = 0;
			break;
		}
		if (sid.b24 == portid.b24) {
			ql_dbg(ql_dbg_edif, vha, 0x910f,
			       "%s free doorbell event : node type = %x %p\n",
			       __func__, e->ntype, e);
			list_del_init(&e->list);
			list_add_tail(&e->list, &edb_list);
		}
	}
	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);

	list_for_each_entry_safe(e, tmp, &edb_list, list)
		qla_edb_node_free(vha, e);
}

/* function called when app is stopping */

void
qla_edb_stop(scsi_qla_host_t *vha)
{
	unsigned long flags;
	struct edb_node *node, *q;

	if (DBELL_INACTIVE(vha)) {
		/* doorbell list not enabled */
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "%s doorbell not enabled\n", __func__);
		return;
	}

	/* grab lock so list doesn't move */
	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);

	vha->e_dbell.db_flags &= ~EDB_ACTIVE; /* mark it not active */
	/* hopefully this is a null list at this point */
	list_for_each_entry_safe(node, q, &vha->e_dbell.head, list) {
		ql_dbg(ql_dbg_edif, vha, 0x910f,
		    "%s freeing edb_node type=%x\n",
		    __func__, node->ntype);
		qla_edb_node_free(vha, node);
	}
	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);

	qla_edif_dbell_bsg_done(vha);
}

static struct edb_node *
qla_edb_node_alloc(scsi_qla_host_t *vha, uint32_t ntype)
{
	struct edb_node	*node;

	node = kzalloc(sizeof(*node), GFP_ATOMIC);
	if (!node) {
		/* couldn't get space */
		ql_dbg(ql_dbg_edif, vha, 0x9100,
		    "edb node unable to be allocated\n");
		return NULL;
	}

	node->ntype = ntype;
	INIT_LIST_HEAD(&node->list);
	return node;
}

/* adds a already allocated enode to the linked list */
static bool
qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr)
{
	unsigned long		flags;

	if (DBELL_INACTIVE(vha)) {
		/* doorbell list not enabled */
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "%s doorbell not enabled\n", __func__);
		return false;
	}

	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
	list_add_tail(&ptr->list, &vha->e_dbell.head);
	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);

	return true;
}

/* adds event to doorbell list */
void
qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype,
	uint32_t data, uint32_t data2, fc_port_t	*sfcport)
{
	struct edb_node	*edbnode;
	fc_port_t *fcport = sfcport;
	port_id_t id;

	if (!vha->hw->flags.edif_enabled) {
		/* edif not enabled */
		return;
	}

	if (DBELL_INACTIVE(vha)) {
		if (fcport)
			fcport->edif.auth_state = dbtype;
		/* doorbell list not enabled */
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "%s doorbell not enabled (type=%d\n", __func__, dbtype);
		return;
	}

	edbnode = qla_edb_node_alloc(vha, dbtype);
	if (!edbnode) {
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "%s unable to alloc db node\n", __func__);
		return;
	}

	if (!fcport) {
		id.b.domain = (data >> 16) & 0xff;
		id.b.area = (data >> 8) & 0xff;
		id.b.al_pa = data & 0xff;
		ql_dbg(ql_dbg_edif, vha, 0x09222,
		    "%s: Arrived s_id: %06x\n", __func__,
		    id.b24);
		fcport = qla2x00_find_fcport_by_pid(vha, &id);
		if (!fcport) {
			ql_dbg(ql_dbg_edif, vha, 0x09102,
			    "%s can't find fcport for sid= 0x%x - ignoring\n",
			__func__, id.b24);
			kfree(edbnode);
			return;
		}
	}

	/* populate the edb node */
	switch (dbtype) {
	case VND_CMD_AUTH_STATE_NEEDED:
	case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
		edbnode->u.plogi_did.b24 = fcport->d_id.b24;
		break;
	case VND_CMD_AUTH_STATE_ELS_RCVD:
		edbnode->u.els_sid.b24 = fcport->d_id.b24;
		break;
	case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
		edbnode->u.sa_aen.port_id = fcport->d_id;
		edbnode->u.sa_aen.status =  data;
		edbnode->u.sa_aen.key_type =  data2;
		edbnode->u.sa_aen.version = EDIF_VERSION1;
		break;
	default:
		ql_dbg(ql_dbg_edif, vha, 0x09102,
			"%s unknown type: %x\n", __func__, dbtype);
		kfree(edbnode);
		edbnode = NULL;
		break;
	}

	if (edbnode) {
		if (!qla_edb_node_add(vha, edbnode)) {
			ql_dbg(ql_dbg_edif, vha, 0x09102,
			    "%s unable to add dbnode\n", __func__);
			kfree(edbnode);
			return;
		}
		ql_dbg(ql_dbg_edif, vha, 0x09102,
		    "%s Doorbell produced : type=%d %p\n", __func__, dbtype, edbnode);
		qla_edif_dbell_bsg_done(vha);
		if (fcport)
			fcport->edif.auth_state = dbtype;
	}
}

void
qla_edif_timer(scsi_qla_host_t *vha)
{
	struct qla_hw_data *ha = vha->hw;

	if (!vha->vp_idx && N2N_TOPO(ha) && ha->flags.n2n_fw_acc_sec) {
		if (DBELL_INACTIVE(vha) &&
		    ha->edif_post_stop_cnt_down) {
			ha->edif_post_stop_cnt_down--;

			/*
			 * turn off auto 'Plogi Acc + secure=1' feature
			 * Set Add FW option[3]
			 * BIT_15, if.
			 */
			if (ha->edif_post_stop_cnt_down == 0) {
				ql_dbg(ql_dbg_async, vha, 0x911d,
				       "%s chip reset to turn off PLOGI ACC + secure\n",
				       __func__);
				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
			}
		} else {
			ha->edif_post_stop_cnt_down = 60;
		}
	}

	if (vha->e_dbell.dbell_bsg_job && time_after_eq(jiffies, vha->e_dbell.bsg_expire))
		qla_edif_dbell_bsg_done(vha);
}

static void qla_noop_sp_done(srb_t *sp, int res)
{
	sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
	/* ref: INIT */
	kref_put(&sp->cmd_kref, qla2x00_sp_release);
}

/*
 * Called from work queue
 * build and send the sa_update iocb to delete an rx sa_index
 */
int
qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
{
	srb_t *sp;
	fc_port_t	*fcport = NULL;
	struct srb_iocb *iocb_cmd = NULL;
	int rval = QLA_SUCCESS;
	struct	edif_sa_ctl *sa_ctl = e->u.sa_update.sa_ctl;
	uint16_t nport_handle = e->u.sa_update.nport_handle;

	ql_dbg(ql_dbg_edif, vha, 0x70e6,
	    "%s: starting,  sa_ctl: %p\n", __func__, sa_ctl);

	if (!sa_ctl) {
		ql_dbg(ql_dbg_edif, vha, 0x70e6,
		    "sa_ctl allocation failed\n");
		rval =  -ENOMEM;
		goto done;
	}

	fcport = sa_ctl->fcport;

	/* Alloc SRB structure */
	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
	if (!sp) {
		ql_dbg(ql_dbg_edif, vha, 0x70e6,
		 "SRB allocation failed\n");
		rval = -ENOMEM;
		goto done;
	}

	fcport->flags |= FCF_ASYNC_SENT;
	iocb_cmd = &sp->u.iocb_cmd;
	iocb_cmd->u.sa_update.sa_ctl = sa_ctl;

	ql_dbg(ql_dbg_edif, vha, 0x3073,
	    "Enter: SA REPL portid=%06x, sa_ctl %p, index %x, nport_handle: 0x%x\n",
	    fcport->d_id.b24, sa_ctl, sa_ctl->index, nport_handle);
	/*
	 * if this is a sadb cleanup delete, mark it so the isr can
	 * take the correct action
	 */
	if (sa_ctl->flags & EDIF_SA_CTL_FLG_CLEANUP_DEL) {
		/* mark this srb as a cleanup delete */
		sp->flags |= SRB_EDIF_CLEANUP_DELETE;
		ql_dbg(ql_dbg_edif, vha, 0x70e6,
		    "%s: sp 0x%p flagged as cleanup delete\n", __func__, sp);
	}

	sp->type = SRB_SA_REPLACE;
	sp->name = "SA_REPLACE";
	sp->fcport = fcport;
	sp->free = qla2x00_rel_sp;
	sp->done = qla_noop_sp_done;

	rval = qla2x00_start_sp(sp);

	if (rval != QLA_SUCCESS) {
		goto done_free_sp;
	}

	return rval;
done_free_sp:
	kref_put(&sp->cmd_kref, qla2x00_sp_release);
	fcport->flags &= ~FCF_ASYNC_SENT;
done:
	fcport->flags &= ~FCF_ASYNC_ACTIVE;
	return rval;
}

void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb)
{
	int	itr = 0;
	struct	scsi_qla_host		*vha = sp->vha;
	struct	qla_sa_update_frame	*sa_frame =
		&sp->u.iocb_cmd.u.sa_update.sa_frame;
	u8 flags = 0;

	switch (sa_frame->flags & (SAU_FLG_INV | SAU_FLG_TX)) {
	case 0:
		ql_dbg(ql_dbg_edif, vha, 0x911d,
		    "%s: EDIF SA UPDATE RX IOCB  vha: 0x%p  index: %d\n",
		    __func__, vha, sa_frame->fast_sa_index);
		break;
	case 1:
		ql_dbg(ql_dbg_edif, vha, 0x911d,
		    "%s: EDIF SA DELETE RX IOCB  vha: 0x%p  index: %d\n",
		    __func__, vha, sa_frame->fast_sa_index);
		flags |= SA_FLAG_INVALIDATE;
		break;
	case 2:
		ql_dbg(ql_dbg_edif, vha, 0x911d,
		    "%s: EDIF SA UPDATE TX IOCB  vha: 0x%p  index: %d\n",
		    __func__, vha, sa_frame->fast_sa_index);
		flags |= SA_FLAG_TX;
		break;
	case 3:
		ql_dbg(ql_dbg_edif, vha, 0x911d,
		    "%s: EDIF SA DELETE TX IOCB  vha: 0x%p  index: %d\n",
		    __func__, vha, sa_frame->fast_sa_index);
		flags |= SA_FLAG_TX | SA_FLAG_INVALIDATE;
		break;
	}

	sa_update_iocb->entry_type = SA_UPDATE_IOCB_TYPE;
	sa_update_iocb->entry_count = 1;
	sa_update_iocb->sys_define = 0;
	sa_update_iocb->entry_status = 0;
	sa_update_iocb->handle = sp->handle;
	sa_update_iocb->u.nport_handle = cpu_to_le16(sp->fcport->loop_id);
	sa_update_iocb->vp_index = sp->fcport->vha->vp_idx;
	sa_update_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
	sa_update_iocb->port_id[1] = sp->fcport->d_id.b.area;
	sa_update_iocb->port_id[2] = sp->fcport->d_id.b.domain;

	sa_update_iocb->flags = flags;
	sa_update_iocb->salt = cpu_to_le32(sa_frame->salt);
	sa_update_iocb->spi = cpu_to_le32(sa_frame->spi);
	sa_update_iocb->sa_index = cpu_to_le16(sa_frame->fast_sa_index);

	sa_update_iocb->sa_control |= SA_CNTL_ENC_FCSP;
	if (sp->fcport->edif.aes_gmac)
		sa_update_iocb->sa_control |= SA_CNTL_AES_GMAC;

	if (sa_frame->flags & SAU_FLG_KEY256) {
		sa_update_iocb->sa_control |= SA_CNTL_KEY256;
		for (itr = 0; itr < 32; itr++)
			sa_update_iocb->sa_key[itr] = sa_frame->sa_key[itr];
	} else {
		sa_update_iocb->sa_control |= SA_CNTL_KEY128;
		for (itr = 0; itr < 16; itr++)
			sa_update_iocb->sa_key[itr] = sa_frame->sa_key[itr];
	}

	ql_dbg(ql_dbg_edif, vha, 0x921d,
	    "%s SAU Port ID = %02x%02x%02x, flags=%xh, index=%u, ctl=%xh, SPI 0x%x flags 0x%x hdl=%x gmac %d\n",
	    __func__, sa_update_iocb->port_id[2], sa_update_iocb->port_id[1],
	    sa_update_iocb->port_id[0], sa_update_iocb->flags, sa_update_iocb->sa_index,
	    sa_update_iocb->sa_control, sa_update_iocb->spi, sa_frame->flags, sp->handle,
	    sp->fcport->edif.aes_gmac);

	if (sa_frame->flags & SAU_FLG_TX)
		sp->fcport->edif.tx_sa_pending = 1;
	else
		sp->fcport->edif.rx_sa_pending = 1;

	sp->fcport->vha->qla_stats.control_requests++;
}

void
qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb)
{
	struct	scsi_qla_host		*vha = sp->vha;
	struct srb_iocb *srb_iocb = &sp->u.iocb_cmd;
	struct	edif_sa_ctl		*sa_ctl = srb_iocb->u.sa_update.sa_ctl;
	uint16_t nport_handle = sp->fcport->loop_id;

	sa_update_iocb->entry_type = SA_UPDATE_IOCB_TYPE;
	sa_update_iocb->entry_count = 1;
	sa_update_iocb->sys_define = 0;
	sa_update_iocb->entry_status = 0;
	sa_update_iocb->handle = sp->handle;

	sa_update_iocb->u.nport_handle = cpu_to_le16(nport_handle);

	sa_update_iocb->vp_index = sp->fcport->vha->vp_idx;
	sa_update_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
	sa_update_iocb->port_id[1] = sp->fcport->d_id.b.area;
	sa_update_iocb->port_id[2] = sp->fcport->d_id.b.domain;

	/* Invalidate the index. salt, spi, control & key are ignore */
	sa_update_iocb->flags = SA_FLAG_INVALIDATE;
	sa_update_iocb->salt = 0;
	sa_update_iocb->spi = 0;
	sa_update_iocb->sa_index = cpu_to_le16(sa_ctl->index);
	sa_update_iocb->sa_control = 0;

	ql_dbg(ql_dbg_edif, vha, 0x921d,
	    "%s SAU DELETE RX Port ID = %02x:%02x:%02x, lid %d flags=%xh, index=%u, hdl=%x\n",
	    __func__, sa_update_iocb->port_id[2], sa_update_iocb->port_id[1],
	    sa_update_iocb->port_id[0], nport_handle, sa_update_iocb->flags,
	    sa_update_iocb->sa_index, sp->handle);

	sp->fcport->vha->qla_stats.control_requests++;
}

void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
{
	struct purex_entry_24xx *p = *pkt;
	struct enode		*ptr;
	int		sid;
	u16 totlen;
	struct purexevent	*purex;
	struct scsi_qla_host *host = NULL;
	int rc;
	struct fc_port *fcport;
	struct qla_els_pt_arg a;
	be_id_t beid;

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

	a.els_opcode = ELS_AUTH_ELS;
	a.nport_handle = p->nport_handle;
	a.rx_xchg_address = p->rx_xchg_addr;
	a.did.b.domain = p->s_id[2];
	a.did.b.area   = p->s_id[1];
	a.did.b.al_pa  = p->s_id[0];
	a.tx_byte_count = a.tx_len = sizeof(struct fc_els_ls_rjt);
	a.tx_addr = vha->hw->elsrej.cdma;
	a.vp_idx = vha->vp_idx;
	a.control_flags = EPD_ELS_RJT;
	a.ox_id = le16_to_cpu(p->ox_id);

	sid = p->s_id[0] | (p->s_id[1] << 8) | (p->s_id[2] << 16);

	totlen = (le16_to_cpu(p->frame_size) & 0x0fff) - PURX_ELS_HEADER_SIZE;
	if (le16_to_cpu(p->status_flags) & 0x8000) {
		totlen = le16_to_cpu(p->trunc_frame_size);
		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
		__qla_consume_iocb(vha, pkt, rsp);
		return;
	}

	if (totlen > ELS_MAX_PAYLOAD) {
		ql_dbg(ql_dbg_edif, vha, 0x0910d,
		    "%s WARNING: verbose ELS frame received (totlen=%x)\n",
		    __func__, totlen);
		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
		__qla_consume_iocb(vha, pkt, rsp);
		return;
	}

	if (!vha->hw->flags.edif_enabled) {
		/* edif support not enabled */
		ql_dbg(ql_dbg_edif, vha, 0x910e, "%s edif not enabled\n",
		    __func__);
		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
		__qla_consume_iocb(vha, pkt, rsp);
		return;
	}

	ptr = qla_enode_alloc(vha, N_PUREX);
	if (!ptr) {
		ql_dbg(ql_dbg_edif, vha, 0x09109,
		    "WARNING: enode alloc failed for sid=%x\n",
		    sid);
		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
		__qla_consume_iocb(vha, pkt, rsp);
		return;
	}

	purex = &ptr->u.purexinfo;
	purex->pur_info.pur_sid = a.did;
	purex->pur_info.pur_bytes_rcvd = totlen;
	purex->pur_info.pur_rx_xchg_address = le32_to_cpu(p->rx_xchg_addr);
	purex->pur_info.pur_nphdl = le16_to_cpu(p->nport_handle);
	purex->pur_info.pur_did.b.domain =  p->d_id[2];
	purex->pur_info.pur_did.b.area =  p->d_id[1];
	purex->pur_info.pur_did.b.al_pa =  p->d_id[0];
	purex->pur_info.vp_idx = p->vp_idx;

	a.sid = purex->pur_info.pur_did;

	rc = __qla_copy_purex_to_buffer(vha, pkt, rsp, purex->msgp,
		purex->msgp_len);
	if (rc) {
		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
		qla_enode_free(vha, ptr);
		return;
	}
	beid.al_pa = purex->pur_info.pur_did.b.al_pa;
	beid.area   = purex->pur_info.pur_did.b.area;
	beid.domain = purex->pur_info.pur_did.b.domain;
	host = qla_find_host_by_d_id(vha, beid);
	if (!host) {
		ql_log(ql_log_fatal, vha, 0x508b,
		    "%s Drop ELS due to unable to find host %06x\n",
		    __func__, purex->pur_info.pur_did.b24);

		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
		qla_enode_free(vha, ptr);
		return;
	}

	fcport = qla2x00_find_fcport_by_pid(host, &purex->pur_info.pur_sid);

	if (DBELL_INACTIVE(vha)) {
		ql_dbg(ql_dbg_edif, host, 0x0910c, "%s e_dbell.db_flags =%x %06x\n",
		    __func__, host->e_dbell.db_flags,
		    fcport ? fcport->d_id.b24 : 0);

		qla_els_reject_iocb(host, (*rsp)->qpair, &a);
		qla_enode_free(host, ptr);
		return;
	}

	if (fcport && EDIF_SESSION_DOWN(fcport)) {
		ql_dbg(ql_dbg_edif, host, 0x13b6,
		    "%s terminate exchange. Send logo to 0x%x\n",
		    __func__, a.did.b24);

		a.tx_byte_count = a.tx_len = 0;
		a.tx_addr = 0;
		a.control_flags = EPD_RX_XCHG;  /* EPD_RX_XCHG = terminate cmd */
		qla_els_reject_iocb(host, (*rsp)->qpair, &a);
		qla_enode_free(host, ptr);
		/* send logo to let remote port knows to tear down session */
		fcport->send_els_logo = 1;
		qlt_schedule_sess_for_deletion(fcport);
		return;
	}

	/* add the local enode to the list */
	qla_enode_add(host, ptr);

	ql_dbg(ql_dbg_edif, host, 0x0910c,
	    "%s COMPLETE purex->pur_info.pur_bytes_rcvd =%xh s:%06x -> d:%06x xchg=%xh\n",
	    __func__, purex->pur_info.pur_bytes_rcvd, purex->pur_info.pur_sid.b24,
	    purex->pur_info.pur_did.b24, purex->pur_info.pur_rx_xchg_address);

	qla_edb_eventcreate(host, VND_CMD_AUTH_STATE_ELS_RCVD, sid, 0, NULL);
}

static uint16_t  qla_edif_get_sa_index_from_freepool(fc_port_t *fcport, int dir)
{
	struct scsi_qla_host *vha = fcport->vha;
	struct qla_hw_data *ha = vha->hw;
	void *sa_id_map;
	unsigned long flags = 0;
	u16 sa_index;

	ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063,
	    "%s: entry\n", __func__);

	if (dir)
		sa_id_map = ha->edif_tx_sa_id_map;
	else
		sa_id_map = ha->edif_rx_sa_id_map;

	spin_lock_irqsave(&ha->sadb_fp_lock, flags);
	sa_index = find_first_zero_bit(sa_id_map, EDIF_NUM_SA_INDEX);
	if (sa_index >=  EDIF_NUM_SA_INDEX) {
		spin_unlock_irqrestore(&ha->sadb_fp_lock, flags);
		return INVALID_EDIF_SA_INDEX;
	}
	set_bit(sa_index, sa_id_map);
	spin_unlock_irqrestore(&ha->sadb_fp_lock, flags);

	if (dir)
		sa_index += EDIF_TX_SA_INDEX_BASE;

	ql_dbg(ql_dbg_edif, vha, 0x3063,
	    "%s: index retrieved from free pool %d\n", __func__, sa_index);

	return sa_index;
}

/* find an sadb entry for an nport_handle */
static struct edif_sa_index_entry *
qla_edif_sadb_find_sa_index_entry(uint16_t nport_handle,
		struct list_head *sa_list)
{
	struct edif_sa_index_entry *entry;
	struct edif_sa_index_entry *tentry;
	struct list_head *indx_list = sa_list;

	list_for_each_entry_safe(entry, tentry, indx_list, next) {
		if (entry->handle == nport_handle)
			return entry;
	}
	return NULL;
}

/* remove an sa_index from the nport_handle and return it to the free pool */
static int qla_edif_sadb_delete_sa_index(fc_port_t *fcport, uint16_t nport_handle,
		uint16_t sa_index)
{
	struct edif_sa_index_entry *entry;
	struct list_head *sa_list;
	int dir = (sa_index < EDIF_TX_SA_INDEX_BASE) ? 0 : 1;
	int slot = 0;
	int free_slot_count = 0;
	scsi_qla_host_t *vha = fcport->vha;
	struct qla_hw_data *ha = vha->hw;
	unsigned long flags = 0;

	ql_dbg(ql_dbg_edif, vha, 0x3063,
	    "%s: entry\n", __func__);

	if (dir)
		sa_list = &ha->sadb_tx_index_list;
	else
		sa_list = &ha->sadb_rx_index_list;

	entry = qla_edif_sadb_find_sa_index_entry(nport_handle, sa_list);
	if (!entry) {
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: no entry found for nport_handle 0x%x\n",
		    __func__, nport_handle);
		return -1;
	}

	spin_lock_irqsave(&ha->sadb_lock, flags);
	/*
	 * each tx/rx direction has up to 2 sa indexes/slots. 1 slot for in flight traffic
	 * the other is use at re-key time.
	 */
	for (slot = 0; slot < 2; slot++) {
		if (entry->sa_pair[slot].sa_index == sa_index) {
			entry->sa_pair[slot].sa_index = INVALID_EDIF_SA_INDEX;
			entry->sa_pair[slot].spi = 0;
			free_slot_count++;
			qla_edif_add_sa_index_to_freepool(fcport, dir, sa_index);
		} else if (entry->sa_pair[slot].sa_index == INVALID_EDIF_SA_INDEX) {
			free_slot_count++;
		}
	}

	if (free_slot_count == 2) {
		list_del(&entry->next);
		kfree(entry);
	}
	spin_unlock_irqrestore(&ha->sadb_lock, flags);

	ql_dbg(ql_dbg_edif, vha, 0x3063,
	    "%s: sa_index %d removed, free_slot_count: %d\n",
	    __func__, sa_index, free_slot_count);

	return 0;
}

void
qla28xx_sa_update_iocb_entry(scsi_qla_host_t *v, struct req_que *req,
	struct sa_update_28xx *pkt)
{
	const char *func = "SA_UPDATE_RESPONSE_IOCB";
	srb_t *sp;
	struct edif_sa_ctl *sa_ctl;
	int old_sa_deleted = 1;
	uint16_t nport_handle;
	struct scsi_qla_host *vha;

	sp = qla2x00_get_sp_from_handle(v, func, req, pkt);

	if (!sp) {
		ql_dbg(ql_dbg_edif, v, 0x3063,
			"%s: no sp found for pkt\n", __func__);
		return;
	}
	/* use sp->vha due to npiv */
	vha = sp->vha;

	switch (pkt->flags & (SA_FLAG_INVALIDATE | SA_FLAG_TX)) {
	case 0:
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: EDIF SA UPDATE RX IOCB  vha: 0x%p  index: %d\n",
		    __func__, vha, pkt->sa_index);
		break;
	case 1:
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: EDIF SA DELETE RX IOCB  vha: 0x%p  index: %d\n",
		    __func__, vha, pkt->sa_index);
		break;
	case 2:
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: EDIF SA UPDATE TX IOCB  vha: 0x%p  index: %d\n",
		    __func__, vha, pkt->sa_index);
		break;
	case 3:
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: EDIF SA DELETE TX IOCB  vha: 0x%p  index: %d\n",
		    __func__, vha, pkt->sa_index);
		break;
	}

	/*
	 * dig the nport handle out of the iocb, fcport->loop_id can not be trusted
	 * to be correct during cleanup sa_update iocbs.
	 */
	nport_handle = sp->fcport->loop_id;

	ql_dbg(ql_dbg_edif, vha, 0x3063,
	    "%s: %8phN comp status=%x old_sa_info=%x new_sa_info=%x lid %d, index=0x%x pkt_flags %xh hdl=%x\n",
	    __func__, sp->fcport->port_name, pkt->u.comp_sts, pkt->old_sa_info, pkt->new_sa_info,
	    nport_handle, pkt->sa_index, pkt->flags, sp->handle);

	/* if rx delete, remove the timer */
	if ((pkt->flags & (SA_FLAG_INVALIDATE | SA_FLAG_TX)) ==  SA_FLAG_INVALIDATE) {
		struct edif_list_entry *edif_entry;

		sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);

		edif_entry = qla_edif_list_find_sa_index(sp->fcport, nport_handle);
		if (edif_entry) {
			ql_dbg(ql_dbg_edif, vha, 0x5033,
			    "%s: removing edif_entry %p, new sa_index: 0x%x\n",
			    __func__, edif_entry, pkt->sa_index);
			qla_edif_list_delete_sa_index(sp->fcport, edif_entry);
			del_timer(&edif_entry->timer);

			ql_dbg(ql_dbg_edif, vha, 0x5033,
			    "%s: releasing edif_entry %p, new sa_index: 0x%x\n",
			    __func__, edif_entry, pkt->sa_index);

			kfree(edif_entry);
		}
	}

	/*
	 * if this is a delete for either tx or rx, make sure it succeeded.
	 * The new_sa_info field should be 0xffff on success
	 */
	if (pkt->flags & SA_FLAG_INVALIDATE)
		old_sa_deleted = (le16_to_cpu(pkt->new_sa_info) == 0xffff) ? 1 : 0;

	/* Process update and delete the same way */

	/* If this is an sadb cleanup delete, bypass sending events to IPSEC */
	if (sp->flags & SRB_EDIF_CLEANUP_DELETE) {
		sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: nph 0x%x, sa_index %d removed from fw\n",
		    __func__, sp->fcport->loop_id, pkt->sa_index);

	} else if ((pkt->entry_status == 0) && (pkt->u.comp_sts == 0) &&
	    old_sa_deleted) {
		/*
		 * Note: Wa are only keeping track of latest SA,
		 * so we know when we can start enableing encryption per I/O.
		 * If all SA's get deleted, let FW reject the IOCB.

		 * TODO: edif: don't set enabled here I think
		 * TODO: edif: prli complete is where it should be set
		 */
		ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063,
			"SA(%x)updated for s_id %02x%02x%02x\n",
			pkt->new_sa_info,
			pkt->port_id[2], pkt->port_id[1], pkt->port_id[0]);
		sp->fcport->edif.enable = 1;
		if (pkt->flags & SA_FLAG_TX) {
			sp->fcport->edif.tx_sa_set = 1;
			sp->fcport->edif.tx_sa_pending = 0;
			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
				QL_VND_SA_STAT_SUCCESS,
				QL_VND_TX_SA_KEY, sp->fcport);
		} else {
			sp->fcport->edif.rx_sa_set = 1;
			sp->fcport->edif.rx_sa_pending = 0;
			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
				QL_VND_SA_STAT_SUCCESS,
				QL_VND_RX_SA_KEY, sp->fcport);
		}
	} else {
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: %8phN SA update FAILED: sa_index: %d, new_sa_info %d, %02x%02x%02x\n",
		    __func__, sp->fcport->port_name, pkt->sa_index, pkt->new_sa_info,
		    pkt->port_id[2], pkt->port_id[1], pkt->port_id[0]);

		if (pkt->flags & SA_FLAG_TX)
			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
				(le16_to_cpu(pkt->u.comp_sts) << 16) | QL_VND_SA_STAT_FAILED,
				QL_VND_TX_SA_KEY, sp->fcport);
		else
			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
				(le16_to_cpu(pkt->u.comp_sts) << 16) | QL_VND_SA_STAT_FAILED,
				QL_VND_RX_SA_KEY, sp->fcport);
	}

	/* for delete, release sa_ctl, sa_index */
	if (pkt->flags & SA_FLAG_INVALIDATE) {
		/* release the sa_ctl */
		sa_ctl = qla_edif_find_sa_ctl_by_index(sp->fcport,
		    le16_to_cpu(pkt->sa_index), (pkt->flags & SA_FLAG_TX));
		if (sa_ctl &&
		    qla_edif_find_sa_ctl_by_index(sp->fcport, sa_ctl->index,
			(pkt->flags & SA_FLAG_TX)) != NULL) {
			ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063,
			    "%s: freeing sa_ctl for index %d\n",
			    __func__, sa_ctl->index);
			qla_edif_free_sa_ctl(sp->fcport, sa_ctl, sa_ctl->index);
		} else {
			ql_dbg(ql_dbg_edif, vha, 0x3063,
			    "%s: sa_ctl NOT freed, sa_ctl: %p\n",
			    __func__, sa_ctl);
		}
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: freeing sa_index %d, nph: 0x%x\n",
		    __func__, le16_to_cpu(pkt->sa_index), nport_handle);
		qla_edif_sadb_delete_sa_index(sp->fcport, nport_handle,
		    le16_to_cpu(pkt->sa_index));
	/*
	 * check for a failed sa_update and remove
	 * the sadb entry.
	 */
	} else if (pkt->u.comp_sts) {
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: freeing sa_index %d, nph: 0x%x\n",
		    __func__, pkt->sa_index, nport_handle);
		qla_edif_sadb_delete_sa_index(sp->fcport, nport_handle,
		    le16_to_cpu(pkt->sa_index));
		switch (le16_to_cpu(pkt->u.comp_sts)) {
		case CS_PORT_EDIF_UNAVAIL:
		case CS_PORT_EDIF_LOGOUT:
			qlt_schedule_sess_for_deletion(sp->fcport);
			break;
		default:
			break;
		}
	}

	sp->done(sp, 0);
}

/**
 * qla28xx_start_scsi_edif() - Send a SCSI type 6 command to the ISP
 * @sp: command to send to the ISP
 *
 * Return: non-zero if a failure occurred, else zero.
 */
int
qla28xx_start_scsi_edif(srb_t *sp)
{
	int             nseg;
	unsigned long   flags;
	struct scsi_cmnd *cmd;
	uint32_t        *clr_ptr;
	uint32_t        index, i;
	uint32_t        handle;
	uint16_t        cnt;
	int16_t        req_cnt;
	uint16_t        tot_dsds;
	__be32 *fcp_dl;
	uint8_t additional_cdb_len;
	struct ct6_dsd *ctx;
	struct scsi_qla_host *vha = sp->vha;
	struct qla_hw_data *ha = vha->hw;
	struct cmd_type_6 *cmd_pkt;
	struct dsd64	*cur_dsd;
	uint8_t		avail_dsds = 0;
	struct scatterlist *sg;
	struct req_que *req = sp->qpair->req;
	spinlock_t *lock = sp->qpair->qp_lock_ptr;

	/* Setup device pointers. */
	cmd = GET_CMD_SP(sp);

	/* So we know we haven't pci_map'ed anything yet */
	tot_dsds = 0;

	/* Send marker if required */
	if (vha->marker_needed != 0) {
		if (qla2x00_marker(vha, sp->qpair, 0, 0, MK_SYNC_ALL) !=
			QLA_SUCCESS) {
			ql_log(ql_log_warn, vha, 0x300c,
			    "qla2x00_marker failed for cmd=%p.\n", cmd);
			return QLA_FUNCTION_FAILED;
		}
		vha->marker_needed = 0;
	}

	/* Acquire ring specific lock */
	spin_lock_irqsave(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)
		goto queuing_error;

	/* Map the sg table so we have an accurate count of sg entries needed */
	if (scsi_sg_count(cmd)) {
		nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
		    scsi_sg_count(cmd), cmd->sc_data_direction);
		if (unlikely(!nseg))
			goto queuing_error;
	} else {
		nseg = 0;
	}

	tot_dsds = nseg;
	req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);

	sp->iores.res_type = RESOURCE_INI;
	sp->iores.iocb_cnt = req_cnt;
	if (qla_get_iocbs(sp->qpair, &sp->iores))
		goto queuing_error;

	if (req->cnt < (req_cnt + 2)) {
		cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
		    rd_reg_dword(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))
			goto queuing_error;
	}

	ctx = sp->u.scmd.ct6_ctx =
	    mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
	if (!ctx) {
		ql_log(ql_log_fatal, vha, 0x3010,
		    "Failed to allocate ctx for cmd=%p.\n", cmd);
		goto queuing_error;
	}

	memset(ctx, 0, sizeof(struct ct6_dsd));
	ctx->fcp_cmnd = dma_pool_zalloc(ha->fcp_cmnd_dma_pool,
	    GFP_ATOMIC, &ctx->fcp_cmnd_dma);
	if (!ctx->fcp_cmnd) {
		ql_log(ql_log_fatal, vha, 0x3011,
		    "Failed to allocate fcp_cmnd for cmd=%p.\n", cmd);
		goto queuing_error;
	}

	/* Initialize the DSD list and dma handle */
	INIT_LIST_HEAD(&ctx->dsd_list);
	ctx->dsd_use_cnt = 0;

	if (cmd->cmd_len > 16) {
		additional_cdb_len = cmd->cmd_len - 16;
		if ((cmd->cmd_len % 4) != 0) {
			/*
			 * SCSI command bigger than 16 bytes must be
			 * multiple of 4
			 */
			ql_log(ql_log_warn, vha, 0x3012,
			    "scsi cmd len %d not multiple of 4 for cmd=%p.\n",
			    cmd->cmd_len, cmd);
			goto queuing_error_fcp_cmnd;
		}
		ctx->fcp_cmnd_len = 12 + cmd->cmd_len + 4;
	} else {
		additional_cdb_len = 0;
		ctx->fcp_cmnd_len = 12 + 16 + 4;
	}

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

	/*
	 * Zero out remaining portion of packet.
	 * tagged queuing modifier -- default is TSK_SIMPLE (0).
	 */
	clr_ptr = (uint32_t *)cmd_pkt + 2;
	memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
	cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);

	/* No data transfer */
	if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
		cmd_pkt->byte_count = cpu_to_le32(0);
		goto no_dsds;
	}

	/* Set transfer direction */
	if (cmd->sc_data_direction == DMA_TO_DEVICE) {
		cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA);
		vha->qla_stats.output_bytes += scsi_bufflen(cmd);
		vha->qla_stats.output_requests++;
		sp->fcport->edif.tx_bytes += scsi_bufflen(cmd);
	} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
		cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA);
		vha->qla_stats.input_bytes += scsi_bufflen(cmd);
		vha->qla_stats.input_requests++;
		sp->fcport->edif.rx_bytes += scsi_bufflen(cmd);
	}

	cmd_pkt->control_flags |= cpu_to_le16(CF_EN_EDIF);
	cmd_pkt->control_flags &= ~(cpu_to_le16(CF_NEW_SA));

	/* One DSD is available in the Command Type 6 IOCB */
	avail_dsds = 1;
	cur_dsd = &cmd_pkt->fcp_dsd;

	/* Load data segments */
	scsi_for_each_sg(cmd, 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.
			 */
			cont_pkt = qla2x00_prep_cont_type1_iocb(vha, req);
			cur_dsd = cont_pkt->dsd;
			avail_dsds = 5;
		}

		sle_dma = sg_dma_address(sg);
		put_unaligned_le64(sle_dma, &cur_dsd->address);
		cur_dsd->length = cpu_to_le32(sg_dma_len(sg));
		cur_dsd++;
		avail_dsds--;
	}

no_dsds:
	/* Set NPORT-ID and LUN number*/
	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->vha->vp_idx;

	cmd_pkt->entry_type = COMMAND_TYPE_6;

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

	int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
	host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));

	/* build FCP_CMND IU */
	int_to_scsilun(cmd->device->lun, &ctx->fcp_cmnd->lun);
	ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len;

	if (cmd->sc_data_direction == DMA_TO_DEVICE)
		ctx->fcp_cmnd->additional_cdb_len |= 1;
	else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
		ctx->fcp_cmnd->additional_cdb_len |= 2;

	/* Populate the FCP_PRIO. */
	if (ha->flags.fcp_prio_enabled)
		ctx->fcp_cmnd->task_attribute |=
		    sp->fcport->fcp_prio << 3;

	memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);

	fcp_dl = (__be32 *)(ctx->fcp_cmnd->cdb + 16 +
	    additional_cdb_len);
	*fcp_dl = htonl((uint32_t)scsi_bufflen(cmd));

	cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len);
	put_unaligned_le64(ctx->fcp_cmnd_dma, &cmd_pkt->fcp_cmnd_dseg_address);

	sp->flags |= SRB_FCP_CMND_DMA_VALID;
	cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
	/* Set total data segment count. */
	cmd_pkt->entry_count = (uint8_t)req_cnt;
	cmd_pkt->entry_status = 0;

	/* Build command packet. */
	req->current_outstanding_cmd = handle;
	req->outstanding_cmds[handle] = sp;
	sp->handle = handle;
	cmd->host_scribble = (unsigned char *)(unsigned long)handle;
	req->cnt -= req_cnt;

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

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

	spin_unlock_irqrestore(lock, flags);

	return QLA_SUCCESS;

queuing_error_fcp_cmnd:
	dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, ctx->fcp_cmnd_dma);
queuing_error:
	if (tot_dsds)
		scsi_dma_unmap(cmd);

	if (sp->u.scmd.ct6_ctx) {
		mempool_free(sp->u.scmd.ct6_ctx, ha->ctx_mempool);
		sp->u.scmd.ct6_ctx = NULL;
	}
	qla_put_iocbs(sp->qpair, &sp->iores);
	spin_unlock_irqrestore(lock, flags);

	return QLA_FUNCTION_FAILED;
}

/**********************************************
 * edif update/delete sa_index list functions *
 **********************************************/

/* clear the edif_indx_list for this port */
void qla_edif_list_del(fc_port_t *fcport)
{
	struct edif_list_entry *indx_lst;
	struct edif_list_entry *tindx_lst;
	struct list_head *indx_list = &fcport->edif.edif_indx_list;
	unsigned long flags = 0;

	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);
	list_for_each_entry_safe(indx_lst, tindx_lst, indx_list, next) {
		list_del(&indx_lst->next);
		kfree(indx_lst);
	}
	spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
}

/******************
 * SADB functions *
 ******************/

/* allocate/retrieve an sa_index for a given spi */
static uint16_t qla_edif_sadb_get_sa_index(fc_port_t *fcport,
		struct qla_sa_update_frame *sa_frame)
{
	struct edif_sa_index_entry *entry;
	struct list_head *sa_list;
	uint16_t sa_index;
	int dir = sa_frame->flags & SAU_FLG_TX;
	int slot = 0;
	int free_slot = -1;
	scsi_qla_host_t *vha = fcport->vha;
	struct qla_hw_data *ha = vha->hw;
	unsigned long flags = 0;
	uint16_t nport_handle = fcport->loop_id;

	ql_dbg(ql_dbg_edif, vha, 0x3063,
	    "%s: entry  fc_port: %p, nport_handle: 0x%x\n",
	    __func__, fcport, nport_handle);

	if (dir)
		sa_list = &ha->sadb_tx_index_list;
	else
		sa_list = &ha->sadb_rx_index_list;

	entry = qla_edif_sadb_find_sa_index_entry(nport_handle, sa_list);
	if (!entry) {
		if ((sa_frame->flags & (SAU_FLG_TX | SAU_FLG_INV)) == SAU_FLG_INV) {
			ql_dbg(ql_dbg_edif, vha, 0x3063,
			    "%s: rx delete request with no entry\n", __func__);
			return RX_DELETE_NO_EDIF_SA_INDEX;
		}

		/* if there is no entry for this nport, add one */
		entry = kzalloc((sizeof(struct edif_sa_index_entry)), GFP_ATOMIC);
		if (!entry)
			return INVALID_EDIF_SA_INDEX;

		sa_index = qla_edif_get_sa_index_from_freepool(fcport, dir);
		if (sa_index == INVALID_EDIF_SA_INDEX) {
			kfree(entry);
			return INVALID_EDIF_SA_INDEX;
		}

		INIT_LIST_HEAD(&entry->next);
		entry->handle = nport_handle;
		entry->fcport = fcport;
		entry->sa_pair[0].spi = sa_frame->spi;
		entry->sa_pair[0].sa_index = sa_index;
		entry->sa_pair[1].spi = 0;
		entry->sa_pair[1].sa_index = INVALID_EDIF_SA_INDEX;
		spin_lock_irqsave(&ha->sadb_lock, flags);
		list_add_tail(&entry->next, sa_list);
		spin_unlock_irqrestore(&ha->sadb_lock, flags);
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: Created new sadb entry for nport_handle 0x%x, spi 0x%x, returning sa_index %d\n",
		    __func__, nport_handle, sa_frame->spi, sa_index);

		return sa_index;
	}

	spin_lock_irqsave(&ha->sadb_lock, flags);

	/* see if we already have an entry for this spi */
	for (slot = 0; slot < 2; slot++) {
		if (entry->sa_pair[slot].sa_index == INVALID_EDIF_SA_INDEX) {
			free_slot = slot;
		} else {
			if (entry->sa_pair[slot].spi == sa_frame->spi) {
				spin_unlock_irqrestore(&ha->sadb_lock, flags);
				ql_dbg(ql_dbg_edif, vha, 0x3063,
				    "%s: sadb slot %d entry for lid 0x%x, spi 0x%x found, sa_index %d\n",
				    __func__, slot, entry->handle, sa_frame->spi,
				    entry->sa_pair[slot].sa_index);
				return entry->sa_pair[slot].sa_index;
			}
		}
	}
	spin_unlock_irqrestore(&ha->sadb_lock, flags);

	/* both slots are used */
	if (free_slot == -1) {
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: WARNING: No free slots in sadb for nport_handle 0x%x, spi: 0x%x\n",
		    __func__, entry->handle, sa_frame->spi);
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: Slot 0  spi: 0x%x  sa_index: %d,  Slot 1  spi: 0x%x  sa_index: %d\n",
		    __func__, entry->sa_pair[0].spi, entry->sa_pair[0].sa_index,
		    entry->sa_pair[1].spi, entry->sa_pair[1].sa_index);

		return INVALID_EDIF_SA_INDEX;
	}

	/* there is at least one free slot, use it */
	sa_index = qla_edif_get_sa_index_from_freepool(fcport, dir);
	if (sa_index == INVALID_EDIF_SA_INDEX) {
		ql_dbg(ql_dbg_edif, fcport->vha, 0x3063,
		    "%s: empty freepool!!\n", __func__);
		return INVALID_EDIF_SA_INDEX;
	}

	spin_lock_irqsave(&ha->sadb_lock, flags);
	entry->sa_pair[free_slot].spi = sa_frame->spi;
	entry->sa_pair[free_slot].sa_index = sa_index;
	spin_unlock_irqrestore(&ha->sadb_lock, flags);
	ql_dbg(ql_dbg_edif, fcport->vha, 0x3063,
	    "%s: sadb slot %d entry for nport_handle 0x%x, spi 0x%x added, returning sa_index %d\n",
	    __func__, free_slot, entry->handle, sa_frame->spi, sa_index);

	return sa_index;
}

/* release any sadb entries -- only done at teardown */
void qla_edif_sadb_release(struct qla_hw_data *ha)
{
	struct edif_sa_index_entry *entry, *tmp;

	list_for_each_entry_safe(entry, tmp, &ha->sadb_rx_index_list, next) {
		list_del(&entry->next);
		kfree(entry);
	}

	list_for_each_entry_safe(entry, tmp, &ha->sadb_tx_index_list, next) {
		list_del(&entry->next);
		kfree(entry);
	}
}

/**************************
 * sadb freepool functions
 **************************/

/* build the rx and tx sa_index free pools -- only done at fcport init */
int qla_edif_sadb_build_free_pool(struct qla_hw_data *ha)
{
	ha->edif_tx_sa_id_map =
	    kcalloc(BITS_TO_LONGS(EDIF_NUM_SA_INDEX), sizeof(long), GFP_KERNEL);

	if (!ha->edif_tx_sa_id_map) {
		ql_log_pci(ql_log_fatal, ha->pdev, 0x0009,
		    "Unable to allocate memory for sadb tx.\n");
		return -ENOMEM;
	}

	ha->edif_rx_sa_id_map =
	    kcalloc(BITS_TO_LONGS(EDIF_NUM_SA_INDEX), sizeof(long), GFP_KERNEL);
	if (!ha->edif_rx_sa_id_map) {
		kfree(ha->edif_tx_sa_id_map);
		ha->edif_tx_sa_id_map = NULL;
		ql_log_pci(ql_log_fatal, ha->pdev, 0x0009,
		    "Unable to allocate memory for sadb rx.\n");
		return -ENOMEM;
	}
	return 0;
}

/* release the free pool - only done during fcport teardown */
void qla_edif_sadb_release_free_pool(struct qla_hw_data *ha)
{
	kfree(ha->edif_tx_sa_id_map);
	ha->edif_tx_sa_id_map = NULL;
	kfree(ha->edif_rx_sa_id_map);
	ha->edif_rx_sa_id_map = NULL;
}

static void __chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha,
		fc_port_t *fcport, uint32_t handle, uint16_t sa_index)
{
	struct edif_list_entry *edif_entry;
	struct edif_sa_ctl *sa_ctl;
	uint16_t delete_sa_index = INVALID_EDIF_SA_INDEX;
	unsigned long flags = 0;
	uint16_t nport_handle = fcport->loop_id;
	uint16_t cached_nport_handle;

	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);
	edif_entry = qla_edif_list_find_sa_index(fcport, nport_handle);
	if (!edif_entry) {
		spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
		return;		/* no pending delete for this handle */
	}

	/*
	 * check for no pending delete for this index or iocb does not
	 * match rx sa_index
	 */
	if (edif_entry->delete_sa_index == INVALID_EDIF_SA_INDEX ||
	    edif_entry->update_sa_index != sa_index) {
		spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
		return;
	}

	/*
	 * wait until we have seen at least EDIF_DELAY_COUNT transfers before
	 * queueing RX delete
	 */
	if (edif_entry->count++ < EDIF_RX_DELETE_FILTER_COUNT) {
		spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
		return;
	}

	ql_dbg(ql_dbg_edif, vha, 0x5033,
	    "%s: invalidating delete_sa_index,  update_sa_index: 0x%x sa_index: 0x%x, delete_sa_index: 0x%x\n",
	    __func__, edif_entry->update_sa_index, sa_index, edif_entry->delete_sa_index);

	delete_sa_index = edif_entry->delete_sa_index;
	edif_entry->delete_sa_index = INVALID_EDIF_SA_INDEX;
	cached_nport_handle = edif_entry->handle;
	spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);

	/* sanity check on the nport handle */
	if (nport_handle != cached_nport_handle) {
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: POST SA DELETE nport_handle mismatch: lid: 0x%x, edif_entry nph: 0x%x\n",
		    __func__, nport_handle, cached_nport_handle);
	}

	/* find the sa_ctl for the delete and schedule the delete */
	sa_ctl = qla_edif_find_sa_ctl_by_index(fcport, delete_sa_index, 0);
	if (sa_ctl) {
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: POST SA DELETE sa_ctl: %p, index recvd %d\n",
		    __func__, sa_ctl, sa_index);
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "delete index %d, update index: %d, nport handle: 0x%x, handle: 0x%x\n",
		    delete_sa_index,
		    edif_entry->update_sa_index, nport_handle, handle);

		sa_ctl->flags = EDIF_SA_CTL_FLG_DEL;
		set_bit(EDIF_SA_CTL_REPL, &sa_ctl->state);
		qla_post_sa_replace_work(fcport->vha, fcport,
		    nport_handle, sa_ctl);
	} else {
		ql_dbg(ql_dbg_edif, vha, 0x3063,
		    "%s: POST SA DELETE sa_ctl not found for delete_sa_index: %d\n",
		    __func__, delete_sa_index);
	}
}

void qla_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha,
		srb_t *sp, struct sts_entry_24xx *sts24)
{
	fc_port_t *fcport = sp->fcport;
	/* sa_index used by this iocb */
	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
	uint32_t handle;

	handle = (uint32_t)LSW(sts24->handle);

	/* find out if this status iosb is for a scsi read */
	if (cmd->sc_data_direction != DMA_FROM_DEVICE)
		return;

	return __chk_edif_rx_sa_delete_pending(vha, fcport, handle,
	   le16_to_cpu(sts24->edif_sa_index));
}

void qlt_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, fc_port_t *fcport,
		struct ctio7_from_24xx *pkt)
{
	__chk_edif_rx_sa_delete_pending(vha, fcport,
	    pkt->handle, le16_to_cpu(pkt->edif_sa_index));
}

static void qla_parse_auth_els_ctl(struct srb *sp)
{
	struct qla_els_pt_arg *a = &sp->u.bsg_cmd.u.els_arg;
	struct bsg_job *bsg_job = sp->u.bsg_cmd.bsg_job;
	struct fc_bsg_request *request = bsg_job->request;
	struct qla_bsg_auth_els_request *p =
	    (struct qla_bsg_auth_els_request *)bsg_job->request;

	a->tx_len = a->tx_byte_count = sp->remap.req.len;
	a->tx_addr = sp->remap.req.dma;
	a->rx_len = a->rx_byte_count = sp->remap.rsp.len;
	a->rx_addr = sp->remap.rsp.dma;

	if (p->e.sub_cmd == SEND_ELS_REPLY) {
		a->control_flags = p->e.extra_control_flags << 13;
		a->rx_xchg_address = cpu_to_le32(p->e.extra_rx_xchg_address);
		if (p->e.extra_control_flags == BSG_CTL_FLAG_LS_ACC)
			a->els_opcode = ELS_LS_ACC;
		else if (p->e.extra_control_flags == BSG_CTL_FLAG_LS_RJT)
			a->els_opcode = ELS_LS_RJT;
	}
	a->did = sp->fcport->d_id;
	a->els_opcode =  request->rqst_data.h_els.command_code;
	a->nport_handle = cpu_to_le16(sp->fcport->loop_id);
	a->vp_idx = sp->vha->vp_idx;
}

int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
{
	struct fc_bsg_request *bsg_request = bsg_job->request;
	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
	fc_port_t *fcport = NULL;
	struct qla_hw_data *ha = vha->hw;
	srb_t *sp;
	int rval =  (DID_ERROR << 16), cnt;
	port_id_t d_id;
	struct qla_bsg_auth_els_request *p =
	    (struct qla_bsg_auth_els_request *)bsg_job->request;
	struct qla_bsg_auth_els_reply *rpl =
	    (struct qla_bsg_auth_els_reply *)bsg_job->reply;

	rpl->version = EDIF_VERSION1;

	d_id.b.al_pa = bsg_request->rqst_data.h_els.port_id[2];
	d_id.b.area = bsg_request->rqst_data.h_els.port_id[1];
	d_id.b.domain = bsg_request->rqst_data.h_els.port_id[0];

	/* find matching d_id in fcport list */
	fcport = qla2x00_find_fcport_by_pid(vha, &d_id);
	if (!fcport) {
		ql_dbg(ql_dbg_edif, vha, 0x911a,
		    "%s fcport not find online portid=%06x.\n",
		    __func__, d_id.b24);
		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
		return -EIO;
	}

	if (qla_bsg_check(vha, bsg_job, fcport))
		return 0;

	if (EDIF_SESS_DELETE(fcport)) {
		ql_dbg(ql_dbg_edif, vha, 0x910d,
		    "%s ELS code %x, no loop id.\n", __func__,
		    bsg_request->rqst_data.r_els.els_code);
		SET_DID_STATUS(bsg_reply->result, DID_BAD_TARGET);
		return -ENXIO;
	}

	if (!vha->flags.online) {
		ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
		SET_DID_STATUS(bsg_reply->result, DID_BAD_TARGET);
		rval = -EIO;
		goto done;
	}

	/* pass through is supported only for ISP 4Gb or higher */
	if (!IS_FWI2_CAPABLE(ha)) {
		ql_dbg(ql_dbg_user, vha, 0x7001,
		    "ELS passthru not supported for ISP23xx based adapters.\n");
		SET_DID_STATUS(bsg_reply->result, DID_BAD_TARGET);
		rval = -EPERM;
		goto done;
	}

	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
	if (!sp) {
		ql_dbg(ql_dbg_user, vha, 0x7004,
		    "Failed get sp pid=%06x\n", fcport->d_id.b24);
		rval = -ENOMEM;
		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
		goto done;
	}

	sp->remap.req.len = bsg_job->request_payload.payload_len;
	sp->remap.req.buf = dma_pool_alloc(ha->purex_dma_pool,
	    GFP_KERNEL, &sp->remap.req.dma);
	if (!sp->remap.req.buf) {
		ql_dbg(ql_dbg_user, vha, 0x7005,
		    "Failed allocate request dma len=%x\n",
		    bsg_job->request_payload.payload_len);
		rval = -ENOMEM;
		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
		goto done_free_sp;
	}

	sp->remap.rsp.len = bsg_job->reply_payload.payload_len;
	sp->remap.rsp.buf = dma_pool_alloc(ha->purex_dma_pool,
	    GFP_KERNEL, &sp->remap.rsp.dma);
	if (!sp->remap.rsp.buf) {
		ql_dbg(ql_dbg_user, vha, 0x7006,
		    "Failed allocate response dma len=%x\n",
		    bsg_job->reply_payload.payload_len);
		rval = -ENOMEM;
		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
		goto done_free_remap_req;
	}
	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
	    bsg_job->request_payload.sg_cnt, sp->remap.req.buf,
	    sp->remap.req.len);
	sp->remap.remapped = true;

	sp->type = SRB_ELS_CMD_HST_NOLOGIN;
	sp->name = "SPCN_BSG_HST_NOLOGIN";
	sp->u.bsg_cmd.bsg_job = bsg_job;
	qla_parse_auth_els_ctl(sp);

	sp->free = qla2x00_bsg_sp_free;
	sp->done = qla2x00_bsg_job_done;

	cnt = 0;
retry:
	rval = qla2x00_start_sp(sp);
	switch (rval) {
	case QLA_SUCCESS:
		ql_dbg(ql_dbg_edif, vha, 0x700a,
		       "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n",
		       __func__, sc_to_str(p->e.sub_cmd), fcport->port_name,
		       p->e.extra_rx_xchg_address, p->e.extra_control_flags,
		       sp->handle, sp->remap.req.len, bsg_job);
		break;
	case EAGAIN:
		msleep(EDIF_MSLEEP_INTERVAL);
		cnt++;
		if (cnt < EDIF_RETRY_COUNT)
			goto retry;
		fallthrough;
	default:
		ql_log(ql_log_warn, vha, 0x700e,
		    "%s qla2x00_start_sp failed = %d\n", __func__, rval);
		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
		rval = -EIO;
		goto done_free_remap_rsp;
	}
	return rval;

done_free_remap_rsp:
	dma_pool_free(ha->purex_dma_pool, sp->remap.rsp.buf,
	    sp->remap.rsp.dma);
done_free_remap_req:
	dma_pool_free(ha->purex_dma_pool, sp->remap.req.buf,
	    sp->remap.req.dma);
done_free_sp:
	qla2x00_rel_sp(sp);

done:
	return rval;
}

void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
{
	u16 cnt = 0;

	if (sess->edif.app_sess_online && DBELL_ACTIVE(vha)) {
		ql_dbg(ql_dbg_disc, vha, 0xf09c,
			"%s: sess %8phN send port_offline event\n",
			__func__, sess->port_name);
		sess->edif.app_sess_online = 0;
		sess->edif.sess_down_acked = 0;
		qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SESSION_SHUTDOWN,
		    sess->d_id.b24, 0, sess);
		qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24);

		while (!READ_ONCE(sess->edif.sess_down_acked) &&
		       !test_bit(VPORT_DELETE, &vha->dpc_flags)) {
			msleep(100);
			cnt++;
			if (cnt > 100)
				break;
		}
		sess->edif.sess_down_acked = 0;
		ql_dbg(ql_dbg_disc, vha, 0xf09c,
		       "%s: sess %8phN port_offline event completed\n",
		       __func__, sess->port_name);
	}
}

void qla_edif_clear_appdata(struct scsi_qla_host *vha, struct fc_port *fcport)
{
	if (!(fcport->flags & FCF_FCSP_DEVICE))
		return;

	qla_edb_clear(vha, fcport->d_id);
	qla_enode_clear(vha, fcport->d_id);
}
