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->context1;
539 ndlp = (struct lpfc_nodelist *) mboxq->context2;
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 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
840 return 0;
841 }
842
843 if (!(vport->fc_flag & FC_PT2PT)) {
844
845 if ((vport->cfg_use_adisc && (vport->fc_flag & FC_RSCN_MODE)) ||
846 ((ndlp->nlp_fcp_info & NLP_FCP_2_DEVICE) &&
847 (ndlp->nlp_type & NLP_FCP_TARGET))) {
848 spin_lock_irq(shost->host_lock);
849 ndlp->nlp_flag |= NLP_NPR_ADISC;
850 spin_unlock_irq(shost->host_lock);
851 return 1;
852 }
853 }
854 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
855 lpfc_unreg_rpi(vport, ndlp);
856 return 0;
857}
858
859
860
861
862
863
864
865
866
867
868void
869lpfc_release_rpi(struct lpfc_hba *phba,
870 struct lpfc_vport *vport,
871 uint16_t rpi)
872{
873 LPFC_MBOXQ_t *pmb;
874 int rc;
875
876 pmb = (LPFC_MBOXQ_t *) mempool_alloc(phba->mbox_mem_pool,
877 GFP_KERNEL);
878 if (!pmb)
879 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
880 "2796 mailbox memory allocation failed \n");
881 else {
882 lpfc_unreg_login(phba, vport->vpi, rpi, pmb);
883 pmb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
884 rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
885 if (rc == MBX_NOT_FINISHED)
886 mempool_free(pmb, phba->mbox_mem_pool);
887 }
888}
889
890static uint32_t
891lpfc_disc_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
892 void *arg, uint32_t evt)
893{
894 struct lpfc_hba *phba;
895 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
896 uint16_t rpi;
897
898 phba = vport->phba;
899
900 if (!(phba->pport->load_flag & FC_UNLOADING) &&
901 (evt == NLP_EVT_CMPL_REG_LOGIN) &&
902 (!pmb->u.mb.mbxStatus)) {
903 rpi = pmb->u.mb.un.varWords[0];
904 lpfc_release_rpi(phba, vport, rpi);
905 }
906 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
907 "0271 Illegal State Transition: node x%x "
908 "event x%x, state x%x Data: x%x x%x\n",
909 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
910 ndlp->nlp_flag);
911 return ndlp->nlp_state;
912}
913
914static uint32_t
915lpfc_cmpl_plogi_illegal(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
916 void *arg, uint32_t evt)
917{
918
919
920
921
922
923 if (!(ndlp->nlp_flag & NLP_RCV_PLOGI)) {
924 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
925 "0272 Illegal State Transition: node x%x "
926 "event x%x, state x%x Data: x%x x%x\n",
927 ndlp->nlp_DID, evt, ndlp->nlp_state, ndlp->nlp_rpi,
928 ndlp->nlp_flag);
929 }
930 return ndlp->nlp_state;
931}
932
933
934
935static uint32_t
936lpfc_rcv_plogi_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
937 void *arg, uint32_t evt)
938{
939 struct lpfc_iocbq *cmdiocb;
940
941 cmdiocb = (struct lpfc_iocbq *) arg;
942
943 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
944 return ndlp->nlp_state;
945 }
946 return NLP_STE_FREED_NODE;
947}
948
949static uint32_t
950lpfc_rcv_els_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
951 void *arg, uint32_t evt)
952{
953 lpfc_issue_els_logo(vport, ndlp, 0);
954 return ndlp->nlp_state;
955}
956
957static uint32_t
958lpfc_rcv_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
959 void *arg, uint32_t evt)
960{
961 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
962 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
963
964 spin_lock_irq(shost->host_lock);
965 ndlp->nlp_flag |= NLP_LOGO_ACC;
966 spin_unlock_irq(shost->host_lock);
967 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
968
969 return ndlp->nlp_state;
970}
971
972static uint32_t
973lpfc_cmpl_logo_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
974 void *arg, uint32_t evt)
975{
976 return NLP_STE_FREED_NODE;
977}
978
979static uint32_t
980lpfc_device_rm_unused_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
981 void *arg, uint32_t evt)
982{
983 return NLP_STE_FREED_NODE;
984}
985
986static uint32_t
987lpfc_device_recov_unused_node(struct lpfc_vport *vport,
988 struct lpfc_nodelist *ndlp,
989 void *arg, uint32_t evt)
990{
991 return ndlp->nlp_state;
992}
993
994static uint32_t
995lpfc_rcv_plogi_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
996 void *arg, uint32_t evt)
997{
998 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
999 struct lpfc_hba *phba = vport->phba;
1000 struct lpfc_iocbq *cmdiocb = arg;
1001 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
1002 uint32_t *lp = (uint32_t *) pcmd->virt;
1003 struct serv_parm *sp = (struct serv_parm *) (lp + 1);
1004 struct ls_rjt stat;
1005 int port_cmp;
1006
1007 memset(&stat, 0, sizeof (struct ls_rjt));
1008
1009
1010
1011
1012 phba->fc_stat.elsLogiCol++;
1013 port_cmp = memcmp(&vport->fc_portname, &sp->portName,
1014 sizeof(struct lpfc_name));
1015
1016 if (port_cmp >= 0) {
1017
1018
1019 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
1020 stat.un.b.lsRjtRsnCodeExp = LSEXP_CMD_IN_PROGRESS;
1021 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
1022 NULL);
1023 } else {
1024 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb) &&
1025 (ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
1026 (vport->num_disc_nodes)) {
1027 spin_lock_irq(shost->host_lock);
1028 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1029 spin_unlock_irq(shost->host_lock);
1030
1031 lpfc_more_plogi(vport);
1032 if (vport->num_disc_nodes == 0) {
1033 spin_lock_irq(shost->host_lock);
1034 vport->fc_flag &= ~FC_NDISC_ACTIVE;
1035 spin_unlock_irq(shost->host_lock);
1036 lpfc_can_disctmo(vport);
1037 lpfc_end_rscn(vport);
1038 }
1039 }
1040 }
1041
1042 return ndlp->nlp_state;
1043}
1044
1045static uint32_t
1046lpfc_rcv_prli_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1047 void *arg, uint32_t evt)
1048{
1049 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1050 struct ls_rjt stat;
1051
1052 memset(&stat, 0, sizeof (struct ls_rjt));
1053 stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
1054 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
1055 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
1056 return ndlp->nlp_state;
1057}
1058
1059static uint32_t
1060lpfc_rcv_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1061 void *arg, uint32_t evt)
1062{
1063 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1064
1065
1066 lpfc_els_abort(vport->phba, ndlp);
1067
1068 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1069 return ndlp->nlp_state;
1070}
1071
1072static uint32_t
1073lpfc_rcv_els_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1074 void *arg, uint32_t evt)
1075{
1076 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1077 struct lpfc_hba *phba = vport->phba;
1078 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1079
1080
1081 lpfc_els_abort(phba, ndlp);
1082
1083 if (evt == NLP_EVT_RCV_LOGO) {
1084 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
1085 } else {
1086 lpfc_issue_els_logo(vport, ndlp, 0);
1087 }
1088
1089
1090 mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000 * 1));
1091 spin_lock_irq(shost->host_lock);
1092 ndlp->nlp_flag |= NLP_DELAY_TMO;
1093 spin_unlock_irq(shost->host_lock);
1094 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
1095 ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
1096 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1097
1098 return ndlp->nlp_state;
1099}
1100
1101static uint32_t
1102lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
1103 struct lpfc_nodelist *ndlp,
1104 void *arg,
1105 uint32_t evt)
1106{
1107 struct lpfc_hba *phba = vport->phba;
1108 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1109 struct lpfc_iocbq *cmdiocb, *rspiocb;
1110 struct lpfc_dmabuf *pcmd, *prsp, *mp;
1111 uint32_t *lp;
1112 uint32_t vid, flag;
1113 IOCB_t *irsp;
1114 struct serv_parm *sp;
1115 uint32_t ed_tov;
1116 LPFC_MBOXQ_t *mbox;
1117 int rc;
1118
1119 cmdiocb = (struct lpfc_iocbq *) arg;
1120 rspiocb = cmdiocb->context_un.rsp_iocb;
1121
1122 if (ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
1123
1124 return ndlp->nlp_state;
1125 }
1126
1127 irsp = &rspiocb->iocb;
1128
1129 if (irsp->ulpStatus)
1130 goto out;
1131
1132 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
1133
1134 prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
1135 if (!prsp)
1136 goto out;
1137
1138 lp = (uint32_t *) prsp->virt;
1139 sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
1140
1141
1142 if ((ndlp->nlp_DID != FDMI_DID) &&
1143 (wwn_to_u64(sp->portName.u.wwn) == 0 ||
1144 wwn_to_u64(sp->nodeName.u.wwn) == 0)) {
1145 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1146 "0142 PLOGI RSP: Invalid WWN.\n");
1147 goto out;
1148 }
1149 if (!lpfc_check_sparm(vport, ndlp, sp, CLASS3, 0))
1150 goto out;
1151
1152 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1153 "0121 PLOGI chkparm OK Data: x%x x%x x%x x%x\n",
1154 ndlp->nlp_DID, ndlp->nlp_state,
1155 ndlp->nlp_flag, ndlp->nlp_rpi);
1156 if (vport->cfg_fcp_class == 2 && (sp->cls2.classValid))
1157 ndlp->nlp_fcp_info |= CLASS2;
1158 else
1159 ndlp->nlp_fcp_info |= CLASS3;
1160
1161 ndlp->nlp_class_sup = 0;
1162 if (sp->cls1.classValid)
1163 ndlp->nlp_class_sup |= FC_COS_CLASS1;
1164 if (sp->cls2.classValid)
1165 ndlp->nlp_class_sup |= FC_COS_CLASS2;
1166 if (sp->cls3.classValid)
1167 ndlp->nlp_class_sup |= FC_COS_CLASS3;
1168 if (sp->cls4.classValid)
1169 ndlp->nlp_class_sup |= FC_COS_CLASS4;
1170 ndlp->nlp_maxframe =
1171 ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) | sp->cmn.bbRcvSizeLsb;
1172
1173 if ((vport->fc_flag & FC_PT2PT) &&
1174 (vport->fc_flag & FC_PT2PT_PLOGI)) {
1175 ed_tov = be32_to_cpu(sp->cmn.e_d_tov);
1176 if (sp->cmn.edtovResolution) {
1177
1178 ed_tov = (phba->fc_edtov + 999999) / 1000000;
1179 }
1180
1181 ndlp->nlp_flag &= ~NLP_SUPPRESS_RSP;
1182 if ((phba->sli.sli_flag & LPFC_SLI_SUPPRESS_RSP) &&
1183 sp->cmn.valid_vendor_ver_level) {
1184 vid = be32_to_cpu(sp->un.vv.vid);
1185 flag = be32_to_cpu(sp->un.vv.flags);
1186 if ((vid == LPFC_VV_EMLX_ID) &&
1187 (flag & LPFC_VV_SUPPRESS_RSP))
1188 ndlp->nlp_flag |= NLP_SUPPRESS_RSP;
1189 }
1190
1191
1192
1193
1194
1195 if (ed_tov > phba->fc_edtov)
1196 phba->fc_edtov = ed_tov;
1197 phba->fc_ratov = (2 * phba->fc_edtov) / 1000;
1198
1199 memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
1200
1201
1202 if (phba->sli_rev == LPFC_SLI_REV4) {
1203 lpfc_issue_reg_vfi(vport);
1204 } else {
1205 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1206 if (!mbox) {
1207 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1208 "0133 PLOGI: no memory "
1209 "for config_link "
1210 "Data: x%x x%x x%x x%x\n",
1211 ndlp->nlp_DID, ndlp->nlp_state,
1212 ndlp->nlp_flag, ndlp->nlp_rpi);
1213 goto out;
1214 }
1215
1216 lpfc_config_link(phba, mbox);
1217
1218 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1219 mbox->vport = vport;
1220 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
1221 if (rc == MBX_NOT_FINISHED) {
1222 mempool_free(mbox, phba->mbox_mem_pool);
1223 goto out;
1224 }
1225 }
1226 }
1227
1228 lpfc_unreg_rpi(vport, ndlp);
1229
1230 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
1231 if (!mbox) {
1232 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1233 "0018 PLOGI: no memory for reg_login "
1234 "Data: x%x x%x x%x x%x\n",
1235 ndlp->nlp_DID, ndlp->nlp_state,
1236 ndlp->nlp_flag, ndlp->nlp_rpi);
1237 goto out;
1238 }
1239
1240 if (lpfc_reg_rpi(phba, vport->vpi, irsp->un.elsreq64.remoteID,
1241 (uint8_t *) sp, mbox, ndlp->nlp_rpi) == 0) {
1242 switch (ndlp->nlp_DID) {
1243 case NameServer_DID:
1244 mbox->mbox_cmpl = lpfc_mbx_cmpl_ns_reg_login;
1245 break;
1246 case FDMI_DID:
1247 mbox->mbox_cmpl = lpfc_mbx_cmpl_fdmi_reg_login;
1248 break;
1249 default:
1250 ndlp->nlp_flag |= NLP_REG_LOGIN_SEND;
1251 mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
1252 }
1253 mbox->context2 = lpfc_nlp_get(ndlp);
1254 mbox->vport = vport;
1255 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
1256 != MBX_NOT_FINISHED) {
1257 lpfc_nlp_set_state(vport, ndlp,
1258 NLP_STE_REG_LOGIN_ISSUE);
1259 return ndlp->nlp_state;
1260 }
1261 if (ndlp->nlp_flag & NLP_REG_LOGIN_SEND)
1262 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
1263
1264
1265
1266 lpfc_nlp_put(ndlp);
1267 mp = (struct lpfc_dmabuf *) mbox->context1;
1268 lpfc_mbuf_free(phba, mp->virt, mp->phys);
1269 kfree(mp);
1270 mempool_free(mbox, phba->mbox_mem_pool);
1271
1272 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1273 "0134 PLOGI: cannot issue reg_login "
1274 "Data: x%x x%x x%x x%x\n",
1275 ndlp->nlp_DID, ndlp->nlp_state,
1276 ndlp->nlp_flag, ndlp->nlp_rpi);
1277 } else {
1278 mempool_free(mbox, phba->mbox_mem_pool);
1279
1280 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1281 "0135 PLOGI: cannot format reg_login "
1282 "Data: x%x x%x x%x x%x\n",
1283 ndlp->nlp_DID, ndlp->nlp_state,
1284 ndlp->nlp_flag, ndlp->nlp_rpi);
1285 }
1286
1287
1288out:
1289 if (ndlp->nlp_DID == NameServer_DID) {
1290 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
1291 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1292 "0261 Cannot Register NameServer login\n");
1293 }
1294
1295
1296
1297
1298
1299
1300 ndlp->nlp_prev_state = ndlp->nlp_state;
1301 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1302 spin_lock_irq(shost->host_lock);
1303 ndlp->nlp_flag |= NLP_DEFER_RM;
1304 spin_unlock_irq(shost->host_lock);
1305 return NLP_STE_FREED_NODE;
1306}
1307
1308static uint32_t
1309lpfc_cmpl_logo_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1310 void *arg, uint32_t evt)
1311{
1312 return ndlp->nlp_state;
1313}
1314
1315static uint32_t
1316lpfc_cmpl_reglogin_plogi_issue(struct lpfc_vport *vport,
1317 struct lpfc_nodelist *ndlp, void *arg, uint32_t evt)
1318{
1319 struct lpfc_hba *phba;
1320 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
1321 MAILBOX_t *mb = &pmb->u.mb;
1322 uint16_t rpi;
1323
1324 phba = vport->phba;
1325
1326 if (!(phba->pport->load_flag & FC_UNLOADING) &&
1327 !mb->mbxStatus) {
1328 rpi = pmb->u.mb.un.varWords[0];
1329 lpfc_release_rpi(phba, vport, rpi);
1330 }
1331 return ndlp->nlp_state;
1332}
1333
1334static uint32_t
1335lpfc_device_rm_plogi_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1336 void *arg, uint32_t evt)
1337{
1338 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1339
1340 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1341 spin_lock_irq(shost->host_lock);
1342 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1343 spin_unlock_irq(shost->host_lock);
1344 return ndlp->nlp_state;
1345 } else {
1346
1347 lpfc_els_abort(vport->phba, ndlp);
1348
1349 lpfc_drop_node(vport, ndlp);
1350 return NLP_STE_FREED_NODE;
1351 }
1352}
1353
1354static uint32_t
1355lpfc_device_recov_plogi_issue(struct lpfc_vport *vport,
1356 struct lpfc_nodelist *ndlp,
1357 void *arg,
1358 uint32_t evt)
1359{
1360 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1361 struct lpfc_hba *phba = vport->phba;
1362
1363
1364
1365
1366 if (vport->fc_flag & FC_RSCN_DEFERRED)
1367 return ndlp->nlp_state;
1368
1369
1370 lpfc_els_abort(phba, ndlp);
1371
1372 ndlp->nlp_prev_state = NLP_STE_PLOGI_ISSUE;
1373 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1374 spin_lock_irq(shost->host_lock);
1375 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1376 spin_unlock_irq(shost->host_lock);
1377
1378 return ndlp->nlp_state;
1379}
1380
1381static uint32_t
1382lpfc_rcv_plogi_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1383 void *arg, uint32_t evt)
1384{
1385 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1386 struct lpfc_hba *phba = vport->phba;
1387 struct lpfc_iocbq *cmdiocb;
1388
1389
1390 lpfc_els_abort(phba, ndlp);
1391
1392 cmdiocb = (struct lpfc_iocbq *) arg;
1393
1394 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
1395 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1396 spin_lock_irq(shost->host_lock);
1397 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1398 spin_unlock_irq(shost->host_lock);
1399 if (vport->num_disc_nodes)
1400 lpfc_more_adisc(vport);
1401 }
1402 return ndlp->nlp_state;
1403 }
1404 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1405 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
1406 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
1407
1408 return ndlp->nlp_state;
1409}
1410
1411static uint32_t
1412lpfc_rcv_prli_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1413 void *arg, uint32_t evt)
1414{
1415 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1416
1417 if (lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
1418 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1419 return ndlp->nlp_state;
1420}
1421
1422static uint32_t
1423lpfc_rcv_logo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1424 void *arg, uint32_t evt)
1425{
1426 struct lpfc_hba *phba = vport->phba;
1427 struct lpfc_iocbq *cmdiocb;
1428
1429 cmdiocb = (struct lpfc_iocbq *) arg;
1430
1431
1432 lpfc_els_abort(phba, ndlp);
1433
1434 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1435 return ndlp->nlp_state;
1436}
1437
1438static uint32_t
1439lpfc_rcv_padisc_adisc_issue(struct lpfc_vport *vport,
1440 struct lpfc_nodelist *ndlp,
1441 void *arg, uint32_t evt)
1442{
1443 struct lpfc_iocbq *cmdiocb;
1444
1445 cmdiocb = (struct lpfc_iocbq *) arg;
1446
1447 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1448 return ndlp->nlp_state;
1449}
1450
1451static uint32_t
1452lpfc_rcv_prlo_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1453 void *arg, uint32_t evt)
1454{
1455 struct lpfc_iocbq *cmdiocb;
1456
1457 cmdiocb = (struct lpfc_iocbq *) arg;
1458
1459
1460 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
1461 return ndlp->nlp_state;
1462}
1463
1464static uint32_t
1465lpfc_cmpl_adisc_adisc_issue(struct lpfc_vport *vport,
1466 struct lpfc_nodelist *ndlp,
1467 void *arg, uint32_t evt)
1468{
1469 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1470 struct lpfc_hba *phba = vport->phba;
1471 struct lpfc_iocbq *cmdiocb, *rspiocb;
1472 IOCB_t *irsp;
1473 ADISC *ap;
1474 int rc;
1475
1476 cmdiocb = (struct lpfc_iocbq *) arg;
1477 rspiocb = cmdiocb->context_un.rsp_iocb;
1478
1479 ap = (ADISC *)lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);
1480 irsp = &rspiocb->iocb;
1481
1482 if ((irsp->ulpStatus) ||
1483 (!lpfc_check_adisc(vport, ndlp, &ap->nodeName, &ap->portName))) {
1484
1485 mod_timer(&ndlp->nlp_delayfunc,
1486 jiffies + msecs_to_jiffies(1000));
1487 spin_lock_irq(shost->host_lock);
1488 ndlp->nlp_flag |= NLP_DELAY_TMO;
1489 spin_unlock_irq(shost->host_lock);
1490 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
1491
1492 memset(&ndlp->nlp_nodename, 0, sizeof(struct lpfc_name));
1493 memset(&ndlp->nlp_portname, 0, sizeof(struct lpfc_name));
1494
1495 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1496 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1497 lpfc_unreg_rpi(vport, ndlp);
1498 return ndlp->nlp_state;
1499 }
1500
1501 if (phba->sli_rev == LPFC_SLI_REV4) {
1502 rc = lpfc_sli4_resume_rpi(ndlp, NULL, NULL);
1503 if (rc) {
1504
1505 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1506 return ndlp->nlp_state;
1507 }
1508 }
1509
1510 if (ndlp->nlp_type & NLP_FCP_TARGET) {
1511 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1512 lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
1513 } else {
1514 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1515 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1516 }
1517
1518 return ndlp->nlp_state;
1519}
1520
1521static uint32_t
1522lpfc_device_rm_adisc_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1523 void *arg, uint32_t evt)
1524{
1525 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1526
1527 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1528 spin_lock_irq(shost->host_lock);
1529 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1530 spin_unlock_irq(shost->host_lock);
1531 return ndlp->nlp_state;
1532 } else {
1533
1534 lpfc_els_abort(vport->phba, ndlp);
1535
1536 lpfc_drop_node(vport, ndlp);
1537 return NLP_STE_FREED_NODE;
1538 }
1539}
1540
1541static uint32_t
1542lpfc_device_recov_adisc_issue(struct lpfc_vport *vport,
1543 struct lpfc_nodelist *ndlp,
1544 void *arg,
1545 uint32_t evt)
1546{
1547 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1548 struct lpfc_hba *phba = vport->phba;
1549
1550
1551
1552
1553 if (vport->fc_flag & FC_RSCN_DEFERRED)
1554 return ndlp->nlp_state;
1555
1556
1557 lpfc_els_abort(phba, ndlp);
1558
1559 ndlp->nlp_prev_state = NLP_STE_ADISC_ISSUE;
1560 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1561 spin_lock_irq(shost->host_lock);
1562 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1563 spin_unlock_irq(shost->host_lock);
1564 lpfc_disc_set_adisc(vport, ndlp);
1565 return ndlp->nlp_state;
1566}
1567
1568static uint32_t
1569lpfc_rcv_plogi_reglogin_issue(struct lpfc_vport *vport,
1570 struct lpfc_nodelist *ndlp,
1571 void *arg,
1572 uint32_t evt)
1573{
1574 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1575
1576 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
1577 return ndlp->nlp_state;
1578}
1579
1580static uint32_t
1581lpfc_rcv_prli_reglogin_issue(struct lpfc_vport *vport,
1582 struct lpfc_nodelist *ndlp,
1583 void *arg,
1584 uint32_t evt)
1585{
1586 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1587 struct ls_rjt stat;
1588
1589 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb)) {
1590 return ndlp->nlp_state;
1591 }
1592 if (vport->phba->nvmet_support) {
1593
1594
1595
1596
1597 if (ndlp->nlp_flag & NLP_RPI_REGISTERED) {
1598 lpfc_rcv_prli(vport, ndlp, cmdiocb);
1599 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1600 } else {
1601
1602
1603
1604
1605 memset(&stat, 0, sizeof(struct ls_rjt));
1606 stat.un.b.lsRjtRsnCode = LSRJT_LOGICAL_BSY;
1607 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
1608 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb,
1609 ndlp, NULL);
1610 return ndlp->nlp_state;
1611 }
1612 } else {
1613
1614 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1615 }
1616 return ndlp->nlp_state;
1617}
1618
1619static uint32_t
1620lpfc_rcv_logo_reglogin_issue(struct lpfc_vport *vport,
1621 struct lpfc_nodelist *ndlp,
1622 void *arg,
1623 uint32_t evt)
1624{
1625 struct lpfc_hba *phba = vport->phba;
1626 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1627 LPFC_MBOXQ_t *mb;
1628 LPFC_MBOXQ_t *nextmb;
1629 struct lpfc_dmabuf *mp;
1630
1631 cmdiocb = (struct lpfc_iocbq *) arg;
1632
1633
1634 if ((mb = phba->sli.mbox_active)) {
1635 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
1636 (ndlp == (struct lpfc_nodelist *) mb->context2)) {
1637 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
1638 lpfc_nlp_put(ndlp);
1639 mb->context2 = NULL;
1640 mb->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
1641 }
1642 }
1643
1644 spin_lock_irq(&phba->hbalock);
1645 list_for_each_entry_safe(mb, nextmb, &phba->sli.mboxq, list) {
1646 if ((mb->u.mb.mbxCommand == MBX_REG_LOGIN64) &&
1647 (ndlp == (struct lpfc_nodelist *) mb->context2)) {
1648 mp = (struct lpfc_dmabuf *) (mb->context1);
1649 if (mp) {
1650 __lpfc_mbuf_free(phba, mp->virt, mp->phys);
1651 kfree(mp);
1652 }
1653 ndlp->nlp_flag &= ~NLP_REG_LOGIN_SEND;
1654 lpfc_nlp_put(ndlp);
1655 list_del(&mb->list);
1656 phba->sli.mboxq_cnt--;
1657 mempool_free(mb, phba->mbox_mem_pool);
1658 }
1659 }
1660 spin_unlock_irq(&phba->hbalock);
1661
1662 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1663 return ndlp->nlp_state;
1664}
1665
1666static uint32_t
1667lpfc_rcv_padisc_reglogin_issue(struct lpfc_vport *vport,
1668 struct lpfc_nodelist *ndlp,
1669 void *arg,
1670 uint32_t evt)
1671{
1672 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1673
1674 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1675 return ndlp->nlp_state;
1676}
1677
1678static uint32_t
1679lpfc_rcv_prlo_reglogin_issue(struct lpfc_vport *vport,
1680 struct lpfc_nodelist *ndlp,
1681 void *arg,
1682 uint32_t evt)
1683{
1684 struct lpfc_iocbq *cmdiocb;
1685
1686 cmdiocb = (struct lpfc_iocbq *) arg;
1687 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
1688 return ndlp->nlp_state;
1689}
1690
1691static uint32_t
1692lpfc_cmpl_reglogin_reglogin_issue(struct lpfc_vport *vport,
1693 struct lpfc_nodelist *ndlp,
1694 void *arg,
1695 uint32_t evt)
1696{
1697 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1698 struct lpfc_hba *phba = vport->phba;
1699 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
1700 MAILBOX_t *mb = &pmb->u.mb;
1701 uint32_t did = mb->un.varWords[1];
1702 int rc = 0;
1703
1704 if (mb->mbxStatus) {
1705
1706 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
1707 "0246 RegLogin failed Data: x%x x%x x%x x%x "
1708 "x%x\n",
1709 did, mb->mbxStatus, vport->port_state,
1710 mb->un.varRegLogin.vpi,
1711 mb->un.varRegLogin.rpi);
1712
1713
1714
1715
1716 if (mb->mbxStatus == MBXERR_RPI_FULL) {
1717 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1718 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1719 return ndlp->nlp_state;
1720 }
1721
1722
1723 mod_timer(&ndlp->nlp_delayfunc,
1724 jiffies + msecs_to_jiffies(1000 * 1));
1725 spin_lock_irq(shost->host_lock);
1726 ndlp->nlp_flag |= NLP_DELAY_TMO;
1727 spin_unlock_irq(shost->host_lock);
1728 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
1729
1730 lpfc_issue_els_logo(vport, ndlp, 0);
1731 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1732 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1733 return ndlp->nlp_state;
1734 }
1735
1736
1737 if (phba->sli_rev < LPFC_SLI_REV4)
1738 ndlp->nlp_rpi = mb->un.varWords[0];
1739
1740 ndlp->nlp_flag |= NLP_RPI_REGISTERED;
1741
1742
1743 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1744 "3066 RegLogin Complete on x%x x%x x%x\n",
1745 did, ndlp->nlp_type, ndlp->nlp_fc4_type);
1746 if (!(ndlp->nlp_type & NLP_FABRIC) &&
1747 (phba->nvmet_support == 0)) {
1748
1749
1750
1751
1752
1753 if (vport->fc_flag & FC_PT2PT) {
1754
1755
1756
1757
1758 ndlp->nlp_fc4_type |= NLP_FC4_FCP;
1759 if ((phba->cfg_enable_fc4_type == LPFC_ENABLE_BOTH) ||
1760 (phba->cfg_enable_fc4_type == LPFC_ENABLE_NVME)) {
1761 ndlp->nlp_fc4_type |= NLP_FC4_NVME;
1762
1763 lpfc_nvme_update_localport(vport);
1764 }
1765
1766 } else if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
1767 ndlp->nlp_fc4_type |= NLP_FC4_FCP;
1768
1769 } else if (ndlp->nlp_fc4_type == 0) {
1770 rc = lpfc_ns_cmd(vport, SLI_CTNS_GFT_ID,
1771 0, ndlp->nlp_DID);
1772 return ndlp->nlp_state;
1773 }
1774
1775 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1776 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
1777 lpfc_issue_els_prli(vport, ndlp, 0);
1778 } else {
1779 if ((vport->fc_flag & FC_PT2PT) && phba->nvmet_support)
1780 phba->targetport->port_id = vport->fc_myDID;
1781
1782
1783
1784
1785 if (ndlp->nlp_type & NLP_FABRIC) {
1786 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1787 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1788 }
1789 }
1790 return ndlp->nlp_state;
1791}
1792
1793static uint32_t
1794lpfc_device_rm_reglogin_issue(struct lpfc_vport *vport,
1795 struct lpfc_nodelist *ndlp,
1796 void *arg,
1797 uint32_t evt)
1798{
1799 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1800
1801 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
1802 spin_lock_irq(shost->host_lock);
1803 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
1804 spin_unlock_irq(shost->host_lock);
1805 return ndlp->nlp_state;
1806 } else {
1807 lpfc_drop_node(vport, ndlp);
1808 return NLP_STE_FREED_NODE;
1809 }
1810}
1811
1812static uint32_t
1813lpfc_device_recov_reglogin_issue(struct lpfc_vport *vport,
1814 struct lpfc_nodelist *ndlp,
1815 void *arg,
1816 uint32_t evt)
1817{
1818 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1819
1820
1821
1822
1823 if (vport->fc_flag & FC_RSCN_DEFERRED)
1824 return ndlp->nlp_state;
1825
1826 ndlp->nlp_prev_state = NLP_STE_REG_LOGIN_ISSUE;
1827 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1828 spin_lock_irq(shost->host_lock);
1829
1830
1831
1832
1833 if (!(ndlp->nlp_flag & NLP_RPI_REGISTERED) ||
1834 !vport->phba->nvmet_support)
1835 ndlp->nlp_flag |= NLP_IGNR_REG_CMPL;
1836
1837 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
1838 spin_unlock_irq(shost->host_lock);
1839 lpfc_disc_set_adisc(vport, ndlp);
1840 return ndlp->nlp_state;
1841}
1842
1843static uint32_t
1844lpfc_rcv_plogi_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1845 void *arg, uint32_t evt)
1846{
1847 struct lpfc_iocbq *cmdiocb;
1848
1849 cmdiocb = (struct lpfc_iocbq *) arg;
1850
1851 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
1852 return ndlp->nlp_state;
1853}
1854
1855static uint32_t
1856lpfc_rcv_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1857 void *arg, uint32_t evt)
1858{
1859 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1860
1861 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
1862 return ndlp->nlp_state;
1863 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
1864 return ndlp->nlp_state;
1865}
1866
1867static uint32_t
1868lpfc_rcv_logo_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1869 void *arg, uint32_t evt)
1870{
1871 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1872
1873
1874 lpfc_els_abort(vport->phba, ndlp);
1875
1876 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
1877 return ndlp->nlp_state;
1878}
1879
1880static uint32_t
1881lpfc_rcv_padisc_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1882 void *arg, uint32_t evt)
1883{
1884 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
1885
1886 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
1887 return ndlp->nlp_state;
1888}
1889
1890
1891
1892
1893
1894
1895static uint32_t
1896lpfc_rcv_prlo_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 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
1902 return ndlp->nlp_state;
1903}
1904
1905static uint32_t
1906lpfc_cmpl_prli_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1907 void *arg, uint32_t evt)
1908{
1909 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1910 struct lpfc_iocbq *cmdiocb, *rspiocb;
1911 struct lpfc_hba *phba = vport->phba;
1912 IOCB_t *irsp;
1913 PRLI *npr;
1914 struct lpfc_nvme_prli *nvpr;
1915 void *temp_ptr;
1916
1917 cmdiocb = (struct lpfc_iocbq *) arg;
1918 rspiocb = cmdiocb->context_un.rsp_iocb;
1919
1920
1921
1922
1923
1924 npr = NULL;
1925 nvpr = NULL;
1926 temp_ptr = lpfc_check_elscmpl_iocb(phba, cmdiocb, rspiocb);
1927 if (cmdiocb->iocb_flag & LPFC_PRLI_FCP_REQ)
1928 npr = (PRLI *) temp_ptr;
1929 else if (cmdiocb->iocb_flag & LPFC_PRLI_NVME_REQ)
1930 nvpr = (struct lpfc_nvme_prli *) temp_ptr;
1931
1932 irsp = &rspiocb->iocb;
1933 if (irsp->ulpStatus) {
1934 if ((vport->port_type == LPFC_NPIV_PORT) &&
1935 vport->cfg_restrict_login) {
1936 goto out;
1937 }
1938
1939
1940
1941
1942
1943 if (npr && ndlp->nlp_flag & NLP_FCP_PRLI_RJT) {
1944 ndlp->nlp_fc4_type &= ~NLP_FC4_FCP;
1945 goto out_err;
1946 }
1947
1948
1949
1950
1951 if ((ndlp->fc4_prli_sent == 1) &&
1952 (ndlp->nlp_state == NLP_STE_PRLI_ISSUE) &&
1953 (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_FCP_INITIATOR)))
1954
1955
1956
1957
1958 goto out_err;
1959
1960 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
1961 ndlp->nlp_type |= NLP_FCP_INITIATOR;
1962 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
1963 return ndlp->nlp_state;
1964 }
1965
1966 if (npr && (npr->acceptRspCode == PRLI_REQ_EXECUTED) &&
1967 (npr->prliType == PRLI_FCP_TYPE)) {
1968 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
1969 "6028 FCP NPR PRLI Cmpl Init %d Target %d\n",
1970 npr->initiatorFunc,
1971 npr->targetFunc);
1972 if (npr->initiatorFunc)
1973 ndlp->nlp_type |= NLP_FCP_INITIATOR;
1974 if (npr->targetFunc) {
1975 ndlp->nlp_type |= NLP_FCP_TARGET;
1976 if (npr->writeXferRdyDis)
1977 ndlp->nlp_flag |= NLP_FIRSTBURST;
1978 }
1979 if (npr->Retry)
1980 ndlp->nlp_fcp_info |= NLP_FCP_2_DEVICE;
1981
1982 } else if (nvpr &&
1983 (bf_get_be32(prli_acc_rsp_code, nvpr) ==
1984 PRLI_REQ_EXECUTED) &&
1985 (bf_get_be32(prli_type_code, nvpr) ==
1986 PRLI_NVME_TYPE)) {
1987
1988
1989 if (bf_get_be32(prli_init, nvpr))
1990 ndlp->nlp_type |= NLP_NVME_INITIATOR;
1991
1992
1993 if (bf_get_be32(prli_tgt, nvpr)) {
1994
1995
1996
1997
1998 ndlp->nlp_type |= NLP_NVME_TARGET;
1999 if (bf_get_be32(prli_disc, nvpr))
2000 ndlp->nlp_type |= NLP_NVME_DISCOVERY;
2001
2002
2003
2004
2005
2006
2007
2008 if ((bf_get_be32(prli_fba, nvpr) == 1) &&
2009 (phba->cfg_nvme_enable_fb) &&
2010 (!phba->nvmet_support)) {
2011
2012
2013
2014 ndlp->nlp_flag |= NLP_FIRSTBURST;
2015 ndlp->nvme_fb_size = bf_get_be32(prli_fb_sz,
2016 nvpr);
2017
2018
2019 if (ndlp->nvme_fb_size)
2020 ndlp->nvme_fb_size <<=
2021 LPFC_NVME_FB_SHIFT;
2022 else
2023 ndlp->nvme_fb_size = LPFC_NVME_MAX_FB;
2024 }
2025 }
2026
2027 lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
2028 "6029 NVME PRLI Cmpl w1 x%08x "
2029 "w4 x%08x w5 x%08x flag x%x, "
2030 "fcp_info x%x nlp_type x%x\n",
2031 be32_to_cpu(nvpr->word1),
2032 be32_to_cpu(nvpr->word4),
2033 be32_to_cpu(nvpr->word5),
2034 ndlp->nlp_flag, ndlp->nlp_fcp_info,
2035 ndlp->nlp_type);
2036 }
2037 if (!(ndlp->nlp_type & NLP_FCP_TARGET) &&
2038 (vport->port_type == LPFC_NPIV_PORT) &&
2039 vport->cfg_restrict_login) {
2040out:
2041 spin_lock_irq(shost->host_lock);
2042 ndlp->nlp_flag |= NLP_TARGET_REMOVE;
2043 spin_unlock_irq(shost->host_lock);
2044 lpfc_issue_els_logo(vport, ndlp, 0);
2045
2046 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
2047 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2048 return ndlp->nlp_state;
2049 }
2050
2051out_err:
2052
2053
2054
2055 if (ndlp->fc4_prli_sent == 0) {
2056 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
2057 if (ndlp->nlp_type & (NLP_FCP_TARGET | NLP_NVME_TARGET))
2058 lpfc_nlp_set_state(vport, ndlp, NLP_STE_MAPPED_NODE);
2059 else if (ndlp->nlp_type &
2060 (NLP_FCP_INITIATOR | NLP_NVME_INITIATOR))
2061 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
2062 } else
2063 lpfc_printf_vlog(vport,
2064 KERN_INFO, LOG_ELS,
2065 "3067 PRLI's still outstanding "
2066 "on x%06x - count %d, Pend Node Mode "
2067 "transition...\n",
2068 ndlp->nlp_DID, ndlp->fc4_prli_sent);
2069
2070 return ndlp->nlp_state;
2071}
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091static uint32_t
2092lpfc_device_rm_prli_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2093 void *arg, uint32_t evt)
2094{
2095 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2096
2097 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
2098 spin_lock_irq(shost->host_lock);
2099 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
2100 spin_unlock_irq(shost->host_lock);
2101 return ndlp->nlp_state;
2102 } else {
2103
2104 lpfc_els_abort(vport->phba, ndlp);
2105
2106 lpfc_drop_node(vport, ndlp);
2107 return NLP_STE_FREED_NODE;
2108 }
2109}
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128static uint32_t
2129lpfc_device_recov_prli_issue(struct lpfc_vport *vport,
2130 struct lpfc_nodelist *ndlp,
2131 void *arg,
2132 uint32_t evt)
2133{
2134 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2135 struct lpfc_hba *phba = vport->phba;
2136
2137
2138
2139
2140 if (vport->fc_flag & FC_RSCN_DEFERRED)
2141 return ndlp->nlp_state;
2142
2143
2144 lpfc_els_abort(phba, ndlp);
2145
2146 ndlp->nlp_prev_state = NLP_STE_PRLI_ISSUE;
2147 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2148 spin_lock_irq(shost->host_lock);
2149 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2150 spin_unlock_irq(shost->host_lock);
2151 lpfc_disc_set_adisc(vport, ndlp);
2152 return ndlp->nlp_state;
2153}
2154
2155static uint32_t
2156lpfc_rcv_plogi_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2157 void *arg, uint32_t evt)
2158{
2159 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2160 struct ls_rjt stat;
2161
2162 memset(&stat, 0, sizeof(struct ls_rjt));
2163 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2164 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2165 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2166 return ndlp->nlp_state;
2167}
2168
2169static uint32_t
2170lpfc_rcv_prli_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2171 void *arg, uint32_t evt)
2172{
2173 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2174 struct ls_rjt stat;
2175
2176 memset(&stat, 0, sizeof(struct ls_rjt));
2177 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2178 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2179 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2180 return ndlp->nlp_state;
2181}
2182
2183static uint32_t
2184lpfc_rcv_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2185 void *arg, uint32_t evt)
2186{
2187 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2188 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2189
2190 spin_lock_irq(shost->host_lock);
2191 ndlp->nlp_flag |= NLP_LOGO_ACC;
2192 spin_unlock_irq(shost->host_lock);
2193 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
2194 return ndlp->nlp_state;
2195}
2196
2197static uint32_t
2198lpfc_rcv_padisc_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2199 void *arg, uint32_t evt)
2200{
2201 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2202 struct ls_rjt stat;
2203
2204 memset(&stat, 0, sizeof(struct ls_rjt));
2205 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2206 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2207 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2208 return ndlp->nlp_state;
2209}
2210
2211static uint32_t
2212lpfc_rcv_prlo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2213 void *arg, uint32_t evt)
2214{
2215 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *)arg;
2216 struct ls_rjt stat;
2217
2218 memset(&stat, 0, sizeof(struct ls_rjt));
2219 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2220 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2221 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2222 return ndlp->nlp_state;
2223}
2224
2225static uint32_t
2226lpfc_cmpl_logo_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2227 void *arg, uint32_t evt)
2228{
2229 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2230
2231 ndlp->nlp_prev_state = NLP_STE_LOGO_ISSUE;
2232 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2233 spin_lock_irq(shost->host_lock);
2234 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2235 spin_unlock_irq(shost->host_lock);
2236 lpfc_disc_set_adisc(vport, ndlp);
2237 return ndlp->nlp_state;
2238}
2239
2240static uint32_t
2241lpfc_device_rm_logo_issue(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2242 void *arg, uint32_t evt)
2243{
2244
2245
2246
2247
2248
2249 lpfc_unreg_rpi(vport, ndlp);
2250
2251 lpfc_els_abort(vport->phba, ndlp);
2252 lpfc_drop_node(vport, ndlp);
2253 return NLP_STE_FREED_NODE;
2254}
2255
2256static uint32_t
2257lpfc_device_recov_logo_issue(struct lpfc_vport *vport,
2258 struct lpfc_nodelist *ndlp,
2259 void *arg, uint32_t evt)
2260{
2261
2262
2263
2264
2265
2266 return ndlp->nlp_state;
2267}
2268
2269static uint32_t
2270lpfc_rcv_plogi_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2271 void *arg, uint32_t evt)
2272{
2273 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2274
2275 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
2276 return ndlp->nlp_state;
2277}
2278
2279static uint32_t
2280lpfc_rcv_prli_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2281 void *arg, uint32_t evt)
2282{
2283 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2284
2285 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
2286 return ndlp->nlp_state;
2287
2288 lpfc_rcv_prli(vport, ndlp, cmdiocb);
2289 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
2290 return ndlp->nlp_state;
2291}
2292
2293static uint32_t
2294lpfc_rcv_logo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2295 void *arg, uint32_t evt)
2296{
2297 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2298
2299 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
2300 return ndlp->nlp_state;
2301}
2302
2303static uint32_t
2304lpfc_rcv_padisc_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2305 void *arg, uint32_t evt)
2306{
2307 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2308
2309 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
2310 return ndlp->nlp_state;
2311}
2312
2313static uint32_t
2314lpfc_rcv_prlo_unmap_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2315 void *arg, uint32_t evt)
2316{
2317 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2318
2319 lpfc_els_rsp_acc(vport, ELS_CMD_PRLO, cmdiocb, ndlp, NULL);
2320 return ndlp->nlp_state;
2321}
2322
2323static uint32_t
2324lpfc_device_recov_unmap_node(struct lpfc_vport *vport,
2325 struct lpfc_nodelist *ndlp,
2326 void *arg,
2327 uint32_t evt)
2328{
2329 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2330
2331 ndlp->nlp_prev_state = NLP_STE_UNMAPPED_NODE;
2332 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2333 spin_lock_irq(shost->host_lock);
2334 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2335 spin_unlock_irq(shost->host_lock);
2336 lpfc_disc_set_adisc(vport, ndlp);
2337
2338 return ndlp->nlp_state;
2339}
2340
2341static uint32_t
2342lpfc_rcv_plogi_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2343 void *arg, uint32_t evt)
2344{
2345 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2346
2347 lpfc_rcv_plogi(vport, ndlp, cmdiocb);
2348 return ndlp->nlp_state;
2349}
2350
2351static uint32_t
2352lpfc_rcv_prli_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2353 void *arg, uint32_t evt)
2354{
2355 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2356
2357 if (!lpfc_rcv_prli_support_check(vport, ndlp, cmdiocb))
2358 return ndlp->nlp_state;
2359 lpfc_els_rsp_prli_acc(vport, cmdiocb, ndlp);
2360 return ndlp->nlp_state;
2361}
2362
2363static uint32_t
2364lpfc_rcv_logo_mapped_node(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
2369 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
2370 return ndlp->nlp_state;
2371}
2372
2373static uint32_t
2374lpfc_rcv_padisc_mapped_node(struct lpfc_vport *vport,
2375 struct lpfc_nodelist *ndlp,
2376 void *arg, uint32_t evt)
2377{
2378 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2379
2380 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
2381 return ndlp->nlp_state;
2382}
2383
2384static uint32_t
2385lpfc_rcv_prlo_mapped_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2386 void *arg, uint32_t evt)
2387{
2388 struct lpfc_hba *phba = vport->phba;
2389 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2390
2391
2392 lpfc_sli_abort_iocb(vport, &phba->sli.sli3_ring[LPFC_FCP_RING],
2393 ndlp->nlp_sid, 0, LPFC_CTX_TGT);
2394
2395
2396 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_PRLO);
2397 return ndlp->nlp_state;
2398}
2399
2400static uint32_t
2401lpfc_device_recov_mapped_node(struct lpfc_vport *vport,
2402 struct lpfc_nodelist *ndlp,
2403 void *arg,
2404 uint32_t evt)
2405{
2406 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2407
2408 ndlp->nlp_prev_state = NLP_STE_MAPPED_NODE;
2409 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2410 spin_lock_irq(shost->host_lock);
2411 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2412 spin_unlock_irq(shost->host_lock);
2413 lpfc_disc_set_adisc(vport, ndlp);
2414 return ndlp->nlp_state;
2415}
2416
2417static uint32_t
2418lpfc_rcv_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2419 void *arg, uint32_t evt)
2420{
2421 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2422 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2423
2424
2425 if (ndlp->nlp_flag & (NLP_LOGO_SND | NLP_LOGO_ACC))
2426 return ndlp->nlp_state;
2427 if (lpfc_rcv_plogi(vport, ndlp, cmdiocb)) {
2428 lpfc_cancel_retry_delay_tmo(vport, ndlp);
2429 spin_lock_irq(shost->host_lock);
2430 ndlp->nlp_flag &= ~(NLP_NPR_ADISC | NLP_NPR_2B_DISC);
2431 spin_unlock_irq(shost->host_lock);
2432 } else if (!(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
2433
2434 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
2435 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2436 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2437 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
2438 }
2439 }
2440 return ndlp->nlp_state;
2441}
2442
2443static uint32_t
2444lpfc_rcv_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2445 void *arg, uint32_t evt)
2446{
2447 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2448 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2449 struct ls_rjt stat;
2450
2451 memset(&stat, 0, sizeof (struct ls_rjt));
2452 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
2453 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
2454 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
2455
2456 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
2457 if (ndlp->nlp_flag & NLP_NPR_ADISC) {
2458 spin_lock_irq(shost->host_lock);
2459 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2460 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2461 spin_unlock_irq(shost->host_lock);
2462 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2463 lpfc_issue_els_adisc(vport, ndlp, 0);
2464 } else {
2465 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2466 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2467 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
2468 }
2469 }
2470 return ndlp->nlp_state;
2471}
2472
2473static uint32_t
2474lpfc_rcv_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2475 void *arg, uint32_t evt)
2476{
2477 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2478
2479 lpfc_rcv_logo(vport, ndlp, cmdiocb, ELS_CMD_LOGO);
2480 return ndlp->nlp_state;
2481}
2482
2483static uint32_t
2484lpfc_rcv_padisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2485 void *arg, uint32_t evt)
2486{
2487 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2488
2489 lpfc_rcv_padisc(vport, ndlp, cmdiocb);
2490
2491
2492
2493
2494
2495 if (!(ndlp->nlp_flag & NLP_DELAY_TMO) &&
2496 !(ndlp->nlp_flag & NLP_NPR_2B_DISC)) {
2497 if (ndlp->nlp_flag & NLP_NPR_ADISC) {
2498 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2499 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2500 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2501 lpfc_issue_els_adisc(vport, ndlp, 0);
2502 } else {
2503 ndlp->nlp_prev_state = NLP_STE_NPR_NODE;
2504 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2505 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
2506 }
2507 }
2508 return ndlp->nlp_state;
2509}
2510
2511static uint32_t
2512lpfc_rcv_prlo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2513 void *arg, uint32_t evt)
2514{
2515 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2516 struct lpfc_iocbq *cmdiocb = (struct lpfc_iocbq *) arg;
2517
2518 spin_lock_irq(shost->host_lock);
2519 ndlp->nlp_flag |= NLP_LOGO_ACC;
2520 spin_unlock_irq(shost->host_lock);
2521
2522 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
2523
2524 if ((ndlp->nlp_flag & NLP_DELAY_TMO) == 0) {
2525 mod_timer(&ndlp->nlp_delayfunc,
2526 jiffies + msecs_to_jiffies(1000 * 1));
2527 spin_lock_irq(shost->host_lock);
2528 ndlp->nlp_flag |= NLP_DELAY_TMO;
2529 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2530 spin_unlock_irq(shost->host_lock);
2531 ndlp->nlp_last_elscmd = ELS_CMD_PLOGI;
2532 } else {
2533 spin_lock_irq(shost->host_lock);
2534 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
2535 spin_unlock_irq(shost->host_lock);
2536 }
2537 return ndlp->nlp_state;
2538}
2539
2540static uint32_t
2541lpfc_cmpl_plogi_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2542 void *arg, uint32_t evt)
2543{
2544 struct lpfc_iocbq *cmdiocb, *rspiocb;
2545 IOCB_t *irsp;
2546 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2547
2548 cmdiocb = (struct lpfc_iocbq *) arg;
2549 rspiocb = cmdiocb->context_un.rsp_iocb;
2550
2551 irsp = &rspiocb->iocb;
2552 if (irsp->ulpStatus) {
2553 spin_lock_irq(shost->host_lock);
2554 ndlp->nlp_flag |= NLP_DEFER_RM;
2555 spin_unlock_irq(shost->host_lock);
2556 return NLP_STE_FREED_NODE;
2557 }
2558 return ndlp->nlp_state;
2559}
2560
2561static uint32_t
2562lpfc_cmpl_prli_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2563 void *arg, uint32_t evt)
2564{
2565 struct lpfc_iocbq *cmdiocb, *rspiocb;
2566 IOCB_t *irsp;
2567
2568 cmdiocb = (struct lpfc_iocbq *) arg;
2569 rspiocb = cmdiocb->context_un.rsp_iocb;
2570
2571 irsp = &rspiocb->iocb;
2572 if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
2573 lpfc_drop_node(vport, ndlp);
2574 return NLP_STE_FREED_NODE;
2575 }
2576 return ndlp->nlp_state;
2577}
2578
2579static uint32_t
2580lpfc_cmpl_logo_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2581 void *arg, uint32_t evt)
2582{
2583 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2584
2585
2586 if (ndlp->nlp_DID == Fabric_DID) {
2587 spin_lock_irq(shost->host_lock);
2588 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
2589 spin_unlock_irq(shost->host_lock);
2590 }
2591 lpfc_unreg_rpi(vport, ndlp);
2592 return ndlp->nlp_state;
2593}
2594
2595static uint32_t
2596lpfc_cmpl_adisc_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2597 void *arg, uint32_t evt)
2598{
2599 struct lpfc_iocbq *cmdiocb, *rspiocb;
2600 IOCB_t *irsp;
2601
2602 cmdiocb = (struct lpfc_iocbq *) arg;
2603 rspiocb = cmdiocb->context_un.rsp_iocb;
2604
2605 irsp = &rspiocb->iocb;
2606 if (irsp->ulpStatus && (ndlp->nlp_flag & NLP_NODEV_REMOVE)) {
2607 lpfc_drop_node(vport, ndlp);
2608 return NLP_STE_FREED_NODE;
2609 }
2610 return ndlp->nlp_state;
2611}
2612
2613static uint32_t
2614lpfc_cmpl_reglogin_npr_node(struct lpfc_vport *vport,
2615 struct lpfc_nodelist *ndlp,
2616 void *arg, uint32_t evt)
2617{
2618 LPFC_MBOXQ_t *pmb = (LPFC_MBOXQ_t *) arg;
2619 MAILBOX_t *mb = &pmb->u.mb;
2620
2621 if (!mb->mbxStatus) {
2622
2623 if (vport->phba->sli_rev < LPFC_SLI_REV4)
2624 ndlp->nlp_rpi = mb->un.varWords[0];
2625 ndlp->nlp_flag |= NLP_RPI_REGISTERED;
2626 if (ndlp->nlp_flag & NLP_LOGO_ACC) {
2627 lpfc_unreg_rpi(vport, ndlp);
2628 }
2629 } else {
2630 if (ndlp->nlp_flag & NLP_NODEV_REMOVE) {
2631 lpfc_drop_node(vport, ndlp);
2632 return NLP_STE_FREED_NODE;
2633 }
2634 }
2635 return ndlp->nlp_state;
2636}
2637
2638static uint32_t
2639lpfc_device_rm_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2640 void *arg, uint32_t evt)
2641{
2642 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2643
2644 if (ndlp->nlp_flag & NLP_NPR_2B_DISC) {
2645 spin_lock_irq(shost->host_lock);
2646 ndlp->nlp_flag |= NLP_NODEV_REMOVE;
2647 spin_unlock_irq(shost->host_lock);
2648 return ndlp->nlp_state;
2649 }
2650 lpfc_drop_node(vport, ndlp);
2651 return NLP_STE_FREED_NODE;
2652}
2653
2654static uint32_t
2655lpfc_device_recov_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2656 void *arg, uint32_t evt)
2657{
2658 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2659
2660
2661
2662
2663 if (vport->fc_flag & FC_RSCN_DEFERRED)
2664 return ndlp->nlp_state;
2665
2666 lpfc_cancel_retry_delay_tmo(vport, ndlp);
2667 spin_lock_irq(shost->host_lock);
2668 ndlp->nlp_flag &= ~(NLP_NODEV_REMOVE | NLP_NPR_2B_DISC);
2669 spin_unlock_irq(shost->host_lock);
2670 return ndlp->nlp_state;
2671}
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
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
2730static uint32_t (*lpfc_disc_action[NLP_STE_MAX_STATE * NLP_EVT_MAX_EVENT])
2731 (struct lpfc_vport *, struct lpfc_nodelist *, void *, uint32_t) = {
2732
2733 lpfc_rcv_plogi_unused_node,
2734 lpfc_rcv_els_unused_node,
2735 lpfc_rcv_logo_unused_node,
2736 lpfc_rcv_els_unused_node,
2737 lpfc_rcv_els_unused_node,
2738 lpfc_rcv_els_unused_node,
2739 lpfc_disc_illegal,
2740 lpfc_disc_illegal,
2741 lpfc_cmpl_logo_unused_node,
2742 lpfc_disc_illegal,
2743 lpfc_disc_illegal,
2744 lpfc_device_rm_unused_node,
2745 lpfc_device_recov_unused_node,
2746
2747 lpfc_rcv_plogi_plogi_issue,
2748 lpfc_rcv_prli_plogi_issue,
2749 lpfc_rcv_logo_plogi_issue,
2750 lpfc_rcv_els_plogi_issue,
2751 lpfc_rcv_els_plogi_issue,
2752 lpfc_rcv_els_plogi_issue,
2753 lpfc_cmpl_plogi_plogi_issue,
2754 lpfc_disc_illegal,
2755 lpfc_cmpl_logo_plogi_issue,
2756 lpfc_disc_illegal,
2757 lpfc_cmpl_reglogin_plogi_issue,
2758 lpfc_device_rm_plogi_issue,
2759 lpfc_device_recov_plogi_issue,
2760
2761 lpfc_rcv_plogi_adisc_issue,
2762 lpfc_rcv_prli_adisc_issue,
2763 lpfc_rcv_logo_adisc_issue,
2764 lpfc_rcv_padisc_adisc_issue,
2765 lpfc_rcv_padisc_adisc_issue,
2766 lpfc_rcv_prlo_adisc_issue,
2767 lpfc_disc_illegal,
2768 lpfc_disc_illegal,
2769 lpfc_disc_illegal,
2770 lpfc_cmpl_adisc_adisc_issue,
2771 lpfc_disc_illegal,
2772 lpfc_device_rm_adisc_issue,
2773 lpfc_device_recov_adisc_issue,
2774
2775 lpfc_rcv_plogi_reglogin_issue,
2776 lpfc_rcv_prli_reglogin_issue,
2777 lpfc_rcv_logo_reglogin_issue,
2778 lpfc_rcv_padisc_reglogin_issue,
2779 lpfc_rcv_padisc_reglogin_issue,
2780 lpfc_rcv_prlo_reglogin_issue,
2781 lpfc_cmpl_plogi_illegal,
2782 lpfc_disc_illegal,
2783 lpfc_disc_illegal,
2784 lpfc_disc_illegal,
2785 lpfc_cmpl_reglogin_reglogin_issue,
2786 lpfc_device_rm_reglogin_issue,
2787 lpfc_device_recov_reglogin_issue,
2788
2789 lpfc_rcv_plogi_prli_issue,
2790 lpfc_rcv_prli_prli_issue,
2791 lpfc_rcv_logo_prli_issue,
2792 lpfc_rcv_padisc_prli_issue,
2793 lpfc_rcv_padisc_prli_issue,
2794 lpfc_rcv_prlo_prli_issue,
2795 lpfc_cmpl_plogi_illegal,
2796 lpfc_cmpl_prli_prli_issue,
2797 lpfc_disc_illegal,
2798 lpfc_disc_illegal,
2799 lpfc_disc_illegal,
2800 lpfc_device_rm_prli_issue,
2801 lpfc_device_recov_prli_issue,
2802
2803 lpfc_rcv_plogi_logo_issue,
2804 lpfc_rcv_prli_logo_issue,
2805 lpfc_rcv_logo_logo_issue,
2806 lpfc_rcv_padisc_logo_issue,
2807 lpfc_rcv_padisc_logo_issue,
2808 lpfc_rcv_prlo_logo_issue,
2809 lpfc_cmpl_plogi_illegal,
2810 lpfc_disc_illegal,
2811 lpfc_cmpl_logo_logo_issue,
2812 lpfc_disc_illegal,
2813 lpfc_disc_illegal,
2814 lpfc_device_rm_logo_issue,
2815 lpfc_device_recov_logo_issue,
2816
2817 lpfc_rcv_plogi_unmap_node,
2818 lpfc_rcv_prli_unmap_node,
2819 lpfc_rcv_logo_unmap_node,
2820 lpfc_rcv_padisc_unmap_node,
2821 lpfc_rcv_padisc_unmap_node,
2822 lpfc_rcv_prlo_unmap_node,
2823 lpfc_disc_illegal,
2824 lpfc_disc_illegal,
2825 lpfc_disc_illegal,
2826 lpfc_disc_illegal,
2827 lpfc_disc_illegal,
2828 lpfc_disc_illegal,
2829 lpfc_device_recov_unmap_node,
2830
2831 lpfc_rcv_plogi_mapped_node,
2832 lpfc_rcv_prli_mapped_node,
2833 lpfc_rcv_logo_mapped_node,
2834 lpfc_rcv_padisc_mapped_node,
2835 lpfc_rcv_padisc_mapped_node,
2836 lpfc_rcv_prlo_mapped_node,
2837 lpfc_disc_illegal,
2838 lpfc_disc_illegal,
2839 lpfc_disc_illegal,
2840 lpfc_disc_illegal,
2841 lpfc_disc_illegal,
2842 lpfc_disc_illegal,
2843 lpfc_device_recov_mapped_node,
2844
2845 lpfc_rcv_plogi_npr_node,
2846 lpfc_rcv_prli_npr_node,
2847 lpfc_rcv_logo_npr_node,
2848 lpfc_rcv_padisc_npr_node,
2849 lpfc_rcv_padisc_npr_node,
2850 lpfc_rcv_prlo_npr_node,
2851 lpfc_cmpl_plogi_npr_node,
2852 lpfc_cmpl_prli_npr_node,
2853 lpfc_cmpl_logo_npr_node,
2854 lpfc_cmpl_adisc_npr_node,
2855 lpfc_cmpl_reglogin_npr_node,
2856 lpfc_device_rm_npr_node,
2857 lpfc_device_recov_npr_node,
2858};
2859
2860int
2861lpfc_disc_state_machine(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2862 void *arg, uint32_t evt)
2863{
2864 uint32_t cur_state, rc;
2865 uint32_t(*func) (struct lpfc_vport *, struct lpfc_nodelist *, void *,
2866 uint32_t);
2867 uint32_t got_ndlp = 0;
2868
2869 if (lpfc_nlp_get(ndlp))
2870 got_ndlp = 1;
2871
2872 cur_state = ndlp->nlp_state;
2873
2874
2875 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2876 "0211 DSM in event x%x on NPort x%x in "
2877 "state %d Data: x%x\n",
2878 evt, ndlp->nlp_DID, cur_state, ndlp->nlp_flag);
2879
2880 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
2881 "DSM in: evt:%d ste:%d did:x%x",
2882 evt, cur_state, ndlp->nlp_DID);
2883
2884 func = lpfc_disc_action[(cur_state * NLP_EVT_MAX_EVENT) + evt];
2885 rc = (func) (vport, ndlp, arg, evt);
2886
2887
2888 if (got_ndlp) {
2889 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2890 "0212 DSM out state %d on NPort x%x Data: x%x\n",
2891 rc, ndlp->nlp_DID, ndlp->nlp_flag);
2892
2893 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
2894 "DSM out: ste:%d did:x%x flg:x%x",
2895 rc, ndlp->nlp_DID, ndlp->nlp_flag);
2896
2897 lpfc_nlp_put(ndlp);
2898 } else {
2899 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2900 "0213 DSM out state %d on NPort free\n", rc);
2901
2902 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_DSM,
2903 "DSM out: ste:%d did:x%x flg:x%x",
2904 rc, 0, 0);
2905 }
2906
2907 return rc;
2908}
2909