cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

qla_edif.c (100657B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Marvell Fibre Channel HBA Driver
      4 * Copyright (c)  2021     Marvell
      5 */
      6#include "qla_def.h"
      7#include "qla_edif.h"
      8
      9#include <linux/kthread.h>
     10#include <linux/vmalloc.h>
     11#include <linux/delay.h>
     12#include <scsi/scsi_tcq.h>
     13
     14static struct edif_sa_index_entry *qla_edif_sadb_find_sa_index_entry(uint16_t nport_handle,
     15		struct list_head *sa_list);
     16static uint16_t qla_edif_sadb_get_sa_index(fc_port_t *fcport,
     17		struct qla_sa_update_frame *sa_frame);
     18static int qla_edif_sadb_delete_sa_index(fc_port_t *fcport, uint16_t nport_handle,
     19		uint16_t sa_index);
     20static int qla_pur_get_pending(scsi_qla_host_t *, fc_port_t *, struct bsg_job *);
     21
     22struct edb_node {
     23	struct  list_head	list;
     24	uint32_t		ntype;
     25	union {
     26		port_id_t	plogi_did;
     27		uint32_t	async;
     28		port_id_t	els_sid;
     29		struct edif_sa_update_aen	sa_aen;
     30	} u;
     31};
     32
     33static struct els_sub_cmd {
     34	uint16_t cmd;
     35	const char *str;
     36} sc_str[] = {
     37	{SEND_ELS, "send ELS"},
     38	{SEND_ELS_REPLY, "send ELS Reply"},
     39	{PULL_ELS, "retrieve ELS"},
     40};
     41
     42const char *sc_to_str(uint16_t cmd)
     43{
     44	int i;
     45	struct els_sub_cmd *e;
     46
     47	for (i = 0; i < ARRAY_SIZE(sc_str); i++) {
     48		e = sc_str + i;
     49		if (cmd == e->cmd)
     50			return e->str;
     51	}
     52	return "unknown";
     53}
     54
     55static struct edif_list_entry *qla_edif_list_find_sa_index(fc_port_t *fcport,
     56		uint16_t handle)
     57{
     58	struct edif_list_entry *entry;
     59	struct edif_list_entry *tentry;
     60	struct list_head *indx_list = &fcport->edif.edif_indx_list;
     61
     62	list_for_each_entry_safe(entry, tentry, indx_list, next) {
     63		if (entry->handle == handle)
     64			return entry;
     65	}
     66	return NULL;
     67}
     68
     69/* timeout called when no traffic and delayed rx sa_index delete */
     70static void qla2x00_sa_replace_iocb_timeout(struct timer_list *t)
     71{
     72	struct edif_list_entry *edif_entry = from_timer(edif_entry, t, timer);
     73	fc_port_t *fcport = edif_entry->fcport;
     74	struct scsi_qla_host *vha = fcport->vha;
     75	struct  edif_sa_ctl *sa_ctl;
     76	uint16_t nport_handle;
     77	unsigned long flags = 0;
     78
     79	ql_dbg(ql_dbg_edif, vha, 0x3069,
     80	    "%s:  nport_handle 0x%x,  SA REPL Delay Timeout, %8phC portid=%06x\n",
     81	    __func__, edif_entry->handle, fcport->port_name, fcport->d_id.b24);
     82
     83	/*
     84	 * if delete_sa_index is valid then no one has serviced this
     85	 * delayed delete
     86	 */
     87	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);
     88
     89	/*
     90	 * delete_sa_index is invalidated when we find the new sa_index in
     91	 * the incoming data stream.  If it is not invalidated then we are
     92	 * still looking for the new sa_index because there is no I/O and we
     93	 * need to just force the rx delete and move on.  Otherwise
     94	 * we could get another rekey which will result in an error 66.
     95	 */
     96	if (edif_entry->delete_sa_index != INVALID_EDIF_SA_INDEX) {
     97		uint16_t delete_sa_index = edif_entry->delete_sa_index;
     98
     99		edif_entry->delete_sa_index = INVALID_EDIF_SA_INDEX;
    100		nport_handle = edif_entry->handle;
    101		spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
    102
    103		sa_ctl = qla_edif_find_sa_ctl_by_index(fcport,
    104		    delete_sa_index, 0);
    105
    106		if (sa_ctl) {
    107			ql_dbg(ql_dbg_edif, vha, 0x3063,
    108			    "%s: sa_ctl: %p, delete index %d, update index: %d, lid: 0x%x\n",
    109			    __func__, sa_ctl, delete_sa_index, edif_entry->update_sa_index,
    110			    nport_handle);
    111
    112			sa_ctl->flags = EDIF_SA_CTL_FLG_DEL;
    113			set_bit(EDIF_SA_CTL_REPL, &sa_ctl->state);
    114			qla_post_sa_replace_work(fcport->vha, fcport,
    115			    nport_handle, sa_ctl);
    116
    117		} else {
    118			ql_dbg(ql_dbg_edif, vha, 0x3063,
    119			    "%s: sa_ctl not found for delete_sa_index: %d\n",
    120			    __func__, edif_entry->delete_sa_index);
    121		}
    122	} else {
    123		spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
    124	}
    125}
    126
    127/*
    128 * create a new list entry for this nport handle and
    129 * add an sa_update index to the list - called for sa_update
    130 */
    131static int qla_edif_list_add_sa_update_index(fc_port_t *fcport,
    132		uint16_t sa_index, uint16_t handle)
    133{
    134	struct edif_list_entry *entry;
    135	unsigned long flags = 0;
    136
    137	/* if the entry exists, then just update the sa_index */
    138	entry = qla_edif_list_find_sa_index(fcport, handle);
    139	if (entry) {
    140		entry->update_sa_index = sa_index;
    141		entry->count = 0;
    142		return 0;
    143	}
    144
    145	/*
    146	 * This is the normal path - there should be no existing entry
    147	 * when update is called.  The exception is at startup
    148	 * when update is called for the first two sa_indexes
    149	 * followed by a delete of the first sa_index
    150	 */
    151	entry = kzalloc((sizeof(struct edif_list_entry)), GFP_ATOMIC);
    152	if (!entry)
    153		return -ENOMEM;
    154
    155	INIT_LIST_HEAD(&entry->next);
    156	entry->handle = handle;
    157	entry->update_sa_index = sa_index;
    158	entry->delete_sa_index = INVALID_EDIF_SA_INDEX;
    159	entry->count = 0;
    160	entry->flags = 0;
    161	timer_setup(&entry->timer, qla2x00_sa_replace_iocb_timeout, 0);
    162	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);
    163	list_add_tail(&entry->next, &fcport->edif.edif_indx_list);
    164	spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
    165	return 0;
    166}
    167
    168/* remove an entry from the list */
    169static void qla_edif_list_delete_sa_index(fc_port_t *fcport, struct edif_list_entry *entry)
    170{
    171	unsigned long flags = 0;
    172
    173	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);
    174	list_del(&entry->next);
    175	spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
    176}
    177
    178int qla_post_sa_replace_work(struct scsi_qla_host *vha,
    179	 fc_port_t *fcport, uint16_t nport_handle, struct edif_sa_ctl *sa_ctl)
    180{
    181	struct qla_work_evt *e;
    182
    183	e = qla2x00_alloc_work(vha, QLA_EVT_SA_REPLACE);
    184	if (!e)
    185		return QLA_FUNCTION_FAILED;
    186
    187	e->u.sa_update.fcport = fcport;
    188	e->u.sa_update.sa_ctl = sa_ctl;
    189	e->u.sa_update.nport_handle = nport_handle;
    190	fcport->flags |= FCF_ASYNC_ACTIVE;
    191	return qla2x00_post_work(vha, e);
    192}
    193
    194static void
    195qla_edif_sa_ctl_init(scsi_qla_host_t *vha, struct fc_port  *fcport)
    196{
    197	ql_dbg(ql_dbg_edif, vha, 0x2058,
    198	    "Init SA_CTL List for fcport - nn %8phN pn %8phN portid=%06x.\n",
    199	    fcport->node_name, fcport->port_name, fcport->d_id.b24);
    200
    201	fcport->edif.tx_rekey_cnt = 0;
    202	fcport->edif.rx_rekey_cnt = 0;
    203
    204	fcport->edif.tx_bytes = 0;
    205	fcport->edif.rx_bytes = 0;
    206}
    207
    208static int qla_bsg_check(scsi_qla_host_t *vha, struct bsg_job *bsg_job,
    209fc_port_t *fcport)
    210{
    211	struct extra_auth_els *p;
    212	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
    213	struct qla_bsg_auth_els_request *req =
    214	    (struct qla_bsg_auth_els_request *)bsg_job->request;
    215
    216	if (!vha->hw->flags.edif_enabled) {
    217		ql_dbg(ql_dbg_edif, vha, 0x9105,
    218		    "%s edif not enabled\n", __func__);
    219		goto done;
    220	}
    221	if (DBELL_INACTIVE(vha)) {
    222		ql_dbg(ql_dbg_edif, vha, 0x09102,
    223		    "%s doorbell not enabled\n", __func__);
    224		goto done;
    225	}
    226
    227	p = &req->e;
    228
    229	/* Get response */
    230	if (p->sub_cmd == PULL_ELS) {
    231		struct qla_bsg_auth_els_reply *rpl =
    232			(struct qla_bsg_auth_els_reply *)bsg_job->reply;
    233
    234		qla_pur_get_pending(vha, fcport, bsg_job);
    235
    236		ql_dbg(ql_dbg_edif, vha, 0x911d,
    237			"%s %s %8phN sid=%x. xchg %x, nb=%xh bsg ptr %p\n",
    238			__func__, sc_to_str(p->sub_cmd), fcport->port_name,
    239			fcport->d_id.b24, rpl->rx_xchg_address,
    240			rpl->r.reply_payload_rcv_len, bsg_job);
    241
    242		goto done;
    243	}
    244	return 0;
    245
    246done:
    247
    248	bsg_job_done(bsg_job, bsg_reply->result,
    249			bsg_reply->reply_payload_rcv_len);
    250	return -EIO;
    251}
    252
    253fc_port_t *
    254qla2x00_find_fcport_by_pid(scsi_qla_host_t *vha, port_id_t *id)
    255{
    256	fc_port_t *f, *tf;
    257
    258	f = NULL;
    259	list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) {
    260		if ((f->flags & FCF_FCSP_DEVICE)) {
    261			ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x2058,
    262			    "Found secure fcport - nn %8phN pn %8phN portid=0x%x, 0x%x.\n",
    263			    f->node_name, f->port_name,
    264			    f->d_id.b24, id->b24);
    265			if (f->d_id.b24 == id->b24)
    266				return f;
    267		}
    268	}
    269	return NULL;
    270}
    271
    272/**
    273 * qla_edif_app_check(): check for valid application id.
    274 * @vha: host adapter pointer
    275 * @appid: application id
    276 * Return: false = fail, true = pass
    277 */
    278static bool
    279qla_edif_app_check(scsi_qla_host_t *vha, struct app_id appid)
    280{
    281	/* check that the app is allow/known to the driver */
    282
    283	if (appid.app_vid == EDIF_APP_ID) {
    284		ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x911d, "%s app id ok\n", __func__);
    285		return true;
    286	}
    287	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app id not ok (%x)",
    288	    __func__, appid.app_vid);
    289
    290	return false;
    291}
    292
    293static void
    294qla_edif_free_sa_ctl(fc_port_t *fcport, struct edif_sa_ctl *sa_ctl,
    295	int index)
    296{
    297	unsigned long flags = 0;
    298
    299	spin_lock_irqsave(&fcport->edif.sa_list_lock, flags);
    300	list_del(&sa_ctl->next);
    301	spin_unlock_irqrestore(&fcport->edif.sa_list_lock, flags);
    302	if (index >= 512)
    303		fcport->edif.tx_rekey_cnt--;
    304	else
    305		fcport->edif.rx_rekey_cnt--;
    306	kfree(sa_ctl);
    307}
    308
    309/* return an index to the freepool */
    310static void qla_edif_add_sa_index_to_freepool(fc_port_t *fcport, int dir,
    311		uint16_t sa_index)
    312{
    313	void *sa_id_map;
    314	struct scsi_qla_host *vha = fcport->vha;
    315	struct qla_hw_data *ha = vha->hw;
    316	unsigned long flags = 0;
    317	u16 lsa_index = sa_index;
    318
    319	ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063,
    320	    "%s: entry\n", __func__);
    321
    322	if (dir) {
    323		sa_id_map = ha->edif_tx_sa_id_map;
    324		lsa_index -= EDIF_TX_SA_INDEX_BASE;
    325	} else {
    326		sa_id_map = ha->edif_rx_sa_id_map;
    327	}
    328
    329	spin_lock_irqsave(&ha->sadb_fp_lock, flags);
    330	clear_bit(lsa_index, sa_id_map);
    331	spin_unlock_irqrestore(&ha->sadb_fp_lock, flags);
    332	ql_dbg(ql_dbg_edif, vha, 0x3063,
    333	    "%s: index %d added to free pool\n", __func__, sa_index);
    334}
    335
    336static void __qla2x00_release_all_sadb(struct scsi_qla_host *vha,
    337	struct fc_port *fcport, struct edif_sa_index_entry *entry,
    338	int pdir)
    339{
    340	struct edif_list_entry *edif_entry;
    341	struct  edif_sa_ctl *sa_ctl;
    342	int i, dir;
    343	int key_cnt = 0;
    344
    345	for (i = 0; i < 2; i++) {
    346		if (entry->sa_pair[i].sa_index == INVALID_EDIF_SA_INDEX)
    347			continue;
    348
    349		if (fcport->loop_id != entry->handle) {
    350			ql_dbg(ql_dbg_edif, vha, 0x3063,
    351			    "%s: ** WARNING %d** entry handle: 0x%x, lid: 0x%x, sa_index: %d\n",
    352			    __func__, i, entry->handle, fcport->loop_id,
    353			    entry->sa_pair[i].sa_index);
    354		}
    355
    356		/* release the sa_ctl */
    357		sa_ctl = qla_edif_find_sa_ctl_by_index(fcport,
    358				entry->sa_pair[i].sa_index, pdir);
    359		if (sa_ctl &&
    360		    qla_edif_find_sa_ctl_by_index(fcport, sa_ctl->index, pdir)) {
    361			ql_dbg(ql_dbg_edif, vha, 0x3063,
    362			    "%s: freeing sa_ctl for index %d\n", __func__, sa_ctl->index);
    363			qla_edif_free_sa_ctl(fcport, sa_ctl, sa_ctl->index);
    364		} else {
    365			ql_dbg(ql_dbg_edif, vha, 0x3063,
    366			    "%s: sa_ctl NOT freed, sa_ctl: %p\n", __func__, sa_ctl);
    367		}
    368
    369		/* Release the index */
    370		ql_dbg(ql_dbg_edif, vha, 0x3063,
    371			"%s: freeing sa_index %d, nph: 0x%x\n",
    372			__func__, entry->sa_pair[i].sa_index, entry->handle);
    373
    374		dir = (entry->sa_pair[i].sa_index <
    375			EDIF_TX_SA_INDEX_BASE) ? 0 : 1;
    376		qla_edif_add_sa_index_to_freepool(fcport, dir,
    377			entry->sa_pair[i].sa_index);
    378
    379		/* Delete timer on RX */
    380		if (pdir != SAU_FLG_TX) {
    381			edif_entry =
    382				qla_edif_list_find_sa_index(fcport, entry->handle);
    383			if (edif_entry) {
    384				ql_dbg(ql_dbg_edif, vha, 0x5033,
    385				    "%s: remove edif_entry %p, update_sa_index: 0x%x, delete_sa_index: 0x%x\n",
    386				    __func__, edif_entry, edif_entry->update_sa_index,
    387				    edif_entry->delete_sa_index);
    388				qla_edif_list_delete_sa_index(fcport, edif_entry);
    389				/*
    390				 * valid delete_sa_index indicates there is a rx
    391				 * delayed delete queued
    392				 */
    393				if (edif_entry->delete_sa_index !=
    394						INVALID_EDIF_SA_INDEX) {
    395					del_timer(&edif_entry->timer);
    396
    397					/* build and send the aen */
    398					fcport->edif.rx_sa_set = 1;
    399					fcport->edif.rx_sa_pending = 0;
    400					qla_edb_eventcreate(vha,
    401							VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
    402							QL_VND_SA_STAT_SUCCESS,
    403							QL_VND_RX_SA_KEY, fcport);
    404				}
    405				ql_dbg(ql_dbg_edif, vha, 0x5033,
    406				    "%s: release edif_entry %p, update_sa_index: 0x%x, delete_sa_index: 0x%x\n",
    407				    __func__, edif_entry, edif_entry->update_sa_index,
    408				    edif_entry->delete_sa_index);
    409
    410				kfree(edif_entry);
    411			}
    412		}
    413		key_cnt++;
    414	}
    415	ql_dbg(ql_dbg_edif, vha, 0x3063,
    416	    "%s: %d %s keys released\n",
    417	    __func__, key_cnt, pdir ? "tx" : "rx");
    418}
    419
    420/* find an release all outstanding sadb sa_indicies */
    421void qla2x00_release_all_sadb(struct scsi_qla_host *vha, struct fc_port *fcport)
    422{
    423	struct edif_sa_index_entry *entry, *tmp;
    424	struct qla_hw_data *ha = vha->hw;
    425	unsigned long flags;
    426
    427	ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063,
    428	    "%s: Starting...\n", __func__);
    429
    430	spin_lock_irqsave(&ha->sadb_lock, flags);
    431
    432	list_for_each_entry_safe(entry, tmp, &ha->sadb_rx_index_list, next) {
    433		if (entry->fcport == fcport) {
    434			list_del(&entry->next);
    435			spin_unlock_irqrestore(&ha->sadb_lock, flags);
    436			__qla2x00_release_all_sadb(vha, fcport, entry, 0);
    437			kfree(entry);
    438			spin_lock_irqsave(&ha->sadb_lock, flags);
    439			break;
    440		}
    441	}
    442
    443	list_for_each_entry_safe(entry, tmp, &ha->sadb_tx_index_list, next) {
    444		if (entry->fcport == fcport) {
    445			list_del(&entry->next);
    446			spin_unlock_irqrestore(&ha->sadb_lock, flags);
    447
    448			__qla2x00_release_all_sadb(vha, fcport, entry, SAU_FLG_TX);
    449
    450			kfree(entry);
    451			spin_lock_irqsave(&ha->sadb_lock, flags);
    452			break;
    453		}
    454	}
    455	spin_unlock_irqrestore(&ha->sadb_lock, flags);
    456}
    457
    458/**
    459 * qla_edif_app_start:  application has announce its present
    460 * @vha: host adapter pointer
    461 * @bsg_job: user request
    462 *
    463 * Set/activate doorbell.  Reset current sessions and re-login with
    464 * secure flag.
    465 */
    466static int
    467qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
    468{
    469	int32_t			rval = 0;
    470	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
    471	struct app_start	appstart;
    472	struct app_start_reply	appreply;
    473	struct fc_port  *fcport, *tf;
    474
    475	ql_log(ql_log_info, vha, 0x1313,
    476	       "EDIF application registration with driver, FC device connections will be re-established.\n");
    477
    478	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
    479	    bsg_job->request_payload.sg_cnt, &appstart,
    480	    sizeof(struct app_start));
    481
    482	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app_vid=%x app_start_flags %x\n",
    483	     __func__, appstart.app_info.app_vid, appstart.app_start_flags);
    484
    485	if (DBELL_INACTIVE(vha)) {
    486		/* mark doorbell as active since an app is now present */
    487		vha->e_dbell.db_flags |= EDB_ACTIVE;
    488	} else {
    489		ql_dbg(ql_dbg_edif, vha, 0x911e, "%s doorbell already active\n",
    490		     __func__);
    491	}
    492
    493	if (N2N_TOPO(vha->hw)) {
    494		if (vha->hw->flags.n2n_fw_acc_sec)
    495			set_bit(N2N_LINK_RESET, &vha->dpc_flags);
    496		else
    497			set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
    498		qla2xxx_wake_dpc(vha);
    499	} else {
    500		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
    501			ql_dbg(ql_dbg_edif, vha, 0x2058,
    502			       "FCSP - nn %8phN pn %8phN portid=%06x.\n",
    503			       fcport->node_name, fcport->port_name,
    504			       fcport->d_id.b24);
    505			ql_dbg(ql_dbg_edif, vha, 0xf084,
    506			       "%s: se_sess %p / sess %p from port %8phC "
    507			       "loop_id %#04x s_id %06x logout %d "
    508			       "keep %d els_logo %d disc state %d auth state %d"
    509			       "stop state %d\n",
    510			       __func__, fcport->se_sess, fcport,
    511			       fcport->port_name, fcport->loop_id,
    512			       fcport->d_id.b24, fcport->logout_on_delete,
    513			       fcport->keep_nport_handle, fcport->send_els_logo,
    514			       fcport->disc_state, fcport->edif.auth_state,
    515			       fcport->edif.app_stop);
    516
    517			if (atomic_read(&vha->loop_state) == LOOP_DOWN)
    518				break;
    519
    520			fcport->edif.app_started = 1;
    521			fcport->login_retry = vha->hw->login_retry_count;
    522
    523			/* no activity */
    524			fcport->edif.app_stop = 0;
    525
    526			ql_dbg(ql_dbg_edif, vha, 0x911e,
    527			       "%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
    528			       __func__, fcport->port_name);
    529			fcport->edif.app_sess_online = 0;
    530			qlt_schedule_sess_for_deletion(fcport);
    531			qla_edif_sa_ctl_init(vha, fcport);
    532		}
    533	}
    534
    535	if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
    536		/* mark as active since an app is now present */
    537		vha->pur_cinfo.enode_flags = ENODE_ACTIVE;
    538	} else {
    539		ql_dbg(ql_dbg_edif, vha, 0x911f, "%s enode already active\n",
    540		     __func__);
    541	}
    542
    543	appreply.host_support_edif = vha->hw->flags.edif_enabled;
    544	appreply.edif_enode_active = vha->pur_cinfo.enode_flags;
    545	appreply.edif_edb_active = vha->e_dbell.db_flags;
    546
    547	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
    548
    549	SET_DID_STATUS(bsg_reply->result, DID_OK);
    550
    551	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
    552							       bsg_job->reply_payload.sg_cnt,
    553							       &appreply,
    554							       sizeof(struct app_start_reply));
    555
    556	ql_dbg(ql_dbg_edif, vha, 0x911d,
    557	    "%s app start completed with 0x%x\n",
    558	    __func__, rval);
    559
    560	return rval;
    561}
    562
    563/**
    564 * qla_edif_app_stop - app has announced it's exiting.
    565 * @vha: host adapter pointer
    566 * @bsg_job: user space command pointer
    567 *
    568 * Free any in flight messages, clear all doorbell events
    569 * to application. Reject any message relate to security.
    570 */
    571static int
    572qla_edif_app_stop(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
    573{
    574	struct app_stop         appstop;
    575	struct fc_bsg_reply     *bsg_reply = bsg_job->reply;
    576	struct fc_port  *fcport, *tf;
    577
    578	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
    579	    bsg_job->request_payload.sg_cnt, &appstop,
    580	    sizeof(struct app_stop));
    581
    582	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s Stopping APP: app_vid=%x\n",
    583	    __func__, appstop.app_info.app_vid);
    584
    585	/* Call db stop and enode stop functions */
    586
    587	/* if we leave this running short waits are operational < 16 secs */
    588	qla_enode_stop(vha);        /* stop enode */
    589	qla_edb_stop(vha);          /* stop db */
    590
    591	list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
    592		if (!(fcport->flags & FCF_FCSP_DEVICE))
    593			continue;
    594
    595		if (fcport->flags & FCF_FCSP_DEVICE) {
    596			ql_dbg(ql_dbg_edif, vha, 0xf084,
    597			    "%s: sess %p from port %8phC lid %#04x s_id %06x logout %d keep %d els_logo %d\n",
    598			    __func__, fcport,
    599			    fcport->port_name, fcport->loop_id, fcport->d_id.b24,
    600			    fcport->logout_on_delete, fcport->keep_nport_handle,
    601			    fcport->send_els_logo);
    602
    603			if (atomic_read(&vha->loop_state) == LOOP_DOWN)
    604				break;
    605
    606			fcport->edif.app_stop = 1;
    607			ql_dbg(ql_dbg_edif, vha, 0x911e,
    608				"%s wwpn %8phC calling qla_edif_reset_auth_wait\n",
    609				__func__, fcport->port_name);
    610
    611			fcport->send_els_logo = 1;
    612			qlt_schedule_sess_for_deletion(fcport);
    613
    614			/* qla_edif_flush_sa_ctl_lists(fcport); */
    615			fcport->edif.app_started = 0;
    616		}
    617	}
    618
    619	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
    620	SET_DID_STATUS(bsg_reply->result, DID_OK);
    621
    622	/* no return interface to app - it assumes we cleaned up ok */
    623
    624	return 0;
    625}
    626
    627static int
    628qla_edif_app_chk_sa_update(scsi_qla_host_t *vha, fc_port_t *fcport,
    629		struct app_plogi_reply *appplogireply)
    630{
    631	int	ret = 0;
    632
    633	if (!(fcport->edif.rx_sa_set && fcport->edif.tx_sa_set)) {
    634		ql_dbg(ql_dbg_edif, vha, 0x911e,
    635		    "%s: wwpn %8phC Both SA indexes has not been SET TX %d, RX %d.\n",
    636		    __func__, fcport->port_name, fcport->edif.tx_sa_set,
    637		    fcport->edif.rx_sa_set);
    638		appplogireply->prli_status = 0;
    639		ret = 1;
    640	} else  {
    641		ql_dbg(ql_dbg_edif, vha, 0x911e,
    642		    "%s wwpn %8phC Both SA(s) updated.\n", __func__,
    643		    fcport->port_name);
    644		fcport->edif.rx_sa_set = fcport->edif.tx_sa_set = 0;
    645		fcport->edif.rx_sa_pending = fcport->edif.tx_sa_pending = 0;
    646		appplogireply->prli_status = 1;
    647	}
    648	return ret;
    649}
    650
    651/**
    652 * qla_edif_app_authok - authentication by app succeeded.  Driver can proceed
    653 *   with prli
    654 * @vha: host adapter pointer
    655 * @bsg_job: user request
    656 */
    657static int
    658qla_edif_app_authok(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
    659{
    660	struct auth_complete_cmd appplogiok;
    661	struct app_plogi_reply	appplogireply = {0};
    662	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
    663	fc_port_t		*fcport = NULL;
    664	port_id_t		portid = {0};
    665
    666	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
    667	    bsg_job->request_payload.sg_cnt, &appplogiok,
    668	    sizeof(struct auth_complete_cmd));
    669
    670	/* silent unaligned access warning */
    671	portid.b.domain = appplogiok.u.d_id.b.domain;
    672	portid.b.area   = appplogiok.u.d_id.b.area;
    673	portid.b.al_pa  = appplogiok.u.d_id.b.al_pa;
    674
    675	switch (appplogiok.type) {
    676	case PL_TYPE_WWPN:
    677		fcport = qla2x00_find_fcport_by_wwpn(vha,
    678		    appplogiok.u.wwpn, 0);
    679		if (!fcport)
    680			ql_dbg(ql_dbg_edif, vha, 0x911d,
    681			    "%s wwpn lookup failed: %8phC\n",
    682			    __func__, appplogiok.u.wwpn);
    683		break;
    684	case PL_TYPE_DID:
    685		fcport = qla2x00_find_fcport_by_pid(vha, &portid);
    686		if (!fcport)
    687			ql_dbg(ql_dbg_edif, vha, 0x911d,
    688			    "%s d_id lookup failed: %x\n", __func__,
    689			    portid.b24);
    690		break;
    691	default:
    692		ql_dbg(ql_dbg_edif, vha, 0x911d,
    693		    "%s undefined type: %x\n", __func__,
    694		    appplogiok.type);
    695		break;
    696	}
    697
    698	if (!fcport) {
    699		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
    700		goto errstate_exit;
    701	}
    702
    703	/*
    704	 * if port is online then this is a REKEY operation
    705	 * Only do sa update checking
    706	 */
    707	if (atomic_read(&fcport->state) == FCS_ONLINE) {
    708		ql_dbg(ql_dbg_edif, vha, 0x911d,
    709		    "%s Skipping PRLI complete based on rekey\n", __func__);
    710		appplogireply.prli_status = 1;
    711		SET_DID_STATUS(bsg_reply->result, DID_OK);
    712		qla_edif_app_chk_sa_update(vha, fcport, &appplogireply);
    713		goto errstate_exit;
    714	}
    715
    716	/* make sure in AUTH_PENDING or else reject */
    717	if (fcport->disc_state != DSC_LOGIN_AUTH_PEND) {
    718		ql_dbg(ql_dbg_edif, vha, 0x911e,
    719		    "%s wwpn %8phC is not in auth pending state (%x)\n",
    720		    __func__, fcport->port_name, fcport->disc_state);
    721		SET_DID_STATUS(bsg_reply->result, DID_OK);
    722		appplogireply.prli_status = 0;
    723		goto errstate_exit;
    724	}
    725
    726	SET_DID_STATUS(bsg_reply->result, DID_OK);
    727	appplogireply.prli_status = 1;
    728	fcport->edif.authok = 1;
    729	if (!(fcport->edif.rx_sa_set && fcport->edif.tx_sa_set)) {
    730		ql_dbg(ql_dbg_edif, vha, 0x911e,
    731		    "%s: wwpn %8phC Both SA indexes has not been SET TX %d, RX %d.\n",
    732		    __func__, fcport->port_name, fcport->edif.tx_sa_set,
    733		    fcport->edif.rx_sa_set);
    734		SET_DID_STATUS(bsg_reply->result, DID_OK);
    735		appplogireply.prli_status = 0;
    736		goto errstate_exit;
    737
    738	} else {
    739		ql_dbg(ql_dbg_edif, vha, 0x911e,
    740		    "%s wwpn %8phC Both SA(s) updated.\n", __func__,
    741		    fcport->port_name);
    742		fcport->edif.rx_sa_set = fcport->edif.tx_sa_set = 0;
    743		fcport->edif.rx_sa_pending = fcport->edif.tx_sa_pending = 0;
    744	}
    745
    746	if (qla_ini_mode_enabled(vha)) {
    747		ql_dbg(ql_dbg_edif, vha, 0x911e,
    748		    "%s AUTH complete - RESUME with prli for wwpn %8phC\n",
    749		    __func__, fcport->port_name);
    750		qla24xx_post_prli_work(vha, fcport);
    751	}
    752
    753errstate_exit:
    754	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
    755	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
    756							       bsg_job->reply_payload.sg_cnt,
    757							       &appplogireply,
    758							       sizeof(struct app_plogi_reply));
    759
    760	return 0;
    761}
    762
    763/**
    764 * qla_edif_app_authfail - authentication by app has failed.  Driver is given
    765 *   notice to tear down current session.
    766 * @vha: host adapter pointer
    767 * @bsg_job: user request
    768 */
    769static int
    770qla_edif_app_authfail(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
    771{
    772	int32_t			rval = 0;
    773	struct auth_complete_cmd appplogifail;
    774	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
    775	fc_port_t		*fcport = NULL;
    776	port_id_t		portid = {0};
    777
    778	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app auth fail\n", __func__);
    779
    780	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
    781	    bsg_job->request_payload.sg_cnt, &appplogifail,
    782	    sizeof(struct auth_complete_cmd));
    783
    784	/* silent unaligned access warning */
    785	portid.b.domain = appplogifail.u.d_id.b.domain;
    786	portid.b.area   = appplogifail.u.d_id.b.area;
    787	portid.b.al_pa  = appplogifail.u.d_id.b.al_pa;
    788
    789	/*
    790	 * TODO: edif: app has failed this plogi. Inform driver to
    791	 * take any action (if any).
    792	 */
    793	switch (appplogifail.type) {
    794	case PL_TYPE_WWPN:
    795		fcport = qla2x00_find_fcport_by_wwpn(vha,
    796		    appplogifail.u.wwpn, 0);
    797		SET_DID_STATUS(bsg_reply->result, DID_OK);
    798		break;
    799	case PL_TYPE_DID:
    800		fcport = qla2x00_find_fcport_by_pid(vha, &portid);
    801		if (!fcport)
    802			ql_dbg(ql_dbg_edif, vha, 0x911d,
    803			    "%s d_id lookup failed: %x\n", __func__,
    804			    portid.b24);
    805		SET_DID_STATUS(bsg_reply->result, DID_OK);
    806		break;
    807	default:
    808		ql_dbg(ql_dbg_edif, vha, 0x911e,
    809		    "%s undefined type: %x\n", __func__,
    810		    appplogifail.type);
    811		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
    812		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
    813		rval = -1;
    814		break;
    815	}
    816
    817	ql_dbg(ql_dbg_edif, vha, 0x911d,
    818	    "%s fcport is 0x%p\n", __func__, fcport);
    819
    820	if (fcport) {
    821		/* set/reset edif values and flags */
    822		ql_dbg(ql_dbg_edif, vha, 0x911e,
    823		    "%s reset the auth process - %8phC, loopid=%x portid=%06x.\n",
    824		    __func__, fcport->port_name, fcport->loop_id, fcport->d_id.b24);
    825
    826		if (qla_ini_mode_enabled(fcport->vha)) {
    827			fcport->send_els_logo = 1;
    828			qlt_schedule_sess_for_deletion(fcport);
    829		}
    830	}
    831
    832	return rval;
    833}
    834
    835/**
    836 * qla_edif_app_getfcinfo - app would like to read session info (wwpn, nportid,
    837 *   [initiator|target] mode.  It can specific session with specific nport id or
    838 *   all sessions.
    839 * @vha: host adapter pointer
    840 * @bsg_job: user request pointer
    841 */
    842static int
    843qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
    844{
    845	int32_t			rval = 0;
    846	int32_t			pcnt = 0;
    847	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
    848	struct app_pinfo_req	app_req;
    849	struct app_pinfo_reply	*app_reply;
    850	port_id_t		tdid;
    851
    852	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s app get fcinfo\n", __func__);
    853
    854	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
    855	    bsg_job->request_payload.sg_cnt, &app_req,
    856	    sizeof(struct app_pinfo_req));
    857
    858	app_reply = kzalloc((sizeof(struct app_pinfo_reply) +
    859	    sizeof(struct app_pinfo) * app_req.num_ports), GFP_KERNEL);
    860
    861	if (!app_reply) {
    862		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
    863		rval = -1;
    864	} else {
    865		struct fc_port	*fcport = NULL, *tf;
    866
    867		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
    868			if (!(fcport->flags & FCF_FCSP_DEVICE))
    869				continue;
    870
    871			tdid = app_req.remote_pid;
    872
    873			ql_dbg(ql_dbg_edif, vha, 0x2058,
    874			    "APP request entry - portid=%06x.\n", tdid.b24);
    875
    876			/* Ran out of space */
    877			if (pcnt >= app_req.num_ports)
    878				break;
    879
    880			if (tdid.b24 != 0 && tdid.b24 != fcport->d_id.b24)
    881				continue;
    882
    883			app_reply->ports[pcnt].rekey_count =
    884				fcport->edif.rekey_cnt;
    885
    886			app_reply->ports[pcnt].remote_type =
    887				VND_CMD_RTYPE_UNKNOWN;
    888			if (fcport->port_type & (FCT_NVME_TARGET | FCT_TARGET))
    889				app_reply->ports[pcnt].remote_type |=
    890					VND_CMD_RTYPE_TARGET;
    891			if (fcport->port_type & (FCT_NVME_INITIATOR | FCT_INITIATOR))
    892				app_reply->ports[pcnt].remote_type |=
    893					VND_CMD_RTYPE_INITIATOR;
    894
    895			app_reply->ports[pcnt].remote_pid = fcport->d_id;
    896
    897			ql_dbg(ql_dbg_edif, vha, 0x2058,
    898			    "Found FC_SP fcport - nn %8phN pn %8phN pcnt %d portid=%06x secure %d.\n",
    899			    fcport->node_name, fcport->port_name, pcnt,
    900			    fcport->d_id.b24, fcport->flags & FCF_FCSP_DEVICE);
    901
    902			switch (fcport->edif.auth_state) {
    903			case VND_CMD_AUTH_STATE_ELS_RCVD:
    904				if (fcport->disc_state == DSC_LOGIN_AUTH_PEND) {
    905					fcport->edif.auth_state = VND_CMD_AUTH_STATE_NEEDED;
    906					app_reply->ports[pcnt].auth_state =
    907						VND_CMD_AUTH_STATE_NEEDED;
    908				} else {
    909					app_reply->ports[pcnt].auth_state =
    910						VND_CMD_AUTH_STATE_ELS_RCVD;
    911				}
    912				break;
    913			default:
    914				app_reply->ports[pcnt].auth_state = fcport->edif.auth_state;
    915				break;
    916			}
    917
    918			memcpy(app_reply->ports[pcnt].remote_wwpn,
    919			    fcport->port_name, 8);
    920
    921			app_reply->ports[pcnt].remote_state =
    922				(atomic_read(&fcport->state) ==
    923				    FCS_ONLINE ? 1 : 0);
    924
    925			pcnt++;
    926
    927			if (tdid.b24 != 0)
    928				break;
    929		}
    930		app_reply->port_count = pcnt;
    931		SET_DID_STATUS(bsg_reply->result, DID_OK);
    932	}
    933
    934	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
    935	bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
    936							       bsg_job->reply_payload.sg_cnt,
    937							       app_reply,
    938							       sizeof(struct app_pinfo_reply) + sizeof(struct app_pinfo) * pcnt);
    939
    940	kfree(app_reply);
    941
    942	return rval;
    943}
    944
    945/**
    946 * qla_edif_app_getstats - app would like to read various statistics info
    947 * @vha: host adapter pointer
    948 * @bsg_job: user request
    949 */
    950static int32_t
    951qla_edif_app_getstats(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
    952{
    953	int32_t			rval = 0;
    954	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
    955	uint32_t size;
    956
    957	struct app_sinfo_req	app_req;
    958	struct app_stats_reply	*app_reply;
    959	uint32_t pcnt = 0;
    960
    961	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
    962	    bsg_job->request_payload.sg_cnt, &app_req,
    963	    sizeof(struct app_sinfo_req));
    964	if (app_req.num_ports == 0) {
    965		ql_dbg(ql_dbg_async, vha, 0x911d,
    966		   "%s app did not indicate number of ports to return\n",
    967		    __func__);
    968		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
    969		rval = -1;
    970	}
    971
    972	size = sizeof(struct app_stats_reply) +
    973	    (sizeof(struct app_sinfo) * app_req.num_ports);
    974
    975	app_reply = kzalloc(size, GFP_KERNEL);
    976	if (!app_reply) {
    977		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
    978		rval = -1;
    979	} else {
    980		struct fc_port	*fcport = NULL, *tf;
    981
    982		list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list) {
    983			if (fcport->edif.enable) {
    984				if (pcnt > app_req.num_ports)
    985					break;
    986
    987				app_reply->elem[pcnt].rekey_count =
    988				    fcport->edif.rekey_cnt;
    989				app_reply->elem[pcnt].tx_bytes =
    990				    fcport->edif.tx_bytes;
    991				app_reply->elem[pcnt].rx_bytes =
    992				    fcport->edif.rx_bytes;
    993
    994				memcpy(app_reply->elem[pcnt].remote_wwpn,
    995				    fcport->port_name, 8);
    996
    997				pcnt++;
    998			}
    999		}
   1000		app_reply->elem_count = pcnt;
   1001		SET_DID_STATUS(bsg_reply->result, DID_OK);
   1002	}
   1003
   1004	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
   1005	bsg_reply->reply_payload_rcv_len =
   1006	    sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
   1007	       bsg_job->reply_payload.sg_cnt, app_reply,
   1008	       sizeof(struct app_stats_reply) + (sizeof(struct app_sinfo) * pcnt));
   1009
   1010	kfree(app_reply);
   1011
   1012	return rval;
   1013}
   1014
   1015int32_t
   1016qla_edif_app_mgmt(struct bsg_job *bsg_job)
   1017{
   1018	struct fc_bsg_request	*bsg_request = bsg_job->request;
   1019	struct fc_bsg_reply	*bsg_reply = bsg_job->reply;
   1020	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
   1021	scsi_qla_host_t		*vha = shost_priv(host);
   1022	struct app_id		appcheck;
   1023	bool done = true;
   1024	int32_t         rval = 0;
   1025	uint32_t	vnd_sc = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
   1026
   1027	ql_dbg(ql_dbg_edif, vha, 0x911d, "%s vnd subcmd=%x\n",
   1028	    __func__, vnd_sc);
   1029
   1030	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
   1031	    bsg_job->request_payload.sg_cnt, &appcheck,
   1032	    sizeof(struct app_id));
   1033
   1034	if (!vha->hw->flags.edif_enabled ||
   1035		test_bit(VPORT_DELETE, &vha->dpc_flags)) {
   1036		ql_dbg(ql_dbg_edif, vha, 0x911d,
   1037		    "%s edif not enabled or vp delete. bsg ptr done %p. dpc_flags %lx\n",
   1038		    __func__, bsg_job, vha->dpc_flags);
   1039
   1040		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
   1041		goto done;
   1042	}
   1043
   1044	if (!qla_edif_app_check(vha, appcheck)) {
   1045		ql_dbg(ql_dbg_edif, vha, 0x911d,
   1046		    "%s app checked failed.\n",
   1047		    __func__);
   1048
   1049		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
   1050		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
   1051		goto done;
   1052	}
   1053
   1054	switch (vnd_sc) {
   1055	case QL_VND_SC_SA_UPDATE:
   1056		done = false;
   1057		rval = qla24xx_sadb_update(bsg_job);
   1058		break;
   1059	case QL_VND_SC_APP_START:
   1060		rval = qla_edif_app_start(vha, bsg_job);
   1061		break;
   1062	case QL_VND_SC_APP_STOP:
   1063		rval = qla_edif_app_stop(vha, bsg_job);
   1064		break;
   1065	case QL_VND_SC_AUTH_OK:
   1066		rval = qla_edif_app_authok(vha, bsg_job);
   1067		break;
   1068	case QL_VND_SC_AUTH_FAIL:
   1069		rval = qla_edif_app_authfail(vha, bsg_job);
   1070		break;
   1071	case QL_VND_SC_GET_FCINFO:
   1072		rval = qla_edif_app_getfcinfo(vha, bsg_job);
   1073		break;
   1074	case QL_VND_SC_GET_STATS:
   1075		rval = qla_edif_app_getstats(vha, bsg_job);
   1076		break;
   1077	default:
   1078		ql_dbg(ql_dbg_edif, vha, 0x911d, "%s unknown cmd=%x\n",
   1079		    __func__,
   1080		    bsg_request->rqst_data.h_vendor.vendor_cmd[1]);
   1081		rval = EXT_STATUS_INVALID_PARAM;
   1082		done = false;
   1083		break;
   1084	}
   1085
   1086done:
   1087	if (done) {
   1088		ql_dbg(ql_dbg_user, vha, 0x7009,
   1089		    "%s: %d  bsg ptr done %p\n", __func__, __LINE__, bsg_job);
   1090		bsg_job_done(bsg_job, bsg_reply->result,
   1091		    bsg_reply->reply_payload_rcv_len);
   1092	}
   1093
   1094	return rval;
   1095}
   1096
   1097static struct edif_sa_ctl *
   1098qla_edif_add_sa_ctl(fc_port_t *fcport, struct qla_sa_update_frame *sa_frame,
   1099	int dir)
   1100{
   1101	struct	edif_sa_ctl *sa_ctl;
   1102	struct qla_sa_update_frame *sap;
   1103	int	index = sa_frame->fast_sa_index;
   1104	unsigned long flags = 0;
   1105
   1106	sa_ctl = kzalloc(sizeof(*sa_ctl), GFP_KERNEL);
   1107	if (!sa_ctl) {
   1108		/* couldn't get space */
   1109		ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
   1110		    "unable to allocate SA CTL\n");
   1111		return NULL;
   1112	}
   1113
   1114	/*
   1115	 * need to allocate sa_index here and save it
   1116	 * in both sa_ctl->index and sa_frame->fast_sa_index;
   1117	 * If alloc fails then delete sa_ctl and return NULL
   1118	 */
   1119	INIT_LIST_HEAD(&sa_ctl->next);
   1120	sap = &sa_ctl->sa_frame;
   1121	*sap = *sa_frame;
   1122	sa_ctl->index = index;
   1123	sa_ctl->fcport = fcport;
   1124	sa_ctl->flags = 0;
   1125	sa_ctl->state = 0L;
   1126	ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
   1127	    "%s: Added sa_ctl %p, index %d, state 0x%lx\n",
   1128	    __func__, sa_ctl, sa_ctl->index, sa_ctl->state);
   1129	spin_lock_irqsave(&fcport->edif.sa_list_lock, flags);
   1130	if (dir == SAU_FLG_TX)
   1131		list_add_tail(&sa_ctl->next, &fcport->edif.tx_sa_list);
   1132	else
   1133		list_add_tail(&sa_ctl->next, &fcport->edif.rx_sa_list);
   1134	spin_unlock_irqrestore(&fcport->edif.sa_list_lock, flags);
   1135
   1136	return sa_ctl;
   1137}
   1138
   1139void
   1140qla_edif_flush_sa_ctl_lists(fc_port_t *fcport)
   1141{
   1142	struct edif_sa_ctl *sa_ctl, *tsa_ctl;
   1143	unsigned long flags = 0;
   1144
   1145	spin_lock_irqsave(&fcport->edif.sa_list_lock, flags);
   1146
   1147	list_for_each_entry_safe(sa_ctl, tsa_ctl, &fcport->edif.tx_sa_list,
   1148	    next) {
   1149		list_del(&sa_ctl->next);
   1150		kfree(sa_ctl);
   1151	}
   1152
   1153	list_for_each_entry_safe(sa_ctl, tsa_ctl, &fcport->edif.rx_sa_list,
   1154	    next) {
   1155		list_del(&sa_ctl->next);
   1156		kfree(sa_ctl);
   1157	}
   1158
   1159	spin_unlock_irqrestore(&fcport->edif.sa_list_lock, flags);
   1160}
   1161
   1162struct edif_sa_ctl *
   1163qla_edif_find_sa_ctl_by_index(fc_port_t *fcport, int index, int dir)
   1164{
   1165	struct edif_sa_ctl *sa_ctl, *tsa_ctl;
   1166	struct list_head *sa_list;
   1167
   1168	if (dir == SAU_FLG_TX)
   1169		sa_list = &fcport->edif.tx_sa_list;
   1170	else
   1171		sa_list = &fcport->edif.rx_sa_list;
   1172
   1173	list_for_each_entry_safe(sa_ctl, tsa_ctl, sa_list, next) {
   1174		if (test_bit(EDIF_SA_CTL_USED, &sa_ctl->state) &&
   1175		    sa_ctl->index == index)
   1176			return sa_ctl;
   1177	}
   1178	return NULL;
   1179}
   1180
   1181/* add the sa to the correct list */
   1182static int
   1183qla24xx_check_sadb_avail_slot(struct bsg_job *bsg_job, fc_port_t *fcport,
   1184	struct qla_sa_update_frame *sa_frame)
   1185{
   1186	struct edif_sa_ctl *sa_ctl = NULL;
   1187	int dir;
   1188	uint16_t sa_index;
   1189
   1190	dir = (sa_frame->flags & SAU_FLG_TX);
   1191
   1192	/* map the spi to an sa_index */
   1193	sa_index = qla_edif_sadb_get_sa_index(fcport, sa_frame);
   1194	if (sa_index == RX_DELETE_NO_EDIF_SA_INDEX) {
   1195		/* process rx delete */
   1196		ql_dbg(ql_dbg_edif, fcport->vha, 0x3063,
   1197		    "%s: rx delete for lid 0x%x, spi 0x%x, no entry found\n",
   1198		    __func__, fcport->loop_id, sa_frame->spi);
   1199
   1200		/* build and send the aen */
   1201		fcport->edif.rx_sa_set = 1;
   1202		fcport->edif.rx_sa_pending = 0;
   1203		qla_edb_eventcreate(fcport->vha,
   1204		    VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
   1205		    QL_VND_SA_STAT_SUCCESS,
   1206		    QL_VND_RX_SA_KEY, fcport);
   1207
   1208		/* force a return of good bsg status; */
   1209		return RX_DELETE_NO_EDIF_SA_INDEX;
   1210	} else if (sa_index == INVALID_EDIF_SA_INDEX) {
   1211		ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
   1212		    "%s: Failed to get sa_index for spi 0x%x, dir: %d\n",
   1213		    __func__, sa_frame->spi, dir);
   1214		return INVALID_EDIF_SA_INDEX;
   1215	}
   1216
   1217	ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
   1218	    "%s: index %d allocated to spi 0x%x, dir: %d, nport_handle: 0x%x\n",
   1219	    __func__, sa_index, sa_frame->spi, dir, fcport->loop_id);
   1220
   1221	/* This is a local copy of sa_frame. */
   1222	sa_frame->fast_sa_index = sa_index;
   1223	/* create the sa_ctl */
   1224	sa_ctl = qla_edif_add_sa_ctl(fcport, sa_frame, dir);
   1225	if (!sa_ctl) {
   1226		ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
   1227		    "%s: Failed to add sa_ctl for spi 0x%x, dir: %d, sa_index: %d\n",
   1228		    __func__, sa_frame->spi, dir, sa_index);
   1229		return -1;
   1230	}
   1231
   1232	set_bit(EDIF_SA_CTL_USED, &sa_ctl->state);
   1233
   1234	if (dir == SAU_FLG_TX)
   1235		fcport->edif.tx_rekey_cnt++;
   1236	else
   1237		fcport->edif.rx_rekey_cnt++;
   1238
   1239	ql_dbg(ql_dbg_edif, fcport->vha, 0x9100,
   1240	    "%s: Found sa_ctl %p, index %d, state 0x%lx, tx_cnt %d, rx_cnt %d, nport_handle: 0x%x\n",
   1241	    __func__, sa_ctl, sa_ctl->index, sa_ctl->state,
   1242	    fcport->edif.tx_rekey_cnt,
   1243	    fcport->edif.rx_rekey_cnt, fcport->loop_id);
   1244
   1245	return 0;
   1246}
   1247
   1248#define QLA_SA_UPDATE_FLAGS_RX_KEY      0x0
   1249#define QLA_SA_UPDATE_FLAGS_TX_KEY      0x2
   1250
   1251int
   1252qla24xx_sadb_update(struct bsg_job *bsg_job)
   1253{
   1254	struct	fc_bsg_reply	*bsg_reply = bsg_job->reply;
   1255	struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
   1256	scsi_qla_host_t *vha = shost_priv(host);
   1257	fc_port_t		*fcport = NULL;
   1258	srb_t			*sp = NULL;
   1259	struct edif_list_entry *edif_entry = NULL;
   1260	int			found = 0;
   1261	int			rval = 0;
   1262	int result = 0;
   1263	struct qla_sa_update_frame sa_frame;
   1264	struct srb_iocb *iocb_cmd;
   1265	port_id_t portid;
   1266
   1267	ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x911d,
   1268	    "%s entered, vha: 0x%p\n", __func__, vha);
   1269
   1270	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
   1271	    bsg_job->request_payload.sg_cnt, &sa_frame,
   1272	    sizeof(struct qla_sa_update_frame));
   1273
   1274	/* Check if host is online */
   1275	if (!vha->flags.online) {
   1276		ql_log(ql_log_warn, vha, 0x70a1, "Host is not online\n");
   1277		rval = -EIO;
   1278		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
   1279		goto done;
   1280	}
   1281
   1282	if (DBELL_INACTIVE(vha)) {
   1283		ql_log(ql_log_warn, vha, 0x70a1, "App not started\n");
   1284		rval = -EIO;
   1285		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
   1286		goto done;
   1287	}
   1288
   1289	/* silent unaligned access warning */
   1290	portid.b.domain = sa_frame.port_id.b.domain;
   1291	portid.b.area   = sa_frame.port_id.b.area;
   1292	portid.b.al_pa  = sa_frame.port_id.b.al_pa;
   1293
   1294	fcport = qla2x00_find_fcport_by_pid(vha, &portid);
   1295	if (fcport) {
   1296		found = 1;
   1297		if (sa_frame.flags == QLA_SA_UPDATE_FLAGS_TX_KEY)
   1298			fcport->edif.tx_bytes = 0;
   1299		if (sa_frame.flags == QLA_SA_UPDATE_FLAGS_RX_KEY)
   1300			fcport->edif.rx_bytes = 0;
   1301	}
   1302
   1303	if (!found) {
   1304		ql_dbg(ql_dbg_edif, vha, 0x70a3, "Failed to find port= %06x\n",
   1305		    sa_frame.port_id.b24);
   1306		rval = -EINVAL;
   1307		SET_DID_STATUS(bsg_reply->result, DID_TARGET_FAILURE);
   1308		goto done;
   1309	}
   1310
   1311	/* make sure the nport_handle is valid */
   1312	if (fcport->loop_id == FC_NO_LOOP_ID) {
   1313		ql_dbg(ql_dbg_edif, vha, 0x70e1,
   1314		    "%s: %8phN lid=FC_NO_LOOP_ID, spi: 0x%x, DS %d, returning NO_CONNECT\n",
   1315		    __func__, fcport->port_name, sa_frame.spi,
   1316		    fcport->disc_state);
   1317		rval = -EINVAL;
   1318		SET_DID_STATUS(bsg_reply->result, DID_NO_CONNECT);
   1319		goto done;
   1320	}
   1321
   1322	/* allocate and queue an sa_ctl */
   1323	result = qla24xx_check_sadb_avail_slot(bsg_job, fcport, &sa_frame);
   1324
   1325	/* failure of bsg */
   1326	if (result == INVALID_EDIF_SA_INDEX) {
   1327		ql_dbg(ql_dbg_edif, vha, 0x70e1,
   1328		    "%s: %8phN, skipping update.\n",
   1329		    __func__, fcport->port_name);
   1330		rval = -EINVAL;
   1331		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
   1332		goto done;
   1333
   1334	/* rx delete failure */
   1335	} else if (result == RX_DELETE_NO_EDIF_SA_INDEX) {
   1336		ql_dbg(ql_dbg_edif, vha, 0x70e1,
   1337		    "%s: %8phN, skipping rx delete.\n",
   1338		    __func__, fcport->port_name);
   1339		SET_DID_STATUS(bsg_reply->result, DID_OK);
   1340		goto done;
   1341	}
   1342
   1343	ql_dbg(ql_dbg_edif, vha, 0x70e1,
   1344	    "%s: %8phN, sa_index in sa_frame: %d flags %xh\n",
   1345	    __func__, fcport->port_name, sa_frame.fast_sa_index,
   1346	    sa_frame.flags);
   1347
   1348	/* looking for rx index and delete */
   1349	if (((sa_frame.flags & SAU_FLG_TX) == 0) &&
   1350	    (sa_frame.flags & SAU_FLG_INV)) {
   1351		uint16_t nport_handle = fcport->loop_id;
   1352		uint16_t sa_index = sa_frame.fast_sa_index;
   1353
   1354		/*
   1355		 * make sure we have an existing rx key, otherwise just process
   1356		 * this as a straight delete just like TX
   1357		 * This is NOT a normal case, it indicates an error recovery or key cleanup
   1358		 * by the ipsec code above us.
   1359		 */
   1360		edif_entry = qla_edif_list_find_sa_index(fcport, fcport->loop_id);
   1361		if (!edif_entry) {
   1362			ql_dbg(ql_dbg_edif, vha, 0x911d,
   1363			    "%s: WARNING: no active sa_index for nport_handle 0x%x, forcing delete for sa_index 0x%x\n",
   1364			    __func__, fcport->loop_id, sa_index);
   1365			goto force_rx_delete;
   1366		}
   1367
   1368		/*
   1369		 * if we have a forced delete for rx, remove the sa_index from the edif list
   1370		 * and proceed with normal delete.  The rx delay timer should not be running
   1371		 */
   1372		if ((sa_frame.flags & SAU_FLG_FORCE_DELETE) == SAU_FLG_FORCE_DELETE) {
   1373			qla_edif_list_delete_sa_index(fcport, edif_entry);
   1374			ql_dbg(ql_dbg_edif, vha, 0x911d,
   1375			    "%s: FORCE DELETE flag found for nport_handle 0x%x, sa_index 0x%x, forcing DELETE\n",
   1376			    __func__, fcport->loop_id, sa_index);
   1377			kfree(edif_entry);
   1378			goto force_rx_delete;
   1379		}
   1380
   1381		/*
   1382		 * delayed rx delete
   1383		 *
   1384		 * if delete_sa_index is not invalid then there is already
   1385		 * a delayed index in progress, return bsg bad status
   1386		 */
   1387		if (edif_entry->delete_sa_index != INVALID_EDIF_SA_INDEX) {
   1388			struct edif_sa_ctl *sa_ctl;
   1389
   1390			ql_dbg(ql_dbg_edif, vha, 0x911d,
   1391			    "%s: delete for lid 0x%x, delete_sa_index %d is pending\n",
   1392			    __func__, edif_entry->handle, edif_entry->delete_sa_index);
   1393
   1394			/* free up the sa_ctl that was allocated with the sa_index */
   1395			sa_ctl = qla_edif_find_sa_ctl_by_index(fcport, sa_index,
   1396			    (sa_frame.flags & SAU_FLG_TX));
   1397			if (sa_ctl) {
   1398				ql_dbg(ql_dbg_edif, vha, 0x3063,
   1399				    "%s: freeing sa_ctl for index %d\n",
   1400				    __func__, sa_ctl->index);
   1401				qla_edif_free_sa_ctl(fcport, sa_ctl, sa_ctl->index);
   1402			}
   1403
   1404			/* release the sa_index */
   1405			ql_dbg(ql_dbg_edif, vha, 0x3063,
   1406			    "%s: freeing sa_index %d, nph: 0x%x\n",
   1407			    __func__, sa_index, nport_handle);
   1408			qla_edif_sadb_delete_sa_index(fcport, nport_handle, sa_index);
   1409
   1410			rval = -EINVAL;
   1411			SET_DID_STATUS(bsg_reply->result, DID_ERROR);
   1412			goto done;
   1413		}
   1414
   1415		fcport->edif.rekey_cnt++;
   1416
   1417		/* configure and start the rx delay timer */
   1418		edif_entry->fcport = fcport;
   1419		edif_entry->timer.expires = jiffies + RX_DELAY_DELETE_TIMEOUT * HZ;
   1420
   1421		ql_dbg(ql_dbg_edif, vha, 0x911d,
   1422		    "%s: adding timer, entry: %p, delete sa_index %d, lid 0x%x to edif_list\n",
   1423		    __func__, edif_entry, sa_index, nport_handle);
   1424
   1425		/*
   1426		 * Start the timer when we queue the delayed rx delete.
   1427		 * This is an activity timer that goes off if we have not
   1428		 * received packets with the new sa_index
   1429		 */
   1430		add_timer(&edif_entry->timer);
   1431
   1432		/*
   1433		 * sa_delete for rx key with an active rx key including this one
   1434		 * add the delete rx sa index to the hash so we can look for it
   1435		 * in the rsp queue.  Do this after making any changes to the
   1436		 * edif_entry as part of the rx delete.
   1437		 */
   1438
   1439		ql_dbg(ql_dbg_edif, vha, 0x911d,
   1440		    "%s: delete sa_index %d, lid 0x%x to edif_list. bsg done ptr %p\n",
   1441		    __func__, sa_index, nport_handle, bsg_job);
   1442
   1443		edif_entry->delete_sa_index = sa_index;
   1444
   1445		bsg_job->reply_len = sizeof(struct fc_bsg_reply);
   1446		bsg_reply->result = DID_OK << 16;
   1447
   1448		goto done;
   1449
   1450	/*
   1451	 * rx index and update
   1452	 * add the index to the list and continue with normal update
   1453	 */
   1454	} else if (((sa_frame.flags & SAU_FLG_TX) == 0) &&
   1455	    ((sa_frame.flags & SAU_FLG_INV) == 0)) {
   1456		/* sa_update for rx key */
   1457		uint32_t nport_handle = fcport->loop_id;
   1458		uint16_t sa_index = sa_frame.fast_sa_index;
   1459		int result;
   1460
   1461		/*
   1462		 * add the update rx sa index to the hash so we can look for it
   1463		 * in the rsp queue and continue normally
   1464		 */
   1465
   1466		ql_dbg(ql_dbg_edif, vha, 0x911d,
   1467		    "%s:  adding update sa_index %d, lid 0x%x to edif_list\n",
   1468		    __func__, sa_index, nport_handle);
   1469
   1470		result = qla_edif_list_add_sa_update_index(fcport, sa_index,
   1471		    nport_handle);
   1472		if (result) {
   1473			ql_dbg(ql_dbg_edif, vha, 0x911d,
   1474			    "%s: SA_UPDATE failed to add new sa index %d to list for lid 0x%x\n",
   1475			    __func__, sa_index, nport_handle);
   1476		}
   1477	}
   1478	if (sa_frame.flags & SAU_FLG_GMAC_MODE)
   1479		fcport->edif.aes_gmac = 1;
   1480	else
   1481		fcport->edif.aes_gmac = 0;
   1482
   1483force_rx_delete:
   1484	/*
   1485	 * sa_update for both rx and tx keys, sa_delete for tx key
   1486	 * immediately process the request
   1487	 */
   1488	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
   1489	if (!sp) {
   1490		rval = -ENOMEM;
   1491		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
   1492		goto done;
   1493	}
   1494
   1495	sp->type = SRB_SA_UPDATE;
   1496	sp->name = "bsg_sa_update";
   1497	sp->u.bsg_job = bsg_job;
   1498	/* sp->free = qla2x00_bsg_sp_free; */
   1499	sp->free = qla2x00_rel_sp;
   1500	sp->done = qla2x00_bsg_job_done;
   1501	iocb_cmd = &sp->u.iocb_cmd;
   1502	iocb_cmd->u.sa_update.sa_frame  = sa_frame;
   1503
   1504	rval = qla2x00_start_sp(sp);
   1505	if (rval != QLA_SUCCESS) {
   1506		ql_log(ql_dbg_edif, vha, 0x70e3,
   1507		    "qla2x00_start_sp failed=%d.\n", rval);
   1508
   1509		qla2x00_rel_sp(sp);
   1510		rval = -EIO;
   1511		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
   1512		goto done;
   1513	}
   1514
   1515	ql_dbg(ql_dbg_edif, vha, 0x911d,
   1516	    "%s:  %s sent, hdl=%x, portid=%06x.\n",
   1517	    __func__, sp->name, sp->handle, fcport->d_id.b24);
   1518
   1519	fcport->edif.rekey_cnt++;
   1520	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
   1521	SET_DID_STATUS(bsg_reply->result, DID_OK);
   1522
   1523	return 0;
   1524
   1525/*
   1526 * send back error status
   1527 */
   1528done:
   1529	bsg_job->reply_len = sizeof(struct fc_bsg_reply);
   1530	ql_dbg(ql_dbg_edif, vha, 0x911d,
   1531	    "%s:status: FAIL, result: 0x%x, bsg ptr done %p\n",
   1532	    __func__, bsg_reply->result, bsg_job);
   1533	bsg_job_done(bsg_job, bsg_reply->result,
   1534	    bsg_reply->reply_payload_rcv_len);
   1535
   1536	return 0;
   1537}
   1538
   1539static void
   1540qla_enode_free(scsi_qla_host_t *vha, struct enode *node)
   1541{
   1542	node->ntype = N_UNDEF;
   1543	kfree(node);
   1544}
   1545
   1546/**
   1547 * qla_enode_init - initialize enode structs & lock
   1548 * @vha: host adapter pointer
   1549 *
   1550 * should only be called when driver attaching
   1551 */
   1552void
   1553qla_enode_init(scsi_qla_host_t *vha)
   1554{
   1555	struct	qla_hw_data *ha = vha->hw;
   1556	char	name[32];
   1557
   1558	if (vha->pur_cinfo.enode_flags == ENODE_ACTIVE) {
   1559		/* list still active - error */
   1560		ql_dbg(ql_dbg_edif, vha, 0x09102, "%s enode still active\n",
   1561		    __func__);
   1562		return;
   1563	}
   1564
   1565	/* initialize lock which protects pur_core & init list */
   1566	spin_lock_init(&vha->pur_cinfo.pur_lock);
   1567	INIT_LIST_HEAD(&vha->pur_cinfo.head);
   1568
   1569	snprintf(name, sizeof(name), "%s_%d_purex", QLA2XXX_DRIVER_NAME,
   1570	    ha->pdev->device);
   1571}
   1572
   1573/**
   1574 * qla_enode_stop - stop and clear and enode data
   1575 * @vha: host adapter pointer
   1576 *
   1577 * called when app notified it is exiting
   1578 */
   1579void
   1580qla_enode_stop(scsi_qla_host_t *vha)
   1581{
   1582	unsigned long flags;
   1583	struct enode *node, *q;
   1584
   1585	if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
   1586		/* doorbell list not enabled */
   1587		ql_dbg(ql_dbg_edif, vha, 0x09102,
   1588		    "%s enode not active\n", __func__);
   1589		return;
   1590	}
   1591
   1592	/* grab lock so list doesn't move */
   1593	spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);
   1594
   1595	vha->pur_cinfo.enode_flags &= ~ENODE_ACTIVE; /* mark it not active */
   1596
   1597	/* hopefully this is a null list at this point */
   1598	list_for_each_entry_safe(node, q, &vha->pur_cinfo.head, list) {
   1599		ql_dbg(ql_dbg_edif, vha, 0x910f,
   1600		    "%s freeing enode type=%x, cnt=%x\n", __func__, node->ntype,
   1601		    node->dinfo.nodecnt);
   1602		list_del_init(&node->list);
   1603		qla_enode_free(vha, node);
   1604	}
   1605	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);
   1606}
   1607
   1608static void qla_enode_clear(scsi_qla_host_t *vha, port_id_t portid)
   1609{
   1610	unsigned    long flags;
   1611	struct enode    *e, *tmp;
   1612	struct purexevent   *purex;
   1613	LIST_HEAD(enode_list);
   1614
   1615	if (vha->pur_cinfo.enode_flags != ENODE_ACTIVE) {
   1616		ql_dbg(ql_dbg_edif, vha, 0x09102,
   1617		       "%s enode not active\n", __func__);
   1618		return;
   1619	}
   1620	spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);
   1621	list_for_each_entry_safe(e, tmp, &vha->pur_cinfo.head, list) {
   1622		purex = &e->u.purexinfo;
   1623		if (purex->pur_info.pur_sid.b24 == portid.b24) {
   1624			ql_dbg(ql_dbg_edif, vha, 0x911d,
   1625			    "%s free ELS sid=%06x. xchg %x, nb=%xh\n",
   1626			    __func__, portid.b24,
   1627			    purex->pur_info.pur_rx_xchg_address,
   1628			    purex->pur_info.pur_bytes_rcvd);
   1629
   1630			list_del_init(&e->list);
   1631			list_add_tail(&e->list, &enode_list);
   1632		}
   1633	}
   1634	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);
   1635
   1636	list_for_each_entry_safe(e, tmp, &enode_list, list) {
   1637		list_del_init(&e->list);
   1638		qla_enode_free(vha, e);
   1639	}
   1640}
   1641
   1642/*
   1643 *  allocate enode struct and populate buffer
   1644 *  returns: enode pointer with buffers
   1645 *           NULL on error
   1646 */
   1647static struct enode *
   1648qla_enode_alloc(scsi_qla_host_t *vha, uint32_t ntype)
   1649{
   1650	struct enode		*node;
   1651	struct purexevent	*purex;
   1652
   1653	node = kzalloc(RX_ELS_SIZE, GFP_ATOMIC);
   1654	if (!node)
   1655		return NULL;
   1656
   1657	purex = &node->u.purexinfo;
   1658	purex->msgp = (u8 *)(node + 1);
   1659	purex->msgp_len = ELS_MAX_PAYLOAD;
   1660
   1661	node->ntype = ntype;
   1662	INIT_LIST_HEAD(&node->list);
   1663	return node;
   1664}
   1665
   1666static void
   1667qla_enode_add(scsi_qla_host_t *vha, struct enode *ptr)
   1668{
   1669	unsigned long flags;
   1670
   1671	ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x9109,
   1672	    "%s add enode for type=%x, cnt=%x\n",
   1673	    __func__, ptr->ntype, ptr->dinfo.nodecnt);
   1674
   1675	spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);
   1676	list_add_tail(&ptr->list, &vha->pur_cinfo.head);
   1677	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);
   1678
   1679	return;
   1680}
   1681
   1682static struct enode *
   1683qla_enode_find(scsi_qla_host_t *vha, uint32_t ntype, uint32_t p1, uint32_t p2)
   1684{
   1685	struct enode		*node_rtn = NULL;
   1686	struct enode		*list_node, *q;
   1687	unsigned long		flags;
   1688	uint32_t		sid;
   1689	struct purexevent	*purex;
   1690
   1691	/* secure the list from moving under us */
   1692	spin_lock_irqsave(&vha->pur_cinfo.pur_lock, flags);
   1693
   1694	list_for_each_entry_safe(list_node, q, &vha->pur_cinfo.head, list) {
   1695
   1696		/* node type determines what p1 and p2 are */
   1697		purex = &list_node->u.purexinfo;
   1698		sid = p1;
   1699
   1700		if (purex->pur_info.pur_sid.b24 == sid) {
   1701			/* found it and its complete */
   1702			node_rtn = list_node;
   1703			list_del(&list_node->list);
   1704			break;
   1705		}
   1706	}
   1707
   1708	spin_unlock_irqrestore(&vha->pur_cinfo.pur_lock, flags);
   1709
   1710	return node_rtn;
   1711}
   1712
   1713/**
   1714 * qla_pur_get_pending - read/return authentication message sent
   1715 *  from remote port
   1716 * @vha: host adapter pointer
   1717 * @fcport: session pointer
   1718 * @bsg_job: user request where the message is copy to.
   1719 */
   1720static int
   1721qla_pur_get_pending(scsi_qla_host_t *vha, fc_port_t *fcport,
   1722	struct bsg_job *bsg_job)
   1723{
   1724	struct enode		*ptr;
   1725	struct purexevent	*purex;
   1726	struct qla_bsg_auth_els_reply *rpl =
   1727	    (struct qla_bsg_auth_els_reply *)bsg_job->reply;
   1728
   1729	bsg_job->reply_len = sizeof(*rpl);
   1730
   1731	ptr = qla_enode_find(vha, N_PUREX, fcport->d_id.b24, PUR_GET);
   1732	if (!ptr) {
   1733		ql_dbg(ql_dbg_edif, vha, 0x9111,
   1734		    "%s no enode data found for %8phN sid=%06x\n",
   1735		    __func__, fcport->port_name, fcport->d_id.b24);
   1736		SET_DID_STATUS(rpl->r.result, DID_IMM_RETRY);
   1737		return -EIO;
   1738	}
   1739
   1740	/*
   1741	 * enode is now off the linked list and is ours to deal with
   1742	 */
   1743	purex = &ptr->u.purexinfo;
   1744
   1745	/* Copy info back to caller */
   1746	rpl->rx_xchg_address = purex->pur_info.pur_rx_xchg_address;
   1747
   1748	SET_DID_STATUS(rpl->r.result, DID_OK);
   1749	rpl->r.reply_payload_rcv_len =
   1750	    sg_pcopy_from_buffer(bsg_job->reply_payload.sg_list,
   1751		bsg_job->reply_payload.sg_cnt, purex->msgp,
   1752		purex->pur_info.pur_bytes_rcvd, 0);
   1753
   1754	/* data copy / passback completed - destroy enode */
   1755	qla_enode_free(vha, ptr);
   1756
   1757	return 0;
   1758}
   1759
   1760/* it is assume qpair lock is held */
   1761static int
   1762qla_els_reject_iocb(scsi_qla_host_t *vha, struct qla_qpair *qp,
   1763	struct qla_els_pt_arg *a)
   1764{
   1765	struct els_entry_24xx *els_iocb;
   1766
   1767	els_iocb = __qla2x00_alloc_iocbs(qp, NULL);
   1768	if (!els_iocb) {
   1769		ql_log(ql_log_warn, vha, 0x700c,
   1770		    "qla2x00_alloc_iocbs failed.\n");
   1771		return QLA_FUNCTION_FAILED;
   1772	}
   1773
   1774	qla_els_pt_iocb(vha, els_iocb, a);
   1775
   1776	ql_dbg(ql_dbg_edif, vha, 0x0183,
   1777	    "Sending ELS reject ox_id %04x s:%06x -> d:%06x\n",
   1778	    a->ox_id, a->sid.b24, a->did.b24);
   1779	ql_dump_buffer(ql_dbg_edif + ql_dbg_verbose, vha, 0x0185,
   1780	    vha->hw->elsrej.c, sizeof(*vha->hw->elsrej.c));
   1781	/* flush iocb to mem before notifying hw doorbell */
   1782	wmb();
   1783	qla2x00_start_iocbs(vha, qp->req);
   1784	return 0;
   1785}
   1786
   1787void
   1788qla_edb_init(scsi_qla_host_t *vha)
   1789{
   1790	if (DBELL_ACTIVE(vha)) {
   1791		/* list already init'd - error */
   1792		ql_dbg(ql_dbg_edif, vha, 0x09102,
   1793		    "edif db already initialized, cannot reinit\n");
   1794		return;
   1795	}
   1796
   1797	/* initialize lock which protects doorbell & init list */
   1798	spin_lock_init(&vha->e_dbell.db_lock);
   1799	INIT_LIST_HEAD(&vha->e_dbell.head);
   1800
   1801	/* create and initialize doorbell */
   1802	init_completion(&vha->e_dbell.dbell);
   1803}
   1804
   1805static void
   1806qla_edb_node_free(scsi_qla_host_t *vha, struct edb_node *node)
   1807{
   1808	/*
   1809	 * releases the space held by this edb node entry
   1810	 * this function does _not_ free the edb node itself
   1811	 * NB: the edb node entry passed should not be on any list
   1812	 *
   1813	 * currently for doorbell there's no additional cleanup
   1814	 * needed, but here as a placeholder for furture use.
   1815	 */
   1816
   1817	if (!node) {
   1818		ql_dbg(ql_dbg_edif, vha, 0x09122,
   1819		    "%s error - no valid node passed\n", __func__);
   1820		return;
   1821	}
   1822
   1823	node->ntype = N_UNDEF;
   1824}
   1825
   1826static void qla_edb_clear(scsi_qla_host_t *vha, port_id_t portid)
   1827{
   1828	unsigned long flags;
   1829	struct edb_node *e, *tmp;
   1830	port_id_t sid;
   1831	LIST_HEAD(edb_list);
   1832
   1833	if (DBELL_INACTIVE(vha)) {
   1834		/* doorbell list not enabled */
   1835		ql_dbg(ql_dbg_edif, vha, 0x09102,
   1836		       "%s doorbell not enabled\n", __func__);
   1837		return;
   1838	}
   1839
   1840	/* grab lock so list doesn't move */
   1841	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
   1842	list_for_each_entry_safe(e, tmp, &vha->e_dbell.head, list) {
   1843		switch (e->ntype) {
   1844		case VND_CMD_AUTH_STATE_NEEDED:
   1845		case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
   1846			sid = e->u.plogi_did;
   1847			break;
   1848		case VND_CMD_AUTH_STATE_ELS_RCVD:
   1849			sid = e->u.els_sid;
   1850			break;
   1851		case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
   1852			/* app wants to see this  */
   1853			continue;
   1854		default:
   1855			ql_log(ql_log_warn, vha, 0x09102,
   1856			       "%s unknown node type: %x\n", __func__, e->ntype);
   1857			sid.b24 = 0;
   1858			break;
   1859		}
   1860		if (sid.b24 == portid.b24) {
   1861			ql_dbg(ql_dbg_edif, vha, 0x910f,
   1862			       "%s free doorbell event : node type = %x %p\n",
   1863			       __func__, e->ntype, e);
   1864			list_del_init(&e->list);
   1865			list_add_tail(&e->list, &edb_list);
   1866		}
   1867	}
   1868	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
   1869
   1870	list_for_each_entry_safe(e, tmp, &edb_list, list) {
   1871		qla_edb_node_free(vha, e);
   1872		list_del_init(&e->list);
   1873		kfree(e);
   1874	}
   1875}
   1876
   1877/* function called when app is stopping */
   1878
   1879void
   1880qla_edb_stop(scsi_qla_host_t *vha)
   1881{
   1882	unsigned long flags;
   1883	struct edb_node *node, *q;
   1884
   1885	if (DBELL_INACTIVE(vha)) {
   1886		/* doorbell list not enabled */
   1887		ql_dbg(ql_dbg_edif, vha, 0x09102,
   1888		    "%s doorbell not enabled\n", __func__);
   1889		return;
   1890	}
   1891
   1892	/* grab lock so list doesn't move */
   1893	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
   1894
   1895	vha->e_dbell.db_flags &= ~EDB_ACTIVE; /* mark it not active */
   1896	/* hopefully this is a null list at this point */
   1897	list_for_each_entry_safe(node, q, &vha->e_dbell.head, list) {
   1898		ql_dbg(ql_dbg_edif, vha, 0x910f,
   1899		    "%s freeing edb_node type=%x\n",
   1900		    __func__, node->ntype);
   1901		qla_edb_node_free(vha, node);
   1902		list_del(&node->list);
   1903
   1904		kfree(node);
   1905	}
   1906	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
   1907
   1908	/* wake up doorbell waiters - they'll be dismissed with error code */
   1909	complete_all(&vha->e_dbell.dbell);
   1910}
   1911
   1912static struct edb_node *
   1913qla_edb_node_alloc(scsi_qla_host_t *vha, uint32_t ntype)
   1914{
   1915	struct edb_node	*node;
   1916
   1917	node = kzalloc(sizeof(*node), GFP_ATOMIC);
   1918	if (!node) {
   1919		/* couldn't get space */
   1920		ql_dbg(ql_dbg_edif, vha, 0x9100,
   1921		    "edb node unable to be allocated\n");
   1922		return NULL;
   1923	}
   1924
   1925	node->ntype = ntype;
   1926	INIT_LIST_HEAD(&node->list);
   1927	return node;
   1928}
   1929
   1930/* adds a already allocated enode to the linked list */
   1931static bool
   1932qla_edb_node_add(scsi_qla_host_t *vha, struct edb_node *ptr)
   1933{
   1934	unsigned long		flags;
   1935
   1936	if (DBELL_INACTIVE(vha)) {
   1937		/* doorbell list not enabled */
   1938		ql_dbg(ql_dbg_edif, vha, 0x09102,
   1939		    "%s doorbell not enabled\n", __func__);
   1940		return false;
   1941	}
   1942
   1943	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
   1944	list_add_tail(&ptr->list, &vha->e_dbell.head);
   1945	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
   1946
   1947	/* ring doorbell for waiters */
   1948	complete(&vha->e_dbell.dbell);
   1949
   1950	return true;
   1951}
   1952
   1953/* adds event to doorbell list */
   1954void
   1955qla_edb_eventcreate(scsi_qla_host_t *vha, uint32_t dbtype,
   1956	uint32_t data, uint32_t data2, fc_port_t	*sfcport)
   1957{
   1958	struct edb_node	*edbnode;
   1959	fc_port_t *fcport = sfcport;
   1960	port_id_t id;
   1961
   1962	if (!vha->hw->flags.edif_enabled) {
   1963		/* edif not enabled */
   1964		return;
   1965	}
   1966
   1967	if (DBELL_INACTIVE(vha)) {
   1968		if (fcport)
   1969			fcport->edif.auth_state = dbtype;
   1970		/* doorbell list not enabled */
   1971		ql_dbg(ql_dbg_edif, vha, 0x09102,
   1972		    "%s doorbell not enabled (type=%d\n", __func__, dbtype);
   1973		return;
   1974	}
   1975
   1976	edbnode = qla_edb_node_alloc(vha, dbtype);
   1977	if (!edbnode) {
   1978		ql_dbg(ql_dbg_edif, vha, 0x09102,
   1979		    "%s unable to alloc db node\n", __func__);
   1980		return;
   1981	}
   1982
   1983	if (!fcport) {
   1984		id.b.domain = (data >> 16) & 0xff;
   1985		id.b.area = (data >> 8) & 0xff;
   1986		id.b.al_pa = data & 0xff;
   1987		ql_dbg(ql_dbg_edif, vha, 0x09222,
   1988		    "%s: Arrived s_id: %06x\n", __func__,
   1989		    id.b24);
   1990		fcport = qla2x00_find_fcport_by_pid(vha, &id);
   1991		if (!fcport) {
   1992			ql_dbg(ql_dbg_edif, vha, 0x09102,
   1993			    "%s can't find fcport for sid= 0x%x - ignoring\n",
   1994			__func__, id.b24);
   1995			kfree(edbnode);
   1996			return;
   1997		}
   1998	}
   1999
   2000	/* populate the edb node */
   2001	switch (dbtype) {
   2002	case VND_CMD_AUTH_STATE_NEEDED:
   2003	case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
   2004		edbnode->u.plogi_did.b24 = fcport->d_id.b24;
   2005		break;
   2006	case VND_CMD_AUTH_STATE_ELS_RCVD:
   2007		edbnode->u.els_sid.b24 = fcport->d_id.b24;
   2008		break;
   2009	case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
   2010		edbnode->u.sa_aen.port_id = fcport->d_id;
   2011		edbnode->u.sa_aen.status =  data;
   2012		edbnode->u.sa_aen.key_type =  data2;
   2013		break;
   2014	default:
   2015		ql_dbg(ql_dbg_edif, vha, 0x09102,
   2016			"%s unknown type: %x\n", __func__, dbtype);
   2017		qla_edb_node_free(vha, edbnode);
   2018		kfree(edbnode);
   2019		edbnode = NULL;
   2020		break;
   2021	}
   2022
   2023	if (edbnode && (!qla_edb_node_add(vha, edbnode))) {
   2024		ql_dbg(ql_dbg_edif, vha, 0x09102,
   2025		    "%s unable to add dbnode\n", __func__);
   2026		qla_edb_node_free(vha, edbnode);
   2027		kfree(edbnode);
   2028		return;
   2029	}
   2030	if (edbnode && fcport)
   2031		fcport->edif.auth_state = dbtype;
   2032	ql_dbg(ql_dbg_edif, vha, 0x09102,
   2033	    "%s Doorbell produced : type=%d %p\n", __func__, dbtype, edbnode);
   2034}
   2035
   2036static struct edb_node *
   2037qla_edb_getnext(scsi_qla_host_t *vha)
   2038{
   2039	unsigned long	flags;
   2040	struct edb_node	*edbnode = NULL;
   2041
   2042	spin_lock_irqsave(&vha->e_dbell.db_lock, flags);
   2043
   2044	/* db nodes are fifo - no qualifications done */
   2045	if (!list_empty(&vha->e_dbell.head)) {
   2046		edbnode = list_first_entry(&vha->e_dbell.head,
   2047		    struct edb_node, list);
   2048		list_del(&edbnode->list);
   2049	}
   2050
   2051	spin_unlock_irqrestore(&vha->e_dbell.db_lock, flags);
   2052
   2053	return edbnode;
   2054}
   2055
   2056void
   2057qla_edif_timer(scsi_qla_host_t *vha)
   2058{
   2059	struct qla_hw_data *ha = vha->hw;
   2060
   2061	if (!vha->vp_idx && N2N_TOPO(ha) && ha->flags.n2n_fw_acc_sec) {
   2062		if (DBELL_INACTIVE(vha) &&
   2063		    ha->edif_post_stop_cnt_down) {
   2064			ha->edif_post_stop_cnt_down--;
   2065
   2066			/*
   2067			 * turn off auto 'Plogi Acc + secure=1' feature
   2068			 * Set Add FW option[3]
   2069			 * BIT_15, if.
   2070			 */
   2071			if (ha->edif_post_stop_cnt_down == 0) {
   2072				ql_dbg(ql_dbg_async, vha, 0x911d,
   2073				       "%s chip reset to turn off PLOGI ACC + secure\n",
   2074				       __func__);
   2075				set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
   2076			}
   2077		} else {
   2078			ha->edif_post_stop_cnt_down = 60;
   2079		}
   2080	}
   2081}
   2082
   2083/*
   2084 * app uses separate thread to read this. It'll wait until the doorbell
   2085 * is rung by the driver or the max wait time has expired
   2086 */
   2087ssize_t
   2088edif_doorbell_show(struct device *dev, struct device_attribute *attr,
   2089		char *buf)
   2090{
   2091	scsi_qla_host_t *vha = shost_priv(class_to_shost(dev));
   2092	struct edb_node	*dbnode = NULL;
   2093	struct edif_app_dbell *ap = (struct edif_app_dbell *)buf;
   2094	uint32_t dat_siz, buf_size, sz;
   2095
   2096	/* TODO: app currently hardcoded to 256. Will transition to bsg */
   2097	sz = 256;
   2098
   2099	/* stop new threads from waiting if we're not init'd */
   2100	if (DBELL_INACTIVE(vha)) {
   2101		ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x09122,
   2102		    "%s error - edif db not enabled\n", __func__);
   2103		return 0;
   2104	}
   2105
   2106	if (!vha->hw->flags.edif_enabled) {
   2107		/* edif not enabled */
   2108		ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x09122,
   2109		    "%s error - edif not enabled\n", __func__);
   2110		return -1;
   2111	}
   2112
   2113	buf_size = 0;
   2114	while ((sz - buf_size) >= sizeof(struct edb_node)) {
   2115		/* remove the next item from the doorbell list */
   2116		dat_siz = 0;
   2117		dbnode = qla_edb_getnext(vha);
   2118		if (dbnode) {
   2119			ap->event_code = dbnode->ntype;
   2120			switch (dbnode->ntype) {
   2121			case VND_CMD_AUTH_STATE_SESSION_SHUTDOWN:
   2122			case VND_CMD_AUTH_STATE_NEEDED:
   2123				ap->port_id = dbnode->u.plogi_did;
   2124				dat_siz += sizeof(ap->port_id);
   2125				break;
   2126			case VND_CMD_AUTH_STATE_ELS_RCVD:
   2127				ap->port_id = dbnode->u.els_sid;
   2128				dat_siz += sizeof(ap->port_id);
   2129				break;
   2130			case VND_CMD_AUTH_STATE_SAUPDATE_COMPL:
   2131				ap->port_id = dbnode->u.sa_aen.port_id;
   2132				memcpy(ap->event_data, &dbnode->u,
   2133						sizeof(struct edif_sa_update_aen));
   2134				dat_siz += sizeof(struct edif_sa_update_aen);
   2135				break;
   2136			default:
   2137				/* unknown node type, rtn unknown ntype */
   2138				ap->event_code = VND_CMD_AUTH_STATE_UNDEF;
   2139				memcpy(ap->event_data, &dbnode->ntype, 4);
   2140				dat_siz += 4;
   2141				break;
   2142			}
   2143
   2144			ql_dbg(ql_dbg_edif, vha, 0x09102,
   2145				"%s Doorbell consumed : type=%d %p\n",
   2146				__func__, dbnode->ntype, dbnode);
   2147			/* we're done with the db node, so free it up */
   2148			qla_edb_node_free(vha, dbnode);
   2149			kfree(dbnode);
   2150		} else {
   2151			break;
   2152		}
   2153
   2154		ap->event_data_size = dat_siz;
   2155		/* 8bytes = ap->event_code + ap->event_data_size */
   2156		buf_size += dat_siz + 8;
   2157		ap = (struct edif_app_dbell *)(buf + buf_size);
   2158	}
   2159	return buf_size;
   2160}
   2161
   2162static void qla_noop_sp_done(srb_t *sp, int res)
   2163{
   2164	/* ref: INIT */
   2165	kref_put(&sp->cmd_kref, qla2x00_sp_release);
   2166}
   2167
   2168/*
   2169 * Called from work queue
   2170 * build and send the sa_update iocb to delete an rx sa_index
   2171 */
   2172int
   2173qla24xx_issue_sa_replace_iocb(scsi_qla_host_t *vha, struct qla_work_evt *e)
   2174{
   2175	srb_t *sp;
   2176	fc_port_t	*fcport = NULL;
   2177	struct srb_iocb *iocb_cmd = NULL;
   2178	int rval = QLA_SUCCESS;
   2179	struct	edif_sa_ctl *sa_ctl = e->u.sa_update.sa_ctl;
   2180	uint16_t nport_handle = e->u.sa_update.nport_handle;
   2181
   2182	ql_dbg(ql_dbg_edif, vha, 0x70e6,
   2183	    "%s: starting,  sa_ctl: %p\n", __func__, sa_ctl);
   2184
   2185	if (!sa_ctl) {
   2186		ql_dbg(ql_dbg_edif, vha, 0x70e6,
   2187		    "sa_ctl allocation failed\n");
   2188		return -ENOMEM;
   2189	}
   2190
   2191	fcport = sa_ctl->fcport;
   2192
   2193	/* Alloc SRB structure */
   2194	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
   2195	if (!sp) {
   2196		ql_dbg(ql_dbg_edif, vha, 0x70e6,
   2197		 "SRB allocation failed\n");
   2198		return -ENOMEM;
   2199	}
   2200
   2201	fcport->flags |= FCF_ASYNC_SENT;
   2202	iocb_cmd = &sp->u.iocb_cmd;
   2203	iocb_cmd->u.sa_update.sa_ctl = sa_ctl;
   2204
   2205	ql_dbg(ql_dbg_edif, vha, 0x3073,
   2206	    "Enter: SA REPL portid=%06x, sa_ctl %p, index %x, nport_handle: 0x%x\n",
   2207	    fcport->d_id.b24, sa_ctl, sa_ctl->index, nport_handle);
   2208	/*
   2209	 * if this is a sadb cleanup delete, mark it so the isr can
   2210	 * take the correct action
   2211	 */
   2212	if (sa_ctl->flags & EDIF_SA_CTL_FLG_CLEANUP_DEL) {
   2213		/* mark this srb as a cleanup delete */
   2214		sp->flags |= SRB_EDIF_CLEANUP_DELETE;
   2215		ql_dbg(ql_dbg_edif, vha, 0x70e6,
   2216		    "%s: sp 0x%p flagged as cleanup delete\n", __func__, sp);
   2217	}
   2218
   2219	sp->type = SRB_SA_REPLACE;
   2220	sp->name = "SA_REPLACE";
   2221	sp->fcport = fcport;
   2222	sp->free = qla2x00_rel_sp;
   2223	sp->done = qla_noop_sp_done;
   2224
   2225	rval = qla2x00_start_sp(sp);
   2226
   2227	if (rval != QLA_SUCCESS)
   2228		rval = QLA_FUNCTION_FAILED;
   2229
   2230	return rval;
   2231}
   2232
   2233void qla24xx_sa_update_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb)
   2234{
   2235	int	itr = 0;
   2236	struct	scsi_qla_host		*vha = sp->vha;
   2237	struct	qla_sa_update_frame	*sa_frame =
   2238		&sp->u.iocb_cmd.u.sa_update.sa_frame;
   2239	u8 flags = 0;
   2240
   2241	switch (sa_frame->flags & (SAU_FLG_INV | SAU_FLG_TX)) {
   2242	case 0:
   2243		ql_dbg(ql_dbg_edif, vha, 0x911d,
   2244		    "%s: EDIF SA UPDATE RX IOCB  vha: 0x%p  index: %d\n",
   2245		    __func__, vha, sa_frame->fast_sa_index);
   2246		break;
   2247	case 1:
   2248		ql_dbg(ql_dbg_edif, vha, 0x911d,
   2249		    "%s: EDIF SA DELETE RX IOCB  vha: 0x%p  index: %d\n",
   2250		    __func__, vha, sa_frame->fast_sa_index);
   2251		flags |= SA_FLAG_INVALIDATE;
   2252		break;
   2253	case 2:
   2254		ql_dbg(ql_dbg_edif, vha, 0x911d,
   2255		    "%s: EDIF SA UPDATE TX IOCB  vha: 0x%p  index: %d\n",
   2256		    __func__, vha, sa_frame->fast_sa_index);
   2257		flags |= SA_FLAG_TX;
   2258		break;
   2259	case 3:
   2260		ql_dbg(ql_dbg_edif, vha, 0x911d,
   2261		    "%s: EDIF SA DELETE TX IOCB  vha: 0x%p  index: %d\n",
   2262		    __func__, vha, sa_frame->fast_sa_index);
   2263		flags |= SA_FLAG_TX | SA_FLAG_INVALIDATE;
   2264		break;
   2265	}
   2266
   2267	sa_update_iocb->entry_type = SA_UPDATE_IOCB_TYPE;
   2268	sa_update_iocb->entry_count = 1;
   2269	sa_update_iocb->sys_define = 0;
   2270	sa_update_iocb->entry_status = 0;
   2271	sa_update_iocb->handle = sp->handle;
   2272	sa_update_iocb->u.nport_handle = cpu_to_le16(sp->fcport->loop_id);
   2273	sa_update_iocb->vp_index = sp->fcport->vha->vp_idx;
   2274	sa_update_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
   2275	sa_update_iocb->port_id[1] = sp->fcport->d_id.b.area;
   2276	sa_update_iocb->port_id[2] = sp->fcport->d_id.b.domain;
   2277
   2278	sa_update_iocb->flags = flags;
   2279	sa_update_iocb->salt = cpu_to_le32(sa_frame->salt);
   2280	sa_update_iocb->spi = cpu_to_le32(sa_frame->spi);
   2281	sa_update_iocb->sa_index = cpu_to_le16(sa_frame->fast_sa_index);
   2282
   2283	sa_update_iocb->sa_control |= SA_CNTL_ENC_FCSP;
   2284	if (sp->fcport->edif.aes_gmac)
   2285		sa_update_iocb->sa_control |= SA_CNTL_AES_GMAC;
   2286
   2287	if (sa_frame->flags & SAU_FLG_KEY256) {
   2288		sa_update_iocb->sa_control |= SA_CNTL_KEY256;
   2289		for (itr = 0; itr < 32; itr++)
   2290			sa_update_iocb->sa_key[itr] = sa_frame->sa_key[itr];
   2291	} else {
   2292		sa_update_iocb->sa_control |= SA_CNTL_KEY128;
   2293		for (itr = 0; itr < 16; itr++)
   2294			sa_update_iocb->sa_key[itr] = sa_frame->sa_key[itr];
   2295	}
   2296
   2297	ql_dbg(ql_dbg_edif, vha, 0x921d,
   2298	    "%s SAU Port ID = %02x%02x%02x, flags=%xh, index=%u, ctl=%xh, SPI 0x%x flags 0x%x hdl=%x gmac %d\n",
   2299	    __func__, sa_update_iocb->port_id[2], sa_update_iocb->port_id[1],
   2300	    sa_update_iocb->port_id[0], sa_update_iocb->flags, sa_update_iocb->sa_index,
   2301	    sa_update_iocb->sa_control, sa_update_iocb->spi, sa_frame->flags, sp->handle,
   2302	    sp->fcport->edif.aes_gmac);
   2303
   2304	if (sa_frame->flags & SAU_FLG_TX)
   2305		sp->fcport->edif.tx_sa_pending = 1;
   2306	else
   2307		sp->fcport->edif.rx_sa_pending = 1;
   2308
   2309	sp->fcport->vha->qla_stats.control_requests++;
   2310}
   2311
   2312void
   2313qla24xx_sa_replace_iocb(srb_t *sp, struct sa_update_28xx *sa_update_iocb)
   2314{
   2315	struct	scsi_qla_host		*vha = sp->vha;
   2316	struct srb_iocb *srb_iocb = &sp->u.iocb_cmd;
   2317	struct	edif_sa_ctl		*sa_ctl = srb_iocb->u.sa_update.sa_ctl;
   2318	uint16_t nport_handle = sp->fcport->loop_id;
   2319
   2320	sa_update_iocb->entry_type = SA_UPDATE_IOCB_TYPE;
   2321	sa_update_iocb->entry_count = 1;
   2322	sa_update_iocb->sys_define = 0;
   2323	sa_update_iocb->entry_status = 0;
   2324	sa_update_iocb->handle = sp->handle;
   2325
   2326	sa_update_iocb->u.nport_handle = cpu_to_le16(nport_handle);
   2327
   2328	sa_update_iocb->vp_index = sp->fcport->vha->vp_idx;
   2329	sa_update_iocb->port_id[0] = sp->fcport->d_id.b.al_pa;
   2330	sa_update_iocb->port_id[1] = sp->fcport->d_id.b.area;
   2331	sa_update_iocb->port_id[2] = sp->fcport->d_id.b.domain;
   2332
   2333	/* Invalidate the index. salt, spi, control & key are ignore */
   2334	sa_update_iocb->flags = SA_FLAG_INVALIDATE;
   2335	sa_update_iocb->salt = 0;
   2336	sa_update_iocb->spi = 0;
   2337	sa_update_iocb->sa_index = cpu_to_le16(sa_ctl->index);
   2338	sa_update_iocb->sa_control = 0;
   2339
   2340	ql_dbg(ql_dbg_edif, vha, 0x921d,
   2341	    "%s SAU DELETE RX Port ID = %02x:%02x:%02x, lid %d flags=%xh, index=%u, hdl=%x\n",
   2342	    __func__, sa_update_iocb->port_id[2], sa_update_iocb->port_id[1],
   2343	    sa_update_iocb->port_id[0], nport_handle, sa_update_iocb->flags,
   2344	    sa_update_iocb->sa_index, sp->handle);
   2345
   2346	sp->fcport->vha->qla_stats.control_requests++;
   2347}
   2348
   2349void qla24xx_auth_els(scsi_qla_host_t *vha, void **pkt, struct rsp_que **rsp)
   2350{
   2351	struct purex_entry_24xx *p = *pkt;
   2352	struct enode		*ptr;
   2353	int		sid;
   2354	u16 totlen;
   2355	struct purexevent	*purex;
   2356	struct scsi_qla_host *host = NULL;
   2357	int rc;
   2358	struct fc_port *fcport;
   2359	struct qla_els_pt_arg a;
   2360	be_id_t beid;
   2361
   2362	memset(&a, 0, sizeof(a));
   2363
   2364	a.els_opcode = ELS_AUTH_ELS;
   2365	a.nport_handle = p->nport_handle;
   2366	a.rx_xchg_address = p->rx_xchg_addr;
   2367	a.did.b.domain = p->s_id[2];
   2368	a.did.b.area   = p->s_id[1];
   2369	a.did.b.al_pa  = p->s_id[0];
   2370	a.tx_byte_count = a.tx_len = sizeof(struct fc_els_ls_rjt);
   2371	a.tx_addr = vha->hw->elsrej.cdma;
   2372	a.vp_idx = vha->vp_idx;
   2373	a.control_flags = EPD_ELS_RJT;
   2374	a.ox_id = le16_to_cpu(p->ox_id);
   2375
   2376	sid = p->s_id[0] | (p->s_id[1] << 8) | (p->s_id[2] << 16);
   2377
   2378	totlen = (le16_to_cpu(p->frame_size) & 0x0fff) - PURX_ELS_HEADER_SIZE;
   2379	if (le16_to_cpu(p->status_flags) & 0x8000) {
   2380		totlen = le16_to_cpu(p->trunc_frame_size);
   2381		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
   2382		__qla_consume_iocb(vha, pkt, rsp);
   2383		return;
   2384	}
   2385
   2386	if (totlen > ELS_MAX_PAYLOAD) {
   2387		ql_dbg(ql_dbg_edif, vha, 0x0910d,
   2388		    "%s WARNING: verbose ELS frame received (totlen=%x)\n",
   2389		    __func__, totlen);
   2390		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
   2391		__qla_consume_iocb(vha, pkt, rsp);
   2392		return;
   2393	}
   2394
   2395	if (!vha->hw->flags.edif_enabled) {
   2396		/* edif support not enabled */
   2397		ql_dbg(ql_dbg_edif, vha, 0x910e, "%s edif not enabled\n",
   2398		    __func__);
   2399		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
   2400		__qla_consume_iocb(vha, pkt, rsp);
   2401		return;
   2402	}
   2403
   2404	ptr = qla_enode_alloc(vha, N_PUREX);
   2405	if (!ptr) {
   2406		ql_dbg(ql_dbg_edif, vha, 0x09109,
   2407		    "WARNING: enode alloc failed for sid=%x\n",
   2408		    sid);
   2409		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
   2410		__qla_consume_iocb(vha, pkt, rsp);
   2411		return;
   2412	}
   2413
   2414	purex = &ptr->u.purexinfo;
   2415	purex->pur_info.pur_sid = a.did;
   2416	purex->pur_info.pur_bytes_rcvd = totlen;
   2417	purex->pur_info.pur_rx_xchg_address = le32_to_cpu(p->rx_xchg_addr);
   2418	purex->pur_info.pur_nphdl = le16_to_cpu(p->nport_handle);
   2419	purex->pur_info.pur_did.b.domain =  p->d_id[2];
   2420	purex->pur_info.pur_did.b.area =  p->d_id[1];
   2421	purex->pur_info.pur_did.b.al_pa =  p->d_id[0];
   2422	purex->pur_info.vp_idx = p->vp_idx;
   2423
   2424	a.sid = purex->pur_info.pur_did;
   2425
   2426	rc = __qla_copy_purex_to_buffer(vha, pkt, rsp, purex->msgp,
   2427		purex->msgp_len);
   2428	if (rc) {
   2429		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
   2430		qla_enode_free(vha, ptr);
   2431		return;
   2432	}
   2433	beid.al_pa = purex->pur_info.pur_did.b.al_pa;
   2434	beid.area   = purex->pur_info.pur_did.b.area;
   2435	beid.domain = purex->pur_info.pur_did.b.domain;
   2436	host = qla_find_host_by_d_id(vha, beid);
   2437	if (!host) {
   2438		ql_log(ql_log_fatal, vha, 0x508b,
   2439		    "%s Drop ELS due to unable to find host %06x\n",
   2440		    __func__, purex->pur_info.pur_did.b24);
   2441
   2442		qla_els_reject_iocb(vha, (*rsp)->qpair, &a);
   2443		qla_enode_free(vha, ptr);
   2444		return;
   2445	}
   2446
   2447	fcport = qla2x00_find_fcport_by_pid(host, &purex->pur_info.pur_sid);
   2448
   2449	if (DBELL_INACTIVE(vha) ||
   2450	    (fcport && EDIF_SESSION_DOWN(fcport))) {
   2451		ql_dbg(ql_dbg_edif, host, 0x0910c, "%s e_dbell.db_flags =%x %06x\n",
   2452		    __func__, host->e_dbell.db_flags,
   2453		    fcport ? fcport->d_id.b24 : 0);
   2454
   2455		qla_els_reject_iocb(host, (*rsp)->qpair, &a);
   2456		qla_enode_free(host, ptr);
   2457		return;
   2458	}
   2459
   2460	/* add the local enode to the list */
   2461	qla_enode_add(host, ptr);
   2462
   2463	ql_dbg(ql_dbg_edif, host, 0x0910c,
   2464	    "%s COMPLETE purex->pur_info.pur_bytes_rcvd =%xh s:%06x -> d:%06x xchg=%xh\n",
   2465	    __func__, purex->pur_info.pur_bytes_rcvd, purex->pur_info.pur_sid.b24,
   2466	    purex->pur_info.pur_did.b24, purex->pur_info.pur_rx_xchg_address);
   2467
   2468	qla_edb_eventcreate(host, VND_CMD_AUTH_STATE_ELS_RCVD, sid, 0, NULL);
   2469}
   2470
   2471static uint16_t  qla_edif_get_sa_index_from_freepool(fc_port_t *fcport, int dir)
   2472{
   2473	struct scsi_qla_host *vha = fcport->vha;
   2474	struct qla_hw_data *ha = vha->hw;
   2475	void *sa_id_map;
   2476	unsigned long flags = 0;
   2477	u16 sa_index;
   2478
   2479	ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063,
   2480	    "%s: entry\n", __func__);
   2481
   2482	if (dir)
   2483		sa_id_map = ha->edif_tx_sa_id_map;
   2484	else
   2485		sa_id_map = ha->edif_rx_sa_id_map;
   2486
   2487	spin_lock_irqsave(&ha->sadb_fp_lock, flags);
   2488	sa_index = find_first_zero_bit(sa_id_map, EDIF_NUM_SA_INDEX);
   2489	if (sa_index >=  EDIF_NUM_SA_INDEX) {
   2490		spin_unlock_irqrestore(&ha->sadb_fp_lock, flags);
   2491		return INVALID_EDIF_SA_INDEX;
   2492	}
   2493	set_bit(sa_index, sa_id_map);
   2494	spin_unlock_irqrestore(&ha->sadb_fp_lock, flags);
   2495
   2496	if (dir)
   2497		sa_index += EDIF_TX_SA_INDEX_BASE;
   2498
   2499	ql_dbg(ql_dbg_edif, vha, 0x3063,
   2500	    "%s: index retrieved from free pool %d\n", __func__, sa_index);
   2501
   2502	return sa_index;
   2503}
   2504
   2505/* find an sadb entry for an nport_handle */
   2506static struct edif_sa_index_entry *
   2507qla_edif_sadb_find_sa_index_entry(uint16_t nport_handle,
   2508		struct list_head *sa_list)
   2509{
   2510	struct edif_sa_index_entry *entry;
   2511	struct edif_sa_index_entry *tentry;
   2512	struct list_head *indx_list = sa_list;
   2513
   2514	list_for_each_entry_safe(entry, tentry, indx_list, next) {
   2515		if (entry->handle == nport_handle)
   2516			return entry;
   2517	}
   2518	return NULL;
   2519}
   2520
   2521/* remove an sa_index from the nport_handle and return it to the free pool */
   2522static int qla_edif_sadb_delete_sa_index(fc_port_t *fcport, uint16_t nport_handle,
   2523		uint16_t sa_index)
   2524{
   2525	struct edif_sa_index_entry *entry;
   2526	struct list_head *sa_list;
   2527	int dir = (sa_index < EDIF_TX_SA_INDEX_BASE) ? 0 : 1;
   2528	int slot = 0;
   2529	int free_slot_count = 0;
   2530	scsi_qla_host_t *vha = fcport->vha;
   2531	struct qla_hw_data *ha = vha->hw;
   2532	unsigned long flags = 0;
   2533
   2534	ql_dbg(ql_dbg_edif, vha, 0x3063,
   2535	    "%s: entry\n", __func__);
   2536
   2537	if (dir)
   2538		sa_list = &ha->sadb_tx_index_list;
   2539	else
   2540		sa_list = &ha->sadb_rx_index_list;
   2541
   2542	entry = qla_edif_sadb_find_sa_index_entry(nport_handle, sa_list);
   2543	if (!entry) {
   2544		ql_dbg(ql_dbg_edif, vha, 0x3063,
   2545		    "%s: no entry found for nport_handle 0x%x\n",
   2546		    __func__, nport_handle);
   2547		return -1;
   2548	}
   2549
   2550	spin_lock_irqsave(&ha->sadb_lock, flags);
   2551	/*
   2552	 * each tx/rx direction has up to 2 sa indexes/slots. 1 slot for in flight traffic
   2553	 * the other is use at re-key time.
   2554	 */
   2555	for (slot = 0; slot < 2; slot++) {
   2556		if (entry->sa_pair[slot].sa_index == sa_index) {
   2557			entry->sa_pair[slot].sa_index = INVALID_EDIF_SA_INDEX;
   2558			entry->sa_pair[slot].spi = 0;
   2559			free_slot_count++;
   2560			qla_edif_add_sa_index_to_freepool(fcport, dir, sa_index);
   2561		} else if (entry->sa_pair[slot].sa_index == INVALID_EDIF_SA_INDEX) {
   2562			free_slot_count++;
   2563		}
   2564	}
   2565
   2566	if (free_slot_count == 2) {
   2567		list_del(&entry->next);
   2568		kfree(entry);
   2569	}
   2570	spin_unlock_irqrestore(&ha->sadb_lock, flags);
   2571
   2572	ql_dbg(ql_dbg_edif, vha, 0x3063,
   2573	    "%s: sa_index %d removed, free_slot_count: %d\n",
   2574	    __func__, sa_index, free_slot_count);
   2575
   2576	return 0;
   2577}
   2578
   2579void
   2580qla28xx_sa_update_iocb_entry(scsi_qla_host_t *v, struct req_que *req,
   2581	struct sa_update_28xx *pkt)
   2582{
   2583	const char *func = "SA_UPDATE_RESPONSE_IOCB";
   2584	srb_t *sp;
   2585	struct edif_sa_ctl *sa_ctl;
   2586	int old_sa_deleted = 1;
   2587	uint16_t nport_handle;
   2588	struct scsi_qla_host *vha;
   2589
   2590	sp = qla2x00_get_sp_from_handle(v, func, req, pkt);
   2591
   2592	if (!sp) {
   2593		ql_dbg(ql_dbg_edif, v, 0x3063,
   2594			"%s: no sp found for pkt\n", __func__);
   2595		return;
   2596	}
   2597	/* use sp->vha due to npiv */
   2598	vha = sp->vha;
   2599
   2600	switch (pkt->flags & (SA_FLAG_INVALIDATE | SA_FLAG_TX)) {
   2601	case 0:
   2602		ql_dbg(ql_dbg_edif, vha, 0x3063,
   2603		    "%s: EDIF SA UPDATE RX IOCB  vha: 0x%p  index: %d\n",
   2604		    __func__, vha, pkt->sa_index);
   2605		break;
   2606	case 1:
   2607		ql_dbg(ql_dbg_edif, vha, 0x3063,
   2608		    "%s: EDIF SA DELETE RX IOCB  vha: 0x%p  index: %d\n",
   2609		    __func__, vha, pkt->sa_index);
   2610		break;
   2611	case 2:
   2612		ql_dbg(ql_dbg_edif, vha, 0x3063,
   2613		    "%s: EDIF SA UPDATE TX IOCB  vha: 0x%p  index: %d\n",
   2614		    __func__, vha, pkt->sa_index);
   2615		break;
   2616	case 3:
   2617		ql_dbg(ql_dbg_edif, vha, 0x3063,
   2618		    "%s: EDIF SA DELETE TX IOCB  vha: 0x%p  index: %d\n",
   2619		    __func__, vha, pkt->sa_index);
   2620		break;
   2621	}
   2622
   2623	/*
   2624	 * dig the nport handle out of the iocb, fcport->loop_id can not be trusted
   2625	 * to be correct during cleanup sa_update iocbs.
   2626	 */
   2627	nport_handle = sp->fcport->loop_id;
   2628
   2629	ql_dbg(ql_dbg_edif, vha, 0x3063,
   2630	    "%s: %8phN comp status=%x old_sa_info=%x new_sa_info=%x lid %d, index=0x%x pkt_flags %xh hdl=%x\n",
   2631	    __func__, sp->fcport->port_name, pkt->u.comp_sts, pkt->old_sa_info, pkt->new_sa_info,
   2632	    nport_handle, pkt->sa_index, pkt->flags, sp->handle);
   2633
   2634	/* if rx delete, remove the timer */
   2635	if ((pkt->flags & (SA_FLAG_INVALIDATE | SA_FLAG_TX)) ==  SA_FLAG_INVALIDATE) {
   2636		struct edif_list_entry *edif_entry;
   2637
   2638		sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
   2639
   2640		edif_entry = qla_edif_list_find_sa_index(sp->fcport, nport_handle);
   2641		if (edif_entry) {
   2642			ql_dbg(ql_dbg_edif, vha, 0x5033,
   2643			    "%s: removing edif_entry %p, new sa_index: 0x%x\n",
   2644			    __func__, edif_entry, pkt->sa_index);
   2645			qla_edif_list_delete_sa_index(sp->fcport, edif_entry);
   2646			del_timer(&edif_entry->timer);
   2647
   2648			ql_dbg(ql_dbg_edif, vha, 0x5033,
   2649			    "%s: releasing edif_entry %p, new sa_index: 0x%x\n",
   2650			    __func__, edif_entry, pkt->sa_index);
   2651
   2652			kfree(edif_entry);
   2653		}
   2654	}
   2655
   2656	/*
   2657	 * if this is a delete for either tx or rx, make sure it succeeded.
   2658	 * The new_sa_info field should be 0xffff on success
   2659	 */
   2660	if (pkt->flags & SA_FLAG_INVALIDATE)
   2661		old_sa_deleted = (le16_to_cpu(pkt->new_sa_info) == 0xffff) ? 1 : 0;
   2662
   2663	/* Process update and delete the same way */
   2664
   2665	/* If this is an sadb cleanup delete, bypass sending events to IPSEC */
   2666	if (sp->flags & SRB_EDIF_CLEANUP_DELETE) {
   2667		sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
   2668		ql_dbg(ql_dbg_edif, vha, 0x3063,
   2669		    "%s: nph 0x%x, sa_index %d removed from fw\n",
   2670		    __func__, sp->fcport->loop_id, pkt->sa_index);
   2671
   2672	} else if ((pkt->entry_status == 0) && (pkt->u.comp_sts == 0) &&
   2673	    old_sa_deleted) {
   2674		/*
   2675		 * Note: Wa are only keeping track of latest SA,
   2676		 * so we know when we can start enableing encryption per I/O.
   2677		 * If all SA's get deleted, let FW reject the IOCB.
   2678
   2679		 * TODO: edif: don't set enabled here I think
   2680		 * TODO: edif: prli complete is where it should be set
   2681		 */
   2682		ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063,
   2683			"SA(%x)updated for s_id %02x%02x%02x\n",
   2684			pkt->new_sa_info,
   2685			pkt->port_id[2], pkt->port_id[1], pkt->port_id[0]);
   2686		sp->fcport->edif.enable = 1;
   2687		if (pkt->flags & SA_FLAG_TX) {
   2688			sp->fcport->edif.tx_sa_set = 1;
   2689			sp->fcport->edif.tx_sa_pending = 0;
   2690			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
   2691				QL_VND_SA_STAT_SUCCESS,
   2692				QL_VND_TX_SA_KEY, sp->fcport);
   2693		} else {
   2694			sp->fcport->edif.rx_sa_set = 1;
   2695			sp->fcport->edif.rx_sa_pending = 0;
   2696			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
   2697				QL_VND_SA_STAT_SUCCESS,
   2698				QL_VND_RX_SA_KEY, sp->fcport);
   2699		}
   2700	} else {
   2701		ql_dbg(ql_dbg_edif, vha, 0x3063,
   2702		    "%s: %8phN SA update FAILED: sa_index: %d, new_sa_info %d, %02x%02x%02x\n",
   2703		    __func__, sp->fcport->port_name, pkt->sa_index, pkt->new_sa_info,
   2704		    pkt->port_id[2], pkt->port_id[1], pkt->port_id[0]);
   2705
   2706		if (pkt->flags & SA_FLAG_TX)
   2707			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
   2708				(le16_to_cpu(pkt->u.comp_sts) << 16) | QL_VND_SA_STAT_FAILED,
   2709				QL_VND_TX_SA_KEY, sp->fcport);
   2710		else
   2711			qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SAUPDATE_COMPL,
   2712				(le16_to_cpu(pkt->u.comp_sts) << 16) | QL_VND_SA_STAT_FAILED,
   2713				QL_VND_RX_SA_KEY, sp->fcport);
   2714	}
   2715
   2716	/* for delete, release sa_ctl, sa_index */
   2717	if (pkt->flags & SA_FLAG_INVALIDATE) {
   2718		/* release the sa_ctl */
   2719		sa_ctl = qla_edif_find_sa_ctl_by_index(sp->fcport,
   2720		    le16_to_cpu(pkt->sa_index), (pkt->flags & SA_FLAG_TX));
   2721		if (sa_ctl &&
   2722		    qla_edif_find_sa_ctl_by_index(sp->fcport, sa_ctl->index,
   2723			(pkt->flags & SA_FLAG_TX)) != NULL) {
   2724			ql_dbg(ql_dbg_edif + ql_dbg_verbose, vha, 0x3063,
   2725			    "%s: freeing sa_ctl for index %d\n",
   2726			    __func__, sa_ctl->index);
   2727			qla_edif_free_sa_ctl(sp->fcport, sa_ctl, sa_ctl->index);
   2728		} else {
   2729			ql_dbg(ql_dbg_edif, vha, 0x3063,
   2730			    "%s: sa_ctl NOT freed, sa_ctl: %p\n",
   2731			    __func__, sa_ctl);
   2732		}
   2733		ql_dbg(ql_dbg_edif, vha, 0x3063,
   2734		    "%s: freeing sa_index %d, nph: 0x%x\n",
   2735		    __func__, le16_to_cpu(pkt->sa_index), nport_handle);
   2736		qla_edif_sadb_delete_sa_index(sp->fcport, nport_handle,
   2737		    le16_to_cpu(pkt->sa_index));
   2738	/*
   2739	 * check for a failed sa_update and remove
   2740	 * the sadb entry.
   2741	 */
   2742	} else if (pkt->u.comp_sts) {
   2743		ql_dbg(ql_dbg_edif, vha, 0x3063,
   2744		    "%s: freeing sa_index %d, nph: 0x%x\n",
   2745		    __func__, pkt->sa_index, nport_handle);
   2746		qla_edif_sadb_delete_sa_index(sp->fcport, nport_handle,
   2747		    le16_to_cpu(pkt->sa_index));
   2748		switch (le16_to_cpu(pkt->u.comp_sts)) {
   2749		case CS_PORT_EDIF_UNAVAIL:
   2750		case CS_PORT_EDIF_LOGOUT:
   2751			qlt_schedule_sess_for_deletion(sp->fcport);
   2752			break;
   2753		default:
   2754			break;
   2755		}
   2756	}
   2757
   2758	sp->done(sp, 0);
   2759}
   2760
   2761/**
   2762 * qla28xx_start_scsi_edif() - Send a SCSI type 6 command to the ISP
   2763 * @sp: command to send to the ISP
   2764 *
   2765 * Return: non-zero if a failure occurred, else zero.
   2766 */
   2767int
   2768qla28xx_start_scsi_edif(srb_t *sp)
   2769{
   2770	int             nseg;
   2771	unsigned long   flags;
   2772	struct scsi_cmnd *cmd;
   2773	uint32_t        *clr_ptr;
   2774	uint32_t        index, i;
   2775	uint32_t        handle;
   2776	uint16_t        cnt;
   2777	int16_t        req_cnt;
   2778	uint16_t        tot_dsds;
   2779	__be32 *fcp_dl;
   2780	uint8_t additional_cdb_len;
   2781	struct ct6_dsd *ctx;
   2782	struct scsi_qla_host *vha = sp->vha;
   2783	struct qla_hw_data *ha = vha->hw;
   2784	struct cmd_type_6 *cmd_pkt;
   2785	struct dsd64	*cur_dsd;
   2786	uint8_t		avail_dsds = 0;
   2787	struct scatterlist *sg;
   2788	struct req_que *req = sp->qpair->req;
   2789	spinlock_t *lock = sp->qpair->qp_lock_ptr;
   2790
   2791	/* Setup device pointers. */
   2792	cmd = GET_CMD_SP(sp);
   2793
   2794	/* So we know we haven't pci_map'ed anything yet */
   2795	tot_dsds = 0;
   2796
   2797	/* Send marker if required */
   2798	if (vha->marker_needed != 0) {
   2799		if (qla2x00_marker(vha, sp->qpair, 0, 0, MK_SYNC_ALL) !=
   2800			QLA_SUCCESS) {
   2801			ql_log(ql_log_warn, vha, 0x300c,
   2802			    "qla2x00_marker failed for cmd=%p.\n", cmd);
   2803			return QLA_FUNCTION_FAILED;
   2804		}
   2805		vha->marker_needed = 0;
   2806	}
   2807
   2808	/* Acquire ring specific lock */
   2809	spin_lock_irqsave(lock, flags);
   2810
   2811	/* Check for room in outstanding command list. */
   2812	handle = req->current_outstanding_cmd;
   2813	for (index = 1; index < req->num_outstanding_cmds; index++) {
   2814		handle++;
   2815		if (handle == req->num_outstanding_cmds)
   2816			handle = 1;
   2817		if (!req->outstanding_cmds[handle])
   2818			break;
   2819	}
   2820	if (index == req->num_outstanding_cmds)
   2821		goto queuing_error;
   2822
   2823	/* Map the sg table so we have an accurate count of sg entries needed */
   2824	if (scsi_sg_count(cmd)) {
   2825		nseg = dma_map_sg(&ha->pdev->dev, scsi_sglist(cmd),
   2826		    scsi_sg_count(cmd), cmd->sc_data_direction);
   2827		if (unlikely(!nseg))
   2828			goto queuing_error;
   2829	} else {
   2830		nseg = 0;
   2831	}
   2832
   2833	tot_dsds = nseg;
   2834	req_cnt = qla24xx_calc_iocbs(vha, tot_dsds);
   2835	if (req->cnt < (req_cnt + 2)) {
   2836		cnt = IS_SHADOW_REG_CAPABLE(ha) ? *req->out_ptr :
   2837		    rd_reg_dword(req->req_q_out);
   2838		if (req->ring_index < cnt)
   2839			req->cnt = cnt - req->ring_index;
   2840		else
   2841			req->cnt = req->length -
   2842			    (req->ring_index - cnt);
   2843		if (req->cnt < (req_cnt + 2))
   2844			goto queuing_error;
   2845	}
   2846
   2847	ctx = sp->u.scmd.ct6_ctx =
   2848	    mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
   2849	if (!ctx) {
   2850		ql_log(ql_log_fatal, vha, 0x3010,
   2851		    "Failed to allocate ctx for cmd=%p.\n", cmd);
   2852		goto queuing_error;
   2853	}
   2854
   2855	memset(ctx, 0, sizeof(struct ct6_dsd));
   2856	ctx->fcp_cmnd = dma_pool_zalloc(ha->fcp_cmnd_dma_pool,
   2857	    GFP_ATOMIC, &ctx->fcp_cmnd_dma);
   2858	if (!ctx->fcp_cmnd) {
   2859		ql_log(ql_log_fatal, vha, 0x3011,
   2860		    "Failed to allocate fcp_cmnd for cmd=%p.\n", cmd);
   2861		goto queuing_error;
   2862	}
   2863
   2864	/* Initialize the DSD list and dma handle */
   2865	INIT_LIST_HEAD(&ctx->dsd_list);
   2866	ctx->dsd_use_cnt = 0;
   2867
   2868	if (cmd->cmd_len > 16) {
   2869		additional_cdb_len = cmd->cmd_len - 16;
   2870		if ((cmd->cmd_len % 4) != 0) {
   2871			/*
   2872			 * SCSI command bigger than 16 bytes must be
   2873			 * multiple of 4
   2874			 */
   2875			ql_log(ql_log_warn, vha, 0x3012,
   2876			    "scsi cmd len %d not multiple of 4 for cmd=%p.\n",
   2877			    cmd->cmd_len, cmd);
   2878			goto queuing_error_fcp_cmnd;
   2879		}
   2880		ctx->fcp_cmnd_len = 12 + cmd->cmd_len + 4;
   2881	} else {
   2882		additional_cdb_len = 0;
   2883		ctx->fcp_cmnd_len = 12 + 16 + 4;
   2884	}
   2885
   2886	cmd_pkt = (struct cmd_type_6 *)req->ring_ptr;
   2887	cmd_pkt->handle = make_handle(req->id, handle);
   2888
   2889	/*
   2890	 * Zero out remaining portion of packet.
   2891	 * tagged queuing modifier -- default is TSK_SIMPLE (0).
   2892	 */
   2893	clr_ptr = (uint32_t *)cmd_pkt + 2;
   2894	memset(clr_ptr, 0, REQUEST_ENTRY_SIZE - 8);
   2895	cmd_pkt->dseg_count = cpu_to_le16(tot_dsds);
   2896
   2897	/* No data transfer */
   2898	if (!scsi_bufflen(cmd) || cmd->sc_data_direction == DMA_NONE) {
   2899		cmd_pkt->byte_count = cpu_to_le32(0);
   2900		goto no_dsds;
   2901	}
   2902
   2903	/* Set transfer direction */
   2904	if (cmd->sc_data_direction == DMA_TO_DEVICE) {
   2905		cmd_pkt->control_flags = cpu_to_le16(CF_WRITE_DATA);
   2906		vha->qla_stats.output_bytes += scsi_bufflen(cmd);
   2907		vha->qla_stats.output_requests++;
   2908		sp->fcport->edif.tx_bytes += scsi_bufflen(cmd);
   2909	} else if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
   2910		cmd_pkt->control_flags = cpu_to_le16(CF_READ_DATA);
   2911		vha->qla_stats.input_bytes += scsi_bufflen(cmd);
   2912		vha->qla_stats.input_requests++;
   2913		sp->fcport->edif.rx_bytes += scsi_bufflen(cmd);
   2914	}
   2915
   2916	cmd_pkt->control_flags |= cpu_to_le16(CF_EN_EDIF);
   2917	cmd_pkt->control_flags &= ~(cpu_to_le16(CF_NEW_SA));
   2918
   2919	/* One DSD is available in the Command Type 6 IOCB */
   2920	avail_dsds = 1;
   2921	cur_dsd = &cmd_pkt->fcp_dsd;
   2922
   2923	/* Load data segments */
   2924	scsi_for_each_sg(cmd, sg, tot_dsds, i) {
   2925		dma_addr_t      sle_dma;
   2926		cont_a64_entry_t *cont_pkt;
   2927
   2928		/* Allocate additional continuation packets? */
   2929		if (avail_dsds == 0) {
   2930			/*
   2931			 * Five DSDs are available in the Continuation
   2932			 * Type 1 IOCB.
   2933			 */
   2934			cont_pkt = qla2x00_prep_cont_type1_iocb(vha, req);
   2935			cur_dsd = cont_pkt->dsd;
   2936			avail_dsds = 5;
   2937		}
   2938
   2939		sle_dma = sg_dma_address(sg);
   2940		put_unaligned_le64(sle_dma, &cur_dsd->address);
   2941		cur_dsd->length = cpu_to_le32(sg_dma_len(sg));
   2942		cur_dsd++;
   2943		avail_dsds--;
   2944	}
   2945
   2946no_dsds:
   2947	/* Set NPORT-ID and LUN number*/
   2948	cmd_pkt->nport_handle = cpu_to_le16(sp->fcport->loop_id);
   2949	cmd_pkt->port_id[0] = sp->fcport->d_id.b.al_pa;
   2950	cmd_pkt->port_id[1] = sp->fcport->d_id.b.area;
   2951	cmd_pkt->port_id[2] = sp->fcport->d_id.b.domain;
   2952	cmd_pkt->vp_index = sp->vha->vp_idx;
   2953
   2954	cmd_pkt->entry_type = COMMAND_TYPE_6;
   2955
   2956	/* Set total data segment count. */
   2957	cmd_pkt->entry_count = (uint8_t)req_cnt;
   2958
   2959	int_to_scsilun(cmd->device->lun, &cmd_pkt->lun);
   2960	host_to_fcp_swap((uint8_t *)&cmd_pkt->lun, sizeof(cmd_pkt->lun));
   2961
   2962	/* build FCP_CMND IU */
   2963	int_to_scsilun(cmd->device->lun, &ctx->fcp_cmnd->lun);
   2964	ctx->fcp_cmnd->additional_cdb_len = additional_cdb_len;
   2965
   2966	if (cmd->sc_data_direction == DMA_TO_DEVICE)
   2967		ctx->fcp_cmnd->additional_cdb_len |= 1;
   2968	else if (cmd->sc_data_direction == DMA_FROM_DEVICE)
   2969		ctx->fcp_cmnd->additional_cdb_len |= 2;
   2970
   2971	/* Populate the FCP_PRIO. */
   2972	if (ha->flags.fcp_prio_enabled)
   2973		ctx->fcp_cmnd->task_attribute |=
   2974		    sp->fcport->fcp_prio << 3;
   2975
   2976	memcpy(ctx->fcp_cmnd->cdb, cmd->cmnd, cmd->cmd_len);
   2977
   2978	fcp_dl = (__be32 *)(ctx->fcp_cmnd->cdb + 16 +
   2979	    additional_cdb_len);
   2980	*fcp_dl = htonl((uint32_t)scsi_bufflen(cmd));
   2981
   2982	cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len);
   2983	put_unaligned_le64(ctx->fcp_cmnd_dma, &cmd_pkt->fcp_cmnd_dseg_address);
   2984
   2985	sp->flags |= SRB_FCP_CMND_DMA_VALID;
   2986	cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
   2987	/* Set total data segment count. */
   2988	cmd_pkt->entry_count = (uint8_t)req_cnt;
   2989	cmd_pkt->entry_status = 0;
   2990
   2991	/* Build command packet. */
   2992	req->current_outstanding_cmd = handle;
   2993	req->outstanding_cmds[handle] = sp;
   2994	sp->handle = handle;
   2995	cmd->host_scribble = (unsigned char *)(unsigned long)handle;
   2996	req->cnt -= req_cnt;
   2997
   2998	/* Adjust ring index. */
   2999	wmb();
   3000	req->ring_index++;
   3001	if (req->ring_index == req->length) {
   3002		req->ring_index = 0;
   3003		req->ring_ptr = req->ring;
   3004	} else {
   3005		req->ring_ptr++;
   3006	}
   3007
   3008	sp->qpair->cmd_cnt++;
   3009	/* Set chip new ring index. */
   3010	wrt_reg_dword(req->req_q_in, req->ring_index);
   3011
   3012	spin_unlock_irqrestore(lock, flags);
   3013
   3014	return QLA_SUCCESS;
   3015
   3016queuing_error_fcp_cmnd:
   3017	dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, ctx->fcp_cmnd_dma);
   3018queuing_error:
   3019	if (tot_dsds)
   3020		scsi_dma_unmap(cmd);
   3021
   3022	if (sp->u.scmd.ct6_ctx) {
   3023		mempool_free(sp->u.scmd.ct6_ctx, ha->ctx_mempool);
   3024		sp->u.scmd.ct6_ctx = NULL;
   3025	}
   3026	spin_unlock_irqrestore(lock, flags);
   3027
   3028	return QLA_FUNCTION_FAILED;
   3029}
   3030
   3031/**********************************************
   3032 * edif update/delete sa_index list functions *
   3033 **********************************************/
   3034
   3035/* clear the edif_indx_list for this port */
   3036void qla_edif_list_del(fc_port_t *fcport)
   3037{
   3038	struct edif_list_entry *indx_lst;
   3039	struct edif_list_entry *tindx_lst;
   3040	struct list_head *indx_list = &fcport->edif.edif_indx_list;
   3041	unsigned long flags = 0;
   3042
   3043	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);
   3044	list_for_each_entry_safe(indx_lst, tindx_lst, indx_list, next) {
   3045		list_del(&indx_lst->next);
   3046		kfree(indx_lst);
   3047	}
   3048	spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
   3049}
   3050
   3051/******************
   3052 * SADB functions *
   3053 ******************/
   3054
   3055/* allocate/retrieve an sa_index for a given spi */
   3056static uint16_t qla_edif_sadb_get_sa_index(fc_port_t *fcport,
   3057		struct qla_sa_update_frame *sa_frame)
   3058{
   3059	struct edif_sa_index_entry *entry;
   3060	struct list_head *sa_list;
   3061	uint16_t sa_index;
   3062	int dir = sa_frame->flags & SAU_FLG_TX;
   3063	int slot = 0;
   3064	int free_slot = -1;
   3065	scsi_qla_host_t *vha = fcport->vha;
   3066	struct qla_hw_data *ha = vha->hw;
   3067	unsigned long flags = 0;
   3068	uint16_t nport_handle = fcport->loop_id;
   3069
   3070	ql_dbg(ql_dbg_edif, vha, 0x3063,
   3071	    "%s: entry  fc_port: %p, nport_handle: 0x%x\n",
   3072	    __func__, fcport, nport_handle);
   3073
   3074	if (dir)
   3075		sa_list = &ha->sadb_tx_index_list;
   3076	else
   3077		sa_list = &ha->sadb_rx_index_list;
   3078
   3079	entry = qla_edif_sadb_find_sa_index_entry(nport_handle, sa_list);
   3080	if (!entry) {
   3081		if ((sa_frame->flags & (SAU_FLG_TX | SAU_FLG_INV)) == SAU_FLG_INV) {
   3082			ql_dbg(ql_dbg_edif, vha, 0x3063,
   3083			    "%s: rx delete request with no entry\n", __func__);
   3084			return RX_DELETE_NO_EDIF_SA_INDEX;
   3085		}
   3086
   3087		/* if there is no entry for this nport, add one */
   3088		entry = kzalloc((sizeof(struct edif_sa_index_entry)), GFP_ATOMIC);
   3089		if (!entry)
   3090			return INVALID_EDIF_SA_INDEX;
   3091
   3092		sa_index = qla_edif_get_sa_index_from_freepool(fcport, dir);
   3093		if (sa_index == INVALID_EDIF_SA_INDEX) {
   3094			kfree(entry);
   3095			return INVALID_EDIF_SA_INDEX;
   3096		}
   3097
   3098		INIT_LIST_HEAD(&entry->next);
   3099		entry->handle = nport_handle;
   3100		entry->fcport = fcport;
   3101		entry->sa_pair[0].spi = sa_frame->spi;
   3102		entry->sa_pair[0].sa_index = sa_index;
   3103		entry->sa_pair[1].spi = 0;
   3104		entry->sa_pair[1].sa_index = INVALID_EDIF_SA_INDEX;
   3105		spin_lock_irqsave(&ha->sadb_lock, flags);
   3106		list_add_tail(&entry->next, sa_list);
   3107		spin_unlock_irqrestore(&ha->sadb_lock, flags);
   3108		ql_dbg(ql_dbg_edif, vha, 0x3063,
   3109		    "%s: Created new sadb entry for nport_handle 0x%x, spi 0x%x, returning sa_index %d\n",
   3110		    __func__, nport_handle, sa_frame->spi, sa_index);
   3111
   3112		return sa_index;
   3113	}
   3114
   3115	spin_lock_irqsave(&ha->sadb_lock, flags);
   3116
   3117	/* see if we already have an entry for this spi */
   3118	for (slot = 0; slot < 2; slot++) {
   3119		if (entry->sa_pair[slot].sa_index == INVALID_EDIF_SA_INDEX) {
   3120			free_slot = slot;
   3121		} else {
   3122			if (entry->sa_pair[slot].spi == sa_frame->spi) {
   3123				spin_unlock_irqrestore(&ha->sadb_lock, flags);
   3124				ql_dbg(ql_dbg_edif, vha, 0x3063,
   3125				    "%s: sadb slot %d entry for lid 0x%x, spi 0x%x found, sa_index %d\n",
   3126				    __func__, slot, entry->handle, sa_frame->spi,
   3127				    entry->sa_pair[slot].sa_index);
   3128				return entry->sa_pair[slot].sa_index;
   3129			}
   3130		}
   3131	}
   3132	spin_unlock_irqrestore(&ha->sadb_lock, flags);
   3133
   3134	/* both slots are used */
   3135	if (free_slot == -1) {
   3136		ql_dbg(ql_dbg_edif, vha, 0x3063,
   3137		    "%s: WARNING: No free slots in sadb for nport_handle 0x%x, spi: 0x%x\n",
   3138		    __func__, entry->handle, sa_frame->spi);
   3139		ql_dbg(ql_dbg_edif, vha, 0x3063,
   3140		    "%s: Slot 0  spi: 0x%x  sa_index: %d,  Slot 1  spi: 0x%x  sa_index: %d\n",
   3141		    __func__, entry->sa_pair[0].spi, entry->sa_pair[0].sa_index,
   3142		    entry->sa_pair[1].spi, entry->sa_pair[1].sa_index);
   3143
   3144		return INVALID_EDIF_SA_INDEX;
   3145	}
   3146
   3147	/* there is at least one free slot, use it */
   3148	sa_index = qla_edif_get_sa_index_from_freepool(fcport, dir);
   3149	if (sa_index == INVALID_EDIF_SA_INDEX) {
   3150		ql_dbg(ql_dbg_edif, fcport->vha, 0x3063,
   3151		    "%s: empty freepool!!\n", __func__);
   3152		return INVALID_EDIF_SA_INDEX;
   3153	}
   3154
   3155	spin_lock_irqsave(&ha->sadb_lock, flags);
   3156	entry->sa_pair[free_slot].spi = sa_frame->spi;
   3157	entry->sa_pair[free_slot].sa_index = sa_index;
   3158	spin_unlock_irqrestore(&ha->sadb_lock, flags);
   3159	ql_dbg(ql_dbg_edif, fcport->vha, 0x3063,
   3160	    "%s: sadb slot %d entry for nport_handle 0x%x, spi 0x%x added, returning sa_index %d\n",
   3161	    __func__, free_slot, entry->handle, sa_frame->spi, sa_index);
   3162
   3163	return sa_index;
   3164}
   3165
   3166/* release any sadb entries -- only done at teardown */
   3167void qla_edif_sadb_release(struct qla_hw_data *ha)
   3168{
   3169	struct edif_sa_index_entry *entry, *tmp;
   3170
   3171	list_for_each_entry_safe(entry, tmp, &ha->sadb_rx_index_list, next) {
   3172		list_del(&entry->next);
   3173		kfree(entry);
   3174	}
   3175
   3176	list_for_each_entry_safe(entry, tmp, &ha->sadb_tx_index_list, next) {
   3177		list_del(&entry->next);
   3178		kfree(entry);
   3179	}
   3180}
   3181
   3182/**************************
   3183 * sadb freepool functions
   3184 **************************/
   3185
   3186/* build the rx and tx sa_index free pools -- only done at fcport init */
   3187int qla_edif_sadb_build_free_pool(struct qla_hw_data *ha)
   3188{
   3189	ha->edif_tx_sa_id_map =
   3190	    kcalloc(BITS_TO_LONGS(EDIF_NUM_SA_INDEX), sizeof(long), GFP_KERNEL);
   3191
   3192	if (!ha->edif_tx_sa_id_map) {
   3193		ql_log_pci(ql_log_fatal, ha->pdev, 0x0009,
   3194		    "Unable to allocate memory for sadb tx.\n");
   3195		return -ENOMEM;
   3196	}
   3197
   3198	ha->edif_rx_sa_id_map =
   3199	    kcalloc(BITS_TO_LONGS(EDIF_NUM_SA_INDEX), sizeof(long), GFP_KERNEL);
   3200	if (!ha->edif_rx_sa_id_map) {
   3201		kfree(ha->edif_tx_sa_id_map);
   3202		ha->edif_tx_sa_id_map = NULL;
   3203		ql_log_pci(ql_log_fatal, ha->pdev, 0x0009,
   3204		    "Unable to allocate memory for sadb rx.\n");
   3205		return -ENOMEM;
   3206	}
   3207	return 0;
   3208}
   3209
   3210/* release the free pool - only done during fcport teardown */
   3211void qla_edif_sadb_release_free_pool(struct qla_hw_data *ha)
   3212{
   3213	kfree(ha->edif_tx_sa_id_map);
   3214	ha->edif_tx_sa_id_map = NULL;
   3215	kfree(ha->edif_rx_sa_id_map);
   3216	ha->edif_rx_sa_id_map = NULL;
   3217}
   3218
   3219static void __chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha,
   3220		fc_port_t *fcport, uint32_t handle, uint16_t sa_index)
   3221{
   3222	struct edif_list_entry *edif_entry;
   3223	struct edif_sa_ctl *sa_ctl;
   3224	uint16_t delete_sa_index = INVALID_EDIF_SA_INDEX;
   3225	unsigned long flags = 0;
   3226	uint16_t nport_handle = fcport->loop_id;
   3227	uint16_t cached_nport_handle;
   3228
   3229	spin_lock_irqsave(&fcport->edif.indx_list_lock, flags);
   3230	edif_entry = qla_edif_list_find_sa_index(fcport, nport_handle);
   3231	if (!edif_entry) {
   3232		spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
   3233		return;		/* no pending delete for this handle */
   3234	}
   3235
   3236	/*
   3237	 * check for no pending delete for this index or iocb does not
   3238	 * match rx sa_index
   3239	 */
   3240	if (edif_entry->delete_sa_index == INVALID_EDIF_SA_INDEX ||
   3241	    edif_entry->update_sa_index != sa_index) {
   3242		spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
   3243		return;
   3244	}
   3245
   3246	/*
   3247	 * wait until we have seen at least EDIF_DELAY_COUNT transfers before
   3248	 * queueing RX delete
   3249	 */
   3250	if (edif_entry->count++ < EDIF_RX_DELETE_FILTER_COUNT) {
   3251		spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
   3252		return;
   3253	}
   3254
   3255	ql_dbg(ql_dbg_edif, vha, 0x5033,
   3256	    "%s: invalidating delete_sa_index,  update_sa_index: 0x%x sa_index: 0x%x, delete_sa_index: 0x%x\n",
   3257	    __func__, edif_entry->update_sa_index, sa_index, edif_entry->delete_sa_index);
   3258
   3259	delete_sa_index = edif_entry->delete_sa_index;
   3260	edif_entry->delete_sa_index = INVALID_EDIF_SA_INDEX;
   3261	cached_nport_handle = edif_entry->handle;
   3262	spin_unlock_irqrestore(&fcport->edif.indx_list_lock, flags);
   3263
   3264	/* sanity check on the nport handle */
   3265	if (nport_handle != cached_nport_handle) {
   3266		ql_dbg(ql_dbg_edif, vha, 0x3063,
   3267		    "%s: POST SA DELETE nport_handle mismatch: lid: 0x%x, edif_entry nph: 0x%x\n",
   3268		    __func__, nport_handle, cached_nport_handle);
   3269	}
   3270
   3271	/* find the sa_ctl for the delete and schedule the delete */
   3272	sa_ctl = qla_edif_find_sa_ctl_by_index(fcport, delete_sa_index, 0);
   3273	if (sa_ctl) {
   3274		ql_dbg(ql_dbg_edif, vha, 0x3063,
   3275		    "%s: POST SA DELETE sa_ctl: %p, index recvd %d\n",
   3276		    __func__, sa_ctl, sa_index);
   3277		ql_dbg(ql_dbg_edif, vha, 0x3063,
   3278		    "delete index %d, update index: %d, nport handle: 0x%x, handle: 0x%x\n",
   3279		    delete_sa_index,
   3280		    edif_entry->update_sa_index, nport_handle, handle);
   3281
   3282		sa_ctl->flags = EDIF_SA_CTL_FLG_DEL;
   3283		set_bit(EDIF_SA_CTL_REPL, &sa_ctl->state);
   3284		qla_post_sa_replace_work(fcport->vha, fcport,
   3285		    nport_handle, sa_ctl);
   3286	} else {
   3287		ql_dbg(ql_dbg_edif, vha, 0x3063,
   3288		    "%s: POST SA DELETE sa_ctl not found for delete_sa_index: %d\n",
   3289		    __func__, delete_sa_index);
   3290	}
   3291}
   3292
   3293void qla_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha,
   3294		srb_t *sp, struct sts_entry_24xx *sts24)
   3295{
   3296	fc_port_t *fcport = sp->fcport;
   3297	/* sa_index used by this iocb */
   3298	struct scsi_cmnd *cmd = GET_CMD_SP(sp);
   3299	uint32_t handle;
   3300
   3301	handle = (uint32_t)LSW(sts24->handle);
   3302
   3303	/* find out if this status iosb is for a scsi read */
   3304	if (cmd->sc_data_direction != DMA_FROM_DEVICE)
   3305		return;
   3306
   3307	return __chk_edif_rx_sa_delete_pending(vha, fcport, handle,
   3308	   le16_to_cpu(sts24->edif_sa_index));
   3309}
   3310
   3311void qlt_chk_edif_rx_sa_delete_pending(scsi_qla_host_t *vha, fc_port_t *fcport,
   3312		struct ctio7_from_24xx *pkt)
   3313{
   3314	__chk_edif_rx_sa_delete_pending(vha, fcport,
   3315	    pkt->handle, le16_to_cpu(pkt->edif_sa_index));
   3316}
   3317
   3318static void qla_parse_auth_els_ctl(struct srb *sp)
   3319{
   3320	struct qla_els_pt_arg *a = &sp->u.bsg_cmd.u.els_arg;
   3321	struct bsg_job *bsg_job = sp->u.bsg_cmd.bsg_job;
   3322	struct fc_bsg_request *request = bsg_job->request;
   3323	struct qla_bsg_auth_els_request *p =
   3324	    (struct qla_bsg_auth_els_request *)bsg_job->request;
   3325
   3326	a->tx_len = a->tx_byte_count = sp->remap.req.len;
   3327	a->tx_addr = sp->remap.req.dma;
   3328	a->rx_len = a->rx_byte_count = sp->remap.rsp.len;
   3329	a->rx_addr = sp->remap.rsp.dma;
   3330
   3331	if (p->e.sub_cmd == SEND_ELS_REPLY) {
   3332		a->control_flags = p->e.extra_control_flags << 13;
   3333		a->rx_xchg_address = cpu_to_le32(p->e.extra_rx_xchg_address);
   3334		if (p->e.extra_control_flags == BSG_CTL_FLAG_LS_ACC)
   3335			a->els_opcode = ELS_LS_ACC;
   3336		else if (p->e.extra_control_flags == BSG_CTL_FLAG_LS_RJT)
   3337			a->els_opcode = ELS_LS_RJT;
   3338	}
   3339	a->did = sp->fcport->d_id;
   3340	a->els_opcode =  request->rqst_data.h_els.command_code;
   3341	a->nport_handle = cpu_to_le16(sp->fcport->loop_id);
   3342	a->vp_idx = sp->vha->vp_idx;
   3343}
   3344
   3345int qla_edif_process_els(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
   3346{
   3347	struct fc_bsg_request *bsg_request = bsg_job->request;
   3348	struct fc_bsg_reply *bsg_reply = bsg_job->reply;
   3349	fc_port_t *fcport = NULL;
   3350	struct qla_hw_data *ha = vha->hw;
   3351	srb_t *sp;
   3352	int rval =  (DID_ERROR << 16);
   3353	port_id_t d_id;
   3354	struct qla_bsg_auth_els_request *p =
   3355	    (struct qla_bsg_auth_els_request *)bsg_job->request;
   3356
   3357	d_id.b.al_pa = bsg_request->rqst_data.h_els.port_id[2];
   3358	d_id.b.area = bsg_request->rqst_data.h_els.port_id[1];
   3359	d_id.b.domain = bsg_request->rqst_data.h_els.port_id[0];
   3360
   3361	/* find matching d_id in fcport list */
   3362	fcport = qla2x00_find_fcport_by_pid(vha, &d_id);
   3363	if (!fcport) {
   3364		ql_dbg(ql_dbg_edif, vha, 0x911a,
   3365		    "%s fcport not find online portid=%06x.\n",
   3366		    __func__, d_id.b24);
   3367		SET_DID_STATUS(bsg_reply->result, DID_ERROR);
   3368		return -EIO;
   3369	}
   3370
   3371	if (qla_bsg_check(vha, bsg_job, fcport))
   3372		return 0;
   3373
   3374	if (fcport->loop_id == FC_NO_LOOP_ID) {
   3375		ql_dbg(ql_dbg_edif, vha, 0x910d,
   3376		    "%s ELS code %x, no loop id.\n", __func__,
   3377		    bsg_request->rqst_data.r_els.els_code);
   3378		SET_DID_STATUS(bsg_reply->result, DID_BAD_TARGET);
   3379		return -ENXIO;
   3380	}
   3381
   3382	if (!vha->flags.online) {
   3383		ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
   3384		SET_DID_STATUS(bsg_reply->result, DID_BAD_TARGET);
   3385		rval = -EIO;
   3386		goto done;
   3387	}
   3388
   3389	/* pass through is supported only for ISP 4Gb or higher */
   3390	if (!IS_FWI2_CAPABLE(ha)) {
   3391		ql_dbg(ql_dbg_user, vha, 0x7001,
   3392		    "ELS passthru not supported for ISP23xx based adapters.\n");
   3393		SET_DID_STATUS(bsg_reply->result, DID_BAD_TARGET);
   3394		rval = -EPERM;
   3395		goto done;
   3396	}
   3397
   3398	sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
   3399	if (!sp) {
   3400		ql_dbg(ql_dbg_user, vha, 0x7004,
   3401		    "Failed get sp pid=%06x\n", fcport->d_id.b24);
   3402		rval = -ENOMEM;
   3403		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
   3404		goto done;
   3405	}
   3406
   3407	sp->remap.req.len = bsg_job->request_payload.payload_len;
   3408	sp->remap.req.buf = dma_pool_alloc(ha->purex_dma_pool,
   3409	    GFP_KERNEL, &sp->remap.req.dma);
   3410	if (!sp->remap.req.buf) {
   3411		ql_dbg(ql_dbg_user, vha, 0x7005,
   3412		    "Failed allocate request dma len=%x\n",
   3413		    bsg_job->request_payload.payload_len);
   3414		rval = -ENOMEM;
   3415		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
   3416		goto done_free_sp;
   3417	}
   3418
   3419	sp->remap.rsp.len = bsg_job->reply_payload.payload_len;
   3420	sp->remap.rsp.buf = dma_pool_alloc(ha->purex_dma_pool,
   3421	    GFP_KERNEL, &sp->remap.rsp.dma);
   3422	if (!sp->remap.rsp.buf) {
   3423		ql_dbg(ql_dbg_user, vha, 0x7006,
   3424		    "Failed allocate response dma len=%x\n",
   3425		    bsg_job->reply_payload.payload_len);
   3426		rval = -ENOMEM;
   3427		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
   3428		goto done_free_remap_req;
   3429	}
   3430	sg_copy_to_buffer(bsg_job->request_payload.sg_list,
   3431	    bsg_job->request_payload.sg_cnt, sp->remap.req.buf,
   3432	    sp->remap.req.len);
   3433	sp->remap.remapped = true;
   3434
   3435	sp->type = SRB_ELS_CMD_HST_NOLOGIN;
   3436	sp->name = "SPCN_BSG_HST_NOLOGIN";
   3437	sp->u.bsg_cmd.bsg_job = bsg_job;
   3438	qla_parse_auth_els_ctl(sp);
   3439
   3440	sp->free = qla2x00_bsg_sp_free;
   3441	sp->done = qla2x00_bsg_job_done;
   3442
   3443	rval = qla2x00_start_sp(sp);
   3444
   3445	ql_dbg(ql_dbg_edif, vha, 0x700a,
   3446	    "%s %s %8phN xchg %x ctlflag %x hdl %x reqlen %xh bsg ptr %p\n",
   3447	    __func__, sc_to_str(p->e.sub_cmd), fcport->port_name,
   3448	    p->e.extra_rx_xchg_address, p->e.extra_control_flags,
   3449	    sp->handle, sp->remap.req.len, bsg_job);
   3450
   3451	if (rval != QLA_SUCCESS) {
   3452		ql_log(ql_log_warn, vha, 0x700e,
   3453		    "qla2x00_start_sp failed = %d\n", rval);
   3454		SET_DID_STATUS(bsg_reply->result, DID_IMM_RETRY);
   3455		rval = -EIO;
   3456		goto done_free_remap_rsp;
   3457	}
   3458	return rval;
   3459
   3460done_free_remap_rsp:
   3461	dma_pool_free(ha->purex_dma_pool, sp->remap.rsp.buf,
   3462	    sp->remap.rsp.dma);
   3463done_free_remap_req:
   3464	dma_pool_free(ha->purex_dma_pool, sp->remap.req.buf,
   3465	    sp->remap.req.dma);
   3466done_free_sp:
   3467	qla2x00_rel_sp(sp);
   3468
   3469done:
   3470	return rval;
   3471}
   3472
   3473void qla_edif_sess_down(struct scsi_qla_host *vha, struct fc_port *sess)
   3474{
   3475	if (sess->edif.app_sess_online && DBELL_ACTIVE(vha)) {
   3476		ql_dbg(ql_dbg_disc, vha, 0xf09c,
   3477			"%s: sess %8phN send port_offline event\n",
   3478			__func__, sess->port_name);
   3479		sess->edif.app_sess_online = 0;
   3480		qla_edb_eventcreate(vha, VND_CMD_AUTH_STATE_SESSION_SHUTDOWN,
   3481		    sess->d_id.b24, 0, sess);
   3482		qla2x00_post_aen_work(vha, FCH_EVT_PORT_OFFLINE, sess->d_id.b24);
   3483	}
   3484}
   3485
   3486void qla_edif_clear_appdata(struct scsi_qla_host *vha, struct fc_port *fcport)
   3487{
   3488	if (!(fcport->flags & FCF_FCSP_DEVICE))
   3489		return;
   3490
   3491	qla_edb_clear(vha, fcport->d_id);
   3492	qla_enode_clear(vha, fcport->d_id);
   3493}