File Index
Files and directories
Sign in
FILE

qla_edif.c

File preview with syntax highlighting.

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