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

source code of linux/drivers/scsi/qla2xxx/qla_edif.c