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