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