1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include <linux/blkdev.h>
25#include <linux/pci.h>
26#include <linux/slab.h>
27#include <linux/interrupt.h>
28
29#include <scsi/scsi.h>
30#include <scsi/scsi_device.h>
31#include <scsi/scsi_host.h>
32#include <scsi/scsi_transport_fc.h>
33#include <scsi/fc/fc_fs.h>
34
35#include "lpfc_hw4.h"
36#include "lpfc_hw.h"
37#include "lpfc_sli.h"
38#include "lpfc_sli4.h"
39#include "lpfc_nl.h"
40#include "lpfc_disc.h"
41#include "lpfc.h"
42#include "lpfc_scsi.h"
43#include "lpfc_nvme.h"
44#include "lpfc_logmsg.h"
45#include "lpfc_crtn.h"
46#include "lpfc_vport.h"
47#include "lpfc_debugfs.h"
48
49
50
51static int
52lpfc_check_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
53 struct lpfc_name *nn, struct lpfc_name *pn)
54{
55
56 if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED))
57 return 0;
58
59
60
61
62 if (memcmp(nn, &ndlp->nlp_nodename, sizeof (struct lpfc_name)))
63 return 0;
64
65 if (memcmp(pn, &ndlp->nlp_portname, sizeof (struct lpfc_name)))
66 return 0;
67
68
69 return 1;
70}
71
72int
73lpfc_check_sparm(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
74 struct serv_parm *sp, uint32_t class, int flogi)
75{
76 volatile struct serv_parm *hsp = &vport->fc_sparam;
77 uint16_t hsp_value, ssp_value = 0;
78
79
80
81
82
83
84
85
86 if (sp->cls1.classValid) {
87 if (!flogi) {
88 hsp_value = ((hsp->cls1.rcvDataSizeMsb << 8) |
89 hsp->cls1.rcvDataSizeLsb);
90 ssp_value = ((sp->cls1.rcvDataSizeMsb << 8) |
91 sp->cls1.rcvDataSizeLsb);
92 if (!ssp_value)
93 goto bad_service_param;
94 if (ssp_value > hsp_value) {
95 sp->cls1.rcvDataSizeLsb =
96 hsp->cls1.rcvDataSizeLsb;
97 sp->cls1.rcvDataSizeMsb =
98 hsp->cls1.rcvDataSizeMsb;
99 }
100 }
101 } else if (class == CLASS1)
102 goto bad_service_param;
103 if (sp->cls2.classValid) {
104 if (!flogi) {
105 hsp_value = ((hsp->cls2.rcvDataSizeMsb << 8) |
106 hsp->cls2.rcvDataSizeLsb);
107 ssp_value = ((sp->cls2.rcvDataSizeMsb << 8) |
108 sp->cls2.rcvDataSizeLsb);
109 if (!ssp_value)
110 goto bad_service_param;
111 if (ssp_value > hsp_value) {
112 sp->cls2.rcvDataSizeLsb =
113 hsp->cls2.rcvDataSizeLsb;
114 sp->cls2.rcvDataSizeMsb =
115 hsp->cls2.rcvDataSizeMsb;
116 }
117 }
118 } else if (class == CLASS2)
119 goto bad_service_param;
120 if (sp->cls3.classValid) {
121 if (!flogi) {
122 hsp_value = ((hsp->cls3.rcvDataSizeMsb << 8) |
123 hsp->cls3.rcvDataSizeLsb);
124 ssp_value = ((sp->cls3.rcvDataSizeMsb << 8) |
125 sp->cls3.rcvDataSizeLsb);
126 if (!ssp_value)
127 goto bad_service_param;
128 if (ssp_value > hsp_value) {
129 sp->cls3.rcvDataSizeLsb =
130 hsp->cls3.rcvDataSizeLsb;
131 sp->cls3.rcvDataSizeMsb =
132 hsp->cls3.rcvDataSizeMsb;
133 }
134 }
135 } else if (class == CLASS3)
136 goto bad_service_param;
137
138
139
140
141
142
143 hsp_value = (hsp->cmn.bbRcvSizeMsb << 8) | hsp->cmn.bbRcvSizeLsb;
144 ssp_value = (sp->cmn.bbRcvSizeMsb << 8) | sp->cmn.bbRcvSizeLsb;
145 if (ssp_value > hsp_value) {
146 sp->cmn.bbRcvSizeLsb = hsp->cmn.bbRcvSizeLsb;
147 sp->cmn.bbRcvSizeMsb = (sp->cmn.bbRcvSizeMsb & 0xF0) |
148 (hsp->cmn.bbRcvSizeMsb & 0x0F);
149 }
150
151 memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof (struct lpfc_name));
152 memcpy(&ndlp->nlp_portname, &sp->portName, sizeof (struct lpfc_name));
153 return 1;
154bad_service_param:
155 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
156 "0207 Device %x "
157 "(%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x) sent "
158 "invalid service parameters. Ignoring device.\n",
159 ndlp->nlp_DID,
160 sp->nodeName.u.wwn[0], sp->nodeName.u.wwn[1],
161 sp->nodeName.u.wwn[2], sp->nodeName.u.wwn[3],
162 sp->nodeName.u.wwn[4], sp->nodeName.u.wwn[5],
163 sp->nodeName.u.wwn[6], sp->nodeName.u.wwn[7]);
164 return 0;
165}
166
167static void *
168lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
169 struct lpfc_iocbq *rspiocb)
170{
171 struct lpfc_dmabuf *pcmd, *prsp;
172 uint32_t *lp;
173 void *ptr = NULL;
174 IOCB_t *irsp;
175
176 irsp = &rspiocb->iocb;
177 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
178
179
180
181
182 if (pcmd) {
183 prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf,
184 list);
185 if (prsp) {
186 lp = (uint32_t *) prsp->virt;
187 ptr = (void *)((uint8_t *)lp + sizeof(uint32_t));
188 }
189 } else {
190
191 if (!(irsp->ulpStatus)) {
192 irsp->ulpStatus = IOSTAT_LOCAL_REJECT;
193 irsp->un.ulpWord[4] = IOERR_SLI_ABORTED;
194 }
195 ptr = NULL;
196 }
197 return ptr;
198}
199
200
201
202
203
204
205
206
207void
208lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp)
209{
210 LIST_HEAD(abort_list);
211 struct lpfc_sli_ring *pring;
212 struct lpfc_iocbq *iocb, *next_iocb;
213
214 pring = lpfc_phba_elsring(phba);
215
216
217 if (unlikely(!pring))
218 return;
219
220
221 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_DISCOVERY,
222 "2819 Abort outstanding I/O on NPort x%x "
223 "Data: x%x x%x x%x\n",
224 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
225 ndlp->nlp_rpi);
226
227 lpfc_fabric_abort_nport(ndlp);
228
229
230
231
232
233
234 spin_lock_irq(&phba->hbalock);
235 if (phba->sli_rev == LPFC_SLI_REV4)
236 spin_lock(&pring->ring_lock);
237 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
238
239 if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp))
240 list_add_tail(&iocb->dlist, &abort_list);
241 }
242 if (phba->sli_rev == LPFC_SLI_REV4)
243 spin_unlock(&pring->ring_lock);
244 spin_unlock_irq(&phba->hbalock);
245
246
247 list_for_each_entry_safe(iocb, next_iocb, &abort_list, dlist) {
248 spin_lock_irq(&phba->hbalock);
249 list_del_init(&iocb->dlist);
250 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
251 spin_unlock_irq(&phba->hbalock);
252 }
253
254 INIT_LIST_HEAD(&abort_list);
255
256
257 spin_lock_irq(&phba->hbalock);
258 if (phba->sli_rev == LPFC_SLI_REV4)
259 spin_lock(&pring->ring_lock);
260
261 list_for_each_entry_safe(iocb, next_iocb, &pring->txq, list) {
262
263 if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) {
264 list_del_init(&iocb->list);
265 list_add_tail(&iocb->list, &abort_list);
266 }
267 }
268
269 if (phba->sli_rev == LPFC_SLI_REV4)
270 spin_unlock(&pring->ring_lock);
271 spin_unlock_irq(&phba->hbalock);
272
273
274 lpfc_sli_cancel_iocbs(phba, &abort_list,
275 IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED);
276
277 lpfc_cancel_retry_delay_tmo(phba->pport, ndlp);
278}
279
280
281
282
283
284
285
286
287static void
288lpfc_defer_pt2pt_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *link_mbox)
289{
290 LPFC_MBOXQ_t *login_mbox;
291 MAILBOX_t *mb = &link_mbox->u.mb;
292 struct lpfc_iocbq *save_iocb;
293 struct lpfc_nodelist *ndlp;
294 int rc;
295
296 ndlp = link_mbox->ctx_ndlp;
297 login_mbox = link_mbox->context3;
298 save_iocb = login_mbox->context3;
299 link_mbox->context3 = NULL;
300 login_mbox->context3 = NULL;
301
302
303 if (mb->mbxStatus) {
304 lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
305 "4575 CONFIG_LINK fails pt2pt discovery: %x\n",
306 mb->mbxStatus);
307 mempool_free(login_mbox, phba->mbox_mem_pool);
308 mempool_free(link_mbox, phba->mbox_mem_pool);
309 kfree(save_iocb);
310 return;
311 }
312
313
314
315
316 rc = lpfc_els_rsp_acc(link_mbox->vport, ELS_CMD_PLOGI,
317 save_iocb, ndlp, login_mbox);
318 if (rc) {
319 lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
320 "4576 PLOGI ACC fails pt2pt discovery: %x\n",
321 rc);
322 mempool_free(login_mbox, phba->mbox_mem_pool);
323 }
324
325 mempool_free(link_mbox, phba->mbox_mem_pool);
326 kfree(save_iocb);
327}
328
329
330
331
332
333
334
335
336
337
338
339
340
341static void
342lpfc_defer_acc_rsp(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
343{
344 struct lpfc_vport *vport = pmb->vport;
345 struct lpfc_nodelist *ndlp = pmb->ctx_ndlp;
346 LPFC_MBOXQ_t *mbox = pmb->context3;
347 struct lpfc_iocbq *piocb = NULL;
348 int rc;
349
350 if (mbox) {
351 pmb->context3 = NULL;
352 piocb = mbox->context3;
353 mbox->context3 = NULL;
354 }
355
356
357
358
359
360 lpfc_nlp_get(ndlp);
361 lpfc_sli4_unreg_rpi_cmpl_clr(phba, pmb);
362
363 if (!piocb) {
364 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
365 "4578 PLOGI ACC fail\n");
366 if (mbox)
367 mempool_free(mbox, phba->mbox_mem_pool);
368 goto out;
369 }
370
371 rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, piocb, ndlp, mbox);
372 if (rc) {
373 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
374 "4579 PLOGI ACC fail %x\n", rc);
375 if (mbox)
376 mempool_free(mbox, phba->mbox_mem_pool);
377 }
378 kfree(piocb);
379out:
380 lpfc_nlp_put(ndlp);
381}
382
383static int
384lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
385 struct lpfc_iocbq *cmdiocb)
386{
387 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
388 struct lpfc_hba *phba = vport->phba;
389 struct lpfc_dmabuf *pcmd;
390 uint64_t nlp_portwwn = 0;
391 uint32_t *lp;
392 IOCB_t *icmd;
393 struct serv_parm *sp;
394 uint32_t ed_tov;
395 LPFC_MBOXQ_t *link_mbox;
396 LPFC_MBOXQ_t *login_mbox;
397 struct lpfc_iocbq *save_iocb;
398 struct ls_rjt stat;
399 uint32_t vid, flag;
400 u16 rpi;
401 int rc, defer_acc;
402
403 memset(&stat, 0, sizeof (struct ls_rjt));
404 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
405 lp = (uint32_t *) pcmd->virt;
406 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
407 if (wwn_to_u64(sp->portName.u.wwn) == 0) {
408 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
409 "0140 PLOGI Reject: invalid nname\n");
410 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
411 stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_PNAME;
412 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
413 NULL);
414 return 0;
415 }
416 if (wwn_to_u64(sp->nodeName.u.wwn) == 0) {
417 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
418 "0141 PLOGI Reject: invalid pname\n");
419 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
420 stat.un.b.lsRjtRsnCodeExp = LSEXP_INVALID_NNAME;
421 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
422 NULL);
423 return 0;
424 }
425
426 nlp_portwwn = wwn_to_u64(ndlp->nlp_portname.u.wwn);
427 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0) == 0)) {
428
429 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
430 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
431 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
432 NULL);
433 return 0;
434 }
435 icmd = &cmdiocb->iocb;
436
437
438 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
439 "0114 PLOGI chkparm OK Data: x%x x%x x%x "
440 "x%x x%x x%x\n",
441 ndlp->nlp_DID, ndlp->nlp_state, ndlp->nlp_flag,
442 ndlp->nlp_rpi, vport->port_state,
443 vport->fc_flag);
444
445 if (vport->cfg_fcp_class == 2 && sp->cls2.classValid)
446 ndlp->nlp_fcp_info |= CLASS2;
447 else
448 ndlp->nlp_fcp_info |= CLASS3;
449
450 defer_acc = 0;
451 ndlp->nlp_class_sup = 0;
452 if (sp->cls1.classValid)
453 ndlp->nlp_class_sup |= FC_COS_CLASS1;
454 if (sp->cls2.classValid)
455 ndlp->nlp_class_sup |= FC_COS_CLASS2;
456 if (sp->cls3.classValid)
457 ndlp->nlp_class_sup |= FC_COS_CLASS3;
458 if (sp->cls4.classValid)
459 ndlp->nlp_class_sup |= FC_COS_CLASS4;
460 ndlp->nlp_maxframe =
461 ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
462
463 switch (ndlp->nlp_state) {
464 case NLP_STE_NPR_NODE:
465 if (!(ndlp->nlp_flag & NLP_NPR_ADISC))
466 break;
467 fallthrough;
468 case NLP_STE_REG_LOGIN_ISSUE:
469 case NLP_STE_PRLI_ISSUE:
470 case NLP_STE_UNMAPPED_NODE:
471 case NLP_STE_MAPPED_NODE:
472
473
474
475
476 if (!(ndlp->nlp_type & NLP_FABRIC) &&
477 !(phba->nvmet_support)) {
478 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
479 ndlp, NULL);
480 return 1;
481 }
482 if (nlp_portwwn != 0 &&
483 nlp_portwwn != wwn_to_u64(sp->portName.u.wwn))
484 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
485 "0143 PLOGI recv'd from DID: x%x "
486 "WWPN changed: old %llx new %llx\n",
487 ndlp->nlp_DID,
488 (unsigned long long)nlp_portwwn,
489 (unsigned long long)
490 wwn_to_u64(sp->portName.u.wwn));
491
492
493 if (phba->nvmet_support &&
494 ndlp->nlp_state == NLP_STE_UNMAPPED_NODE)
495 lpfc_nvmet_invalidate_host(phba, ndlp);
496
497 ndlp->nlp_prev_state = ndlp->nlp_state;
498
499 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
500 break;
501 }
502
503 ndlp->nlp_type &= ~(NLP_FCP_TARGET | NLP_FCP_INITIATOR);
504 ndlp->nlp_type &= ~(NLP_NVME_TARGET | NLP_NVME_INITIATOR);
505 ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
506 ndlp->nlp_flag &= ~NLP_FIRSTBURST;
507
508 login_mbox = NULL;
509 link_mbox = NULL;
510 save_iocb = NULL;
511
512
513 if ((vport->fc_flag & FC_PT2PT) &&
514 !(vport->fc_flag & FC_PT2PT_PLOGI)) {
515
516 vport->fc_myDID = icmd->un.rcvels.parmRo;
517
518 ed_tov = be32_to_cpu(sp->cmn.e_d_tov);
519 if (sp->cmn.edtovResolution) {
520
521 ed_tov = (phba->fc_edtov + 999999) / 1000000;
522 }
523
524
525
526
527
528 if (ed_tov > phba->fc_edtov)
529 phba->fc_edtov = ed_tov;
530 phba->fc_ratov = (2 * phba->fc_edtov) / 1000;
531
532 memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
533
534
535
536 if (phba->sli_rev == LPFC_SLI_REV4)
537 lpfc_issue_reg_vfi(vport);
538 else {
539 defer_acc = 1;
540 link_mbox = mempool_alloc(phba->mbox_mem_pool,
541 GFP_KERNEL);
542 if (!link_mbox)
543 goto out;
544 lpfc_config_link(phba, link_mbox);
545 link_mbox->mbox_cmpl = lpfc_defer_pt2pt_acc;
546 link_mbox->vport = vport;
547 link_mbox->ctx_ndlp = ndlp;
548
549 save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);
550 if (!save_iocb)
551 goto out;
552
553 memcpy((uint8_t *)save_iocb, (uint8_t *)cmdiocb,
554 sizeof(struct lpfc_iocbq));
555 }
556
557 lpfc_can_disctmo(vport);
558 }
559
560 ndlp->nlp_flag &= ~NLP_SUPPRESS_RSP;
561 if ((phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) &&
562 sp->cmn.valid_vendor_ver_level) {
563 vid = be32_to_cpu(sp->un.vv.vid);
564 flag = be32_to_cpu(sp->un.vv.flags);
565 if ((vid == LPFC_VV_EMLX_ID) && (flag & LPFC_VV_SUPPRESS_RSP))
566 ndlp->nlp_flag |= NLP_SUPPRESS_RSP;
567 }
568
569 login_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
570 if (!login_mbox)
571 goto out;
572
573
574 if (phba->nvmet_support && !defer_acc) {
575 link_mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
576 if (!link_mbox)
577 goto out;
578
579
580
581
582
583 save_iocb = kzalloc(sizeof(*save_iocb), GFP_KERNEL);
584 if (!save_iocb)
585 goto out;
586
587
588 rpi = phba->sli4_hba.rpi_ids[ndlp->nlp_rpi];
589 lpfc_unreg_login(phba, vport->vpi, rpi, link_mbox);
590 link_mbox->vport = vport;
591 link_mbox->ctx_ndlp = ndlp;
592 link_mbox->mbox_cmpl = lpfc_defer_acc_rsp;
593
594 if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
595 (!(vport->fc_flag & FC_OFFLINE_MODE)))
596 ndlp->nlp_flag |= NLP_UNREG_INP;
597
598
599 memcpy(save_iocb, cmdiocb, sizeof(*save_iocb));
600
601
602 defer_acc = 1;
603 } else if (phba->sli_rev == LPFC_SLI_REV4)
604 lpfc_unreg_rpi(vport, ndlp);
605
606 rc = lpfc_reg_rpi(phba, vport->vpi, icmd->un.rcvels.remoteID,
607 (uint8_t *)sp, login_mbox, ndlp->nlp_rpi);
608 if (rc)
609 goto out;
610
611
612
613
614 login_mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
615
616
617
618
619 login_mbox->vport = vport;
620 spin_lock_irq(shost->host_lock);
621 ndlp->nlp_flag |= (NLP_ACC_REGLOGIN | NLP_RCV_PLOGI);
622 spin_unlock_irq(shost->host_lock);
623
624
625
626
627
628
629
630
631
632
633
634 if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) &&
635 (vport->fc_flag & FC_FABRIC)) {
636
637 lpfc_els_abort(phba, ndlp);
638 }
639
640 if ((vport->port_type == LPFC_NPIV_PORT &&
641 vport->cfg_restrict_login)) {
642
643
644 kfree(save_iocb);
645
646
647
648
649
650
651 spin_lock_irq(shost->host_lock);
652 ndlp->nlp_flag |= NLP_RM_DFLT_RPI;
653 spin_unlock_irq(shost->host_lock);
654 stat.un.b.lsRjtRsnCode = LSRJT_INVALID_CMD;
655 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
656 rc = lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
657 ndlp, login_mbox);
658 if (rc)
659 mempool_free(login_mbox, phba->mbox_mem_pool);
660 return 1;
661 }
662 if (defer_acc) {
663
664
665
666
667
668
669
670
671
672
673
674
675
676 link_mbox->context3 = login_mbox;
677 login_mbox->context3 = save_iocb;
678
679
680 rc = lpfc_sli_issue_mbox(phba, link_mbox, MBX_NOWAIT);
681 if (rc == MBX_NOT_FINISHED)
682 goto out;
683 return 1;
684 }
685
686 rc = lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, login_mbox);
687 if (rc)
688 mempool_free(login_mbox, phba->mbox_mem_pool);
689 return 1;
690out:
691 if (defer_acc)
692 lpfc_printf_log(phba, KERN_ERR, LOG_TRACE_EVENT,
693 "4577 discovery failure: %p %p %p\n",
694 save_iocb, link_mbox, login_mbox);
695 kfree(save_iocb);
696 if (link_mbox)
697 mempool_free(link_mbox, phba->mbox_mem_pool);
698 if (login_mbox)
699 mempool_free(login_mbox, phba->mbox_mem_pool);
700
701 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
702 stat.un.b.lsRjtRsnCodeExp = LSEXP_OUT_OF_RESOURCE;
703 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
704 return 0;
705}
706
707
708
709
710
711
712
713
714
715static void
716lpfc_mbx_cmpl_resume_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
717{
718 struct lpfc_vport *vport;
719 struct lpfc_iocbq *elsiocb;
720 struct lpfc_nodelist *ndlp;
721 uint32_t cmd;
722
723 elsiocb = (struct lpfc_iocbq *)mboxq->ctx_buf;
724 ndlp = (struct lpfc_nodelist *)mboxq->ctx_ndlp;
725 vport = mboxq->vport;
726 cmd = elsiocb->drvrTimeout;
727
728 if (cmd == ELS_CMD_ADISC) {
729 lpfc_els_rsp_adisc_acc(vport, elsiocb, ndlp);
730 } else {
731 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, elsiocb,
732 ndlp, NULL);
733 }
734 kfree(elsiocb);
735 mempool_free(mboxq, phba->mbox_mem_pool);
736}
737
738static int
739lpfc_rcv_padisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
740 struct lpfc_iocbq *cmdiocb)
741{
742 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
743 struct lpfc_iocbq *elsiocb;
744 struct lpfc_dmabuf *pcmd;
745 struct serv_parm *sp;
746 struct lpfc_name *pnn, *ppn;
747 struct ls_rjt stat;
748 ADISC *ap;
749 IOCB_t *icmd;
750 uint32_t *lp;
751 uint32_t cmd;
752
753 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
754 lp = (uint32_t *) pcmd->virt;
755
756 cmd = *lp++;
757 if (cmd == ELS_CMD_ADISC) {
758 ap = (ADISC *) lp;
759 pnn = (struct lpfc_name *) & ap->nodeName;
760 ppn = (struct lpfc_name *) & ap->portName;
761 } else {
762 sp = (struct serv_parm *) lp;
763 pnn = (struct lpfc_name *) & sp->nodeName;
764 ppn = (struct lpfc_name *) & sp->portName;
765 }
766
767 icmd = &cmdiocb->iocb;
768 if (icmd->ulpStatus == 0 && lpfc_check_adisc(vport, ndlp, pnn, ppn)) {
769
770
771
772
773
774
775 if (vport->phba->sli_rev == LPFC_SLI_REV4) {
776 elsiocb = kmalloc(sizeof(struct lpfc_iocbq),
777 GFP_KERNEL);
778 if (elsiocb) {
779
780
781 memcpy((uint8_t *)elsiocb, (uint8_t *)cmdiocb,
782 sizeof(struct lpfc_iocbq));
783
784
785 elsiocb->drvrTimeout = cmd;
786
787 lpfc_sli4_resume_rpi(ndlp,
788 lpfc_mbx_cmpl_resume_rpi, elsiocb);
789 goto out;
790 }
791 }
792
793 if (cmd == ELS_CMD_ADISC) {
794 lpfc_els_rsp_adisc_acc(vport, cmdiocb, ndlp);
795 } else {
796 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb,
797 ndlp, NULL);
798 }
799out:
800
801
802
803
804
805
806 if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) {
807 if (ndlp->nlp_state != NLP_STE_MAPPED_NODE)
808 lpfc_nlp_set_state(vport, ndlp,
809 NLP_STE_MAPPED_NODE);
810 }
811
812 return 1;
813 }
814
815 stat.un.b.lsRjtRsvd0 = 0;
816 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
817 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
818 stat.un.b.vendorUnique = 0;
819 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
820
821
822 mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000));
823
824 spin_lock_irq(shost->host_lock);
825 ndlp->nlp_flag |= NLP_DELAY_TMO;
826 spin_unlock_irq(shost->host_lock);
827 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
828 ndlp->nlp_prev_state = ndlp->nlp_state;
829 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
830 return 0;
831}
832
833static int
834lpfc_rcv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
835 struct lpfc_iocbq *cmdiocb, uint32_t els_cmd)
836{
837 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
838 struct lpfc_hba *phba = vport->phba;
839 struct lpfc_vport **vports;
840 int i, active_vlink_present = 0 ;
841
842
843
844
845
846 spin_lock_irq(shost->host_lock);
847 ndlp->nlp_flag |= NLP_LOGO_ACC;
848 spin_unlock_irq(shost->host_lock);
849 if (els_cmd == ELS_CMD_PRLO)
850 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
851 else
852 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
853
854
855 if (phba->nvmet_support &&
856 ndlp->nlp_state == NLP_STE_UNMAPPED_NODE)
857 lpfc_nvmet_invalidate_host(phba, ndlp);
858
859 if (ndlp->nlp_DID == Fabric_DID) {
860 if (vport->port_state <= LPFC_FDISC)
861 goto out;
862 lpfc_linkdown_port(vport);
863 spin_lock_irq(shost->host_lock);
864 vport->fc_flag |= FC_VPORT_LOGO_RCVD;
865 spin_unlock_irq(shost->host_lock);
866 vports = lpfc_create_vport_work_array(phba);
867 if (vports) {
868 for (i = 0; i <= phba->max_vports && vports[i] != NULL;
869 i++) {
870 if ((!(vports[i]->fc_flag &
871 FC_VPORT_LOGO_RCVD)) &&
872 (vports[i]->port_state > LPFC_FDISC)) {
873 active_vlink_present = 1;
874 break;
875 }
876 }
877 lpfc_destroy_vport_work_array(phba, vports);
878 }
879
880
881
882
883
884
885 if (!(vport->load_flag & FC_UNLOADING) &&
886 active_vlink_present) {
887
888
889
890
891 mod_timer(&ndlp->nlp_delayfunc,
892 jiffies + msecs_to_jiffies(1000));
893 spin_lock_irq(shost->host_lock);
894 ndlp->nlp_flag |= NLP_DELAY_TMO;
895 spin_unlock_irq(shost->host_lock);
896 ndlp->nlp_last_elscmd = ELS_CMD_FDISC;
897 vport->port_state = LPFC_FDISC;
898 } else {
899 spin_lock_irq(shost->host_lock);
900 phba->pport->fc_flag &= ~FC_LOGO_RCVD_DID_CHNG;
901 spin_unlock_irq(shost->host_lock);
902 lpfc_retry_pport_discovery(phba);
903 }
904 } else if ((!(ndlp->nlp_type & NLP_FABRIC) &&
905 ((ndlp->nlp_type & NLP_FCP_TARGET) ||
906 !(ndlp->nlp_type & NLP_FCP_INITIATOR))) ||
907 (ndlp->nlp_state == NLP_STE_ADISC_ISSUE)) {
908
909 mod_timer(&ndlp->nlp_delayfunc,
910 jiffies + msecs_to_jiffies(1000 * 1));
911 spin_lock_irq(shost->host_lock);
912 ndlp->nlp_flag |= NLP_DELAY_TMO;
913 spin_unlock_irq(shost->host_lock);
914
915 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
916 }
917out:
918 ndlp->nlp_prev_state = ndlp->nlp_state;
919 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
920
921 spin_lock_irq(shost->host_lock);
922 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
923 spin_unlock_irq(shost->host_lock);
924
925
926
927
928
929 return 0;
930}
931
932static uint32_t
933lpfc_rcv_prli_support_check(struct lpfc_vport *vport,
934 struct lpfc_nodelist *ndlp,
935 struct lpfc_iocbq *cmdiocb)
936{
937 struct ls_rjt stat;
938 uint32_t *payload;
939 uint32_t cmd;
940
941 payload = ((struct lpfc_dmabuf *)cmdiocb->context2)->virt;
942 cmd = *payload;
943 if (vport->phba->nvmet_support) {
944
945 if (cmd == ELS_CMD_PRLI)
946 goto out;
947 } else {
948
949 if (!vport->nvmei_support && (cmd == ELS_CMD_NVMEPRLI))
950 goto out;
951 }
952 return 1;
953out:
954 lpfc_printf_vlog(vport, KERN_WARNING, LOG_NVME_DISC,
955 "6115 Rcv PRLI (%x) check failed: ndlp rpi %d "
956 "state x%x flags x%x\n",
957 cmd, ndlp->nlp_rpi, ndlp->nlp_state,
958 ndlp->nlp_flag);
959 memset(&stat, 0, sizeof(struct ls_rjt));
960 stat.un.b.lsRjtRsnCode = LSRJT_CMD_UNSUPPORTED;
961 stat.un.b.lsRjtRsnCodeExp = LSEXP_REQ_UNSUPPORTED;
962 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
963 ndlp, NULL);
964 return 0;
965}
966
967static void
968lpfc_rcv_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
969 struct lpfc_iocbq *cmdiocb)
970{
971 struct lpfc_hba *phba = vport->phba;
972 struct lpfc_dmabuf *pcmd;
973 uint32_t *lp;
974 PRLI *npr;
975 struct fc_rport *rport = ndlp->rport;
976 u32 roles;
977
978 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
979 lp = (uint32_t *) pcmd->virt;
980 npr = (PRLI *) ((uint8_t *) lp + sizeof (uint32_t));
981
982 if ((npr->prliType == PRLI_FCP_TYPE) ||
983 (npr->prliType == PRLI_NVME_TYPE)) {
984 if (npr->initiatorFunc) {
985 if (npr->prliType == PRLI_FCP_TYPE)
986 ndlp->nlp_type |= NLP_FCP_INITIATOR;
987 if (npr->prliType == PRLI_NVME_TYPE)
988 ndlp->nlp_type |= NLP_NVME_INITIATOR;
989 }
990 if (npr->targetFunc) {
991 if (npr->prliType == PRLI_FCP_TYPE)
992 ndlp->nlp_type |= NLP_FCP_TARGET;
993 if (npr->prliType == PRLI_NVME_TYPE)
994 ndlp->nlp_type |= NLP_NVME_TARGET;
995 if (npr->writeXferRdyDis)
996 ndlp->nlp_flag |= NLP_FIRSTBURST;
997 }
998 if (npr->Retry && ndlp->nlp_type &
999 (NLP_FCP_INITIATOR | NLP_FCP_TARGET))
1000 ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
1001
1002 if (npr->Retry && phba->nsler &&
1003 ndlp->nlp_type & (NLP_NVME_INITIATOR | NLP_NVME_TARGET))
1004 ndlp->nlp_nvme_info |= NLP_NVME_NSLER;
1005
1006
1007
1008
1009
1010
1011
1012 if (phba->nvmet_support && (npr->prliType == PRLI_NVME_TYPE)) {
1013 ndlp->nlp_fc4_type |= NLP_FC4_NVME;
1014 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1015 }
1016 if (npr->prliType == PRLI_FCP_TYPE)
1017 ndlp->nlp_fc4_type |= NLP_FC4_FCP;
1018 }
1019 if (rport) {
1020
1021 roles = FC_RPORT_ROLE_UNKNOWN;
1022 if (ndlp->nlp_type & NLP_FCP_INITIATOR)
1023 roles |= FC_RPORT_ROLE_FCP_INITIATOR;
1024 if (ndlp->nlp_type & NLP_FCP_TARGET)
1025 roles |= FC_RPORT_ROLE_FCP_TARGET;
1026
1027 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_RPORT,
1028 "rport rolechg: role:x%x did:x%x flg:x%x",
1029 roles, ndlp->nlp_DID, ndlp->nlp_flag);
1030
1031 if (vport->cfg_enable_fc4_type != LPFC_ENABLE_NVME)
1032 fc_remote_port_rolechg(rport, roles);
1033 }
1034}
1035
1036static uint32_t
1037lpfc_disc_set_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
1038{
1039 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1040
1041 if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED)) {
1042 spin_lock_irq(shost->host_lock);
1043 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
1044 spin_unlock_irq(shost->host_lock);
1045 return 0;
1046 }
1047
1048 if (!(vport->fc_flag & FC_PT2PT)) {
1049
1050 if (vport->cfg_use_adisc && ((vport->fc_flag & FC_RSCN_MODE) ||
1051 ((ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) &&
1052 (ndlp->nlp_type & NLP_FCP_TARGET)))) {
1053 spin_lock_irq(shost->host_lock);
1054 ndlp->nlp_flag |= NLP_NPR_ADISC;
1055 spin_unlock_irq(shost->host_lock);
1056 return 1;
1057 }
1058 }
1059
1060 spin_lock_irq(shost->host_lock);
1061 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
1062 spin_unlock_irq(shost->host_lock);
1063 lpfc_unreg_rpi(vport, ndlp);
1064 return 0;
1065}
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077static void
1078lpfc_release_rpi(struct lpfc_hba *phba, struct lpfc_vport *vport,
1079 struct lpfc_nodelist *ndlp, uint16_t rpi)
1080{
1081 LPFC_MBOXQ_t *pmb;
1082 int rc;
1083
1084
1085
1086
1087 if (ndlp->nlp_flag & NLP_UNREG_INP) {
1088 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1089 "1435 release_rpi SKIP UNREG x%x on "
1090 "NPort x%x deferred x%x flg x%x "
1091 "Data: x%px\n",
1092 ndlp->nlp_rpi, ndlp->nlp_DID,
1093 ndlp->nlp_defer_did,
1094 ndlp->nlp_flag, ndlp);
1095 return;
1096 }
1097
1098 pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
1099 GFP_KERNEL);
1100 if (!pmb)
1101 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
1102 "2796 mailbox memory allocation failed \n");
1103 else {
1104 lpfc_unreg_login(phba, vport->vpi, rpi, pmb);
1105 pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1106 pmb->vport = vport;
1107 pmb->ctx_ndlp = ndlp;
1108
1109 if (((ndlp->nlp_DID & Fabric_DID_MASK) != Fabric_DID_MASK) &&
1110 (!(vport->fc_flag & FC_OFFLINE_MODE)))
1111 ndlp->nlp_flag |= NLP_UNREG_INP;
1112
1113 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1114 "1437 release_rpi UNREG x%x "
1115 "on NPort x%x flg x%x\n",
1116 ndlp->nlp_rpi, ndlp->nlp_DID, ndlp->nlp_flag);
1117
1118 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
1119 if (rc == MBX_NOT_FINISHED)
1120 mempool_free(pmb, phba->mbox_mem_pool);
1121 }
1122}
1123
1124static uint32_t
1125lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1126 void *arg, uint32_t evt)
1127{
1128 struct lpfc_hba *phba;
1129 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
1130 uint16_t rpi;
1131
1132 phba = vport->phba;
1133
1134 if (!(phba->pport->load_flag & FC_UNLOADING) &&
1135 (evt == NLP_EVT_CMPL_REG_LOGIN) &&
1136 (!pmb->u.mb.mbxStatus)) {
1137 rpi = pmb->u.mb.un.varWords[0];
1138 lpfc_release_rpi(phba, vport, ndlp, rpi);
1139 }
1140 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
1141 "0271 Illegal State Transition: node x%x "
1142 "event x%x, state x%x Data: x%x x%x\n",
1143 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
1144 ndlp->nlp_flag);
1145 return ndlp->nlp_state;
1146}
1147
1148static uint32_t
1149lpfc_cmpl_plogi_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1150 void *arg, uint32_t evt)
1151{
1152
1153
1154
1155
1156
1157 if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) {
1158 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
1159 "0272 Illegal State Transition: node x%x "
1160 "event x%x, state x%x Data: x%x x%x\n",
1161 ndlp->nlp_DID, evt, ndlp->nlp_state,
1162 ndlp->nlp_rpi, ndlp->nlp_flag);
1163 }
1164 return ndlp->nlp_state;
1165}
1166
1167
1168
1169static uint32_t
1170lpfc_rcv_plogi_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1171 void *arg, uint32_t evt)
1172{
1173 struct lpfc_iocbq *cmdiocb;
1174
1175 cmdiocb = (struct lpfc_iocbq *) arg;
1176
1177 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
1178 return ndlp->nlp_state;
1179 }
1180 return NLP_STE_FREED_NODE;
1181}
1182
1183static uint32_t
1184lpfc_rcv_els_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1185 void *arg, uint32_t evt)
1186{
1187 lpfc_issue_els_logo(vport, ndlp, 0);
1188 return ndlp->nlp_state;
1189}
1190
1191static uint32_t
1192lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1193 void *arg, uint32_t evt)
1194{
1195 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1196 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1197
1198 spin_lock_irq(shost->host_lock);
1199 ndlp->nlp_flag |= NLP_LOGO_ACC;
1200 spin_unlock_irq(shost->host_lock);
1201 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
1202
1203 return ndlp->nlp_state;
1204}
1205
1206static uint32_t
1207lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1208 void *arg, uint32_t evt)
1209{
1210 return NLP_STE_FREED_NODE;
1211}
1212
1213static uint32_t
1214lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1215 void *arg, uint32_t evt)
1216{
1217 return NLP_STE_FREED_NODE;
1218}
1219
1220static uint32_t
1221lpfc_device_recov_unused_node(struct lpfc_vport *vport,
1222 struct lpfc_nodelist *ndlp,
1223 void *arg, uint32_t evt)
1224{
1225 return ndlp->nlp_state;
1226}
1227
1228static uint32_t
1229lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1230 void *arg, uint32_t evt)
1231{
1232 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1233 struct lpfc_hba *phba = vport->phba;
1234 struct lpfc_iocbq *cmdiocb = arg;
1235 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
1236 uint32_t *lp = (uint32_t *) pcmd->virt;
1237 struct serv_parm *sp = (struct serv_parm *) (lp + 1);
1238 struct ls_rjt stat;
1239 int port_cmp;
1240
1241 memset(&stat, 0, sizeof (struct ls_rjt));
1242
1243
1244
1245
1246 phba->fc_stat.elsLogiCol++;
1247 port_cmp = memcmp(&vport->fc_portname, &sp->portName,
1248 sizeof(struct lpfc_name));
1249
1250 if (port_cmp >= 0) {
1251
1252
1253 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
1254 stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;
1255 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
1256 NULL);
1257 } else {
1258 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb) &&
1259 (ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
1260 (vport->num_disc_nodes)) {
1261 spin_lock_irq(shost->host_lock);
1262 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1263 spin_unlock_irq(shost->host_lock);
1264
1265 lpfc_more_plogi(vport);
1266 if (vport->num_disc_nodes == 0) {
1267 spin_lock_irq(shost->host_lock);
1268 vport->fc_flag &= ~FC_NDISC_ACTIVE;
1269 spin_unlock_irq(shost->host_lock);
1270 lpfc_can_disctmo(vport);
1271 lpfc_end_rscn(vport);
1272 }
1273 }
1274 }
1275
1276 return ndlp->nlp_state;
1277}
1278
1279static uint32_t
1280lpfc_rcv_prli_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1281 void *arg, uint32_t evt)
1282{
1283 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1284 struct ls_rjt stat;
1285
1286 memset(&stat, 0, sizeof (struct ls_rjt));
1287 stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
1288 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
1289 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
1290 return ndlp->nlp_state;
1291}
1292
1293static uint32_t
1294lpfc_rcv_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1295 void *arg, uint32_t evt)
1296{
1297 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1298
1299
1300 if (vport->phba->sli_rev == LPFC_SLI_REV3)
1301 ndlp->nlp_rpi = cmdiocb->iocb.ulpIoTag;
1302
1303 lpfc_els_abort(vport->phba, ndlp);
1304
1305 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1306 return ndlp->nlp_state;
1307}
1308
1309static uint32_t
1310lpfc_rcv_els_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1311 void *arg, uint32_t evt)
1312{
1313 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1314 struct lpfc_hba *phba = vport->phba;
1315 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1316
1317
1318 lpfc_els_abort(phba, ndlp);
1319
1320 if (evt == NLP_EVT_RCV_LOGO) {
1321 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
1322 } else {
1323 lpfc_issue_els_logo(vport, ndlp, 0);
1324 }
1325
1326
1327 mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000 * 1));
1328 spin_lock_irq(shost->host_lock);
1329 ndlp->nlp_flag |= NLP_DELAY_TMO;
1330 spin_unlock_irq(shost->host_lock);
1331 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
1332 ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
1333 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1334
1335 return ndlp->nlp_state;
1336}
1337
1338static uint32_t
1339lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
1340 struct lpfc_nodelist *ndlp,
1341 void *arg,
1342 uint32_t evt)
1343{
1344 struct lpfc_hba *phba = vport->phba;
1345 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1346 struct lpfc_iocbq *cmdiocb, *rspiocb;
1347 struct lpfc_dmabuf *pcmd, *prsp, *mp;
1348 uint32_t *lp;
1349 uint32_t vid, flag;
1350 IOCB_t *irsp;
1351 struct serv_parm *sp;
1352 uint32_t ed_tov;
1353 LPFC_MBOXQ_t *mbox;
1354 int rc;
1355
1356 cmdiocb = (struct lpfc_iocbq *) arg;
1357 rspiocb = cmdiocb->context_un.rsp_iocb;
1358
1359 if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
1360
1361 return ndlp->nlp_state;
1362 }
1363
1364 irsp = &rspiocb->iocb;
1365
1366 if (irsp->ulpStatus)
1367 goto out;
1368
1369 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
1370
1371 prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
1372 if (!prsp)
1373 goto out;
1374
1375 lp = (uint32_t *) prsp->virt;
1376 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
1377
1378
1379 if ((ndlp->nlp_DID != FDMI_DID) &&
1380 (wwn_to_u64(sp->portName.u.wwn) == 0 ||
1381 wwn_to_u64(sp->nodeName.u.wwn) == 0)) {
1382 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
1383 "0142 PLOGI RSP: Invalid WWN.\n");
1384 goto out;
1385 }
1386 if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0))
1387 goto out;
1388
1389 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1390 "0121 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",
1391 ndlp->nlp_DID, ndlp->nlp_state,
1392 ndlp->nlp_flag, ndlp->nlp_rpi);
1393 if (vport->cfg_fcp_class == 2 && (sp->cls2.classValid))
1394 ndlp->nlp_fcp_info |= CLASS2;
1395 else
1396 ndlp->nlp_fcp_info |= CLASS3;
1397
1398 ndlp->nlp_class_sup = 0;
1399 if (sp->cls1.classValid)
1400 ndlp->nlp_class_sup |= FC_COS_CLASS1;
1401 if (sp->cls2.classValid)
1402 ndlp->nlp_class_sup |= FC_COS_CLASS2;
1403 if (sp->cls3.classValid)
1404 ndlp->nlp_class_sup |= FC_COS_CLASS3;
1405 if (sp->cls4.classValid)
1406 ndlp->nlp_class_sup |= FC_COS_CLASS4;
1407 ndlp->nlp_maxframe =
1408 ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
1409
1410 if ((vport->fc_flag & FC_PT2PT) &&
1411 (vport->fc_flag & FC_PT2PT_PLOGI)) {
1412 ed_tov = be32_to_cpu(sp->cmn.e_d_tov);
1413 if (sp->cmn.edtovResolution) {
1414
1415 ed_tov = (phba->fc_edtov + 999999) / 1000000;
1416 }
1417
1418 ndlp->nlp_flag &= ~NLP_SUPPRESS_RSP;
1419 if ((phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) &&
1420 sp->cmn.valid_vendor_ver_level) {
1421 vid = be32_to_cpu(sp->un.vv.vid);
1422 flag = be32_to_cpu(sp->un.vv.flags);
1423 if ((vid == LPFC_VV_EMLX_ID) &&
1424 (flag & LPFC_VV_SUPPRESS_RSP))
1425 ndlp->nlp_flag |= NLP_SUPPRESS_RSP;
1426 }
1427
1428
1429
1430
1431
1432 if (ed_tov > phba->fc_edtov)
1433 phba->fc_edtov = ed_tov;
1434 phba->fc_ratov = (2 * phba->fc_edtov) / 1000;
1435
1436 memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
1437
1438
1439 if (phba->sli_rev == LPFC_SLI_REV4) {
1440 lpfc_issue_reg_vfi(vport);
1441 } else {
1442 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1443 if (!mbox) {
1444 lpfc_printf_vlog(vport, KERN_ERR,
1445 LOG_TRACE_EVENT,
1446 "0133 PLOGI: no memory "
1447 "for config_link "
1448 "Data: x%x x%x x%x x%x\n",
1449 ndlp->nlp_DID, ndlp->nlp_state,
1450 ndlp->nlp_flag, ndlp->nlp_rpi);
1451 goto out;
1452 }
1453
1454 lpfc_config_link(phba, mbox);
1455
1456 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1457 mbox->vport = vport;
1458 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
1459 if (rc == MBX_NOT_FINISHED) {
1460 mempool_free(mbox, phba->mbox_mem_pool);
1461 goto out;
1462 }
1463 }
1464 }
1465
1466 lpfc_unreg_rpi(vport, ndlp);
1467
1468 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1469 if (!mbox) {
1470 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
1471 "0018 PLOGI: no memory for reg_login "
1472 "Data: x%x x%x x%x x%x\n",
1473 ndlp->nlp_DID, ndlp->nlp_state,
1474 ndlp->nlp_flag, ndlp->nlp_rpi);
1475 goto out;
1476 }
1477
1478 if (lpfc_reg_rpi(phba, vport->vpi, irsp->un.elsreq64.remoteID,
1479 (uint8_t *) sp, mbox, ndlp->nlp_rpi) == 0) {
1480 switch (ndlp->nlp_DID) {
1481 case NameServer_DID:
1482 mbox->mbox_cmpl = lpfc_mbx_cmpl_ns_reg_login;
1483 break;
1484 case FDMI_DID:
1485 mbox->mbox_cmpl = lpfc_mbx_cmpl_fdmi_reg_login;
1486 break;
1487 default:
1488 ndlp->nlp_flag |= NLP_REG_LOGIN_SEND;
1489 mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
1490 }
1491 mbox->ctx_ndlp = lpfc_nlp_get(ndlp);
1492 mbox->vport = vport;
1493 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
1494 != MBX_NOT_FINISHED) {
1495 lpfc_nlp_set_state(vport, ndlp,
1496 NLP_STE_REG_LOGIN_ISSUE);
1497 return ndlp->nlp_state;
1498 }
1499 if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND)
1500 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
1501
1502
1503
1504 lpfc_nlp_put(ndlp);
1505 mp = (struct lpfc_dmabuf *)mbox->ctx_buf;
1506 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1507 kfree(mp);
1508 mempool_free(mbox, phba->mbox_mem_pool);
1509
1510 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
1511 "0134 PLOGI: cannot issue reg_login "
1512 "Data: x%x x%x x%x x%x\n",
1513 ndlp->nlp_DID, ndlp->nlp_state,
1514 ndlp->nlp_flag, ndlp->nlp_rpi);
1515 } else {
1516 mempool_free(mbox, phba->mbox_mem_pool);
1517
1518 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
1519 "0135 PLOGI: cannot format reg_login "
1520 "Data: x%x x%x x%x x%x\n",
1521 ndlp->nlp_DID, ndlp->nlp_state,
1522 ndlp->nlp_flag, ndlp->nlp_rpi);
1523 }
1524
1525
1526out:
1527 if (ndlp->nlp_DID == NameServer_DID) {
1528 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
1529 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
1530 "0261 Cannot Register NameServer login\n");
1531 }
1532
1533
1534
1535
1536
1537
1538 ndlp->nlp_prev_state = ndlp->nlp_state;
1539 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1540 spin_lock_irq(shost->host_lock);
1541 ndlp->nlp_flag |= NLP_DEFER_RM;
1542 spin_unlock_irq(shost->host_lock);
1543 return NLP_STE_FREED_NODE;
1544}
1545
1546static uint32_t
1547lpfc_cmpl_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1548 void *arg, uint32_t evt)
1549{
1550 return ndlp->nlp_state;
1551}
1552
1553static uint32_t
1554lpfc_cmpl_reglogin_plogi_issue(struct lpfc_vport *vport,
1555 struct lpfc_nodelist *ndlp, void *arg, uint32_t evt)
1556{
1557 struct lpfc_hba *phba;
1558 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
1559 MAILBOX_t *mb = &pmb->u.mb;
1560 uint16_t rpi;
1561
1562 phba = vport->phba;
1563
1564 if (!(phba->pport->load_flag & FC_UNLOADING) &&
1565 !mb->mbxStatus) {
1566 rpi = pmb->u.mb.un.varWords[0];
1567 lpfc_release_rpi(phba, vport, ndlp, rpi);
1568 }
1569 return ndlp->nlp_state;
1570}
1571
1572static uint32_t
1573lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1574 void *arg, uint32_t evt)
1575{
1576 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1577
1578 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1579 spin_lock_irq(shost->host_lock);
1580 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1581 spin_unlock_irq(shost->host_lock);
1582 return ndlp->nlp_state;
1583 } else {
1584
1585 lpfc_els_abort(vport->phba, ndlp);
1586
1587 lpfc_drop_node(vport, ndlp);
1588 return NLP_STE_FREED_NODE;
1589 }
1590}
1591
1592static uint32_t
1593lpfc_device_recov_plogi_issue(struct lpfc_vport *vport,
1594 struct lpfc_nodelist *ndlp,
1595 void *arg,
1596 uint32_t evt)
1597{
1598 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1599 struct lpfc_hba *phba = vport->phba;
1600
1601
1602
1603
1604 if (vport->fc_flag & FC_RSCN_DEFERRED)
1605 return ndlp->nlp_state;
1606
1607
1608 lpfc_els_abort(phba, ndlp);
1609
1610 ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
1611 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1612 spin_lock_irq(shost->host_lock);
1613 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1614 spin_unlock_irq(shost->host_lock);
1615
1616 return ndlp->nlp_state;
1617}
1618
1619static uint32_t
1620lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1621 void *arg, uint32_t evt)
1622{
1623 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1624 struct lpfc_hba *phba = vport->phba;
1625 struct lpfc_iocbq *cmdiocb;
1626
1627
1628 lpfc_els_abort(phba, ndlp);
1629
1630 cmdiocb = (struct lpfc_iocbq *) arg;
1631
1632 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
1633 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1634 spin_lock_irq(shost->host_lock);
1635 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1636 spin_unlock_irq(shost->host_lock);
1637 if (vport->num_disc_nodes)
1638 lpfc_more_adisc(vport);
1639 }
1640 return ndlp->nlp_state;
1641 }
1642 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1643 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
1644 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
1645
1646 return ndlp->nlp_state;
1647}
1648
1649static uint32_t
1650lpfc_rcv_prli_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1651 void *arg, uint32_t evt)
1652{
1653 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1654
1655 if (lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
1656 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1657 return ndlp->nlp_state;
1658}
1659
1660static uint32_t
1661lpfc_rcv_logo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1662 void *arg, uint32_t evt)
1663{
1664 struct lpfc_hba *phba = vport->phba;
1665 struct lpfc_iocbq *cmdiocb;
1666
1667 cmdiocb = (struct lpfc_iocbq *) arg;
1668
1669
1670 lpfc_els_abort(phba, ndlp);
1671
1672 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1673 return ndlp->nlp_state;
1674}
1675
1676static uint32_t
1677lpfc_rcv_padisc_adisc_issue(struct lpfc_vport *vport,
1678 struct lpfc_nodelist *ndlp,
1679 void *arg, uint32_t evt)
1680{
1681 struct lpfc_iocbq *cmdiocb;
1682
1683 cmdiocb = (struct lpfc_iocbq *) arg;
1684
1685 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1686 return ndlp->nlp_state;
1687}
1688
1689static uint32_t
1690lpfc_rcv_prlo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1691 void *arg, uint32_t evt)
1692{
1693 struct lpfc_iocbq *cmdiocb;
1694
1695 cmdiocb = (struct lpfc_iocbq *) arg;
1696
1697
1698 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
1699 return ndlp->nlp_state;
1700}
1701
1702static uint32_t
1703lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport,
1704 struct lpfc_nodelist *ndlp,
1705 void *arg, uint32_t evt)
1706{
1707 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1708 struct lpfc_hba *phba = vport->phba;
1709 struct lpfc_iocbq *cmdiocb, *rspiocb;
1710 IOCB_t *irsp;
1711 ADISC *ap;
1712 int rc;
1713
1714 cmdiocb = (struct lpfc_iocbq *) arg;
1715 rspiocb = cmdiocb->context_un.rsp_iocb;
1716
1717 ap = (ADISC *)lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);
1718 irsp = &rspiocb->iocb;
1719
1720 if ((irsp->ulpStatus) ||
1721 (!lpfc_check_adisc(vport, ndlp, &ap->nodeName, &ap->portName))) {
1722
1723 mod_timer(&ndlp->nlp_delayfunc,
1724 jiffies + msecs_to_jiffies(1000));
1725 spin_lock_irq(shost->host_lock);
1726 ndlp->nlp_flag |= NLP_DELAY_TMO;
1727 spin_unlock_irq(shost->host_lock);
1728 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
1729
1730 memset(&ndlp->nlp_nodename, 0, sizeof(struct lpfc_name));
1731 memset(&ndlp->nlp_portname, 0, sizeof(struct lpfc_name));
1732
1733 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1734 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1735 lpfc_unreg_rpi(vport, ndlp);
1736 return ndlp->nlp_state;
1737 }
1738
1739 if (phba->sli_rev == LPFC_SLI_REV4) {
1740 rc = lpfc_sli4_resume_rpi(ndlp, NULL, NULL);
1741 if (rc) {
1742
1743 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1744 return ndlp->nlp_state;
1745 }
1746 }
1747
1748 if (ndlp->nlp_type & NLP_FCP_TARGET)
1749 ndlp->nlp_fc4_type |= NLP_FC4_FCP;
1750
1751 if (ndlp->nlp_type & NLP_NVME_TARGET)
1752 ndlp->nlp_fc4_type |= NLP_FC4_NVME;
1753
1754 if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET)) {
1755 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1756 lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
1757 } else {
1758 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1759 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1760 }
1761
1762 return ndlp->nlp_state;
1763}
1764
1765static uint32_t
1766lpfc_device_rm_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1767 void *arg, uint32_t evt)
1768{
1769 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1770
1771 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1772 spin_lock_irq(shost->host_lock);
1773 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1774 spin_unlock_irq(shost->host_lock);
1775 return ndlp->nlp_state;
1776 } else {
1777
1778 lpfc_els_abort(vport->phba, ndlp);
1779
1780 lpfc_drop_node(vport, ndlp);
1781 return NLP_STE_FREED_NODE;
1782 }
1783}
1784
1785static uint32_t
1786lpfc_device_recov_adisc_issue(struct lpfc_vport *vport,
1787 struct lpfc_nodelist *ndlp,
1788 void *arg,
1789 uint32_t evt)
1790{
1791 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1792 struct lpfc_hba *phba = vport->phba;
1793
1794
1795
1796
1797 if (vport->fc_flag & FC_RSCN_DEFERRED)
1798 return ndlp->nlp_state;
1799
1800
1801 lpfc_els_abort(phba, ndlp);
1802
1803 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1804 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1805 spin_lock_irq(shost->host_lock);
1806 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1807 spin_unlock_irq(shost->host_lock);
1808 lpfc_disc_set_adisc(vport, ndlp);
1809 return ndlp->nlp_state;
1810}
1811
1812static uint32_t
1813lpfc_rcv_plogi_reglogin_issue(struct lpfc_vport *vport,
1814 struct lpfc_nodelist *ndlp,
1815 void *arg,
1816 uint32_t evt)
1817{
1818 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1819
1820 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
1821 return ndlp->nlp_state;
1822}
1823
1824static uint32_t
1825lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport,
1826 struct lpfc_nodelist *ndlp,
1827 void *arg,
1828 uint32_t evt)
1829{
1830 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1831 struct ls_rjt stat;
1832
1833 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb)) {
1834 return ndlp->nlp_state;
1835 }
1836 if (vport->phba->nvmet_support) {
1837
1838
1839
1840
1841 if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
1842 lpfc_rcv_prli(vport, ndlp, cmdiocb);
1843 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1844 } else {
1845
1846
1847
1848
1849 memset(&stat, 0, sizeof(struct ls_rjt));
1850 stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
1851 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
1852 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
1853 ndlp, NULL);
1854 return ndlp->nlp_state;
1855 }
1856 } else {
1857
1858 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1859 }
1860 return ndlp->nlp_state;
1861}
1862
1863static uint32_t
1864lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
1865 struct lpfc_nodelist *ndlp,
1866 void *arg,
1867 uint32_t evt)
1868{
1869 struct lpfc_hba *phba = vport->phba;
1870 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1871 LPFC_MBOXQ_t *mb;
1872 LPFC_MBOXQ_t *nextmb;
1873 struct lpfc_dmabuf *mp;
1874 struct lpfc_nodelist *ns_ndlp;
1875
1876 cmdiocb = (struct lpfc_iocbq *) arg;
1877
1878
1879 if ((mb = phba->sli.mbox_active)) {
1880 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
1881 (ndlp == (struct lpfc_nodelist *)mb->ctx_ndlp)) {
1882 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
1883 lpfc_nlp_put(ndlp);
1884 mb->ctx_ndlp = NULL;
1885 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1886 }
1887 }
1888
1889 spin_lock_irq(&phba->hbalock);
1890 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
1891 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
1892 (ndlp == (struct lpfc_nodelist *)mb->ctx_ndlp)) {
1893 mp = (struct lpfc_dmabuf *)(mb->ctx_buf);
1894 if (mp) {
1895 __lpfc_mbuf_free(phba, mp->virt, mp->phys);
1896 kfree(mp);
1897 }
1898 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
1899 lpfc_nlp_put(ndlp);
1900 list_del(&mb->list);
1901 phba->sli.mboxq_cnt--;
1902 mempool_free(mb, phba->mbox_mem_pool);
1903 }
1904 }
1905 spin_unlock_irq(&phba->hbalock);
1906
1907
1908 if (vport->cfg_enable_fc4_type != LPFC_ENABLE_FCP) {
1909 ns_ndlp = lpfc_findnode_did(vport, NameServer_DID);
1910 if (ns_ndlp && NLP_CHK_NODE_ACT(ns_ndlp))
1911 lpfc_els_abort(phba, ns_ndlp);
1912 }
1913
1914 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1915 return ndlp->nlp_state;
1916}
1917
1918static uint32_t
1919lpfc_rcv_padisc_reglogin_issue(struct lpfc_vport *vport,
1920 struct lpfc_nodelist *ndlp,
1921 void *arg,
1922 uint32_t evt)
1923{
1924 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1925
1926 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1927 return ndlp->nlp_state;
1928}
1929
1930static uint32_t
1931lpfc_rcv_prlo_reglogin_issue(struct lpfc_vport *vport,
1932 struct lpfc_nodelist *ndlp,
1933 void *arg,
1934 uint32_t evt)
1935{
1936 struct lpfc_iocbq *cmdiocb;
1937
1938 cmdiocb = (struct lpfc_iocbq *) arg;
1939 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
1940 return ndlp->nlp_state;
1941}
1942
1943static uint32_t
1944lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
1945 struct lpfc_nodelist *ndlp,
1946 void *arg,
1947 uint32_t evt)
1948{
1949 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1950 struct lpfc_hba *phba = vport->phba;
1951 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
1952 MAILBOX_t *mb = &pmb->u.mb;
1953 uint32_t did = mb->un.varWords[1];
1954
1955 if (mb->mbxStatus) {
1956
1957 lpfc_printf_vlog(vport, KERN_ERR, LOG_TRACE_EVENT,
1958 "0246 RegLogin failed Data: x%x x%x x%x x%x "
1959 "x%x\n",
1960 did, mb->mbxStatus, vport->port_state,
1961 mb->un.varRegLogin.vpi,
1962 mb->un.varRegLogin.rpi);
1963
1964
1965
1966
1967 if (mb->mbxStatus == MBXERR_RPI_FULL) {
1968 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1969 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1970 return ndlp->nlp_state;
1971 }
1972
1973
1974 mod_timer(&ndlp->nlp_delayfunc,
1975 jiffies + msecs_to_jiffies(1000 * 1));
1976 spin_lock_irq(shost->host_lock);
1977 ndlp->nlp_flag |= NLP_DELAY_TMO;
1978 spin_unlock_irq(shost->host_lock);
1979 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
1980
1981 lpfc_issue_els_logo(vport, ndlp, 0);
1982 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1983 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1984 return ndlp->nlp_state;
1985 }
1986
1987
1988 if (phba->sli_rev < LPFC_SLI_REV4)
1989 ndlp->nlp_rpi = mb->un.varWords[0];
1990
1991 ndlp->nlp_flag |= NLP_RPI_REGISTERED;
1992
1993
1994 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1995 "3066 RegLogin Complete on x%x x%x x%x\n",
1996 did, ndlp->nlp_type, ndlp->nlp_fc4_type);
1997 if (!(ndlp->nlp_type & NLP_FABRIC) &&
1998 (phba->nvmet_support == 0)) {
1999
2000
2001
2002
2003
2004 if (vport->fc_flag & FC_PT2PT) {
2005
2006
2007
2008
2009 ndlp->nlp_fc4_type |= NLP_FC4_FCP;
2010 if ((vport->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
2011 (vport->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
2012 ndlp->nlp_fc4_type |= NLP_FC4_NVME;
2013
2014 lpfc_nvme_update_localport(vport);
2015 }
2016
2017 } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
2018 ndlp->nlp_fc4_type |= NLP_FC4_FCP;
2019
2020 } else if (ndlp->nlp_fc4_type == 0) {
2021
2022
2023
2024
2025 if (vport->cfg_enable_fc4_type != LPFC_ENABLE_FCP) {
2026 lpfc_ns_cmd(vport, SLI_CTNS_GFT_ID, 0,
2027 ndlp->nlp_DID);
2028 return ndlp->nlp_state;
2029 }
2030 ndlp->nlp_fc4_type = NLP_FC4_FCP;
2031 }
2032
2033 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
2034 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
2035 if (lpfc_issue_els_prli(vport, ndlp, 0)) {
2036 lpfc_issue_els_logo(vport, ndlp, 0);
2037 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
2038 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2039 }
2040 } else {
2041 if ((vport->fc_flag & FC_PT2PT) && phba->nvmet_support)
2042 phba->targetport->port_id = vport->fc_myDID;
2043
2044
2045
2046
2047 if (ndlp->nlp_type & NLP_FABRIC) {
2048 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
2049 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
2050 }
2051 }
2052 return ndlp->nlp_state;
2053}
2054
2055static uint32_t
2056lpfc_device_rm_reglogin_issue(struct lpfc_vport *vport,
2057 struct lpfc_nodelist *ndlp,
2058 void *arg,
2059 uint32_t evt)
2060{
2061 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2062
2063 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
2064 spin_lock_irq(shost->host_lock);
2065 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
2066 spin_unlock_irq(shost->host_lock);
2067 return ndlp->nlp_state;
2068 } else {
2069 lpfc_drop_node(vport, ndlp);
2070 return NLP_STE_FREED_NODE;
2071 }
2072}
2073
2074static uint32_t
2075lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport,
2076 struct lpfc_nodelist *ndlp,
2077 void *arg,
2078 uint32_t evt)
2079{
2080 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2081
2082
2083
2084
2085 if (vport->fc_flag & FC_RSCN_DEFERRED)
2086 return ndlp->nlp_state;
2087
2088 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
2089 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2090 spin_lock_irq(shost->host_lock);
2091
2092
2093
2094
2095 if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED) ||
2096 !vport->phba->nvmet_support)
2097 ndlp->nlp_flag |= NLP_IGNR_REG_CMPL;
2098
2099 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2100 spin_unlock_irq(shost->host_lock);
2101 lpfc_disc_set_adisc(vport, ndlp);
2102 return ndlp->nlp_state;
2103}
2104
2105static uint32_t
2106lpfc_rcv_plogi_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2107 void *arg, uint32_t evt)
2108{
2109 struct lpfc_iocbq *cmdiocb;
2110
2111 cmdiocb = (struct lpfc_iocbq *) arg;
2112
2113 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
2114 return ndlp->nlp_state;
2115}
2116
2117static uint32_t
2118lpfc_rcv_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2119 void *arg, uint32_t evt)
2120{
2121 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2122
2123 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
2124 return ndlp->nlp_state;
2125 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
2126 return ndlp->nlp_state;
2127}
2128
2129static uint32_t
2130lpfc_rcv_logo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2131 void *arg, uint32_t evt)
2132{
2133 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2134
2135
2136 lpfc_els_abort(vport->phba, ndlp);
2137
2138 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
2139 return ndlp->nlp_state;
2140}
2141
2142static uint32_t
2143lpfc_rcv_padisc_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2144 void *arg, uint32_t evt)
2145{
2146 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2147
2148 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
2149 return ndlp->nlp_state;
2150}
2151
2152
2153
2154
2155
2156
2157static uint32_t
2158lpfc_rcv_prlo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2159 void *arg, uint32_t evt)
2160{
2161 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2162
2163 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
2164 return ndlp->nlp_state;
2165}
2166
2167static uint32_t
2168lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2169 void *arg, uint32_t evt)
2170{
2171 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2172 struct lpfc_iocbq *cmdiocb, *rspiocb;
2173 struct lpfc_hba *phba = vport->phba;
2174 IOCB_t *irsp;
2175 PRLI *npr;
2176 struct lpfc_nvme_prli *nvpr;
2177 void *temp_ptr;
2178
2179 cmdiocb = (struct lpfc_iocbq *) arg;
2180 rspiocb = cmdiocb->context_un.rsp_iocb;
2181
2182
2183
2184
2185
2186 npr = NULL;
2187 nvpr = NULL;
2188 temp_ptr = lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);
2189 if (cmdiocb->iocb_flag & LPFC_PRLI_FCP_REQ)
2190 npr = (PRLI *) temp_ptr;
2191 else if (cmdiocb->iocb_flag & LPFC_PRLI_NVME_REQ)
2192 nvpr = (struct lpfc_nvme_prli *) temp_ptr;
2193
2194 irsp = &rspiocb->iocb;
2195 if (irsp->ulpStatus) {
2196 if ((vport->port_type == LPFC_NPIV_PORT) &&
2197 vport->cfg_restrict_login) {
2198 goto out;
2199 }
2200
2201
2202 if (npr)
2203 ndlp->nlp_fc4_type &= ~NLP_FC4_FCP;
2204 if (nvpr)
2205 ndlp->nlp_fc4_type &= ~NLP_FC4_NVME;
2206
2207
2208 goto out_err;
2209 }
2210
2211 if (npr && (npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
2212 (npr->prliType == PRLI_FCP_TYPE)) {
2213 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
2214 "6028 FCP NPR PRLI Cmpl Init %d Target %d\n",
2215 npr->initiatorFunc,
2216 npr->targetFunc);
2217 if (npr->initiatorFunc)
2218 ndlp->nlp_type |= NLP_FCP_INITIATOR;
2219 if (npr->targetFunc) {
2220 ndlp->nlp_type |= NLP_FCP_TARGET;
2221 if (npr->writeXferRdyDis)
2222 ndlp->nlp_flag |= NLP_FIRSTBURST;
2223 }
2224 if (npr->Retry)
2225 ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
2226
2227 } else if (nvpr &&
2228 (bf_get_be32(prli_acc_rsp_code, nvpr) ==
2229 PRLI_REQ_EXECUTED) &&
2230 (bf_get_be32(prli_type_code, nvpr) ==
2231 PRLI_NVME_TYPE)) {
2232
2233
2234 if (bf_get_be32(prli_init, nvpr))
2235 ndlp->nlp_type |= NLP_NVME_INITIATOR;
2236
2237 if (phba->nsler && bf_get_be32(prli_nsler, nvpr) &&
2238 bf_get_be32(prli_conf, nvpr))
2239
2240 ndlp->nlp_nvme_info |= NLP_NVME_NSLER;
2241 else
2242 ndlp->nlp_nvme_info &= ~NLP_NVME_NSLER;
2243
2244
2245 if (bf_get_be32(prli_tgt, nvpr)) {
2246
2247
2248
2249
2250 ndlp->nlp_type |= NLP_NVME_TARGET;
2251 if (bf_get_be32(prli_disc, nvpr))
2252 ndlp->nlp_type |= NLP_NVME_DISCOVERY;
2253
2254
2255
2256
2257
2258
2259
2260 if ((bf_get_be32(prli_fba, nvpr) == 1) &&
2261 (phba->cfg_nvme_enable_fb) &&
2262 (!phba->nvmet_support)) {
2263
2264
2265
2266 ndlp->nlp_flag |= NLP_FIRSTBURST;
2267 ndlp->nvme_fb_size = bf_get_be32(prli_fb_sz,
2268 nvpr);
2269
2270
2271 if (ndlp->nvme_fb_size)
2272 ndlp->nvme_fb_size <<=
2273 LPFC_NVME_FB_SHIFT;
2274 else
2275 ndlp->nvme_fb_size = LPFC_NVME_MAX_FB;
2276 }
2277 }
2278
2279 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
2280 "6029 NVME PRLI Cmpl w1 x%08x "
2281 "w4 x%08x w5 x%08x flag x%x, "
2282 "fcp_info x%x nlp_type x%x\n",
2283 be32_to_cpu(nvpr->word1),
2284 be32_to_cpu(nvpr->word4),
2285 be32_to_cpu(nvpr->word5),
2286 ndlp->nlp_flag, ndlp->nlp_fcp_info,
2287 ndlp->nlp_type);
2288 }
2289 if (!(ndlp->nlp_type & NLP_FCP_TARGET) &&
2290 (vport->port_type == LPFC_NPIV_PORT) &&
2291 vport->cfg_restrict_login) {
2292out:
2293 spin_lock_irq(shost->host_lock);
2294 ndlp->nlp_flag |= NLP_TARGET_REMOVE;
2295 spin_unlock_irq(shost->host_lock);
2296 lpfc_issue_els_logo(vport, ndlp, 0);
2297
2298 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
2299 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2300 return ndlp->nlp_state;
2301 }
2302
2303out_err:
2304
2305
2306
2307 if (ndlp->fc4_prli_sent == 0) {
2308 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
2309 if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET))
2310 lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
2311 else if (ndlp->nlp_type &
2312 (NLP_FCP_INITIATOR | NLP_NVME_INITIATOR))
2313 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
2314 } else
2315 lpfc_printf_vlog(vport,
2316 KERN_INFO, LOG_ELS,
2317 "3067 PRLI's still outstanding "
2318 "on x%06x - count %d, Pend Node Mode "
2319 "transition...\n",
2320 ndlp->nlp_DID, ndlp->fc4_prli_sent);
2321
2322 return ndlp->nlp_state;
2323}
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343static uint32_t
2344lpfc_device_rm_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2345 void *arg, uint32_t evt)
2346{
2347 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2348
2349 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
2350 spin_lock_irq(shost->host_lock);
2351 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
2352 spin_unlock_irq(shost->host_lock);
2353 return ndlp->nlp_state;
2354 } else {
2355
2356 lpfc_els_abort(vport->phba, ndlp);
2357
2358 lpfc_drop_node(vport, ndlp);
2359 return NLP_STE_FREED_NODE;
2360 }
2361}
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380static uint32_t
2381lpfc_device_recov_prli_issue(struct lpfc_vport *vport,
2382 struct lpfc_nodelist *ndlp,
2383 void *arg,
2384 uint32_t evt)
2385{
2386 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2387 struct lpfc_hba *phba = vport->phba;
2388
2389
2390
2391
2392 if (vport->fc_flag & FC_RSCN_DEFERRED)
2393 return ndlp->nlp_state;
2394
2395
2396 lpfc_els_abort(phba, ndlp);
2397
2398 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
2399 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2400 spin_lock_irq(shost->host_lock);
2401 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2402 spin_unlock_irq(shost->host_lock);
2403 lpfc_disc_set_adisc(vport, ndlp);
2404 return ndlp->nlp_state;
2405}
2406
2407static uint32_t
2408lpfc_rcv_plogi_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2409 void *arg, uint32_t evt)
2410{
2411 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2412 struct ls_rjt stat;
2413
2414 memset(&stat, 0, sizeof(struct ls_rjt));
2415 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2416 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2417 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2418 return ndlp->nlp_state;
2419}
2420
2421static uint32_t
2422lpfc_rcv_prli_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2423 void *arg, uint32_t evt)
2424{
2425 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2426 struct ls_rjt stat;
2427
2428 memset(&stat, 0, sizeof(struct ls_rjt));
2429 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2430 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2431 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2432 return ndlp->nlp_state;
2433}
2434
2435static uint32_t
2436lpfc_rcv_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2437 void *arg, uint32_t evt)
2438{
2439 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2440 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2441
2442 spin_lock_irq(shost->host_lock);
2443 ndlp->nlp_flag |= NLP_LOGO_ACC;
2444 spin_unlock_irq(shost->host_lock);
2445 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
2446 return ndlp->nlp_state;
2447}
2448
2449static uint32_t
2450lpfc_rcv_padisc_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2451 void *arg, uint32_t evt)
2452{
2453 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2454 struct ls_rjt stat;
2455
2456 memset(&stat, 0, sizeof(struct ls_rjt));
2457 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2458 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2459 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2460 return ndlp->nlp_state;
2461}
2462
2463static uint32_t
2464lpfc_rcv_prlo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2465 void *arg, uint32_t evt)
2466{
2467 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2468 struct ls_rjt stat;
2469
2470 memset(&stat, 0, sizeof(struct ls_rjt));
2471 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2472 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2473 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2474 return ndlp->nlp_state;
2475}
2476
2477static uint32_t
2478lpfc_cmpl_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2479 void *arg, uint32_t evt)
2480{
2481 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2482
2483 ndlp->nlp_prev_state = NLP_STE_LOGO_ISSUE;
2484 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2485 spin_lock_irq(shost->host_lock);
2486 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2487 spin_unlock_irq(shost->host_lock);
2488 lpfc_disc_set_adisc(vport, ndlp);
2489 return ndlp->nlp_state;
2490}
2491
2492static uint32_t
2493lpfc_device_rm_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2494 void *arg, uint32_t evt)
2495{
2496
2497
2498
2499
2500
2501 lpfc_unreg_rpi(vport, ndlp);
2502
2503 lpfc_els_abort(vport->phba, ndlp);
2504 lpfc_drop_node(vport, ndlp);
2505 return NLP_STE_FREED_NODE;
2506}
2507
2508static uint32_t
2509lpfc_device_recov_logo_issue(struct lpfc_vport *vport,
2510 struct lpfc_nodelist *ndlp,
2511 void *arg, uint32_t evt)
2512{
2513
2514
2515
2516
2517
2518 return ndlp->nlp_state;
2519}
2520
2521static uint32_t
2522lpfc_rcv_plogi_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2523 void *arg, uint32_t evt)
2524{
2525 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2526
2527 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
2528 return ndlp->nlp_state;
2529}
2530
2531static uint32_t
2532lpfc_rcv_prli_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2533 void *arg, uint32_t evt)
2534{
2535 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2536
2537 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
2538 return ndlp->nlp_state;
2539
2540 lpfc_rcv_prli(vport, ndlp, cmdiocb);
2541 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
2542 return ndlp->nlp_state;
2543}
2544
2545static uint32_t
2546lpfc_rcv_logo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2547 void *arg, uint32_t evt)
2548{
2549 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2550
2551 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
2552 return ndlp->nlp_state;
2553}
2554
2555static uint32_t
2556lpfc_rcv_padisc_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2557 void *arg, uint32_t evt)
2558{
2559 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2560
2561 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
2562 return ndlp->nlp_state;
2563}
2564
2565static uint32_t
2566lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2567 void *arg, uint32_t evt)
2568{
2569 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2570
2571 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
2572 return ndlp->nlp_state;
2573}
2574
2575static uint32_t
2576lpfc_device_recov_unmap_node(struct lpfc_vport *vport,
2577 struct lpfc_nodelist *ndlp,
2578 void *arg,
2579 uint32_t evt)
2580{
2581 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2582
2583 ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE;
2584 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2585 spin_lock_irq(shost->host_lock);
2586 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2587 ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);
2588 spin_unlock_irq(shost->host_lock);
2589 lpfc_disc_set_adisc(vport, ndlp);
2590
2591 return ndlp->nlp_state;
2592}
2593
2594static uint32_t
2595lpfc_rcv_plogi_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2596 void *arg, uint32_t evt)
2597{
2598 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2599
2600 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
2601 return ndlp->nlp_state;
2602}
2603
2604static uint32_t
2605lpfc_rcv_prli_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2606 void *arg, uint32_t evt)
2607{
2608 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2609
2610 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
2611 return ndlp->nlp_state;
2612 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
2613 return ndlp->nlp_state;
2614}
2615
2616static uint32_t
2617lpfc_rcv_logo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2618 void *arg, uint32_t evt)
2619{
2620 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2621
2622 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
2623 return ndlp->nlp_state;
2624}
2625
2626static uint32_t
2627lpfc_rcv_padisc_mapped_node(struct lpfc_vport *vport,
2628 struct lpfc_nodelist *ndlp,
2629 void *arg, uint32_t evt)
2630{
2631 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2632
2633 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
2634 return ndlp->nlp_state;
2635}
2636
2637static uint32_t
2638lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2639 void *arg, uint32_t evt)
2640{
2641 struct lpfc_hba *phba = vport->phba;
2642 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2643
2644
2645 lpfc_sli_abort_iocb(vport, &phba->sli.sli3_ring[LPFC_FCP_RING],
2646 ndlp->nlp_sid, 0, LPFC_CTX_TGT);
2647
2648
2649 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
2650 return ndlp->nlp_state;
2651}
2652
2653static uint32_t
2654lpfc_device_recov_mapped_node(struct lpfc_vport *vport,
2655 struct lpfc_nodelist *ndlp,
2656 void *arg,
2657 uint32_t evt)
2658{
2659 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2660
2661 ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE;
2662 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2663 spin_lock_irq(shost->host_lock);
2664 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2665 ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);
2666 spin_unlock_irq(shost->host_lock);
2667 lpfc_disc_set_adisc(vport, ndlp);
2668 return ndlp->nlp_state;
2669}
2670
2671static uint32_t
2672lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2673 void *arg, uint32_t evt)
2674{
2675 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2676 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2677
2678
2679 if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC))
2680 return ndlp->nlp_state;
2681 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
2682 lpfc_cancel_retry_delay_tmo(vport, ndlp);
2683 spin_lock_irq(shost->host_lock);
2684 ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC);
2685 spin_unlock_irq(shost->host_lock);
2686 } else if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
2687
2688 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
2689 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2690 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2691 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
2692 }
2693 }
2694 return ndlp->nlp_state;
2695}
2696
2697static uint32_t
2698lpfc_rcv_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2699 void *arg, uint32_t evt)
2700{
2701 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2702 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2703 struct ls_rjt stat;
2704
2705 memset(&stat, 0, sizeof (struct ls_rjt));
2706 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2707 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2708 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2709
2710 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
2711 if (ndlp->nlp_flag & NLP_NPR_ADISC) {
2712 spin_lock_irq(shost->host_lock);
2713 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2714 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2715 spin_unlock_irq(shost->host_lock);
2716 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2717 lpfc_issue_els_adisc(vport, ndlp, 0);
2718 } else {
2719 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2720 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2721 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
2722 }
2723 }
2724 return ndlp->nlp_state;
2725}
2726
2727static uint32_t
2728lpfc_rcv_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2729 void *arg, uint32_t evt)
2730{
2731 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2732
2733 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
2734 return ndlp->nlp_state;
2735}
2736
2737static uint32_t
2738lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2739 void *arg, uint32_t evt)
2740{
2741 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2742
2743 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
2744
2745
2746
2747
2748
2749 if (!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
2750 !(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
2751 if (ndlp->nlp_flag & NLP_NPR_ADISC) {
2752 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2753 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2754 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2755 lpfc_issue_els_adisc(vport, ndlp, 0);
2756 } else {
2757 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2758 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2759 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
2760 }
2761 }
2762 return ndlp->nlp_state;
2763}
2764
2765static uint32_t
2766lpfc_rcv_prlo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2767 void *arg, uint32_t evt)
2768{
2769 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2770 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2771
2772 spin_lock_irq(shost->host_lock);
2773 ndlp->nlp_flag |= NLP_LOGO_ACC;
2774 spin_unlock_irq(shost->host_lock);
2775
2776 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
2777
2778 if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) {
2779 mod_timer(&ndlp->nlp_delayfunc,
2780 jiffies + msecs_to_jiffies(1000 * 1));
2781 spin_lock_irq(shost->host_lock);
2782 ndlp->nlp_flag |= NLP_DELAY_TMO;
2783 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2784 spin_unlock_irq(shost->host_lock);
2785 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
2786 } else {
2787 spin_lock_irq(shost->host_lock);
2788 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2789 spin_unlock_irq(shost->host_lock);
2790 }
2791 return ndlp->nlp_state;
2792}
2793
2794static uint32_t
2795lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2796 void *arg, uint32_t evt)
2797{
2798 struct lpfc_iocbq *cmdiocb, *rspiocb;
2799 IOCB_t *irsp;
2800 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2801
2802 cmdiocb = (struct lpfc_iocbq *) arg;
2803 rspiocb = cmdiocb->context_un.rsp_iocb;
2804
2805 irsp = &rspiocb->iocb;
2806 if (irsp->ulpStatus) {
2807 spin_lock_irq(shost->host_lock);
2808 ndlp->nlp_flag |= NLP_DEFER_RM;
2809 spin_unlock_irq(shost->host_lock);
2810 return NLP_STE_FREED_NODE;
2811 }
2812 return ndlp->nlp_state;
2813}
2814
2815static uint32_t
2816lpfc_cmpl_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2817 void *arg, uint32_t evt)
2818{
2819 struct lpfc_iocbq *cmdiocb, *rspiocb;
2820 IOCB_t *irsp;
2821
2822 cmdiocb = (struct lpfc_iocbq *) arg;
2823 rspiocb = cmdiocb->context_un.rsp_iocb;
2824
2825 irsp = &rspiocb->iocb;
2826 if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
2827 lpfc_drop_node(vport, ndlp);
2828 return NLP_STE_FREED_NODE;
2829 }
2830 return ndlp->nlp_state;
2831}
2832
2833static uint32_t
2834lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2835 void *arg, uint32_t evt)
2836{
2837 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2838
2839
2840 if (ndlp->nlp_DID == Fabric_DID) {
2841 spin_lock_irq(shost->host_lock);
2842 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
2843 spin_unlock_irq(shost->host_lock);
2844 }
2845 lpfc_unreg_rpi(vport, ndlp);
2846 return ndlp->nlp_state;
2847}
2848
2849static uint32_t
2850lpfc_cmpl_adisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2851 void *arg, uint32_t evt)
2852{
2853 struct lpfc_iocbq *cmdiocb, *rspiocb;
2854 IOCB_t *irsp;
2855
2856 cmdiocb = (struct lpfc_iocbq *) arg;
2857 rspiocb = cmdiocb->context_un.rsp_iocb;
2858
2859 irsp = &rspiocb->iocb;
2860 if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
2861 lpfc_drop_node(vport, ndlp);
2862 return NLP_STE_FREED_NODE;
2863 }
2864 return ndlp->nlp_state;
2865}
2866
2867static uint32_t
2868lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport,
2869 struct lpfc_nodelist *ndlp,
2870 void *arg, uint32_t evt)
2871{
2872 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
2873 MAILBOX_t *mb = &pmb->u.mb;
2874
2875 if (!mb->mbxStatus) {
2876
2877 if (vport->phba->sli_rev < LPFC_SLI_REV4)
2878 ndlp->nlp_rpi = mb->un.varWords[0];
2879 ndlp->nlp_flag |= NLP_RPI_REGISTERED;
2880 if (ndlp->nlp_flag & NLP_LOGO_ACC) {
2881 lpfc_unreg_rpi(vport, ndlp);
2882 }
2883 } else {
2884 if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
2885 lpfc_drop_node(vport, ndlp);
2886 return NLP_STE_FREED_NODE;
2887 }
2888 }
2889 return ndlp->nlp_state;
2890}
2891
2892static uint32_t
2893lpfc_device_rm_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2894 void *arg, uint32_t evt)
2895{
2896 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2897
2898 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
2899 spin_lock_irq(shost->host_lock);
2900 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
2901 spin_unlock_irq(shost->host_lock);
2902 return ndlp->nlp_state;
2903 }
2904 lpfc_drop_node(vport, ndlp);
2905 return NLP_STE_FREED_NODE;
2906}
2907
2908static uint32_t
2909lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2910 void *arg, uint32_t evt)
2911{
2912 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2913
2914
2915
2916
2917 if (vport->fc_flag & FC_RSCN_DEFERRED)
2918 return ndlp->nlp_state;
2919
2920 lpfc_cancel_retry_delay_tmo(vport, ndlp);
2921 spin_lock_irq(shost->host_lock);
2922 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2923 ndlp->nlp_fc4_type &= ~(NLP_FC4_FCP | NLP_FC4_NVME);
2924 spin_unlock_irq(shost->host_lock);
2925 return ndlp->nlp_state;
2926}
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
2986 (struct lpfc_vport *, struct lpfc_nodelist *, void *, uint32_t) = {
2987
2988 lpfc_rcv_plogi_unused_node,
2989 lpfc_rcv_els_unused_node,
2990 lpfc_rcv_logo_unused_node,
2991 lpfc_rcv_els_unused_node,
2992 lpfc_rcv_els_unused_node,
2993 lpfc_rcv_els_unused_node,
2994 lpfc_disc_illegal,
2995 lpfc_disc_illegal,
2996 lpfc_cmpl_logo_unused_node,
2997 lpfc_disc_illegal,
2998 lpfc_disc_illegal,
2999 lpfc_device_rm_unused_node,
3000 lpfc_device_recov_unused_node,
3001
3002 lpfc_rcv_plogi_plogi_issue,
3003 lpfc_rcv_prli_plogi_issue,
3004 lpfc_rcv_logo_plogi_issue,
3005 lpfc_rcv_els_plogi_issue,
3006 lpfc_rcv_els_plogi_issue,
3007 lpfc_rcv_els_plogi_issue,
3008 lpfc_cmpl_plogi_plogi_issue,
3009 lpfc_disc_illegal,
3010 lpfc_cmpl_logo_plogi_issue,
3011 lpfc_disc_illegal,
3012 lpfc_cmpl_reglogin_plogi_issue,
3013 lpfc_device_rm_plogi_issue,
3014 lpfc_device_recov_plogi_issue,
3015
3016 lpfc_rcv_plogi_adisc_issue,
3017 lpfc_rcv_prli_adisc_issue,
3018 lpfc_rcv_logo_adisc_issue,
3019 lpfc_rcv_padisc_adisc_issue,
3020 lpfc_rcv_padisc_adisc_issue,
3021 lpfc_rcv_prlo_adisc_issue,
3022 lpfc_disc_illegal,
3023 lpfc_disc_illegal,
3024 lpfc_disc_illegal,
3025 lpfc_cmpl_adisc_adisc_issue,
3026 lpfc_disc_illegal,
3027 lpfc_device_rm_adisc_issue,
3028 lpfc_device_recov_adisc_issue,
3029
3030 lpfc_rcv_plogi_reglogin_issue,
3031 lpfc_rcv_prli_reglogin_issue,
3032 lpfc_rcv_logo_reglogin_issue,
3033 lpfc_rcv_padisc_reglogin_issue,
3034 lpfc_rcv_padisc_reglogin_issue,
3035 lpfc_rcv_prlo_reglogin_issue,
3036 lpfc_cmpl_plogi_illegal,
3037 lpfc_disc_illegal,
3038 lpfc_disc_illegal,
3039 lpfc_disc_illegal,
3040 lpfc_cmpl_reglogin_reglogin_issue,
3041 lpfc_device_rm_reglogin_issue,
3042 lpfc_device_recov_reglogin_issue,
3043
3044 lpfc_rcv_plogi_prli_issue,
3045 lpfc_rcv_prli_prli_issue,
3046 lpfc_rcv_logo_prli_issue,
3047 lpfc_rcv_padisc_prli_issue,
3048 lpfc_rcv_padisc_prli_issue,
3049 lpfc_rcv_prlo_prli_issue,
3050 lpfc_cmpl_plogi_illegal,
3051 lpfc_cmpl_prli_prli_issue,
3052 lpfc_disc_illegal,
3053 lpfc_disc_illegal,
3054 lpfc_disc_illegal,
3055 lpfc_device_rm_prli_issue,
3056 lpfc_device_recov_prli_issue,
3057
3058 lpfc_rcv_plogi_logo_issue,
3059 lpfc_rcv_prli_logo_issue,
3060 lpfc_rcv_logo_logo_issue,
3061 lpfc_rcv_padisc_logo_issue,
3062 lpfc_rcv_padisc_logo_issue,
3063 lpfc_rcv_prlo_logo_issue,
3064 lpfc_cmpl_plogi_illegal,
3065 lpfc_disc_illegal,
3066 lpfc_cmpl_logo_logo_issue,
3067 lpfc_disc_illegal,
3068 lpfc_disc_illegal,
3069 lpfc_device_rm_logo_issue,
3070 lpfc_device_recov_logo_issue,
3071
3072 lpfc_rcv_plogi_unmap_node,
3073 lpfc_rcv_prli_unmap_node,
3074 lpfc_rcv_logo_unmap_node,
3075 lpfc_rcv_padisc_unmap_node,
3076 lpfc_rcv_padisc_unmap_node,
3077 lpfc_rcv_prlo_unmap_node,
3078 lpfc_disc_illegal,
3079 lpfc_disc_illegal,
3080 lpfc_disc_illegal,
3081 lpfc_disc_illegal,
3082 lpfc_disc_illegal,
3083 lpfc_disc_illegal,
3084 lpfc_device_recov_unmap_node,
3085
3086 lpfc_rcv_plogi_mapped_node,
3087 lpfc_rcv_prli_mapped_node,
3088 lpfc_rcv_logo_mapped_node,
3089 lpfc_rcv_padisc_mapped_node,
3090 lpfc_rcv_padisc_mapped_node,
3091 lpfc_rcv_prlo_mapped_node,
3092 lpfc_disc_illegal,
3093 lpfc_disc_illegal,
3094 lpfc_disc_illegal,
3095 lpfc_disc_illegal,
3096 lpfc_disc_illegal,
3097 lpfc_disc_illegal,
3098 lpfc_device_recov_mapped_node,
3099
3100 lpfc_rcv_plogi_npr_node,
3101 lpfc_rcv_prli_npr_node,
3102 lpfc_rcv_logo_npr_node,
3103 lpfc_rcv_padisc_npr_node,
3104 lpfc_rcv_padisc_npr_node,
3105 lpfc_rcv_prlo_npr_node,
3106 lpfc_cmpl_plogi_npr_node,
3107 lpfc_cmpl_prli_npr_node,
3108 lpfc_cmpl_logo_npr_node,
3109 lpfc_cmpl_adisc_npr_node,
3110 lpfc_cmpl_reglogin_npr_node,
3111 lpfc_device_rm_npr_node,
3112 lpfc_device_recov_npr_node,
3113};
3114
3115int
3116lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
3117 void *arg, uint32_t evt)
3118{
3119 uint32_t cur_state, rc;
3120 uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *,
3121 uint32_t);
3122 uint32_t got_ndlp = 0;
3123 uint32_t data1;
3124
3125 if (lpfc_nlp_get(ndlp))
3126 got_ndlp = 1;
3127
3128 cur_state = ndlp->nlp_state;
3129
3130 data1 = (((uint32_t)ndlp->nlp_fc4_type << 16) |
3131 ((uint32_t)ndlp->nlp_type));
3132
3133 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
3134 "0211 DSM in event x%x on NPort x%x in "
3135 "state %d rpi x%x Data: x%x x%x\n",
3136 evt, ndlp->nlp_DID, cur_state, ndlp->nlp_rpi,
3137 ndlp->nlp_flag, data1);
3138
3139 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
3140 "DSM in: evt:%d ste:%d did:x%x",
3141 evt, cur_state, ndlp->nlp_DID);
3142
3143 func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt];
3144 rc = (func) (vport, ndlp, arg, evt);
3145
3146
3147 if (got_ndlp) {
3148 data1 = (((uint32_t)ndlp->nlp_fc4_type << 16) |
3149 ((uint32_t)ndlp->nlp_type));
3150 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
3151 "0212 DSM out state %d on NPort x%x "
3152 "rpi x%x Data: x%x x%x\n",
3153 rc, ndlp->nlp_DID, ndlp->nlp_rpi, ndlp->nlp_flag,
3154 data1);
3155
3156 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
3157 "DSM out: ste:%d did:x%x flg:x%x",
3158 rc, ndlp->nlp_DID, ndlp->nlp_flag);
3159
3160 lpfc_nlp_put(ndlp);
3161 } else {
3162 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
3163 "0213 DSM out state %d on NPort free\n", rc);
3164
3165 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
3166 "DSM out: ste:%d did:x%x flg:x%x",
3167 rc, 0, 0);
3168 }
3169
3170 return rc;
3171}
3172