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