1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/blkdev.h>
23#include <linux/pci.h>
24#include <linux/interrupt.h>
25
26#include <scsi/scsi.h>
27#include <scsi/scsi_device.h>
28#include <scsi/scsi_host.h>
29#include <scsi/scsi_transport_fc.h>
30
31#include "lpfc_hw.h"
32#include "lpfc_sli.h"
33#include "lpfc_nl.h"
34#include "lpfc_disc.h"
35#include "lpfc_scsi.h"
36#include "lpfc.h"
37#include "lpfc_logmsg.h"
38#include "lpfc_crtn.h"
39#include "lpfc_vport.h"
40#include "lpfc_debugfs.h"
41
42static int lpfc_els_retry(struct lpfc_hba *, struct lpfc_iocbq *,
43 struct lpfc_iocbq *);
44static void lpfc_cmpl_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *,
45 struct lpfc_iocbq *);
46static void lpfc_fabric_abort_vport(struct lpfc_vport *vport);
47static int lpfc_issue_els_fdisc(struct lpfc_vport *vport,
48 struct lpfc_nodelist *ndlp, uint8_t retry);
49static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba,
50 struct lpfc_iocbq *iocb);
51static void lpfc_register_new_vport(struct lpfc_hba *phba,
52 struct lpfc_vport *vport,
53 struct lpfc_nodelist *ndlp);
54
55static int lpfc_max_els_tries = 3;
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79int
80lpfc_els_chk_latt(struct lpfc_vport *vport)
81{
82 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
83 struct lpfc_hba *phba = vport->phba;
84 uint32_t ha_copy;
85
86 if (vport->port_state >= LPFC_VPORT_READY ||
87 phba->link_state == LPFC_LINK_DOWN)
88 return 0;
89
90
91 ha_copy = readl(phba->HAregaddr);
92
93 if (!(ha_copy & HA_LATT))
94 return 0;
95
96
97 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
98 "0237 Pending Link Event during "
99 "Discovery: State x%x\n",
100 phba->pport->port_state);
101
102
103
104
105
106
107
108 spin_lock_irq(shost->host_lock);
109 vport->fc_flag |= FC_ABORT_DISCOVERY;
110 spin_unlock_irq(shost->host_lock);
111
112 if (phba->link_state != LPFC_CLEAR_LA)
113 lpfc_issue_clear_la(phba, vport);
114
115 return 1;
116}
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146static struct lpfc_iocbq *
147lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
148 uint16_t cmdSize, uint8_t retry,
149 struct lpfc_nodelist *ndlp, uint32_t did,
150 uint32_t elscmd)
151{
152 struct lpfc_hba *phba = vport->phba;
153 struct lpfc_iocbq *elsiocb;
154 struct lpfc_dmabuf *pcmd, *prsp, *pbuflist;
155 struct ulp_bde64 *bpl;
156 IOCB_t *icmd;
157
158
159 if (!lpfc_is_link_up(phba))
160 return NULL;
161
162
163 elsiocb = lpfc_sli_get_iocbq(phba);
164
165 if (elsiocb == NULL)
166 return NULL;
167
168 icmd = &elsiocb->iocb;
169
170
171
172 pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
173 if (pcmd)
174 pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys);
175 if (!pcmd || !pcmd->virt)
176 goto els_iocb_free_pcmb_exit;
177
178 INIT_LIST_HEAD(&pcmd->list);
179
180
181 if (expectRsp) {
182 prsp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
183 if (prsp)
184 prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
185 &prsp->phys);
186 if (!prsp || !prsp->virt)
187 goto els_iocb_free_prsp_exit;
188 INIT_LIST_HEAD(&prsp->list);
189 } else
190 prsp = NULL;
191
192
193 pbuflist = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
194 if (pbuflist)
195 pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
196 &pbuflist->phys);
197 if (!pbuflist || !pbuflist->virt)
198 goto els_iocb_free_pbuf_exit;
199
200 INIT_LIST_HEAD(&pbuflist->list);
201
202 icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
203 icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
204 icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
205 icmd->un.elsreq64.remoteID = did;
206 if (expectRsp) {
207 icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
208 icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
209 icmd->ulpTimeout = phba->fc_ratov * 2;
210 } else {
211 icmd->un.elsreq64.bdl.bdeSize = sizeof(struct ulp_bde64);
212 icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX;
213 }
214 icmd->ulpBdeCount = 1;
215 icmd->ulpLe = 1;
216 icmd->ulpClass = CLASS3;
217
218 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
219 icmd->un.elsreq64.myID = vport->fc_myDID;
220
221
222 icmd->ulpContext = vport->vpi;
223 icmd->ulpCt_h = 0;
224 icmd->ulpCt_l = 1;
225 }
226
227 bpl = (struct ulp_bde64 *) pbuflist->virt;
228 bpl->addrLow = le32_to_cpu(putPaddrLow(pcmd->phys));
229 bpl->addrHigh = le32_to_cpu(putPaddrHigh(pcmd->phys));
230 bpl->tus.f.bdeSize = cmdSize;
231 bpl->tus.f.bdeFlags = 0;
232 bpl->tus.w = le32_to_cpu(bpl->tus.w);
233
234 if (expectRsp) {
235 bpl++;
236 bpl->addrLow = le32_to_cpu(putPaddrLow(prsp->phys));
237 bpl->addrHigh = le32_to_cpu(putPaddrHigh(prsp->phys));
238 bpl->tus.f.bdeSize = FCELSSIZE;
239 bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
240 bpl->tus.w = le32_to_cpu(bpl->tus.w);
241 }
242
243
244 elsiocb->context1 = lpfc_nlp_get(ndlp);
245 if (!elsiocb->context1)
246 goto els_iocb_free_pbuf_exit;
247 elsiocb->context2 = pcmd;
248 elsiocb->context3 = pbuflist;
249 elsiocb->retry = retry;
250 elsiocb->vport = vport;
251 elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT;
252
253 if (prsp) {
254 list_add(&prsp->list, &pcmd->list);
255 }
256 if (expectRsp) {
257
258 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
259 "0116 Xmit ELS command x%x to remote "
260 "NPORT x%x I/O tag: x%x, port state: x%x\n",
261 elscmd, did, elsiocb->iotag,
262 vport->port_state);
263 } else {
264
265 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
266 "0117 Xmit ELS response x%x to remote "
267 "NPORT x%x I/O tag: x%x, size: x%x\n",
268 elscmd, ndlp->nlp_DID, elsiocb->iotag,
269 cmdSize);
270 }
271 return elsiocb;
272
273els_iocb_free_pbuf_exit:
274 lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
275 kfree(pbuflist);
276
277els_iocb_free_prsp_exit:
278 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
279 kfree(prsp);
280
281els_iocb_free_pcmb_exit:
282 kfree(pcmd);
283 lpfc_sli_release_iocbq(phba, elsiocb);
284 return NULL;
285}
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303static int
304lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
305{
306 struct lpfc_hba *phba = vport->phba;
307 LPFC_MBOXQ_t *mbox;
308 struct lpfc_dmabuf *mp;
309 struct lpfc_nodelist *ndlp;
310 struct serv_parm *sp;
311 int rc;
312 int err = 0;
313
314 sp = &phba->fc_fabparam;
315 ndlp = lpfc_findnode_did(vport, Fabric_DID);
316 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
317 err = 1;
318 goto fail;
319 }
320
321 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
322 if (!mbox) {
323 err = 2;
324 goto fail;
325 }
326
327 vport->port_state = LPFC_FABRIC_CFG_LINK;
328 lpfc_config_link(phba, mbox);
329 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
330 mbox->vport = vport;
331
332 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
333 if (rc == MBX_NOT_FINISHED) {
334 err = 3;
335 goto fail_free_mbox;
336 }
337
338 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
339 if (!mbox) {
340 err = 4;
341 goto fail;
342 }
343 rc = lpfc_reg_login(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox,
344 0);
345 if (rc) {
346 err = 5;
347 goto fail_free_mbox;
348 }
349
350 mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login;
351 mbox->vport = vport;
352
353
354
355 mbox->context2 = lpfc_nlp_get(ndlp);
356
357 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
358 if (rc == MBX_NOT_FINISHED) {
359 err = 6;
360 goto fail_issue_reg_login;
361 }
362
363 return 0;
364
365fail_issue_reg_login:
366
367
368
369 lpfc_nlp_put(ndlp);
370 mp = (struct lpfc_dmabuf *) mbox->context1;
371 lpfc_mbuf_free(phba, mp->virt, mp->phys);
372 kfree(mp);
373fail_free_mbox:
374 mempool_free(mbox, phba->mbox_mem_pool);
375
376fail:
377 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
378 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
379 "0249 Cannot issue Register Fabric login: Err %d\n", err);
380 return -ENXIO;
381}
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403static int
404lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
405 struct serv_parm *sp, IOCB_t *irsp)
406{
407 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
408 struct lpfc_hba *phba = vport->phba;
409 struct lpfc_nodelist *np;
410 struct lpfc_nodelist *next_np;
411
412 spin_lock_irq(shost->host_lock);
413 vport->fc_flag |= FC_FABRIC;
414 spin_unlock_irq(shost->host_lock);
415
416 phba->fc_edtov = be32_to_cpu(sp->cmn.e_d_tov);
417 if (sp->cmn.edtovResolution)
418 phba->fc_edtov = (phba->fc_edtov + 999999) / 1000000;
419
420 phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
421
422 if (phba->fc_topology == TOPOLOGY_LOOP) {
423 spin_lock_irq(shost->host_lock);
424 vport->fc_flag |= FC_PUBLIC_LOOP;
425 spin_unlock_irq(shost->host_lock);
426 } else {
427
428
429
430
431 vport->fc_sparam.cmn.altBbCredit = 1;
432 }
433
434 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
435 memcpy(&ndlp->nlp_portname, &sp->portName, sizeof(struct lpfc_name));
436 memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof(struct lpfc_name));
437 ndlp->nlp_class_sup = 0;
438 if (sp->cls1.classValid)
439 ndlp->nlp_class_sup |= FC_COS_CLASS1;
440 if (sp->cls2.classValid)
441 ndlp->nlp_class_sup |= FC_COS_CLASS2;
442 if (sp->cls3.classValid)
443 ndlp->nlp_class_sup |= FC_COS_CLASS3;
444 if (sp->cls4.classValid)
445 ndlp->nlp_class_sup |= FC_COS_CLASS4;
446 ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
447 sp->cmn.bbRcvSizeLsb;
448 memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
449
450 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
451 if (sp->cmn.response_multiple_NPort) {
452 lpfc_printf_vlog(vport, KERN_WARNING,
453 LOG_ELS | LOG_VPORT,
454 "1816 FLOGI NPIV supported, "
455 "response data 0x%x\n",
456 sp->cmn.response_multiple_NPort);
457 phba->link_flag |= LS_NPIV_FAB_SUPPORTED;
458 } else {
459
460
461 lpfc_printf_vlog(vport, KERN_WARNING,
462 LOG_ELS | LOG_VPORT,
463 "1817 Fabric does not support NPIV "
464 "- configuring single port mode.\n");
465 phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
466 }
467 }
468
469 if ((vport->fc_prevDID != vport->fc_myDID) &&
470 !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
471
472
473
474
475 list_for_each_entry_safe(np, next_np,
476 &vport->fc_nodes, nlp_listp) {
477 if (!NLP_CHK_NODE_ACT(np))
478 continue;
479 if ((np->nlp_state != NLP_STE_NPR_NODE) ||
480 !(np->nlp_flag & NLP_NPR_ADISC))
481 continue;
482 spin_lock_irq(shost->host_lock);
483 np->nlp_flag &= ~NLP_NPR_ADISC;
484 spin_unlock_irq(shost->host_lock);
485 lpfc_unreg_rpi(vport, np);
486 }
487 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
488 lpfc_mbx_unreg_vpi(vport);
489 spin_lock_irq(shost->host_lock);
490 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
491 spin_unlock_irq(shost->host_lock);
492 }
493 }
494
495 lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE);
496
497 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED &&
498 vport->fc_flag & FC_VPORT_NEEDS_REG_VPI) {
499 lpfc_register_new_vport(phba, vport, ndlp);
500 return 0;
501 }
502 lpfc_issue_fabric_reglogin(vport);
503 return 0;
504}
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526static int
527lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
528 struct serv_parm *sp)
529{
530 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
531 struct lpfc_hba *phba = vport->phba;
532 LPFC_MBOXQ_t *mbox;
533 int rc;
534
535 spin_lock_irq(shost->host_lock);
536 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
537 spin_unlock_irq(shost->host_lock);
538
539 phba->fc_edtov = FF_DEF_EDTOV;
540 phba->fc_ratov = FF_DEF_RATOV;
541 rc = memcmp(&vport->fc_portname, &sp->portName,
542 sizeof(vport->fc_portname));
543 if (rc >= 0) {
544
545 spin_lock_irq(shost->host_lock);
546 vport->fc_flag |= FC_PT2PT_PLOGI;
547 spin_unlock_irq(shost->host_lock);
548
549
550
551
552
553
554
555 if (rc)
556 vport->fc_myDID = PT2PT_LocalID;
557
558 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
559 if (!mbox)
560 goto fail;
561
562 lpfc_config_link(phba, mbox);
563
564 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
565 mbox->vport = vport;
566 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
567 if (rc == MBX_NOT_FINISHED) {
568 mempool_free(mbox, phba->mbox_mem_pool);
569 goto fail;
570 }
571
572
573
574 lpfc_nlp_put(ndlp);
575
576 ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID);
577 if (!ndlp) {
578
579
580
581
582 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
583 if (!ndlp)
584 goto fail;
585 lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID);
586 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
587 ndlp = lpfc_enable_node(vport, ndlp,
588 NLP_STE_UNUSED_NODE);
589 if(!ndlp)
590 goto fail;
591 }
592
593 memcpy(&ndlp->nlp_portname, &sp->portName,
594 sizeof(struct lpfc_name));
595 memcpy(&ndlp->nlp_nodename, &sp->nodeName,
596 sizeof(struct lpfc_name));
597
598 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
599 spin_lock_irq(shost->host_lock);
600 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
601 spin_unlock_irq(shost->host_lock);
602 } else
603
604
605
606
607 lpfc_nlp_put(ndlp);
608
609
610 phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
611
612 spin_lock_irq(shost->host_lock);
613 vport->fc_flag |= FC_PT2PT;
614 spin_unlock_irq(shost->host_lock);
615
616
617 lpfc_disc_start(vport);
618 return 0;
619fail:
620 return -ENXIO;
621}
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646static void
647lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
648 struct lpfc_iocbq *rspiocb)
649{
650 struct lpfc_vport *vport = cmdiocb->vport;
651 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
652 IOCB_t *irsp = &rspiocb->iocb;
653 struct lpfc_nodelist *ndlp = cmdiocb->context1;
654 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
655 struct serv_parm *sp;
656 int rc;
657
658
659 if (lpfc_els_chk_latt(vport)) {
660
661
662
663 lpfc_nlp_put(ndlp);
664 goto out;
665 }
666
667 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
668 "FLOGI cmpl: status:x%x/x%x state:x%x",
669 irsp->ulpStatus, irsp->un.ulpWord[4],
670 vport->port_state);
671
672 if (irsp->ulpStatus) {
673
674 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
675 goto out;
676
677
678 spin_lock_irq(shost->host_lock);
679 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
680 spin_unlock_irq(shost->host_lock);
681
682
683
684
685
686 if (phba->alpa_map[0] == 0) {
687 vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
688 }
689
690
691 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
692 "0100 FLOGI failure Data: x%x x%x "
693 "x%x\n",
694 irsp->ulpStatus, irsp->un.ulpWord[4],
695 irsp->ulpTimeout);
696 goto flogifail;
697 }
698
699
700
701
702
703 prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
704
705 sp = prsp->virt + sizeof(uint32_t);
706
707
708 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
709 "0101 FLOGI completes sucessfully "
710 "Data: x%x x%x x%x x%x\n",
711 irsp->un.ulpWord[4], sp->cmn.e_d_tov,
712 sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution);
713
714 if (vport->port_state == LPFC_FLOGI) {
715
716
717
718
719 if (sp->cmn.fPort)
720 rc = lpfc_cmpl_els_flogi_fabric(vport, ndlp, sp, irsp);
721 else
722 rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
723
724 if (!rc)
725 goto out;
726 }
727
728flogifail:
729 lpfc_nlp_put(ndlp);
730
731 if (!lpfc_error_lost_link(irsp)) {
732
733 lpfc_disc_list_loopmap(vport);
734
735
736 lpfc_disc_start(vport);
737 } else if (((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
738 ((irsp->un.ulpWord[4] != IOERR_SLI_ABORTED) &&
739 (irsp->un.ulpWord[4] != IOERR_SLI_DOWN))) &&
740 (phba->link_state != LPFC_CLEAR_LA)) {
741
742 lpfc_issue_clear_la(phba, vport);
743 }
744out:
745 lpfc_els_free_iocb(phba, cmdiocb);
746}
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770static int
771lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
772 uint8_t retry)
773{
774 struct lpfc_hba *phba = vport->phba;
775 struct serv_parm *sp;
776 IOCB_t *icmd;
777 struct lpfc_iocbq *elsiocb;
778 struct lpfc_sli_ring *pring;
779 uint8_t *pcmd;
780 uint16_t cmdsize;
781 uint32_t tmo;
782 int rc;
783
784 pring = &phba->sli.ring[LPFC_ELS_RING];
785
786 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
787 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
788 ndlp->nlp_DID, ELS_CMD_FLOGI);
789
790 if (!elsiocb)
791 return 1;
792
793 icmd = &elsiocb->iocb;
794 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
795
796
797 *((uint32_t *) (pcmd)) = ELS_CMD_FLOGI;
798 pcmd += sizeof(uint32_t);
799 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
800 sp = (struct serv_parm *) pcmd;
801
802
803 sp->cmn.e_d_tov = 0;
804 sp->cmn.w2.r_a_tov = 0;
805 sp->cls1.classValid = 0;
806 sp->cls2.seqDelivery = 1;
807 sp->cls3.seqDelivery = 1;
808 if (sp->cmn.fcphLow < FC_PH3)
809 sp->cmn.fcphLow = FC_PH3;
810 if (sp->cmn.fcphHigh < FC_PH3)
811 sp->cmn.fcphHigh = FC_PH3;
812
813 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
814 sp->cmn.request_multiple_Nport = 1;
815
816
817 icmd->ulpCt_h = 1;
818 icmd->ulpCt_l = 0;
819 }
820
821 if (phba->fc_topology != TOPOLOGY_LOOP) {
822 icmd->un.elsreq64.myID = 0;
823 icmd->un.elsreq64.fl = 1;
824 }
825
826 tmo = phba->fc_ratov;
827 phba->fc_ratov = LPFC_DISC_FLOGI_TMO;
828 lpfc_set_disctmo(vport);
829 phba->fc_ratov = tmo;
830
831 phba->fc_stat.elsXmitFLOGI++;
832 elsiocb->iocb_cmpl = lpfc_cmpl_els_flogi;
833
834 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
835 "Issue FLOGI: opt:x%x",
836 phba->sli3_options, 0, 0);
837
838 rc = lpfc_issue_fabric_iocb(phba, elsiocb);
839 if (rc == IOCB_ERROR) {
840 lpfc_els_free_iocb(phba, elsiocb);
841 return 1;
842 }
843 return 0;
844}
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860int
861lpfc_els_abort_flogi(struct lpfc_hba *phba)
862{
863 struct lpfc_sli_ring *pring;
864 struct lpfc_iocbq *iocb, *next_iocb;
865 struct lpfc_nodelist *ndlp;
866 IOCB_t *icmd;
867
868
869 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
870 "0201 Abort outstanding I/O on NPort x%x\n",
871 Fabric_DID);
872
873 pring = &phba->sli.ring[LPFC_ELS_RING];
874
875
876
877
878
879 spin_lock_irq(&phba->hbalock);
880 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
881 icmd = &iocb->iocb;
882 if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
883 icmd->un.elsreq64.bdl.ulpIoTag32) {
884 ndlp = (struct lpfc_nodelist *)(iocb->context1);
885 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
886 (ndlp->nlp_DID == Fabric_DID))
887 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
888 }
889 }
890 spin_unlock_irq(&phba->hbalock);
891
892 return 0;
893}
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911int
912lpfc_initial_flogi(struct lpfc_vport *vport)
913{
914 struct lpfc_hba *phba = vport->phba;
915 struct lpfc_nodelist *ndlp;
916
917 vport->port_state = LPFC_FLOGI;
918 lpfc_set_disctmo(vport);
919
920
921 ndlp = lpfc_findnode_did(vport, Fabric_DID);
922 if (!ndlp) {
923
924 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
925 if (!ndlp)
926 return 0;
927 lpfc_nlp_init(vport, ndlp, Fabric_DID);
928
929 lpfc_enqueue_node(vport, ndlp);
930 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
931
932 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
933 if (!ndlp)
934 return 0;
935 }
936
937 if (lpfc_issue_els_flogi(vport, ndlp, 0))
938
939
940
941 lpfc_nlp_put(ndlp);
942
943 return 1;
944}
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962int
963lpfc_initial_fdisc(struct lpfc_vport *vport)
964{
965 struct lpfc_hba *phba = vport->phba;
966 struct lpfc_nodelist *ndlp;
967
968
969 ndlp = lpfc_findnode_did(vport, Fabric_DID);
970 if (!ndlp) {
971
972 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
973 if (!ndlp)
974 return 0;
975 lpfc_nlp_init(vport, ndlp, Fabric_DID);
976
977 lpfc_enqueue_node(vport, ndlp);
978 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
979
980 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
981 if (!ndlp)
982 return 0;
983 }
984
985 if (lpfc_issue_els_fdisc(vport, ndlp, 0)) {
986
987
988
989 lpfc_nlp_put(ndlp);
990 return 0;
991 }
992 return 1;
993}
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006void
1007lpfc_more_plogi(struct lpfc_vport *vport)
1008{
1009 int sentplogi;
1010
1011 if (vport->num_disc_nodes)
1012 vport->num_disc_nodes--;
1013
1014
1015 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1016 "0232 Continue discovery with %d PLOGIs to go "
1017 "Data: x%x x%x x%x\n",
1018 vport->num_disc_nodes, vport->fc_plogi_cnt,
1019 vport->fc_flag, vport->port_state);
1020
1021 if (vport->fc_flag & FC_NLP_MORE)
1022
1023 sentplogi = lpfc_els_disc_plogi(vport);
1024
1025 return;
1026}
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059static struct lpfc_nodelist *
1060lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
1061 struct lpfc_nodelist *ndlp)
1062{
1063 struct lpfc_vport *vport = ndlp->vport;
1064 struct lpfc_nodelist *new_ndlp;
1065 struct lpfc_rport_data *rdata;
1066 struct fc_rport *rport;
1067 struct serv_parm *sp;
1068 uint8_t name[sizeof(struct lpfc_name)];
1069 uint32_t rc, keepDID = 0;
1070
1071
1072
1073
1074 if (ndlp->nlp_type & NLP_FABRIC)
1075 return ndlp;
1076
1077 sp = (struct serv_parm *) ((uint8_t *) prsp + sizeof(uint32_t));
1078 memset(name, 0, sizeof(struct lpfc_name));
1079
1080
1081
1082
1083 new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName);
1084
1085 if (new_ndlp == ndlp && NLP_CHK_NODE_ACT(new_ndlp))
1086 return ndlp;
1087
1088 if (!new_ndlp) {
1089 rc = memcmp(&ndlp->nlp_portname, name,
1090 sizeof(struct lpfc_name));
1091 if (!rc)
1092 return ndlp;
1093 new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
1094 if (!new_ndlp)
1095 return ndlp;
1096 lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
1097 } else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
1098 rc = memcmp(&ndlp->nlp_portname, name,
1099 sizeof(struct lpfc_name));
1100 if (!rc)
1101 return ndlp;
1102 new_ndlp = lpfc_enable_node(vport, new_ndlp,
1103 NLP_STE_UNUSED_NODE);
1104 if (!new_ndlp)
1105 return ndlp;
1106 keepDID = new_ndlp->nlp_DID;
1107 } else
1108 keepDID = new_ndlp->nlp_DID;
1109
1110 lpfc_unreg_rpi(vport, new_ndlp);
1111 new_ndlp->nlp_DID = ndlp->nlp_DID;
1112 new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
1113
1114 if (ndlp->nlp_flag & NLP_NPR_2B_DISC)
1115 new_ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1116 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1117
1118
1119 lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state);
1120
1121
1122 if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) {
1123
1124
1125
1126
1127
1128 rport = ndlp->rport;
1129 if (rport) {
1130 rdata = rport->dd_data;
1131 if (rdata->pnode == ndlp) {
1132 lpfc_nlp_put(ndlp);
1133 ndlp->rport = NULL;
1134 rdata->pnode = lpfc_nlp_get(new_ndlp);
1135 new_ndlp->rport = rport;
1136 }
1137 new_ndlp->nlp_type = ndlp->nlp_type;
1138 }
1139
1140
1141
1142
1143 if (ndlp->nlp_DID == 0) {
1144 spin_lock_irq(&phba->ndlp_lock);
1145 NLP_SET_FREE_REQ(ndlp);
1146 spin_unlock_irq(&phba->ndlp_lock);
1147 }
1148
1149
1150 ndlp->nlp_DID = keepDID;
1151 lpfc_drop_node(vport, ndlp);
1152 }
1153 else {
1154 lpfc_unreg_rpi(vport, ndlp);
1155
1156 ndlp->nlp_DID = keepDID;
1157 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1158 }
1159 return new_ndlp;
1160}
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173void
1174lpfc_end_rscn(struct lpfc_vport *vport)
1175{
1176 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1177
1178 if (vport->fc_flag & FC_RSCN_MODE) {
1179
1180
1181
1182
1183 if (vport->fc_rscn_id_cnt ||
1184 (vport->fc_flag & FC_RSCN_DISCOVERY) != 0)
1185 lpfc_els_handle_rscn(vport);
1186 else {
1187 spin_lock_irq(shost->host_lock);
1188 vport->fc_flag &= ~FC_RSCN_MODE;
1189 spin_unlock_irq(shost->host_lock);
1190 }
1191 }
1192}
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214static void
1215lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1216 struct lpfc_iocbq *rspiocb)
1217{
1218 struct lpfc_vport *vport = cmdiocb->vport;
1219 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1220 IOCB_t *irsp;
1221 struct lpfc_nodelist *ndlp;
1222 struct lpfc_dmabuf *prsp;
1223 int disc, rc, did, type;
1224
1225
1226 cmdiocb->context_un.rsp_iocb = rspiocb;
1227
1228 irsp = &rspiocb->iocb;
1229 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1230 "PLOGI cmpl: status:x%x/x%x did:x%x",
1231 irsp->ulpStatus, irsp->un.ulpWord[4],
1232 irsp->un.elsreq64.remoteID);
1233
1234 ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
1235 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
1236 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1237 "0136 PLOGI completes to NPort x%x "
1238 "with no ndlp. Data: x%x x%x x%x\n",
1239 irsp->un.elsreq64.remoteID,
1240 irsp->ulpStatus, irsp->un.ulpWord[4],
1241 irsp->ulpIoTag);
1242 goto out;
1243 }
1244
1245
1246
1247
1248 spin_lock_irq(shost->host_lock);
1249 disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
1250 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1251 spin_unlock_irq(shost->host_lock);
1252 rc = 0;
1253
1254
1255 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1256 "0102 PLOGI completes to NPort x%x "
1257 "Data: x%x x%x x%x x%x x%x\n",
1258 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
1259 irsp->ulpTimeout, disc, vport->num_disc_nodes);
1260
1261 if (lpfc_els_chk_latt(vport)) {
1262 spin_lock_irq(shost->host_lock);
1263 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1264 spin_unlock_irq(shost->host_lock);
1265 goto out;
1266 }
1267
1268
1269 type = ndlp->nlp_type;
1270 did = ndlp->nlp_DID;
1271
1272 if (irsp->ulpStatus) {
1273
1274 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
1275
1276 if (disc) {
1277 spin_lock_irq(shost->host_lock);
1278 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1279 spin_unlock_irq(shost->host_lock);
1280 }
1281 goto out;
1282 }
1283
1284
1285 if (lpfc_error_lost_link(irsp))
1286 rc = NLP_STE_FREED_NODE;
1287 else
1288 rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1289 NLP_EVT_CMPL_PLOGI);
1290 } else {
1291
1292 prsp = list_entry(((struct lpfc_dmabuf *)
1293 cmdiocb->context2)->list.next,
1294 struct lpfc_dmabuf, list);
1295 ndlp = lpfc_plogi_confirm_nport(phba, prsp->virt, ndlp);
1296 rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1297 NLP_EVT_CMPL_PLOGI);
1298 }
1299
1300 if (disc && vport->num_disc_nodes) {
1301
1302 lpfc_more_plogi(vport);
1303
1304 if (vport->num_disc_nodes == 0) {
1305 spin_lock_irq(shost->host_lock);
1306 vport->fc_flag &= ~FC_NDISC_ACTIVE;
1307 spin_unlock_irq(shost->host_lock);
1308
1309 lpfc_can_disctmo(vport);
1310 lpfc_end_rscn(vport);
1311 }
1312 }
1313
1314out:
1315 lpfc_els_free_iocb(phba, cmdiocb);
1316 return;
1317}
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340int
1341lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
1342{
1343 struct lpfc_hba *phba = vport->phba;
1344 struct serv_parm *sp;
1345 IOCB_t *icmd;
1346 struct lpfc_nodelist *ndlp;
1347 struct lpfc_iocbq *elsiocb;
1348 struct lpfc_sli_ring *pring;
1349 struct lpfc_sli *psli;
1350 uint8_t *pcmd;
1351 uint16_t cmdsize;
1352 int ret;
1353
1354 psli = &phba->sli;
1355 pring = &psli->ring[LPFC_ELS_RING];
1356
1357 ndlp = lpfc_findnode_did(vport, did);
1358 if (ndlp && !NLP_CHK_NODE_ACT(ndlp))
1359 ndlp = NULL;
1360
1361
1362 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
1363 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
1364 ELS_CMD_PLOGI);
1365 if (!elsiocb)
1366 return 1;
1367
1368 icmd = &elsiocb->iocb;
1369 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1370
1371
1372 *((uint32_t *) (pcmd)) = ELS_CMD_PLOGI;
1373 pcmd += sizeof(uint32_t);
1374 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
1375 sp = (struct serv_parm *) pcmd;
1376
1377 if (sp->cmn.fcphLow < FC_PH_4_3)
1378 sp->cmn.fcphLow = FC_PH_4_3;
1379
1380 if (sp->cmn.fcphHigh < FC_PH3)
1381 sp->cmn.fcphHigh = FC_PH3;
1382
1383 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1384 "Issue PLOGI: did:x%x",
1385 did, 0, 0);
1386
1387 phba->fc_stat.elsXmitPLOGI++;
1388 elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi;
1389 ret = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
1390
1391 if (ret == IOCB_ERROR) {
1392 lpfc_els_free_iocb(phba, elsiocb);
1393 return 1;
1394 }
1395 return 0;
1396}
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411static void
1412lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1413 struct lpfc_iocbq *rspiocb)
1414{
1415 struct lpfc_vport *vport = cmdiocb->vport;
1416 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1417 IOCB_t *irsp;
1418 struct lpfc_sli *psli;
1419 struct lpfc_nodelist *ndlp;
1420
1421 psli = &phba->sli;
1422
1423 cmdiocb->context_un.rsp_iocb = rspiocb;
1424
1425 irsp = &(rspiocb->iocb);
1426 ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
1427 spin_lock_irq(shost->host_lock);
1428 ndlp->nlp_flag &= ~NLP_PRLI_SND;
1429 spin_unlock_irq(shost->host_lock);
1430
1431 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1432 "PRLI cmpl: status:x%x/x%x did:x%x",
1433 irsp->ulpStatus, irsp->un.ulpWord[4],
1434 ndlp->nlp_DID);
1435
1436 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1437 "0103 PRLI completes to NPort x%x "
1438 "Data: x%x x%x x%x x%x\n",
1439 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
1440 irsp->ulpTimeout, vport->num_disc_nodes);
1441
1442 vport->fc_prli_sent--;
1443
1444 if (lpfc_els_chk_latt(vport))
1445 goto out;
1446
1447 if (irsp->ulpStatus) {
1448
1449 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
1450
1451 goto out;
1452 }
1453
1454
1455 if (lpfc_error_lost_link(irsp))
1456 goto out;
1457 else
1458 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1459 NLP_EVT_CMPL_PRLI);
1460 } else
1461
1462 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1463 NLP_EVT_CMPL_PRLI);
1464out:
1465 lpfc_els_free_iocb(phba, cmdiocb);
1466 return;
1467}
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490int
1491lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1492 uint8_t retry)
1493{
1494 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1495 struct lpfc_hba *phba = vport->phba;
1496 PRLI *npr;
1497 IOCB_t *icmd;
1498 struct lpfc_iocbq *elsiocb;
1499 struct lpfc_sli_ring *pring;
1500 struct lpfc_sli *psli;
1501 uint8_t *pcmd;
1502 uint16_t cmdsize;
1503
1504 psli = &phba->sli;
1505 pring = &psli->ring[LPFC_ELS_RING];
1506
1507 cmdsize = (sizeof(uint32_t) + sizeof(PRLI));
1508 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1509 ndlp->nlp_DID, ELS_CMD_PRLI);
1510 if (!elsiocb)
1511 return 1;
1512
1513 icmd = &elsiocb->iocb;
1514 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1515
1516
1517 memset(pcmd, 0, (sizeof(PRLI) + sizeof(uint32_t)));
1518 *((uint32_t *) (pcmd)) = ELS_CMD_PRLI;
1519 pcmd += sizeof(uint32_t);
1520
1521
1522 npr = (PRLI *) pcmd;
1523
1524
1525
1526
1527 if (phba->vpd.rev.feaLevelHigh >= 0x02) {
1528 npr->ConfmComplAllowed = 1;
1529 npr->Retry = 1;
1530 npr->TaskRetryIdReq = 1;
1531 }
1532 npr->estabImagePair = 1;
1533 npr->readXferRdyDis = 1;
1534
1535
1536 npr->prliType = PRLI_FCP_TYPE;
1537 npr->initiatorFunc = 1;
1538
1539 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1540 "Issue PRLI: did:x%x",
1541 ndlp->nlp_DID, 0, 0);
1542
1543 phba->fc_stat.elsXmitPRLI++;
1544 elsiocb->iocb_cmpl = lpfc_cmpl_els_prli;
1545 spin_lock_irq(shost->host_lock);
1546 ndlp->nlp_flag |= NLP_PRLI_SND;
1547 spin_unlock_irq(shost->host_lock);
1548 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
1549 spin_lock_irq(shost->host_lock);
1550 ndlp->nlp_flag &= ~NLP_PRLI_SND;
1551 spin_unlock_irq(shost->host_lock);
1552 lpfc_els_free_iocb(phba, elsiocb);
1553 return 1;
1554 }
1555 vport->fc_prli_sent++;
1556 return 0;
1557}
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571static void
1572lpfc_rscn_disc(struct lpfc_vport *vport)
1573{
1574 lpfc_can_disctmo(vport);
1575
1576
1577
1578 if (vport->fc_npr_cnt)
1579 if (lpfc_els_disc_plogi(vport))
1580 return;
1581
1582 lpfc_end_rscn(vport);
1583}
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595static void
1596lpfc_adisc_done(struct lpfc_vport *vport)
1597{
1598 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1599 struct lpfc_hba *phba = vport->phba;
1600
1601
1602
1603
1604
1605 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
1606 !(vport->fc_flag & FC_RSCN_MODE)) {
1607 lpfc_issue_reg_vpi(phba, vport);
1608 return;
1609 }
1610
1611
1612
1613
1614 if (vport->port_state < LPFC_VPORT_READY) {
1615
1616 if (vport->port_type == LPFC_PHYSICAL_PORT)
1617 lpfc_issue_clear_la(phba, vport);
1618 if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
1619 vport->num_disc_nodes = 0;
1620
1621 if (vport->fc_npr_cnt)
1622 lpfc_els_disc_plogi(vport);
1623 if (!vport->num_disc_nodes) {
1624 spin_lock_irq(shost->host_lock);
1625 vport->fc_flag &= ~FC_NDISC_ACTIVE;
1626 spin_unlock_irq(shost->host_lock);
1627 lpfc_can_disctmo(vport);
1628 lpfc_end_rscn(vport);
1629 }
1630 }
1631 vport->port_state = LPFC_VPORT_READY;
1632 } else
1633 lpfc_rscn_disc(vport);
1634}
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645void
1646lpfc_more_adisc(struct lpfc_vport *vport)
1647{
1648 int sentadisc;
1649
1650 if (vport->num_disc_nodes)
1651 vport->num_disc_nodes--;
1652
1653 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1654 "0210 Continue discovery with %d ADISCs to go "
1655 "Data: x%x x%x x%x\n",
1656 vport->num_disc_nodes, vport->fc_adisc_cnt,
1657 vport->fc_flag, vport->port_state);
1658
1659 if (vport->fc_flag & FC_NLP_MORE) {
1660 lpfc_set_disctmo(vport);
1661
1662 sentadisc = lpfc_els_disc_adisc(vport);
1663 }
1664 if (!vport->num_disc_nodes)
1665 lpfc_adisc_done(vport);
1666 return;
1667}
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685static void
1686lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1687 struct lpfc_iocbq *rspiocb)
1688{
1689 struct lpfc_vport *vport = cmdiocb->vport;
1690 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1691 IOCB_t *irsp;
1692 struct lpfc_nodelist *ndlp;
1693 int disc;
1694
1695
1696 cmdiocb->context_un.rsp_iocb = rspiocb;
1697
1698 irsp = &(rspiocb->iocb);
1699 ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
1700
1701 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1702 "ADISC cmpl: status:x%x/x%x did:x%x",
1703 irsp->ulpStatus, irsp->un.ulpWord[4],
1704 ndlp->nlp_DID);
1705
1706
1707
1708
1709 spin_lock_irq(shost->host_lock);
1710 disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
1711 ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC);
1712 spin_unlock_irq(shost->host_lock);
1713
1714 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1715 "0104 ADISC completes to NPort x%x "
1716 "Data: x%x x%x x%x x%x x%x\n",
1717 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
1718 irsp->ulpTimeout, disc, vport->num_disc_nodes);
1719
1720 if (lpfc_els_chk_latt(vport)) {
1721 spin_lock_irq(shost->host_lock);
1722 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1723 spin_unlock_irq(shost->host_lock);
1724 goto out;
1725 }
1726
1727 if (irsp->ulpStatus) {
1728
1729 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
1730
1731 if (disc) {
1732 spin_lock_irq(shost->host_lock);
1733 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1734 spin_unlock_irq(shost->host_lock);
1735 lpfc_set_disctmo(vport);
1736 }
1737 goto out;
1738 }
1739
1740
1741 if (!lpfc_error_lost_link(irsp))
1742 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1743 NLP_EVT_CMPL_ADISC);
1744 } else
1745
1746 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1747 NLP_EVT_CMPL_ADISC);
1748
1749
1750 if (disc && vport->num_disc_nodes)
1751 lpfc_more_adisc(vport);
1752out:
1753 lpfc_els_free_iocb(phba, cmdiocb);
1754 return;
1755}
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777int
1778lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1779 uint8_t retry)
1780{
1781 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1782 struct lpfc_hba *phba = vport->phba;
1783 ADISC *ap;
1784 IOCB_t *icmd;
1785 struct lpfc_iocbq *elsiocb;
1786 struct lpfc_sli *psli = &phba->sli;
1787 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
1788 uint8_t *pcmd;
1789 uint16_t cmdsize;
1790
1791 cmdsize = (sizeof(uint32_t) + sizeof(ADISC));
1792 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1793 ndlp->nlp_DID, ELS_CMD_ADISC);
1794 if (!elsiocb)
1795 return 1;
1796
1797 icmd = &elsiocb->iocb;
1798 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1799
1800
1801 *((uint32_t *) (pcmd)) = ELS_CMD_ADISC;
1802 pcmd += sizeof(uint32_t);
1803
1804
1805 ap = (ADISC *) pcmd;
1806 ap->hardAL_PA = phba->fc_pref_ALPA;
1807 memcpy(&ap->portName, &vport->fc_portname, sizeof(struct lpfc_name));
1808 memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
1809 ap->DID = be32_to_cpu(vport->fc_myDID);
1810
1811 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1812 "Issue ADISC: did:x%x",
1813 ndlp->nlp_DID, 0, 0);
1814
1815 phba->fc_stat.elsXmitADISC++;
1816 elsiocb->iocb_cmpl = lpfc_cmpl_els_adisc;
1817 spin_lock_irq(shost->host_lock);
1818 ndlp->nlp_flag |= NLP_ADISC_SND;
1819 spin_unlock_irq(shost->host_lock);
1820 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
1821 spin_lock_irq(shost->host_lock);
1822 ndlp->nlp_flag &= ~NLP_ADISC_SND;
1823 spin_unlock_irq(shost->host_lock);
1824 lpfc_els_free_iocb(phba, elsiocb);
1825 return 1;
1826 }
1827 return 0;
1828}
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842static void
1843lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1844 struct lpfc_iocbq *rspiocb)
1845{
1846 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
1847 struct lpfc_vport *vport = ndlp->vport;
1848 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1849 IOCB_t *irsp;
1850 struct lpfc_sli *psli;
1851
1852 psli = &phba->sli;
1853
1854 cmdiocb->context_un.rsp_iocb = rspiocb;
1855
1856 irsp = &(rspiocb->iocb);
1857 spin_lock_irq(shost->host_lock);
1858 ndlp->nlp_flag &= ~NLP_LOGO_SND;
1859 spin_unlock_irq(shost->host_lock);
1860
1861 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1862 "LOGO cmpl: status:x%x/x%x did:x%x",
1863 irsp->ulpStatus, irsp->un.ulpWord[4],
1864 ndlp->nlp_DID);
1865
1866 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1867 "0105 LOGO completes to NPort x%x "
1868 "Data: x%x x%x x%x x%x\n",
1869 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
1870 irsp->ulpTimeout, vport->num_disc_nodes);
1871
1872 if (lpfc_els_chk_latt(vport))
1873 goto out;
1874
1875 if (ndlp->nlp_flag & NLP_TARGET_REMOVE) {
1876
1877
1878
1879 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1880 NLP_EVT_DEVICE_RM);
1881 goto out;
1882 }
1883
1884 if (irsp->ulpStatus) {
1885
1886 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
1887
1888 goto out;
1889
1890
1891 if (lpfc_error_lost_link(irsp))
1892 goto out;
1893 else
1894 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1895 NLP_EVT_CMPL_LOGO);
1896 } else
1897
1898
1899
1900 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1901 NLP_EVT_CMPL_LOGO);
1902out:
1903 lpfc_els_free_iocb(phba, cmdiocb);
1904 return;
1905}
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927int
1928lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1929 uint8_t retry)
1930{
1931 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1932 struct lpfc_hba *phba = vport->phba;
1933 IOCB_t *icmd;
1934 struct lpfc_iocbq *elsiocb;
1935 struct lpfc_sli_ring *pring;
1936 struct lpfc_sli *psli;
1937 uint8_t *pcmd;
1938 uint16_t cmdsize;
1939 int rc;
1940
1941 psli = &phba->sli;
1942 pring = &psli->ring[LPFC_ELS_RING];
1943
1944 spin_lock_irq(shost->host_lock);
1945 if (ndlp->nlp_flag & NLP_LOGO_SND) {
1946 spin_unlock_irq(shost->host_lock);
1947 return 0;
1948 }
1949 spin_unlock_irq(shost->host_lock);
1950
1951 cmdsize = (2 * sizeof(uint32_t)) + sizeof(struct lpfc_name);
1952 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1953 ndlp->nlp_DID, ELS_CMD_LOGO);
1954 if (!elsiocb)
1955 return 1;
1956
1957 icmd = &elsiocb->iocb;
1958 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1959 *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
1960 pcmd += sizeof(uint32_t);
1961
1962
1963 *((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID);
1964 pcmd += sizeof(uint32_t);
1965 memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name));
1966
1967 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1968 "Issue LOGO: did:x%x",
1969 ndlp->nlp_DID, 0, 0);
1970
1971 phba->fc_stat.elsXmitLOGO++;
1972 elsiocb->iocb_cmpl = lpfc_cmpl_els_logo;
1973 spin_lock_irq(shost->host_lock);
1974 ndlp->nlp_flag |= NLP_LOGO_SND;
1975 spin_unlock_irq(shost->host_lock);
1976 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
1977
1978 if (rc == IOCB_ERROR) {
1979 spin_lock_irq(shost->host_lock);
1980 ndlp->nlp_flag &= ~NLP_LOGO_SND;
1981 spin_unlock_irq(shost->host_lock);
1982 lpfc_els_free_iocb(phba, elsiocb);
1983 return 1;
1984 }
1985 return 0;
1986}
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004static void
2005lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2006 struct lpfc_iocbq *rspiocb)
2007{
2008 struct lpfc_vport *vport = cmdiocb->vport;
2009 IOCB_t *irsp;
2010
2011 irsp = &rspiocb->iocb;
2012
2013 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2014 "ELS cmd cmpl: status:x%x/x%x did:x%x",
2015 irsp->ulpStatus, irsp->un.ulpWord[4],
2016 irsp->un.elsreq64.remoteID);
2017
2018 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2019 "0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n",
2020 irsp->ulpIoTag, irsp->ulpStatus,
2021 irsp->un.ulpWord[4], irsp->ulpTimeout);
2022
2023 lpfc_els_chk_latt(vport);
2024 lpfc_els_free_iocb(phba, cmdiocb);
2025 return;
2026}
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050int
2051lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
2052{
2053 struct lpfc_hba *phba = vport->phba;
2054 IOCB_t *icmd;
2055 struct lpfc_iocbq *elsiocb;
2056 struct lpfc_sli_ring *pring;
2057 struct lpfc_sli *psli;
2058 uint8_t *pcmd;
2059 uint16_t cmdsize;
2060 struct lpfc_nodelist *ndlp;
2061
2062 psli = &phba->sli;
2063 pring = &psli->ring[LPFC_ELS_RING];
2064 cmdsize = (sizeof(uint32_t) + sizeof(SCR));
2065
2066 ndlp = lpfc_findnode_did(vport, nportid);
2067 if (!ndlp) {
2068 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
2069 if (!ndlp)
2070 return 1;
2071 lpfc_nlp_init(vport, ndlp, nportid);
2072 lpfc_enqueue_node(vport, ndlp);
2073 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
2074 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
2075 if (!ndlp)
2076 return 1;
2077 }
2078
2079 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
2080 ndlp->nlp_DID, ELS_CMD_SCR);
2081
2082 if (!elsiocb) {
2083
2084
2085
2086 lpfc_nlp_put(ndlp);
2087 return 1;
2088 }
2089
2090 icmd = &elsiocb->iocb;
2091 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2092
2093 *((uint32_t *) (pcmd)) = ELS_CMD_SCR;
2094 pcmd += sizeof(uint32_t);
2095
2096
2097 memset(pcmd, 0, sizeof(SCR));
2098 ((SCR *) pcmd)->Function = SCR_FUNC_FULL;
2099
2100 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2101 "Issue SCR: did:x%x",
2102 ndlp->nlp_DID, 0, 0);
2103
2104 phba->fc_stat.elsXmitSCR++;
2105 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
2106 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2107
2108
2109
2110
2111 lpfc_nlp_put(ndlp);
2112 lpfc_els_free_iocb(phba, elsiocb);
2113 return 1;
2114 }
2115
2116
2117
2118 lpfc_nlp_put(ndlp);
2119 return 0;
2120}
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144static int
2145lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
2146{
2147 struct lpfc_hba *phba = vport->phba;
2148 IOCB_t *icmd;
2149 struct lpfc_iocbq *elsiocb;
2150 struct lpfc_sli_ring *pring;
2151 struct lpfc_sli *psli;
2152 FARP *fp;
2153 uint8_t *pcmd;
2154 uint32_t *lp;
2155 uint16_t cmdsize;
2156 struct lpfc_nodelist *ondlp;
2157 struct lpfc_nodelist *ndlp;
2158
2159 psli = &phba->sli;
2160 pring = &psli->ring[LPFC_ELS_RING];
2161 cmdsize = (sizeof(uint32_t) + sizeof(FARP));
2162
2163 ndlp = lpfc_findnode_did(vport, nportid);
2164 if (!ndlp) {
2165 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
2166 if (!ndlp)
2167 return 1;
2168 lpfc_nlp_init(vport, ndlp, nportid);
2169 lpfc_enqueue_node(vport, ndlp);
2170 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
2171 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
2172 if (!ndlp)
2173 return 1;
2174 }
2175
2176 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
2177 ndlp->nlp_DID, ELS_CMD_RNID);
2178 if (!elsiocb) {
2179
2180
2181
2182 lpfc_nlp_put(ndlp);
2183 return 1;
2184 }
2185
2186 icmd = &elsiocb->iocb;
2187 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2188
2189 *((uint32_t *) (pcmd)) = ELS_CMD_FARPR;
2190 pcmd += sizeof(uint32_t);
2191
2192
2193 fp = (FARP *) (pcmd);
2194 memset(fp, 0, sizeof(FARP));
2195 lp = (uint32_t *) pcmd;
2196 *lp++ = be32_to_cpu(nportid);
2197 *lp++ = be32_to_cpu(vport->fc_myDID);
2198 fp->Rflags = 0;
2199 fp->Mflags = (FARP_MATCH_PORT | FARP_MATCH_NODE);
2200
2201 memcpy(&fp->RportName, &vport->fc_portname, sizeof(struct lpfc_name));
2202 memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
2203 ondlp = lpfc_findnode_did(vport, nportid);
2204 if (ondlp && NLP_CHK_NODE_ACT(ondlp)) {
2205 memcpy(&fp->OportName, &ondlp->nlp_portname,
2206 sizeof(struct lpfc_name));
2207 memcpy(&fp->OnodeName, &ondlp->nlp_nodename,
2208 sizeof(struct lpfc_name));
2209 }
2210
2211 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2212 "Issue FARPR: did:x%x",
2213 ndlp->nlp_DID, 0, 0);
2214
2215 phba->fc_stat.elsXmitFARPR++;
2216 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
2217 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
2218
2219
2220
2221
2222 lpfc_nlp_put(ndlp);
2223 lpfc_els_free_iocb(phba, elsiocb);
2224 return 1;
2225 }
2226
2227
2228
2229 lpfc_nlp_put(ndlp);
2230 return 0;
2231}
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245void
2246lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
2247{
2248 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2249 struct lpfc_work_evt *evtp;
2250
2251 if (!(nlp->nlp_flag & NLP_DELAY_TMO))
2252 return;
2253 spin_lock_irq(shost->host_lock);
2254 nlp->nlp_flag &= ~NLP_DELAY_TMO;
2255 spin_unlock_irq(shost->host_lock);
2256 del_timer_sync(&nlp->nlp_delayfunc);
2257 nlp->nlp_last_elscmd = 0;
2258 if (!list_empty(&nlp->els_retry_evt.evt_listp)) {
2259 list_del_init(&nlp->els_retry_evt.evt_listp);
2260
2261 evtp = &nlp->els_retry_evt;
2262 lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1);
2263 }
2264 if (nlp->nlp_flag & NLP_NPR_2B_DISC) {
2265 spin_lock_irq(shost->host_lock);
2266 nlp->nlp_flag &= ~NLP_NPR_2B_DISC;
2267 spin_unlock_irq(shost->host_lock);
2268 if (vport->num_disc_nodes) {
2269 if (vport->port_state < LPFC_VPORT_READY) {
2270
2271 lpfc_more_adisc(vport);
2272 } else {
2273
2274 lpfc_more_plogi(vport);
2275 if (vport->num_disc_nodes == 0) {
2276 spin_lock_irq(shost->host_lock);
2277 vport->fc_flag &= ~FC_NDISC_ACTIVE;
2278 spin_unlock_irq(shost->host_lock);
2279 lpfc_can_disctmo(vport);
2280 lpfc_end_rscn(vport);
2281 }
2282 }
2283 }
2284 }
2285 return;
2286}
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302void
2303lpfc_els_retry_delay(unsigned long ptr)
2304{
2305 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) ptr;
2306 struct lpfc_vport *vport = ndlp->vport;
2307 struct lpfc_hba *phba = vport->phba;
2308 unsigned long flags;
2309 struct lpfc_work_evt *evtp = &ndlp->els_retry_evt;
2310
2311 spin_lock_irqsave(&phba->hbalock, flags);
2312 if (!list_empty(&evtp->evt_listp)) {
2313 spin_unlock_irqrestore(&phba->hbalock, flags);
2314 return;
2315 }
2316
2317
2318
2319
2320 evtp->evt_arg1 = lpfc_nlp_get(ndlp);
2321 if (evtp->evt_arg1) {
2322 evtp->evt = LPFC_EVT_ELS_RETRY;
2323 list_add_tail(&evtp->evt_listp, &phba->work_list);
2324 lpfc_worker_wake_up(phba);
2325 }
2326 spin_unlock_irqrestore(&phba->hbalock, flags);
2327 return;
2328}
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339void
2340lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
2341{
2342 struct lpfc_vport *vport = ndlp->vport;
2343 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2344 uint32_t cmd, did, retry;
2345
2346 spin_lock_irq(shost->host_lock);
2347 did = ndlp->nlp_DID;
2348 cmd = ndlp->nlp_last_elscmd;
2349 ndlp->nlp_last_elscmd = 0;
2350
2351 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
2352 spin_unlock_irq(shost->host_lock);
2353 return;
2354 }
2355
2356 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
2357 spin_unlock_irq(shost->host_lock);
2358
2359
2360
2361
2362
2363 del_timer_sync(&ndlp->nlp_delayfunc);
2364 retry = ndlp->nlp_retry;
2365
2366 switch (cmd) {
2367 case ELS_CMD_FLOGI:
2368 lpfc_issue_els_flogi(vport, ndlp, retry);
2369 break;
2370 case ELS_CMD_PLOGI:
2371 if (!lpfc_issue_els_plogi(vport, ndlp->nlp_DID, retry)) {
2372 ndlp->nlp_prev_state = ndlp->nlp_state;
2373 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
2374 }
2375 break;
2376 case ELS_CMD_ADISC:
2377 if (!lpfc_issue_els_adisc(vport, ndlp, retry)) {
2378 ndlp->nlp_prev_state = ndlp->nlp_state;
2379 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2380 }
2381 break;
2382 case ELS_CMD_PRLI:
2383 if (!lpfc_issue_els_prli(vport, ndlp, retry)) {
2384 ndlp->nlp_prev_state = ndlp->nlp_state;
2385 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
2386 }
2387 break;
2388 case ELS_CMD_LOGO:
2389 if (!lpfc_issue_els_logo(vport, ndlp, retry)) {
2390 ndlp->nlp_prev_state = ndlp->nlp_state;
2391 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2392 }
2393 break;
2394 case ELS_CMD_FDISC:
2395 lpfc_issue_els_fdisc(vport, ndlp, retry);
2396 break;
2397 }
2398 return;
2399}
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422static int
2423lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2424 struct lpfc_iocbq *rspiocb)
2425{
2426 struct lpfc_vport *vport = cmdiocb->vport;
2427 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2428 IOCB_t *irsp = &rspiocb->iocb;
2429 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2430 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
2431 uint32_t *elscmd;
2432 struct ls_rjt stat;
2433 int retry = 0, maxretry = lpfc_max_els_tries, delay = 0;
2434 int logerr = 0;
2435 uint32_t cmd = 0;
2436 uint32_t did;
2437
2438
2439
2440
2441
2442
2443 if (pcmd && pcmd->virt) {
2444 elscmd = (uint32_t *) (pcmd->virt);
2445 cmd = *elscmd++;
2446 }
2447
2448 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
2449 did = ndlp->nlp_DID;
2450 else {
2451
2452 did = irsp->un.elsreq64.remoteID;
2453 ndlp = lpfc_findnode_did(vport, did);
2454 if ((!ndlp || !NLP_CHK_NODE_ACT(ndlp))
2455 && (cmd != ELS_CMD_PLOGI))
2456 return 1;
2457 }
2458
2459 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2460 "Retry ELS: wd7:x%x wd4:x%x did:x%x",
2461 *(((uint32_t *) irsp) + 7), irsp->un.ulpWord[4], ndlp->nlp_DID);
2462
2463 switch (irsp->ulpStatus) {
2464 case IOSTAT_FCP_RSP_ERROR:
2465 case IOSTAT_REMOTE_STOP:
2466 break;
2467
2468 case IOSTAT_LOCAL_REJECT:
2469 switch ((irsp->un.ulpWord[4] & 0xff)) {
2470 case IOERR_LOOP_OPEN_FAILURE:
2471 if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0)
2472 delay = 1000;
2473 retry = 1;
2474 break;
2475
2476 case IOERR_ILLEGAL_COMMAND:
2477 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
2478 "0124 Retry illegal cmd x%x "
2479 "retry:x%x delay:x%x\n",
2480 cmd, cmdiocb->retry, delay);
2481 retry = 1;
2482
2483 maxretry = 8;
2484 if (cmdiocb->retry > 2)
2485 delay = 1000;
2486 break;
2487
2488 case IOERR_NO_RESOURCES:
2489 logerr = 1;
2490 retry = 1;
2491 if (cmdiocb->retry > 100)
2492 delay = 100;
2493 maxretry = 250;
2494 break;
2495
2496 case IOERR_ILLEGAL_FRAME:
2497 delay = 100;
2498 retry = 1;
2499 break;
2500
2501 case IOERR_SEQUENCE_TIMEOUT:
2502 case IOERR_INVALID_RPI:
2503 retry = 1;
2504 break;
2505 }
2506 break;
2507
2508 case IOSTAT_NPORT_RJT:
2509 case IOSTAT_FABRIC_RJT:
2510 if (irsp->un.ulpWord[4] & RJT_UNAVAIL_TEMP) {
2511 retry = 1;
2512 break;
2513 }
2514 break;
2515
2516 case IOSTAT_NPORT_BSY:
2517 case IOSTAT_FABRIC_BSY:
2518 logerr = 1;
2519 retry = 1;
2520 break;
2521
2522 case IOSTAT_LS_RJT:
2523 stat.un.lsRjtError = be32_to_cpu(irsp->un.ulpWord[4]);
2524
2525
2526
2527 switch (stat.un.b.lsRjtRsnCode) {
2528 case LSRJT_UNABLE_TPC:
2529 if (stat.un.b.lsRjtRsnCodeExp ==
2530 LSEXP_CMD_IN_PROGRESS) {
2531 if (cmd == ELS_CMD_PLOGI) {
2532 delay = 1000;
2533 maxretry = 48;
2534 }
2535 retry = 1;
2536 break;
2537 }
2538 if (cmd == ELS_CMD_PLOGI) {
2539 delay = 1000;
2540 maxretry = lpfc_max_els_tries + 1;
2541 retry = 1;
2542 break;
2543 }
2544 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
2545 (cmd == ELS_CMD_FDISC) &&
2546 (stat.un.b.lsRjtRsnCodeExp == LSEXP_OUT_OF_RESOURCE)){
2547 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
2548 "0125 FDISC Failed (x%x). "
2549 "Fabric out of resources\n",
2550 stat.un.lsRjtError);
2551 lpfc_vport_set_state(vport,
2552 FC_VPORT_NO_FABRIC_RSCS);
2553 }
2554 break;
2555
2556 case LSRJT_LOGICAL_BSY:
2557 if ((cmd == ELS_CMD_PLOGI) ||
2558 (cmd == ELS_CMD_PRLI)) {
2559 delay = 1000;
2560 maxretry = 48;
2561 } else if (cmd == ELS_CMD_FDISC) {
2562
2563 maxretry = 48;
2564 if (cmdiocb->retry >= 32)
2565 delay = 1000;
2566 }
2567 retry = 1;
2568 break;
2569
2570 case LSRJT_LOGICAL_ERR:
2571
2572
2573
2574
2575 if (cmd == ELS_CMD_FDISC &&
2576 stat.un.b.lsRjtRsnCodeExp == LSEXP_PORT_LOGIN_REQ) {
2577 maxretry = 3;
2578 delay = 1000;
2579 retry = 1;
2580 break;
2581 }
2582 case LSRJT_PROTOCOL_ERR:
2583 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
2584 (cmd == ELS_CMD_FDISC) &&
2585 ((stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_PNAME) ||
2586 (stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_NPORT_ID))
2587 ) {
2588 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
2589 "0122 FDISC Failed (x%x). "
2590 "Fabric Detected Bad WWN\n",
2591 stat.un.lsRjtError);
2592 lpfc_vport_set_state(vport,
2593 FC_VPORT_FABRIC_REJ_WWN);
2594 }
2595 break;
2596 }
2597 break;
2598
2599 case IOSTAT_INTERMED_RSP:
2600 case IOSTAT_BA_RJT:
2601 break;
2602
2603 default:
2604 break;
2605 }
2606
2607 if (did == FDMI_DID)
2608 retry = 1;
2609
2610 if ((cmd == ELS_CMD_FLOGI) &&
2611 (phba->fc_topology != TOPOLOGY_LOOP) &&
2612 !lpfc_error_lost_link(irsp)) {
2613
2614 retry = 1;
2615 maxretry = 48;
2616 if (cmdiocb->retry >= 32)
2617 delay = 1000;
2618 }
2619
2620 if ((++cmdiocb->retry) >= maxretry) {
2621 phba->fc_stat.elsRetryExceeded++;
2622 retry = 0;
2623 }
2624
2625 if ((vport->load_flag & FC_UNLOADING) != 0)
2626 retry = 0;
2627
2628 if (retry) {
2629
2630
2631 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2632 "0107 Retry ELS command x%x to remote "
2633 "NPORT x%x Data: x%x x%x\n",
2634 cmd, did, cmdiocb->retry, delay);
2635
2636 if (((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) &&
2637 ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
2638 ((irsp->un.ulpWord[4] & 0xff) != IOERR_NO_RESOURCES))) {
2639
2640
2641
2642 if (timer_pending(&vport->fc_disctmo) ||
2643 (vport->fc_flag & FC_RSCN_MODE))
2644 lpfc_set_disctmo(vport);
2645 }
2646
2647 phba->fc_stat.elsXmitRetry++;
2648 if (ndlp && NLP_CHK_NODE_ACT(ndlp) && delay) {
2649 phba->fc_stat.elsDelayRetry++;
2650 ndlp->nlp_retry = cmdiocb->retry;
2651
2652
2653 mod_timer(&ndlp->nlp_delayfunc,
2654 jiffies + msecs_to_jiffies(delay));
2655 spin_lock_irq(shost->host_lock);
2656 ndlp->nlp_flag |= NLP_DELAY_TMO;
2657 spin_unlock_irq(shost->host_lock);
2658
2659 ndlp->nlp_prev_state = ndlp->nlp_state;
2660 if (cmd == ELS_CMD_PRLI)
2661 lpfc_nlp_set_state(vport, ndlp,
2662 NLP_STE_REG_LOGIN_ISSUE);
2663 else
2664 lpfc_nlp_set_state(vport, ndlp,
2665 NLP_STE_NPR_NODE);
2666 ndlp->nlp_last_elscmd = cmd;
2667
2668 return 1;
2669 }
2670 switch (cmd) {
2671 case ELS_CMD_FLOGI:
2672 lpfc_issue_els_flogi(vport, ndlp, cmdiocb->retry);
2673 return 1;
2674 case ELS_CMD_FDISC:
2675 lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry);
2676 return 1;
2677 case ELS_CMD_PLOGI:
2678 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
2679 ndlp->nlp_prev_state = ndlp->nlp_state;
2680 lpfc_nlp_set_state(vport, ndlp,
2681 NLP_STE_PLOGI_ISSUE);
2682 }
2683 lpfc_issue_els_plogi(vport, did, cmdiocb->retry);
2684 return 1;
2685 case ELS_CMD_ADISC:
2686 ndlp->nlp_prev_state = ndlp->nlp_state;
2687 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
2688 lpfc_issue_els_adisc(vport, ndlp, cmdiocb->retry);
2689 return 1;
2690 case ELS_CMD_PRLI:
2691 ndlp->nlp_prev_state = ndlp->nlp_state;
2692 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
2693 lpfc_issue_els_prli(vport, ndlp, cmdiocb->retry);
2694 return 1;
2695 case ELS_CMD_LOGO:
2696 ndlp->nlp_prev_state = ndlp->nlp_state;
2697 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
2698 lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry);
2699 return 1;
2700 }
2701 }
2702
2703 if (logerr) {
2704 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
2705 "0137 No retry ELS command x%x to remote "
2706 "NPORT x%x: Out of Resources: Error:x%x/%x\n",
2707 cmd, did, irsp->ulpStatus,
2708 irsp->un.ulpWord[4]);
2709 }
2710 else {
2711 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2712 "0108 No retry ELS command x%x to remote "
2713 "NPORT x%x Retried:%d Error:x%x/%x\n",
2714 cmd, did, cmdiocb->retry, irsp->ulpStatus,
2715 irsp->un.ulpWord[4]);
2716 }
2717 return 0;
2718}
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734static int
2735lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1)
2736{
2737 struct lpfc_dmabuf *buf_ptr;
2738
2739
2740 if (!list_empty(&buf_ptr1->list)) {
2741 list_remove_head(&buf_ptr1->list, buf_ptr,
2742 struct lpfc_dmabuf,
2743 list);
2744 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
2745 kfree(buf_ptr);
2746 }
2747 lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys);
2748 kfree(buf_ptr1);
2749 return 0;
2750}
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764static int
2765lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr)
2766{
2767 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
2768 kfree(buf_ptr);
2769 return 0;
2770}
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799int
2800lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
2801{
2802 struct lpfc_dmabuf *buf_ptr, *buf_ptr1;
2803 struct lpfc_nodelist *ndlp;
2804
2805 ndlp = (struct lpfc_nodelist *)elsiocb->context1;
2806 if (ndlp) {
2807 if (ndlp->nlp_flag & NLP_DEFER_RM) {
2808 lpfc_nlp_put(ndlp);
2809
2810
2811
2812
2813 if (!lpfc_nlp_not_used(ndlp)) {
2814
2815
2816
2817 ndlp->nlp_flag &= ~NLP_DEFER_RM;
2818 }
2819 }
2820 else
2821 lpfc_nlp_put(ndlp);
2822 elsiocb->context1 = NULL;
2823 }
2824
2825 if (elsiocb->context2) {
2826 if (elsiocb->iocb_flag & LPFC_DELAY_MEM_FREE) {
2827
2828
2829
2830
2831 elsiocb->iocb_flag &= ~LPFC_DELAY_MEM_FREE;
2832 buf_ptr = elsiocb->context2;
2833 elsiocb->context2 = NULL;
2834 if (buf_ptr) {
2835 buf_ptr1 = NULL;
2836 spin_lock_irq(&phba->hbalock);
2837 if (!list_empty(&buf_ptr->list)) {
2838 list_remove_head(&buf_ptr->list,
2839 buf_ptr1, struct lpfc_dmabuf,
2840 list);
2841 INIT_LIST_HEAD(&buf_ptr1->list);
2842 list_add_tail(&buf_ptr1->list,
2843 &phba->elsbuf);
2844 phba->elsbuf_cnt++;
2845 }
2846 INIT_LIST_HEAD(&buf_ptr->list);
2847 list_add_tail(&buf_ptr->list, &phba->elsbuf);
2848 phba->elsbuf_cnt++;
2849 spin_unlock_irq(&phba->hbalock);
2850 }
2851 } else {
2852 buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2;
2853 lpfc_els_free_data(phba, buf_ptr1);
2854 }
2855 }
2856
2857 if (elsiocb->context3) {
2858 buf_ptr = (struct lpfc_dmabuf *) elsiocb->context3;
2859 lpfc_els_free_bpl(phba, buf_ptr);
2860 }
2861 lpfc_sli_release_iocbq(phba, elsiocb);
2862 return 0;
2863}
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882static void
2883lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2884 struct lpfc_iocbq *rspiocb)
2885{
2886 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2887 struct lpfc_vport *vport = cmdiocb->vport;
2888 IOCB_t *irsp;
2889
2890 irsp = &rspiocb->iocb;
2891 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
2892 "ACC LOGO cmpl: status:x%x/x%x did:x%x",
2893 irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID);
2894
2895 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2896 "0109 ACC to LOGO completes to NPort x%x "
2897 "Data: x%x x%x x%x\n",
2898 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
2899 ndlp->nlp_rpi);
2900
2901 if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
2902
2903 if (!lpfc_nlp_not_used(ndlp)) {
2904
2905
2906
2907 lpfc_unreg_rpi(vport, ndlp);
2908 } else {
2909
2910
2911
2912 cmdiocb->context1 = NULL;
2913 }
2914 }
2915 lpfc_els_free_iocb(phba, cmdiocb);
2916 return;
2917}
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932void
2933lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
2934{
2935 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
2936 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
2937
2938 pmb->context1 = NULL;
2939 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2940 kfree(mp);
2941 mempool_free(pmb, phba->mbox_mem_pool);
2942 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
2943 lpfc_nlp_put(ndlp);
2944
2945
2946
2947
2948 lpfc_nlp_not_used(ndlp);
2949 }
2950 return;
2951}
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969static void
2970lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2971 struct lpfc_iocbq *rspiocb)
2972{
2973 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2974 struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL;
2975 struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
2976 IOCB_t *irsp;
2977 uint8_t *pcmd;
2978 LPFC_MBOXQ_t *mbox = NULL;
2979 struct lpfc_dmabuf *mp = NULL;
2980 uint32_t ls_rjt = 0;
2981
2982 irsp = &rspiocb->iocb;
2983
2984 if (cmdiocb->context_un.mbox)
2985 mbox = cmdiocb->context_un.mbox;
2986
2987
2988
2989
2990 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
2991 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
2992 (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
2993
2994
2995
2996 if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
2997 ls_rjt = 1;
2998 }
2999
3000
3001 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) {
3002 if (mbox) {
3003 mp = (struct lpfc_dmabuf *) mbox->context1;
3004 if (mp) {
3005 lpfc_mbuf_free(phba, mp->virt, mp->phys);
3006 kfree(mp);
3007 }
3008 mempool_free(mbox, phba->mbox_mem_pool);
3009 }
3010 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
3011 (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
3012 if (lpfc_nlp_not_used(ndlp)) {
3013 ndlp = NULL;
3014
3015
3016
3017
3018 cmdiocb->context1 = NULL;
3019 }
3020 goto out;
3021 }
3022
3023 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3024 "ELS rsp cmpl: status:x%x/x%x did:x%x",
3025 irsp->ulpStatus, irsp->un.ulpWord[4],
3026 cmdiocb->iocb.un.elsreq64.remoteID);
3027
3028 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3029 "0110 ELS response tag x%x completes "
3030 "Data: x%x x%x x%x x%x x%x x%x x%x\n",
3031 cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus,
3032 rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout,
3033 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
3034 ndlp->nlp_rpi);
3035 if (mbox) {
3036 if ((rspiocb->iocb.ulpStatus == 0)
3037 && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) {
3038 lpfc_unreg_rpi(vport, ndlp);
3039
3040
3041
3042 mbox->context2 = lpfc_nlp_get(ndlp);
3043 mbox->vport = vport;
3044 if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) {
3045 mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
3046 mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
3047 }
3048 else {
3049 mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
3050 ndlp->nlp_prev_state = ndlp->nlp_state;
3051 lpfc_nlp_set_state(vport, ndlp,
3052 NLP_STE_REG_LOGIN_ISSUE);
3053 }
3054 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
3055 != MBX_NOT_FINISHED)
3056 goto out;
3057 else
3058
3059
3060
3061 lpfc_nlp_put(ndlp);
3062
3063
3064 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
3065 "0138 ELS rsp: Cannot issue reg_login for x%x "
3066 "Data: x%x x%x x%x\n",
3067 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
3068 ndlp->nlp_rpi);
3069
3070 if (lpfc_nlp_not_used(ndlp)) {
3071 ndlp = NULL;
3072
3073
3074
3075
3076 cmdiocb->context1 = NULL;
3077 }
3078 } else {
3079
3080 if (!lpfc_error_lost_link(irsp) &&
3081 ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
3082 if (lpfc_nlp_not_used(ndlp)) {
3083 ndlp = NULL;
3084
3085
3086
3087
3088
3089 cmdiocb->context1 = NULL;
3090 }
3091 }
3092 }
3093 mp = (struct lpfc_dmabuf *) mbox->context1;
3094 if (mp) {
3095 lpfc_mbuf_free(phba, mp->virt, mp->phys);
3096 kfree(mp);
3097 }
3098 mempool_free(mbox, phba->mbox_mem_pool);
3099 }
3100out:
3101 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
3102 spin_lock_irq(shost->host_lock);
3103 ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI);
3104 spin_unlock_irq(shost->host_lock);
3105
3106
3107
3108
3109
3110
3111 if (ls_rjt)
3112 if (lpfc_nlp_not_used(ndlp))
3113
3114
3115
3116
3117 cmdiocb->context1 = NULL;
3118 }
3119
3120 lpfc_els_free_iocb(phba, cmdiocb);
3121 return;
3122}
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149int
3150lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
3151 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
3152 LPFC_MBOXQ_t *mbox)
3153{
3154 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3155 struct lpfc_hba *phba = vport->phba;
3156 IOCB_t *icmd;
3157 IOCB_t *oldcmd;
3158 struct lpfc_iocbq *elsiocb;
3159 struct lpfc_sli_ring *pring;
3160 struct lpfc_sli *psli;
3161 uint8_t *pcmd;
3162 uint16_t cmdsize;
3163 int rc;
3164 ELS_PKT *els_pkt_ptr;
3165
3166 psli = &phba->sli;
3167 pring = &psli->ring[LPFC_ELS_RING];
3168 oldcmd = &oldiocb->iocb;
3169
3170 switch (flag) {
3171 case ELS_CMD_ACC:
3172 cmdsize = sizeof(uint32_t);
3173 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
3174 ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
3175 if (!elsiocb) {
3176 spin_lock_irq(shost->host_lock);
3177 ndlp->nlp_flag &= ~NLP_LOGO_ACC;
3178 spin_unlock_irq(shost->host_lock);
3179 return 1;
3180 }
3181
3182 icmd = &elsiocb->iocb;
3183 icmd->ulpContext = oldcmd->ulpContext;
3184 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3185 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
3186 pcmd += sizeof(uint32_t);
3187
3188 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3189 "Issue ACC: did:x%x flg:x%x",
3190 ndlp->nlp_DID, ndlp->nlp_flag, 0);
3191 break;
3192 case ELS_CMD_PLOGI:
3193 cmdsize = (sizeof(struct serv_parm) + sizeof(uint32_t));
3194 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
3195 ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
3196 if (!elsiocb)
3197 return 1;
3198
3199 icmd = &elsiocb->iocb;
3200 icmd->ulpContext = oldcmd->ulpContext;
3201 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3202
3203 if (mbox)
3204 elsiocb->context_un.mbox = mbox;
3205
3206 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
3207 pcmd += sizeof(uint32_t);
3208 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
3209
3210 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3211 "Issue ACC PLOGI: did:x%x flg:x%x",
3212 ndlp->nlp_DID, ndlp->nlp_flag, 0);
3213 break;
3214 case ELS_CMD_PRLO:
3215 cmdsize = sizeof(uint32_t) + sizeof(PRLO);
3216 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
3217 ndlp, ndlp->nlp_DID, ELS_CMD_PRLO);
3218 if (!elsiocb)
3219 return 1;
3220
3221 icmd = &elsiocb->iocb;
3222 icmd->ulpContext = oldcmd->ulpContext;
3223 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3224
3225 memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt,
3226 sizeof(uint32_t) + sizeof(PRLO));
3227 *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC;
3228 els_pkt_ptr = (ELS_PKT *) pcmd;
3229 els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
3230
3231 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3232 "Issue ACC PRLO: did:x%x flg:x%x",
3233 ndlp->nlp_DID, ndlp->nlp_flag, 0);
3234 break;
3235 default:
3236 return 1;
3237 }
3238
3239 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3240 "0128 Xmit ELS ACC response tag x%x, XRI: x%x, "
3241 "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x\n",
3242 elsiocb->iotag, elsiocb->iocb.ulpContext,
3243 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
3244 ndlp->nlp_rpi);
3245 if (ndlp->nlp_flag & NLP_LOGO_ACC) {
3246 spin_lock_irq(shost->host_lock);
3247 ndlp->nlp_flag &= ~NLP_LOGO_ACC;
3248 spin_unlock_irq(shost->host_lock);
3249 elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc;
3250 } else {
3251 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
3252 }
3253
3254 phba->fc_stat.elsXmitACC++;
3255 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
3256 if (rc == IOCB_ERROR) {
3257 lpfc_els_free_iocb(phba, elsiocb);
3258 return 1;
3259 }
3260 return 0;
3261}
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285int
3286lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
3287 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
3288 LPFC_MBOXQ_t *mbox)
3289{
3290 struct lpfc_hba *phba = vport->phba;
3291 IOCB_t *icmd;
3292 IOCB_t *oldcmd;
3293 struct lpfc_iocbq *elsiocb;
3294 struct lpfc_sli_ring *pring;
3295 struct lpfc_sli *psli;
3296 uint8_t *pcmd;
3297 uint16_t cmdsize;
3298 int rc;
3299
3300 psli = &phba->sli;
3301 pring = &psli->ring[LPFC_ELS_RING];
3302
3303 cmdsize = 2 * sizeof(uint32_t);
3304 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
3305 ndlp->nlp_DID, ELS_CMD_LS_RJT);
3306 if (!elsiocb)
3307 return 1;
3308
3309 icmd = &elsiocb->iocb;
3310 oldcmd = &oldiocb->iocb;
3311 icmd->ulpContext = oldcmd->ulpContext;
3312 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3313
3314 *((uint32_t *) (pcmd)) = ELS_CMD_LS_RJT;
3315 pcmd += sizeof(uint32_t);
3316 *((uint32_t *) (pcmd)) = rejectError;
3317
3318 if (mbox)
3319 elsiocb->context_un.mbox = mbox;
3320
3321
3322 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3323 "0129 Xmit ELS RJT x%x response tag x%x "
3324 "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
3325 "rpi x%x\n",
3326 rejectError, elsiocb->iotag,
3327 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
3328 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
3329 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3330 "Issue LS_RJT: did:x%x flg:x%x err:x%x",
3331 ndlp->nlp_DID, ndlp->nlp_flag, rejectError);
3332
3333 phba->fc_stat.elsXmitLSRJT++;
3334 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
3335 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
3336
3337 if (rc == IOCB_ERROR) {
3338 lpfc_els_free_iocb(phba, elsiocb);
3339 return 1;
3340 }
3341 return 0;
3342}
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363int
3364lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
3365 struct lpfc_nodelist *ndlp)
3366{
3367 struct lpfc_hba *phba = vport->phba;
3368 struct lpfc_sli *psli = &phba->sli;
3369 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
3370 ADISC *ap;
3371 IOCB_t *icmd, *oldcmd;
3372 struct lpfc_iocbq *elsiocb;
3373 uint8_t *pcmd;
3374 uint16_t cmdsize;
3375 int rc;
3376
3377 cmdsize = sizeof(uint32_t) + sizeof(ADISC);
3378 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
3379 ndlp->nlp_DID, ELS_CMD_ACC);
3380 if (!elsiocb)
3381 return 1;
3382
3383 icmd = &elsiocb->iocb;
3384 oldcmd = &oldiocb->iocb;
3385 icmd->ulpContext = oldcmd->ulpContext;
3386
3387
3388 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3389 "0130 Xmit ADISC ACC response iotag x%x xri: "
3390 "x%x, did x%x, nlp_flag x%x, nlp_state x%x rpi x%x\n",
3391 elsiocb->iotag, elsiocb->iocb.ulpContext,
3392 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
3393 ndlp->nlp_rpi);
3394 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3395
3396 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
3397 pcmd += sizeof(uint32_t);
3398
3399 ap = (ADISC *) (pcmd);
3400 ap->hardAL_PA = phba->fc_pref_ALPA;
3401 memcpy(&ap->portName, &vport->fc_portname, sizeof(struct lpfc_name));
3402 memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
3403 ap->DID = be32_to_cpu(vport->fc_myDID);
3404
3405 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3406 "Issue ACC ADISC: did:x%x flg:x%x",
3407 ndlp->nlp_DID, ndlp->nlp_flag, 0);
3408
3409 phba->fc_stat.elsXmitACC++;
3410 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
3411 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
3412 if (rc == IOCB_ERROR) {
3413 lpfc_els_free_iocb(phba, elsiocb);
3414 return 1;
3415 }
3416 return 0;
3417}
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438int
3439lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
3440 struct lpfc_nodelist *ndlp)
3441{
3442 struct lpfc_hba *phba = vport->phba;
3443 PRLI *npr;
3444 lpfc_vpd_t *vpd;
3445 IOCB_t *icmd;
3446 IOCB_t *oldcmd;
3447 struct lpfc_iocbq *elsiocb;
3448 struct lpfc_sli_ring *pring;
3449 struct lpfc_sli *psli;
3450 uint8_t *pcmd;
3451 uint16_t cmdsize;
3452 int rc;
3453
3454 psli = &phba->sli;
3455 pring = &psli->ring[LPFC_ELS_RING];
3456
3457 cmdsize = sizeof(uint32_t) + sizeof(PRLI);
3458 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
3459 ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)));
3460 if (!elsiocb)
3461 return 1;
3462
3463 icmd = &elsiocb->iocb;
3464 oldcmd = &oldiocb->iocb;
3465 icmd->ulpContext = oldcmd->ulpContext;
3466
3467 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3468 "0131 Xmit PRLI ACC response tag x%x xri x%x, "
3469 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
3470 elsiocb->iotag, elsiocb->iocb.ulpContext,
3471 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
3472 ndlp->nlp_rpi);
3473 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3474
3475 *((uint32_t *) (pcmd)) = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK));
3476 pcmd += sizeof(uint32_t);
3477
3478
3479 memset(pcmd, 0, sizeof(PRLI));
3480
3481 npr = (PRLI *) pcmd;
3482 vpd = &phba->vpd;
3483
3484
3485
3486
3487 if ((ndlp->nlp_type & NLP_FCP_TARGET) &&
3488 (vpd->rev.feaLevelHigh >= 0x02)) {
3489 npr->ConfmComplAllowed = 1;
3490 npr->Retry = 1;
3491 npr->TaskRetryIdReq = 1;
3492 }
3493
3494 npr->acceptRspCode = PRLI_REQ_EXECUTED;
3495 npr->estabImagePair = 1;
3496 npr->readXferRdyDis = 1;
3497 npr->ConfmComplAllowed = 1;
3498
3499 npr->prliType = PRLI_FCP_TYPE;
3500 npr->initiatorFunc = 1;
3501
3502 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3503 "Issue ACC PRLI: did:x%x flg:x%x",
3504 ndlp->nlp_DID, ndlp->nlp_flag, 0);
3505
3506 phba->fc_stat.elsXmitACC++;
3507 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
3508
3509 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
3510 if (rc == IOCB_ERROR) {
3511 lpfc_els_free_iocb(phba, elsiocb);
3512 return 1;
3513 }
3514 return 0;
3515}
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543static int
3544lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
3545 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
3546{
3547 struct lpfc_hba *phba = vport->phba;
3548 RNID *rn;
3549 IOCB_t *icmd, *oldcmd;
3550 struct lpfc_iocbq *elsiocb;
3551 struct lpfc_sli_ring *pring;
3552 struct lpfc_sli *psli;
3553 uint8_t *pcmd;
3554 uint16_t cmdsize;
3555 int rc;
3556
3557 psli = &phba->sli;
3558 pring = &psli->ring[LPFC_ELS_RING];
3559
3560 cmdsize = sizeof(uint32_t) + sizeof(uint32_t)
3561 + (2 * sizeof(struct lpfc_name));
3562 if (format)
3563 cmdsize += sizeof(RNID_TOP_DISC);
3564
3565 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
3566 ndlp->nlp_DID, ELS_CMD_ACC);
3567 if (!elsiocb)
3568 return 1;
3569
3570 icmd = &elsiocb->iocb;
3571 oldcmd = &oldiocb->iocb;
3572 icmd->ulpContext = oldcmd->ulpContext;
3573
3574 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3575 "0132 Xmit RNID ACC response tag x%x xri x%x\n",
3576 elsiocb->iotag, elsiocb->iocb.ulpContext);
3577 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3578 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
3579 pcmd += sizeof(uint32_t);
3580
3581 memset(pcmd, 0, sizeof(RNID));
3582 rn = (RNID *) (pcmd);
3583 rn->Format = format;
3584 rn->CommonLen = (2 * sizeof(struct lpfc_name));
3585 memcpy(&rn->portName, &vport->fc_portname, sizeof(struct lpfc_name));
3586 memcpy(&rn->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
3587 switch (format) {
3588 case 0:
3589 rn->SpecificLen = 0;
3590 break;
3591 case RNID_TOPOLOGY_DISC:
3592 rn->SpecificLen = sizeof(RNID_TOP_DISC);
3593 memcpy(&rn->un.topologyDisc.portName,
3594 &vport->fc_portname, sizeof(struct lpfc_name));
3595 rn->un.topologyDisc.unitType = RNID_HBA;
3596 rn->un.topologyDisc.physPort = 0;
3597 rn->un.topologyDisc.attachedNodes = 0;
3598 break;
3599 default:
3600 rn->CommonLen = 0;
3601 rn->SpecificLen = 0;
3602 break;
3603 }
3604
3605 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3606 "Issue ACC RNID: did:x%x flg:x%x",
3607 ndlp->nlp_DID, ndlp->nlp_flag, 0);
3608
3609 phba->fc_stat.elsXmitACC++;
3610 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
3611 lpfc_nlp_put(ndlp);
3612 elsiocb->context1 = NULL;
3613
3614
3615 rc = lpfc_sli_issue_iocb(phba, pring, elsiocb, 0);
3616 if (rc == IOCB_ERROR) {
3617 lpfc_els_free_iocb(phba, elsiocb);
3618 return 1;
3619 }
3620 return 0;
3621}
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642int
3643lpfc_els_disc_adisc(struct lpfc_vport *vport)
3644{
3645 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3646 struct lpfc_nodelist *ndlp, *next_ndlp;
3647 int sentadisc = 0;
3648
3649
3650 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
3651 if (!NLP_CHK_NODE_ACT(ndlp))
3652 continue;
3653 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
3654 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
3655 (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) {
3656 spin_lock_irq(shost->host_lock);
3657 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
3658 spin_unlock_irq(shost->host_lock);
3659 ndlp->nlp_prev_state = ndlp->nlp_state;
3660 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
3661 lpfc_issue_els_adisc(vport, ndlp, 0);
3662 sentadisc++;
3663 vport->num_disc_nodes++;
3664 if (vport->num_disc_nodes >=
3665 vport->cfg_discovery_threads) {
3666 spin_lock_irq(shost->host_lock);
3667 vport->fc_flag |= FC_NLP_MORE;
3668 spin_unlock_irq(shost->host_lock);
3669 break;
3670 }
3671 }
3672 }
3673 if (sentadisc == 0) {
3674 spin_lock_irq(shost->host_lock);
3675 vport->fc_flag &= ~FC_NLP_MORE;
3676 spin_unlock_irq(shost->host_lock);
3677 }
3678 return sentadisc;
3679}
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700int
3701lpfc_els_disc_plogi(struct lpfc_vport *vport)
3702{
3703 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3704 struct lpfc_nodelist *ndlp, *next_ndlp;
3705 int sentplogi = 0;
3706
3707
3708 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
3709 if (!NLP_CHK_NODE_ACT(ndlp))
3710 continue;
3711 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
3712 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
3713 (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 &&
3714 (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) {
3715 ndlp->nlp_prev_state = ndlp->nlp_state;
3716 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
3717 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
3718 sentplogi++;
3719 vport->num_disc_nodes++;
3720 if (vport->num_disc_nodes >=
3721 vport->cfg_discovery_threads) {
3722 spin_lock_irq(shost->host_lock);
3723 vport->fc_flag |= FC_NLP_MORE;
3724 spin_unlock_irq(shost->host_lock);
3725 break;
3726 }
3727 }
3728 }
3729 if (sentplogi) {
3730 lpfc_set_disctmo(vport);
3731 }
3732 else {
3733 spin_lock_irq(shost->host_lock);
3734 vport->fc_flag &= ~FC_NLP_MORE;
3735 spin_unlock_irq(shost->host_lock);
3736 }
3737 return sentplogi;
3738}
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749void
3750lpfc_els_flush_rscn(struct lpfc_vport *vport)
3751{
3752 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3753 struct lpfc_hba *phba = vport->phba;
3754 int i;
3755
3756 spin_lock_irq(shost->host_lock);
3757 if (vport->fc_rscn_flush) {
3758
3759 spin_unlock_irq(shost->host_lock);
3760 return;
3761 }
3762
3763 vport->fc_rscn_flush = 1;
3764 spin_unlock_irq(shost->host_lock);
3765
3766 for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
3767 lpfc_in_buf_free(phba, vport->fc_rscn_id_list[i]);
3768 vport->fc_rscn_id_list[i] = NULL;
3769 }
3770 spin_lock_irq(shost->host_lock);
3771 vport->fc_rscn_id_cnt = 0;
3772 vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY);
3773 spin_unlock_irq(shost->host_lock);
3774 lpfc_can_disctmo(vport);
3775
3776 vport->fc_rscn_flush = 0;
3777}
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791int
3792lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
3793{
3794 D_ID ns_did;
3795 D_ID rscn_did;
3796 uint32_t *lp;
3797 uint32_t payload_len, i;
3798 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3799
3800 ns_did.un.word = did;
3801
3802
3803 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
3804 return 0;
3805
3806
3807 if (vport->fc_flag & FC_RSCN_DISCOVERY)
3808 return did;
3809
3810 spin_lock_irq(shost->host_lock);
3811 if (vport->fc_rscn_flush) {
3812
3813 spin_unlock_irq(shost->host_lock);
3814 return 0;
3815 }
3816
3817 vport->fc_rscn_flush = 1;
3818 spin_unlock_irq(shost->host_lock);
3819 for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
3820 lp = vport->fc_rscn_id_list[i]->virt;
3821 payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK);
3822 payload_len -= sizeof(uint32_t);
3823 while (payload_len) {
3824 rscn_did.un.word = be32_to_cpu(*lp++);
3825 payload_len -= sizeof(uint32_t);
3826 switch (rscn_did.un.b.resv) {
3827 case 0:
3828 if (ns_did.un.word == rscn_did.un.word)
3829 goto return_did_out;
3830 break;
3831 case 1:
3832 if ((ns_did.un.b.domain == rscn_did.un.b.domain)
3833 && (ns_did.un.b.area == rscn_did.un.b.area))
3834 goto return_did_out;
3835 break;
3836 case 2:
3837 if (ns_did.un.b.domain == rscn_did.un.b.domain)
3838 goto return_did_out;
3839 break;
3840 default:
3841
3842 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
3843 "0217 Unknown Identifier in "
3844 "RSCN payload Data: x%x\n",
3845 rscn_did.un.word);
3846 case 3:
3847 goto return_did_out;
3848 }
3849 }
3850 }
3851
3852 vport->fc_rscn_flush = 0;
3853 return 0;
3854return_did_out:
3855
3856 vport->fc_rscn_flush = 0;
3857 return did;
3858}
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871static int
3872lpfc_rscn_recovery_check(struct lpfc_vport *vport)
3873{
3874 struct lpfc_nodelist *ndlp = NULL;
3875
3876
3877 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
3878 if (!NLP_CHK_NODE_ACT(ndlp) ||
3879 (ndlp->nlp_state == NLP_STE_UNUSED_NODE) ||
3880 !lpfc_rscn_payload_check(vport, ndlp->nlp_DID))
3881 continue;
3882 lpfc_disc_state_machine(vport, ndlp, NULL,
3883 NLP_EVT_DEVICE_RECOVERY);
3884 lpfc_cancel_retry_delay_tmo(vport, ndlp);
3885 }
3886 return 0;
3887}
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911static int
3912lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
3913 struct lpfc_nodelist *ndlp)
3914{
3915 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3916 struct lpfc_hba *phba = vport->phba;
3917 struct lpfc_dmabuf *pcmd;
3918 uint32_t *lp, *datap;
3919 IOCB_t *icmd;
3920 uint32_t payload_len, length, nportid, *cmd;
3921 int rscn_cnt;
3922 int rscn_id = 0, hba_id = 0;
3923 int i;
3924
3925 icmd = &cmdiocb->iocb;
3926 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3927 lp = (uint32_t *) pcmd->virt;
3928
3929 payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK);
3930 payload_len -= sizeof(uint32_t);
3931
3932 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
3933 "0214 RSCN received Data: x%x x%x x%x x%x\n",
3934 vport->fc_flag, payload_len, *lp,
3935 vport->fc_rscn_id_cnt);
3936 for (i = 0; i < payload_len/sizeof(uint32_t); i++)
3937 fc_host_post_event(shost, fc_get_event_number(),
3938 FCH_EVT_RSCN, lp[i]);
3939
3940
3941
3942
3943 if (vport->port_state <= LPFC_NS_QRY) {
3944 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3945 "RCV RSCN ignore: did:x%x/ste:x%x flg:x%x",
3946 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
3947
3948 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
3949 return 0;
3950 }
3951
3952
3953
3954
3955 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
3956 !(vport->cfg_peer_port_login)) {
3957 i = payload_len;
3958 datap = lp;
3959 while (i > 0) {
3960 nportid = *datap++;
3961 nportid = ((be32_to_cpu(nportid)) & Mask_DID);
3962 i -= sizeof(uint32_t);
3963 rscn_id++;
3964 if (lpfc_find_vport_by_did(phba, nportid))
3965 hba_id++;
3966 }
3967 if (rscn_id == hba_id) {
3968
3969 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
3970 "0219 Ignore RSCN "
3971 "Data: x%x x%x x%x x%x\n",
3972 vport->fc_flag, payload_len,
3973 *lp, vport->fc_rscn_id_cnt);
3974 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
3975 "RCV RSCN vport: did:x%x/ste:x%x flg:x%x",
3976 ndlp->nlp_DID, vport->port_state,
3977 ndlp->nlp_flag);
3978
3979 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb,
3980 ndlp, NULL);
3981 return 0;
3982 }
3983 }
3984
3985 spin_lock_irq(shost->host_lock);
3986 if (vport->fc_rscn_flush) {
3987
3988 spin_unlock_irq(shost->host_lock);
3989 vport->fc_flag |= FC_RSCN_DISCOVERY;
3990
3991 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
3992 return 0;
3993 }
3994
3995 vport->fc_rscn_flush = 1;
3996 spin_unlock_irq(shost->host_lock);
3997
3998 rscn_cnt = vport->fc_rscn_id_cnt;
3999
4000
4001
4002 if (vport->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) {
4003 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
4004 "RCV RSCN defer: did:x%x/ste:x%x flg:x%x",
4005 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
4006
4007 spin_lock_irq(shost->host_lock);
4008 vport->fc_flag |= FC_RSCN_DEFERRED;
4009 if ((rscn_cnt < FC_MAX_HOLD_RSCN) &&
4010 !(vport->fc_flag & FC_RSCN_DISCOVERY)) {
4011 vport->fc_flag |= FC_RSCN_MODE;
4012 spin_unlock_irq(shost->host_lock);
4013 if (rscn_cnt) {
4014 cmd = vport->fc_rscn_id_list[rscn_cnt-1]->virt;
4015 length = be32_to_cpu(*cmd & ~ELS_CMD_MASK);
4016 }
4017 if ((rscn_cnt) &&
4018 (payload_len + length <= LPFC_BPL_SIZE)) {
4019 *cmd &= ELS_CMD_MASK;
4020 *cmd |= cpu_to_be32(payload_len + length);
4021 memcpy(((uint8_t *)cmd) + length, lp,
4022 payload_len);
4023 } else {
4024 vport->fc_rscn_id_list[rscn_cnt] = pcmd;
4025 vport->fc_rscn_id_cnt++;
4026
4027
4028
4029 cmdiocb->context2 = NULL;
4030 }
4031
4032 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
4033 "0235 Deferred RSCN "
4034 "Data: x%x x%x x%x\n",
4035 vport->fc_rscn_id_cnt, vport->fc_flag,
4036 vport->port_state);
4037 } else {
4038 vport->fc_flag |= FC_RSCN_DISCOVERY;
4039 spin_unlock_irq(shost->host_lock);
4040
4041 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
4042 "0234 ReDiscovery RSCN "
4043 "Data: x%x x%x x%x\n",
4044 vport->fc_rscn_id_cnt, vport->fc_flag,
4045 vport->port_state);
4046 }
4047
4048 vport->fc_rscn_flush = 0;
4049
4050 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4051
4052 lpfc_rscn_recovery_check(vport);
4053 spin_lock_irq(shost->host_lock);
4054 vport->fc_flag &= ~FC_RSCN_DEFERRED;
4055 spin_unlock_irq(shost->host_lock);
4056 return 0;
4057 }
4058 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
4059 "RCV RSCN: did:x%x/ste:x%x flg:x%x",
4060 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
4061
4062 spin_lock_irq(shost->host_lock);
4063 vport->fc_flag |= FC_RSCN_MODE;
4064 spin_unlock_irq(shost->host_lock);
4065 vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd;
4066
4067 vport->fc_rscn_flush = 0;
4068
4069
4070
4071
4072 cmdiocb->context2 = NULL;
4073 lpfc_set_disctmo(vport);
4074
4075 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4076
4077 lpfc_rscn_recovery_check(vport);
4078 return lpfc_els_handle_rscn(vport);
4079}
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097int
4098lpfc_els_handle_rscn(struct lpfc_vport *vport)
4099{
4100 struct lpfc_nodelist *ndlp;
4101 struct lpfc_hba *phba = vport->phba;
4102
4103
4104 if (vport->load_flag & FC_UNLOADING) {
4105 lpfc_els_flush_rscn(vport);
4106 return 0;
4107 }
4108
4109
4110 lpfc_set_disctmo(vport);
4111
4112
4113 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
4114 "0215 RSCN processed Data: x%x x%x x%x x%x\n",
4115 vport->fc_flag, 0, vport->fc_rscn_id_cnt,
4116 vport->port_state);
4117
4118
4119 vport->fc_ns_retry = 0;
4120 vport->num_disc_nodes = 0;
4121
4122 ndlp = lpfc_findnode_did(vport, NameServer_DID);
4123 if (ndlp && NLP_CHK_NODE_ACT(ndlp)
4124 && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
4125
4126 if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, 0) == 0)
4127
4128
4129 return 1;
4130 } else {
4131
4132
4133 ndlp = lpfc_findnode_did(vport, NameServer_DID);
4134 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
4135
4136
4137 return 1;
4138
4139 if (ndlp) {
4140 ndlp = lpfc_enable_node(vport, ndlp,
4141 NLP_STE_PLOGI_ISSUE);
4142 if (!ndlp) {
4143 lpfc_els_flush_rscn(vport);
4144 return 0;
4145 }
4146 ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
4147 } else {
4148 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
4149 if (!ndlp) {
4150 lpfc_els_flush_rscn(vport);
4151 return 0;
4152 }
4153 lpfc_nlp_init(vport, ndlp, NameServer_DID);
4154 ndlp->nlp_prev_state = ndlp->nlp_state;
4155 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
4156 }
4157 ndlp->nlp_type |= NLP_FABRIC;
4158 lpfc_issue_els_plogi(vport, NameServer_DID, 0);
4159
4160
4161
4162 return 1;
4163 }
4164
4165 lpfc_els_flush_rscn(vport);
4166 return 0;
4167}
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194static int
4195lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4196 struct lpfc_nodelist *ndlp)
4197{
4198 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
4199 struct lpfc_hba *phba = vport->phba;
4200 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
4201 uint32_t *lp = (uint32_t *) pcmd->virt;
4202 IOCB_t *icmd = &cmdiocb->iocb;
4203 struct serv_parm *sp;
4204 LPFC_MBOXQ_t *mbox;
4205 struct ls_rjt stat;
4206 uint32_t cmd, did;
4207 int rc;
4208
4209 cmd = *lp++;
4210 sp = (struct serv_parm *) lp;
4211
4212
4213
4214 lpfc_set_disctmo(vport);
4215
4216 if (phba->fc_topology == TOPOLOGY_LOOP) {
4217
4218 did = icmd->un.elsreq64.remoteID;
4219
4220
4221
4222 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
4223 "0113 An FLOGI ELS command x%x was "
4224 "received from DID x%x in Loop Mode\n",
4225 cmd, did);
4226 return 1;
4227 }
4228
4229 did = Fabric_DID;
4230
4231 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3))) {
4232
4233
4234
4235
4236 rc = memcmp(&vport->fc_portname, &sp->portName,
4237 sizeof(struct lpfc_name));
4238
4239 if (!rc) {
4240 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
4241 if (!mbox)
4242 return 1;
4243
4244 lpfc_linkdown(phba);
4245 lpfc_init_link(phba, mbox,
4246 phba->cfg_topology,
4247 phba->cfg_link_speed);
4248 mbox->mb.un.varInitLnk.lipsr_AL_PA = 0;
4249 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
4250 mbox->vport = vport;
4251 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
4252 lpfc_set_loopback_flag(phba);
4253 if (rc == MBX_NOT_FINISHED) {
4254 mempool_free(mbox, phba->mbox_mem_pool);
4255 }
4256 return 1;
4257 } else if (rc > 0) {
4258 spin_lock_irq(shost->host_lock);
4259 vport->fc_flag |= FC_PT2PT_PLOGI;
4260 spin_unlock_irq(shost->host_lock);
4261 }
4262 spin_lock_irq(shost->host_lock);
4263 vport->fc_flag |= FC_PT2PT;
4264 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
4265 spin_unlock_irq(shost->host_lock);
4266 } else {
4267
4268 stat.un.b.lsRjtRsvd0 = 0;
4269 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
4270 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
4271 stat.un.b.vendorUnique = 0;
4272 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
4273 NULL);
4274 return 1;
4275 }
4276
4277
4278 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
4279
4280 return 0;
4281}
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299static int
4300lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4301 struct lpfc_nodelist *ndlp)
4302{
4303 struct lpfc_dmabuf *pcmd;
4304 uint32_t *lp;
4305 IOCB_t *icmd;
4306 RNID *rn;
4307 struct ls_rjt stat;
4308 uint32_t cmd, did;
4309
4310 icmd = &cmdiocb->iocb;
4311 did = icmd->un.elsreq64.remoteID;
4312 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
4313 lp = (uint32_t *) pcmd->virt;
4314
4315 cmd = *lp++;
4316 rn = (RNID *) lp;
4317
4318
4319
4320 switch (rn->Format) {
4321 case 0:
4322 case RNID_TOPOLOGY_DISC:
4323
4324 lpfc_els_rsp_rnid_acc(vport, rn->Format, cmdiocb, ndlp);
4325 break;
4326 default:
4327
4328 stat.un.b.lsRjtRsvd0 = 0;
4329 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
4330 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
4331 stat.un.b.vendorUnique = 0;
4332 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
4333 NULL);
4334 }
4335 return 0;
4336}
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351static int
4352lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4353 struct lpfc_nodelist *ndlp)
4354{
4355 struct ls_rjt stat;
4356
4357
4358 stat.un.b.lsRjtRsvd0 = 0;
4359 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
4360 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
4361 stat.un.b.vendorUnique = 0;
4362 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
4363 return 0;
4364}
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385static void
4386lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
4387{
4388 struct lpfc_sli *psli = &phba->sli;
4389 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
4390 MAILBOX_t *mb;
4391 IOCB_t *icmd;
4392 RPS_RSP *rps_rsp;
4393 uint8_t *pcmd;
4394 struct lpfc_iocbq *elsiocb;
4395 struct lpfc_nodelist *ndlp;
4396 uint16_t xri, status;
4397 uint32_t cmdsize;
4398
4399 mb = &pmb->mb;
4400
4401 ndlp = (struct lpfc_nodelist *) pmb->context2;
4402 xri = (uint16_t) ((unsigned long)(pmb->context1));
4403 pmb->context1 = NULL;
4404 pmb->context2 = NULL;
4405
4406 if (mb->mbxStatus) {
4407 mempool_free(pmb, phba->mbox_mem_pool);
4408 return;
4409 }
4410
4411 cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t);
4412 mempool_free(pmb, phba->mbox_mem_pool);
4413 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
4414 lpfc_max_els_tries, ndlp,
4415 ndlp->nlp_DID, ELS_CMD_ACC);
4416
4417
4418 lpfc_nlp_put(ndlp);
4419
4420 if (!elsiocb)
4421 return;
4422
4423 icmd = &elsiocb->iocb;
4424 icmd->ulpContext = xri;
4425
4426 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4427 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
4428 pcmd += sizeof(uint32_t);
4429 rps_rsp = (RPS_RSP *)pcmd;
4430
4431 if (phba->fc_topology != TOPOLOGY_LOOP)
4432 status = 0x10;
4433 else
4434 status = 0x8;
4435 if (phba->pport->fc_flag & FC_FABRIC)
4436 status |= 0x4;
4437
4438 rps_rsp->rsvd1 = 0;
4439 rps_rsp->portStatus = cpu_to_be16(status);
4440 rps_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt);
4441 rps_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt);
4442 rps_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt);
4443 rps_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt);
4444 rps_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord);
4445 rps_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt);
4446
4447 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
4448 "0118 Xmit ELS RPS ACC response tag x%x xri x%x, "
4449 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
4450 elsiocb->iotag, elsiocb->iocb.ulpContext,
4451 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
4452 ndlp->nlp_rpi);
4453 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
4454 phba->fc_stat.elsXmitACC++;
4455 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR)
4456 lpfc_els_free_iocb(phba, elsiocb);
4457 return;
4458}
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478static int
4479lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4480 struct lpfc_nodelist *ndlp)
4481{
4482 struct lpfc_hba *phba = vport->phba;
4483 uint32_t *lp;
4484 uint8_t flag;
4485 LPFC_MBOXQ_t *mbox;
4486 struct lpfc_dmabuf *pcmd;
4487 RPS *rps;
4488 struct ls_rjt stat;
4489
4490 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
4491 (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
4492
4493 goto reject_out;
4494
4495 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
4496 lp = (uint32_t *) pcmd->virt;
4497 flag = (be32_to_cpu(*lp++) & 0xf);
4498 rps = (RPS *) lp;
4499
4500 if ((flag == 0) ||
4501 ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) ||
4502 ((flag == 2) && (memcmp(&rps->un.portName, &vport->fc_portname,
4503 sizeof(struct lpfc_name)) == 0))) {
4504
4505 printk("Fix me....\n");
4506 dump_stack();
4507 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
4508 if (mbox) {
4509 lpfc_read_lnk_stat(phba, mbox);
4510 mbox->context1 =
4511 (void *)((unsigned long) cmdiocb->iocb.ulpContext);
4512 mbox->context2 = lpfc_nlp_get(ndlp);
4513 mbox->vport = vport;
4514 mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
4515 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
4516 != MBX_NOT_FINISHED)
4517
4518 return 0;
4519
4520
4521
4522 lpfc_nlp_put(ndlp);
4523 mempool_free(mbox, phba->mbox_mem_pool);
4524 }
4525 }
4526
4527reject_out:
4528
4529 stat.un.b.lsRjtRsvd0 = 0;
4530 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
4531 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
4532 stat.un.b.vendorUnique = 0;
4533 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
4534 return 0;
4535}
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556static int
4557lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
4558 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
4559{
4560 struct lpfc_hba *phba = vport->phba;
4561 IOCB_t *icmd, *oldcmd;
4562 RPL_RSP rpl_rsp;
4563 struct lpfc_iocbq *elsiocb;
4564 struct lpfc_sli *psli = &phba->sli;
4565 struct lpfc_sli_ring *pring = &psli->ring[LPFC_ELS_RING];
4566 uint8_t *pcmd;
4567
4568 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
4569 ndlp->nlp_DID, ELS_CMD_ACC);
4570
4571 if (!elsiocb)
4572 return 1;
4573
4574 icmd = &elsiocb->iocb;
4575 oldcmd = &oldiocb->iocb;
4576 icmd->ulpContext = oldcmd->ulpContext;
4577
4578 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4579 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
4580 pcmd += sizeof(uint16_t);
4581 *((uint16_t *)(pcmd)) = be16_to_cpu(cmdsize);
4582 pcmd += sizeof(uint16_t);
4583
4584
4585 rpl_rsp.listLen = be32_to_cpu(1);
4586 rpl_rsp.index = 0;
4587 rpl_rsp.port_num_blk.portNum = 0;
4588 rpl_rsp.port_num_blk.portID = be32_to_cpu(vport->fc_myDID);
4589 memcpy(&rpl_rsp.port_num_blk.portName, &vport->fc_portname,
4590 sizeof(struct lpfc_name));
4591 memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t));
4592
4593 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4594 "0120 Xmit ELS RPL ACC response tag x%x "
4595 "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
4596 "rpi x%x\n",
4597 elsiocb->iotag, elsiocb->iocb.ulpContext,
4598 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
4599 ndlp->nlp_rpi);
4600 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
4601 phba->fc_stat.elsXmitACC++;
4602 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
4603 lpfc_els_free_iocb(phba, elsiocb);
4604 return 1;
4605 }
4606 return 0;
4607}
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625static int
4626lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4627 struct lpfc_nodelist *ndlp)
4628{
4629 struct lpfc_dmabuf *pcmd;
4630 uint32_t *lp;
4631 uint32_t maxsize;
4632 uint16_t cmdsize;
4633 RPL *rpl;
4634 struct ls_rjt stat;
4635
4636 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
4637 (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
4638
4639 stat.un.b.lsRjtRsvd0 = 0;
4640 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
4641 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
4642 stat.un.b.vendorUnique = 0;
4643 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
4644 NULL);
4645
4646 return 0;
4647 }
4648
4649 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
4650 lp = (uint32_t *) pcmd->virt;
4651 rpl = (RPL *) (lp + 1);
4652
4653 maxsize = be32_to_cpu(rpl->maxsize);
4654
4655
4656 if ((rpl->index == 0) &&
4657 ((maxsize == 0) ||
4658 ((maxsize * sizeof(uint32_t)) >= sizeof(RPL_RSP)))) {
4659 cmdsize = sizeof(uint32_t) + sizeof(RPL_RSP);
4660 } else {
4661 cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t);
4662 }
4663 lpfc_els_rsp_rpl_acc(vport, cmdsize, cmdiocb, ndlp);
4664
4665 return 0;
4666}
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692static int
4693lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4694 struct lpfc_nodelist *ndlp)
4695{
4696 struct lpfc_dmabuf *pcmd;
4697 uint32_t *lp;
4698 IOCB_t *icmd;
4699 FARP *fp;
4700 uint32_t cmd, cnt, did;
4701
4702 icmd = &cmdiocb->iocb;
4703 did = icmd->un.elsreq64.remoteID;
4704 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
4705 lp = (uint32_t *) pcmd->virt;
4706
4707 cmd = *lp++;
4708 fp = (FARP *) lp;
4709
4710 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4711 "0601 FARP-REQ received from DID x%x\n", did);
4712
4713 if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) {
4714 return 0;
4715 }
4716
4717 cnt = 0;
4718
4719 if (fp->Mflags & FARP_MATCH_PORT) {
4720 if (memcmp(&fp->RportName, &vport->fc_portname,
4721 sizeof(struct lpfc_name)) == 0)
4722 cnt = 1;
4723 }
4724
4725
4726 if (fp->Mflags & FARP_MATCH_NODE) {
4727 if (memcmp(&fp->RnodeName, &vport->fc_nodename,
4728 sizeof(struct lpfc_name)) == 0)
4729 cnt = 1;
4730 }
4731
4732 if (cnt) {
4733 if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
4734 (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) {
4735
4736 if (fp->Rflags & FARP_REQUEST_PLOGI) {
4737 ndlp->nlp_prev_state = ndlp->nlp_state;
4738 lpfc_nlp_set_state(vport, ndlp,
4739 NLP_STE_PLOGI_ISSUE);
4740 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
4741 }
4742
4743
4744 if (fp->Rflags & FARP_REQUEST_FARPR)
4745 lpfc_issue_els_farpr(vport, did, 0);
4746 }
4747 }
4748 return 0;
4749}
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765static int
4766lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4767 struct lpfc_nodelist *ndlp)
4768{
4769 struct lpfc_dmabuf *pcmd;
4770 uint32_t *lp;
4771 IOCB_t *icmd;
4772 uint32_t cmd, did;
4773
4774 icmd = &cmdiocb->iocb;
4775 did = icmd->un.elsreq64.remoteID;
4776 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
4777 lp = (uint32_t *) pcmd->virt;
4778
4779 cmd = *lp++;
4780
4781 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4782 "0600 FARP-RSP received from DID x%x\n", did);
4783
4784 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4785
4786 return 0;
4787}
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808static int
4809lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4810 struct lpfc_nodelist *fan_ndlp)
4811{
4812 struct lpfc_hba *phba = vport->phba;
4813 uint32_t *lp;
4814 FAN *fp;
4815
4816 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0265 FAN received\n");
4817 lp = (uint32_t *)((struct lpfc_dmabuf *)cmdiocb->context2)->virt;
4818 fp = (FAN *) ++lp;
4819
4820 if ((vport == phba->pport) &&
4821 (vport->port_state == LPFC_LOCAL_CFG_LINK)) {
4822 if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName,
4823 sizeof(struct lpfc_name))) ||
4824 (memcmp(&phba->fc_fabparam.portName, &fp->FportName,
4825 sizeof(struct lpfc_name)))) {
4826
4827 lpfc_initial_flogi(vport);
4828 } else {
4829
4830 vport->fc_myDID = vport->fc_prevDID;
4831 lpfc_issue_fabric_reglogin(vport);
4832 }
4833 }
4834 return 0;
4835}
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847void
4848lpfc_els_timeout(unsigned long ptr)
4849{
4850 struct lpfc_vport *vport = (struct lpfc_vport *) ptr;
4851 struct lpfc_hba *phba = vport->phba;
4852 uint32_t tmo_posted;
4853 unsigned long iflag;
4854
4855 spin_lock_irqsave(&vport->work_port_lock, iflag);
4856 tmo_posted = vport->work_port_events & WORKER_ELS_TMO;
4857 if (!tmo_posted)
4858 vport->work_port_events |= WORKER_ELS_TMO;
4859 spin_unlock_irqrestore(&vport->work_port_lock, iflag);
4860
4861 if (!tmo_posted)
4862 lpfc_worker_wake_up(phba);
4863 return;
4864}
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875void
4876lpfc_els_timeout_handler(struct lpfc_vport *vport)
4877{
4878 struct lpfc_hba *phba = vport->phba;
4879 struct lpfc_sli_ring *pring;
4880 struct lpfc_iocbq *tmp_iocb, *piocb;
4881 IOCB_t *cmd = NULL;
4882 struct lpfc_dmabuf *pcmd;
4883 uint32_t els_command = 0;
4884 uint32_t timeout;
4885 uint32_t remote_ID = 0xffffffff;
4886
4887
4888 if ((vport->work_port_events & WORKER_ELS_TMO) == 0) {
4889 return;
4890 }
4891 spin_lock_irq(&phba->hbalock);
4892 timeout = (uint32_t)(phba->fc_ratov << 1);
4893
4894 pring = &phba->sli.ring[LPFC_ELS_RING];
4895
4896 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
4897 cmd = &piocb->iocb;
4898
4899 if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 ||
4900 piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
4901 piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
4902 continue;
4903
4904 if (piocb->vport != vport)
4905 continue;
4906
4907 pcmd = (struct lpfc_dmabuf *) piocb->context2;
4908 if (pcmd)
4909 els_command = *(uint32_t *) (pcmd->virt);
4910
4911 if (els_command == ELS_CMD_FARP ||
4912 els_command == ELS_CMD_FARPR ||
4913 els_command == ELS_CMD_FDISC)
4914 continue;
4915
4916 if (piocb->drvrTimeout > 0) {
4917 if (piocb->drvrTimeout >= timeout)
4918 piocb->drvrTimeout -= timeout;
4919 else
4920 piocb->drvrTimeout = 0;
4921 continue;
4922 }
4923
4924 remote_ID = 0xffffffff;
4925 if (cmd->ulpCommand != CMD_GEN_REQUEST64_CR)
4926 remote_ID = cmd->un.elsreq64.remoteID;
4927 else {
4928 struct lpfc_nodelist *ndlp;
4929 ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext);
4930 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
4931 remote_ID = ndlp->nlp_DID;
4932 }
4933 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
4934 "0127 ELS timeout Data: x%x x%x x%x "
4935 "x%x\n", els_command,
4936 remote_ID, cmd->ulpCommand, cmd->ulpIoTag);
4937 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
4938 }
4939 spin_unlock_irq(&phba->hbalock);
4940
4941 if (phba->sli.ring[LPFC_ELS_RING].txcmplq_cnt)
4942 mod_timer(&vport->els_tmofunc, jiffies + HZ * timeout);
4943}
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965void
4966lpfc_els_flush_cmd(struct lpfc_vport *vport)
4967{
4968 LIST_HEAD(completions);
4969 struct lpfc_hba *phba = vport->phba;
4970 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
4971 struct lpfc_iocbq *tmp_iocb, *piocb;
4972 IOCB_t *cmd = NULL;
4973
4974 lpfc_fabric_abort_vport(vport);
4975
4976 spin_lock_irq(&phba->hbalock);
4977 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
4978 cmd = &piocb->iocb;
4979
4980 if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
4981 continue;
4982 }
4983
4984
4985 if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN ||
4986 cmd->ulpCommand == CMD_QUE_RING_BUF64_CN ||
4987 cmd->ulpCommand == CMD_CLOSE_XRI_CN ||
4988 cmd->ulpCommand == CMD_ABORT_XRI_CN)
4989 continue;
4990
4991 if (piocb->vport != vport)
4992 continue;
4993
4994 list_move_tail(&piocb->list, &completions);
4995 pring->txq_cnt--;
4996 }
4997
4998 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
4999 if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
5000 continue;
5001 }
5002
5003 if (piocb->vport != vport)
5004 continue;
5005
5006 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
5007 }
5008 spin_unlock_irq(&phba->hbalock);
5009
5010 while (!list_empty(&completions)) {
5011 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
5012 cmd = &piocb->iocb;
5013 list_del_init(&piocb->list);
5014
5015 if (!piocb->iocb_cmpl)
5016 lpfc_sli_release_iocbq(phba, piocb);
5017 else {
5018 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
5019 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
5020 (piocb->iocb_cmpl) (phba, piocb, piocb);
5021 }
5022 }
5023
5024 return;
5025}
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044void
5045lpfc_els_flush_all_cmd(struct lpfc_hba *phba)
5046{
5047 LIST_HEAD(completions);
5048 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
5049 struct lpfc_iocbq *tmp_iocb, *piocb;
5050 IOCB_t *cmd = NULL;
5051
5052 lpfc_fabric_abort_hba(phba);
5053 spin_lock_irq(&phba->hbalock);
5054 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
5055 cmd = &piocb->iocb;
5056 if (piocb->iocb_flag & LPFC_IO_LIBDFC)
5057 continue;
5058
5059 if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN ||
5060 cmd->ulpCommand == CMD_QUE_RING_BUF64_CN ||
5061 cmd->ulpCommand == CMD_CLOSE_XRI_CN ||
5062 cmd->ulpCommand == CMD_ABORT_XRI_CN)
5063 continue;
5064 list_move_tail(&piocb->list, &completions);
5065 pring->txq_cnt--;
5066 }
5067 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
5068 if (piocb->iocb_flag & LPFC_IO_LIBDFC)
5069 continue;
5070 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
5071 }
5072 spin_unlock_irq(&phba->hbalock);
5073 while (!list_empty(&completions)) {
5074 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
5075 cmd = &piocb->iocb;
5076 list_del_init(&piocb->list);
5077 if (!piocb->iocb_cmpl)
5078 lpfc_sli_release_iocbq(phba, piocb);
5079 else {
5080 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
5081 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
5082 (piocb->iocb_cmpl) (phba, piocb, piocb);
5083 }
5084 }
5085 return;
5086}
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097void
5098lpfc_send_els_failure_event(struct lpfc_hba *phba,
5099 struct lpfc_iocbq *cmdiocbp,
5100 struct lpfc_iocbq *rspiocbp)
5101{
5102 struct lpfc_vport *vport = cmdiocbp->vport;
5103 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5104 struct lpfc_lsrjt_event lsrjt_event;
5105 struct lpfc_fabric_event_header fabric_event;
5106 struct ls_rjt stat;
5107 struct lpfc_nodelist *ndlp;
5108 uint32_t *pcmd;
5109
5110 ndlp = cmdiocbp->context1;
5111 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
5112 return;
5113
5114 if (rspiocbp->iocb.ulpStatus == IOSTAT_LS_RJT) {
5115 lsrjt_event.header.event_type = FC_REG_ELS_EVENT;
5116 lsrjt_event.header.subcategory = LPFC_EVENT_LSRJT_RCV;
5117 memcpy(lsrjt_event.header.wwpn, &ndlp->nlp_portname,
5118 sizeof(struct lpfc_name));
5119 memcpy(lsrjt_event.header.wwnn, &ndlp->nlp_nodename,
5120 sizeof(struct lpfc_name));
5121 pcmd = (uint32_t *) (((struct lpfc_dmabuf *)
5122 cmdiocbp->context2)->virt);
5123 lsrjt_event.command = *pcmd;
5124 stat.un.lsRjtError = be32_to_cpu(rspiocbp->iocb.un.ulpWord[4]);
5125 lsrjt_event.reason_code = stat.un.b.lsRjtRsnCode;
5126 lsrjt_event.explanation = stat.un.b.lsRjtRsnCodeExp;
5127 fc_host_post_vendor_event(shost,
5128 fc_get_event_number(),
5129 sizeof(lsrjt_event),
5130 (char *)&lsrjt_event,
5131 SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
5132 return;
5133 }
5134 if ((rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) ||
5135 (rspiocbp->iocb.ulpStatus == IOSTAT_FABRIC_BSY)) {
5136 fabric_event.event_type = FC_REG_FABRIC_EVENT;
5137 if (rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY)
5138 fabric_event.subcategory = LPFC_EVENT_PORT_BUSY;
5139 else
5140 fabric_event.subcategory = LPFC_EVENT_FABRIC_BUSY;
5141 memcpy(fabric_event.wwpn, &ndlp->nlp_portname,
5142 sizeof(struct lpfc_name));
5143 memcpy(fabric_event.wwnn, &ndlp->nlp_nodename,
5144 sizeof(struct lpfc_name));
5145 fc_host_post_vendor_event(shost,
5146 fc_get_event_number(),
5147 sizeof(fabric_event),
5148 (char *)&fabric_event,
5149 SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
5150 return;
5151 }
5152
5153}
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164static void
5165lpfc_send_els_event(struct lpfc_vport *vport,
5166 struct lpfc_nodelist *ndlp,
5167 uint32_t cmd)
5168{
5169 struct lpfc_els_event_header els_data;
5170 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5171
5172 els_data.event_type = FC_REG_ELS_EVENT;
5173 switch (cmd) {
5174 case ELS_CMD_PLOGI:
5175 els_data.subcategory = LPFC_EVENT_PLOGI_RCV;
5176 break;
5177 case ELS_CMD_PRLO:
5178 els_data.subcategory = LPFC_EVENT_PRLO_RCV;
5179 break;
5180 case ELS_CMD_ADISC:
5181 els_data.subcategory = LPFC_EVENT_ADISC_RCV;
5182 break;
5183 default:
5184 return;
5185 }
5186 memcpy(els_data.wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name));
5187 memcpy(els_data.wwnn, &ndlp->nlp_nodename, sizeof(struct lpfc_name));
5188 fc_host_post_vendor_event(shost,
5189 fc_get_event_number(),
5190 sizeof(els_data),
5191 (char *)&els_data,
5192 SCSI_NL_VID_TYPE_PCI | PCI_VENDOR_ID_EMULEX);
5193
5194 return;
5195}
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212static void
5213lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5214 struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb)
5215{
5216 struct Scsi_Host *shost;
5217 struct lpfc_nodelist *ndlp;
5218 struct ls_rjt stat;
5219 uint32_t *payload;
5220 uint32_t cmd, did, newnode, rjt_err = 0;
5221 IOCB_t *icmd = &elsiocb->iocb;
5222
5223 if (!vport || !(elsiocb->context2))
5224 goto dropit;
5225
5226 newnode = 0;
5227 payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt;
5228 cmd = *payload;
5229 if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0)
5230 lpfc_post_buffer(phba, pring, 1);
5231
5232 did = icmd->un.rcvels.remoteID;
5233 if (icmd->ulpStatus) {
5234 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5235 "RCV Unsol ELS: status:x%x/x%x did:x%x",
5236 icmd->ulpStatus, icmd->un.ulpWord[4], did);
5237 goto dropit;
5238 }
5239
5240
5241 if (lpfc_els_chk_latt(vport))
5242 goto dropit;
5243
5244
5245 if (vport->load_flag & FC_UNLOADING)
5246 goto dropit;
5247
5248 ndlp = lpfc_findnode_did(vport, did);
5249 if (!ndlp) {
5250
5251 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
5252 if (!ndlp)
5253 goto dropit;
5254
5255 lpfc_nlp_init(vport, ndlp, did);
5256 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
5257 newnode = 1;
5258 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
5259 ndlp->nlp_type |= NLP_FABRIC;
5260 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
5261 ndlp = lpfc_enable_node(vport, ndlp,
5262 NLP_STE_UNUSED_NODE);
5263 if (!ndlp)
5264 goto dropit;
5265 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
5266 newnode = 1;
5267 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
5268 ndlp->nlp_type |= NLP_FABRIC;
5269 } else if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
5270
5271 ndlp = lpfc_nlp_get(ndlp);
5272 if (!ndlp)
5273 goto dropit;
5274 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
5275 newnode = 1;
5276 }
5277
5278 phba->fc_stat.elsRcvFrame++;
5279
5280 elsiocb->context1 = lpfc_nlp_get(ndlp);
5281 elsiocb->vport = vport;
5282
5283 if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) {
5284 cmd &= ELS_CMD_MASK;
5285 }
5286
5287 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
5288 "0112 ELS command x%x received from NPORT x%x "
5289 "Data: x%x\n", cmd, did, vport->port_state);
5290 switch (cmd) {
5291 case ELS_CMD_PLOGI:
5292 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5293 "RCV PLOGI: did:x%x/ste:x%x flg:x%x",
5294 did, vport->port_state, ndlp->nlp_flag);
5295
5296 phba->fc_stat.elsRcvPLOGI++;
5297 ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp);
5298
5299 lpfc_send_els_event(vport, ndlp, cmd);
5300 if (vport->port_state < LPFC_DISC_AUTH) {
5301 if (!(phba->pport->fc_flag & FC_PT2PT) ||
5302 (phba->pport->fc_flag & FC_PT2PT_PLOGI)) {
5303 rjt_err = LSRJT_UNABLE_TPC;
5304 break;
5305 }
5306
5307
5308
5309
5310 }
5311
5312 shost = lpfc_shost_from_vport(vport);
5313 spin_lock_irq(shost->host_lock);
5314 ndlp->nlp_flag &= ~NLP_TARGET_REMOVE;
5315 spin_unlock_irq(shost->host_lock);
5316
5317 lpfc_disc_state_machine(vport, ndlp, elsiocb,
5318 NLP_EVT_RCV_PLOGI);
5319
5320 break;
5321 case ELS_CMD_FLOGI:
5322 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5323 "RCV FLOGI: did:x%x/ste:x%x flg:x%x",
5324 did, vport->port_state, ndlp->nlp_flag);
5325
5326 phba->fc_stat.elsRcvFLOGI++;
5327 lpfc_els_rcv_flogi(vport, elsiocb, ndlp);
5328 if (newnode)
5329 lpfc_nlp_put(ndlp);
5330 break;
5331 case ELS_CMD_LOGO:
5332 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5333 "RCV LOGO: did:x%x/ste:x%x flg:x%x",
5334 did, vport->port_state, ndlp->nlp_flag);
5335
5336 phba->fc_stat.elsRcvLOGO++;
5337 if (vport->port_state < LPFC_DISC_AUTH) {
5338 rjt_err = LSRJT_UNABLE_TPC;
5339 break;
5340 }
5341 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO);
5342 break;
5343 case ELS_CMD_PRLO:
5344 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5345 "RCV PRLO: did:x%x/ste:x%x flg:x%x",
5346 did, vport->port_state, ndlp->nlp_flag);
5347
5348 phba->fc_stat.elsRcvPRLO++;
5349 lpfc_send_els_event(vport, ndlp, cmd);
5350 if (vport->port_state < LPFC_DISC_AUTH) {
5351 rjt_err = LSRJT_UNABLE_TPC;
5352 break;
5353 }
5354 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO);
5355 break;
5356 case ELS_CMD_RSCN:
5357 phba->fc_stat.elsRcvRSCN++;
5358 lpfc_els_rcv_rscn(vport, elsiocb, ndlp);
5359 if (newnode)
5360 lpfc_nlp_put(ndlp);
5361 break;
5362 case ELS_CMD_ADISC:
5363 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5364 "RCV ADISC: did:x%x/ste:x%x flg:x%x",
5365 did, vport->port_state, ndlp->nlp_flag);
5366
5367 lpfc_send_els_event(vport, ndlp, cmd);
5368 phba->fc_stat.elsRcvADISC++;
5369 if (vport->port_state < LPFC_DISC_AUTH) {
5370 rjt_err = LSRJT_UNABLE_TPC;
5371 break;
5372 }
5373 lpfc_disc_state_machine(vport, ndlp, elsiocb,
5374 NLP_EVT_RCV_ADISC);
5375 break;
5376 case ELS_CMD_PDISC:
5377 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5378 "RCV PDISC: did:x%x/ste:x%x flg:x%x",
5379 did, vport->port_state, ndlp->nlp_flag);
5380
5381 phba->fc_stat.elsRcvPDISC++;
5382 if (vport->port_state < LPFC_DISC_AUTH) {
5383 rjt_err = LSRJT_UNABLE_TPC;
5384 break;
5385 }
5386 lpfc_disc_state_machine(vport, ndlp, elsiocb,
5387 NLP_EVT_RCV_PDISC);
5388 break;
5389 case ELS_CMD_FARPR:
5390 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5391 "RCV FARPR: did:x%x/ste:x%x flg:x%x",
5392 did, vport->port_state, ndlp->nlp_flag);
5393
5394 phba->fc_stat.elsRcvFARPR++;
5395 lpfc_els_rcv_farpr(vport, elsiocb, ndlp);
5396 break;
5397 case ELS_CMD_FARP:
5398 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5399 "RCV FARP: did:x%x/ste:x%x flg:x%x",
5400 did, vport->port_state, ndlp->nlp_flag);
5401
5402 phba->fc_stat.elsRcvFARP++;
5403 lpfc_els_rcv_farp(vport, elsiocb, ndlp);
5404 break;
5405 case ELS_CMD_FAN:
5406 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5407 "RCV FAN: did:x%x/ste:x%x flg:x%x",
5408 did, vport->port_state, ndlp->nlp_flag);
5409
5410 phba->fc_stat.elsRcvFAN++;
5411 lpfc_els_rcv_fan(vport, elsiocb, ndlp);
5412 break;
5413 case ELS_CMD_PRLI:
5414 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5415 "RCV PRLI: did:x%x/ste:x%x flg:x%x",
5416 did, vport->port_state, ndlp->nlp_flag);
5417
5418 phba->fc_stat.elsRcvPRLI++;
5419 if (vport->port_state < LPFC_DISC_AUTH) {
5420 rjt_err = LSRJT_UNABLE_TPC;
5421 break;
5422 }
5423 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI);
5424 break;
5425 case ELS_CMD_LIRR:
5426 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5427 "RCV LIRR: did:x%x/ste:x%x flg:x%x",
5428 did, vport->port_state, ndlp->nlp_flag);
5429
5430 phba->fc_stat.elsRcvLIRR++;
5431 lpfc_els_rcv_lirr(vport, elsiocb, ndlp);
5432 if (newnode)
5433 lpfc_nlp_put(ndlp);
5434 break;
5435 case ELS_CMD_RPS:
5436 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5437 "RCV RPS: did:x%x/ste:x%x flg:x%x",
5438 did, vport->port_state, ndlp->nlp_flag);
5439
5440 phba->fc_stat.elsRcvRPS++;
5441 lpfc_els_rcv_rps(vport, elsiocb, ndlp);
5442 if (newnode)
5443 lpfc_nlp_put(ndlp);
5444 break;
5445 case ELS_CMD_RPL:
5446 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5447 "RCV RPL: did:x%x/ste:x%x flg:x%x",
5448 did, vport->port_state, ndlp->nlp_flag);
5449
5450 phba->fc_stat.elsRcvRPL++;
5451 lpfc_els_rcv_rpl(vport, elsiocb, ndlp);
5452 if (newnode)
5453 lpfc_nlp_put(ndlp);
5454 break;
5455 case ELS_CMD_RNID:
5456 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5457 "RCV RNID: did:x%x/ste:x%x flg:x%x",
5458 did, vport->port_state, ndlp->nlp_flag);
5459
5460 phba->fc_stat.elsRcvRNID++;
5461 lpfc_els_rcv_rnid(vport, elsiocb, ndlp);
5462 if (newnode)
5463 lpfc_nlp_put(ndlp);
5464 break;
5465 default:
5466 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
5467 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x",
5468 cmd, did, vport->port_state);
5469
5470
5471 rjt_err = LSRJT_INVALID_CMD;
5472
5473
5474 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
5475 "0115 Unknown ELS command x%x "
5476 "received from NPORT x%x\n", cmd, did);
5477 if (newnode)
5478 lpfc_nlp_put(ndlp);
5479 break;
5480 }
5481
5482
5483 if (rjt_err) {
5484 memset(&stat, 0, sizeof(stat));
5485 stat.un.b.lsRjtRsnCode = rjt_err;
5486 stat.un.b.lsRjtRsnCodeExp = LSEXP_NOTHING_MORE;
5487 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp,
5488 NULL);
5489 }
5490
5491 lpfc_nlp_put(elsiocb->context1);
5492 elsiocb->context1 = NULL;
5493 return;
5494
5495dropit:
5496 if (vport && !(vport->load_flag & FC_UNLOADING))
5497 lpfc_printf_log(phba, KERN_ERR, LOG_ELS,
5498 "(%d):0111 Dropping received ELS cmd "
5499 "Data: x%x x%x x%x\n",
5500 vport->vpi, icmd->ulpStatus,
5501 icmd->un.ulpWord[4], icmd->ulpTimeout);
5502 phba->fc_stat.elsRcvDrop++;
5503}
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518static struct lpfc_vport *
5519lpfc_find_vport_by_vpid(struct lpfc_hba *phba, uint16_t vpi)
5520{
5521 struct lpfc_vport *vport;
5522 unsigned long flags;
5523
5524 spin_lock_irqsave(&phba->hbalock, flags);
5525 list_for_each_entry(vport, &phba->port_list, listentry) {
5526 if (vport->vpi == vpi) {
5527 spin_unlock_irqrestore(&phba->hbalock, flags);
5528 return vport;
5529 }
5530 }
5531 spin_unlock_irqrestore(&phba->hbalock, flags);
5532 return NULL;
5533}
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547void
5548lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
5549 struct lpfc_iocbq *elsiocb)
5550{
5551 struct lpfc_vport *vport = phba->pport;
5552 IOCB_t *icmd = &elsiocb->iocb;
5553 dma_addr_t paddr;
5554 struct lpfc_dmabuf *bdeBuf1 = elsiocb->context2;
5555 struct lpfc_dmabuf *bdeBuf2 = elsiocb->context3;
5556
5557 elsiocb->context1 = NULL;
5558 elsiocb->context2 = NULL;
5559 elsiocb->context3 = NULL;
5560
5561 if (icmd->ulpStatus == IOSTAT_NEED_BUFFER) {
5562 lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
5563 } else if (icmd->ulpStatus == IOSTAT_LOCAL_REJECT &&
5564 (icmd->un.ulpWord[4] & 0xff) == IOERR_RCV_BUFFER_WAITING) {
5565 phba->fc_stat.NoRcvBuf++;
5566
5567 if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
5568 lpfc_post_buffer(phba, pring, 0);
5569 return;
5570 }
5571
5572 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
5573 (icmd->ulpCommand == CMD_IOCB_RCV_ELS64_CX ||
5574 icmd->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
5575 if (icmd->unsli3.rcvsli3.vpi == 0xffff)
5576 vport = phba->pport;
5577 else {
5578 uint16_t vpi = icmd->unsli3.rcvsli3.vpi;
5579 vport = lpfc_find_vport_by_vpid(phba, vpi);
5580 }
5581 }
5582
5583
5584
5585 if (icmd->ulpBdeCount == 0)
5586 return;
5587
5588
5589
5590
5591 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
5592 elsiocb->context2 = bdeBuf1;
5593 } else {
5594 paddr = getPaddr(icmd->un.cont64[0].addrHigh,
5595 icmd->un.cont64[0].addrLow);
5596 elsiocb->context2 = lpfc_sli_ringpostbuf_get(phba, pring,
5597 paddr);
5598 }
5599
5600 lpfc_els_unsol_buffer(phba, pring, vport, elsiocb);
5601
5602
5603
5604
5605 if (elsiocb->context2) {
5606 lpfc_in_buf_free(phba, (struct lpfc_dmabuf *)elsiocb->context2);
5607 elsiocb->context2 = NULL;
5608 }
5609
5610
5611 if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) &&
5612 icmd->ulpBdeCount == 2) {
5613 elsiocb->context2 = bdeBuf2;
5614 lpfc_els_unsol_buffer(phba, pring, vport, elsiocb);
5615
5616 if (elsiocb->context2) {
5617 lpfc_in_buf_free(phba, elsiocb->context2);
5618 elsiocb->context2 = NULL;
5619 }
5620 }
5621}
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636void
5637lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
5638{
5639 struct lpfc_nodelist *ndlp, *ndlp_fdmi;
5640
5641 ndlp = lpfc_findnode_did(vport, NameServer_DID);
5642 if (!ndlp) {
5643 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
5644 if (!ndlp) {
5645 if (phba->fc_topology == TOPOLOGY_LOOP) {
5646 lpfc_disc_start(vport);
5647 return;
5648 }
5649 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
5650 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
5651 "0251 NameServer login: no memory\n");
5652 return;
5653 }
5654 lpfc_nlp_init(vport, ndlp, NameServer_DID);
5655 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
5656 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
5657 if (!ndlp) {
5658 if (phba->fc_topology == TOPOLOGY_LOOP) {
5659 lpfc_disc_start(vport);
5660 return;
5661 }
5662 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
5663 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
5664 "0348 NameServer login: node freed\n");
5665 return;
5666 }
5667 }
5668 ndlp->nlp_type |= NLP_FABRIC;
5669
5670 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
5671
5672 if (lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0)) {
5673 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
5674 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
5675 "0252 Cannot issue NameServer login\n");
5676 return;
5677 }
5678
5679 if (vport->cfg_fdmi_on) {
5680 ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
5681 GFP_KERNEL);
5682 if (ndlp_fdmi) {
5683 lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
5684 ndlp_fdmi->nlp_type |= NLP_FABRIC;
5685 lpfc_nlp_set_state(vport, ndlp_fdmi,
5686 NLP_STE_PLOGI_ISSUE);
5687 lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID,
5688 0);
5689 }
5690 }
5691 return;
5692}
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706static void
5707lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5708{
5709 struct lpfc_vport *vport = pmb->vport;
5710 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5711 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
5712 MAILBOX_t *mb = &pmb->mb;
5713
5714 spin_lock_irq(shost->host_lock);
5715 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
5716 spin_unlock_irq(shost->host_lock);
5717
5718 if (mb->mbxStatus) {
5719 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
5720 "0915 Register VPI failed: 0x%x\n",
5721 mb->mbxStatus);
5722
5723 switch (mb->mbxStatus) {
5724 case 0x11:
5725 case 0x9603:
5726 case 0x9602:
5727
5728 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
5729 spin_lock_irq(shost->host_lock);
5730 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
5731 spin_unlock_irq(shost->host_lock);
5732 lpfc_can_disctmo(vport);
5733 break;
5734 default:
5735
5736 lpfc_mbx_unreg_vpi(vport);
5737 spin_lock_irq(shost->host_lock);
5738 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
5739 spin_unlock_irq(shost->host_lock);
5740 if (vport->port_type == LPFC_PHYSICAL_PORT)
5741 lpfc_initial_flogi(vport);
5742 else
5743 lpfc_initial_fdisc(vport);
5744 break;
5745 }
5746
5747 } else {
5748 if (vport == phba->pport)
5749 lpfc_issue_fabric_reglogin(vport);
5750 else
5751 lpfc_do_scr_ns_plogi(phba, vport);
5752 }
5753
5754
5755
5756
5757 lpfc_nlp_put(ndlp);
5758
5759 mempool_free(pmb, phba->mbox_mem_pool);
5760 return;
5761}
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772static void
5773lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
5774 struct lpfc_nodelist *ndlp)
5775{
5776 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5777 LPFC_MBOXQ_t *mbox;
5778
5779 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
5780 if (mbox) {
5781 lpfc_reg_vpi(phba, vport->vpi, vport->fc_myDID, mbox);
5782 mbox->vport = vport;
5783 mbox->context2 = lpfc_nlp_get(ndlp);
5784 mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport;
5785 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
5786 == MBX_NOT_FINISHED) {
5787
5788
5789
5790 lpfc_nlp_put(ndlp);
5791 mempool_free(mbox, phba->mbox_mem_pool);
5792
5793 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
5794 "0253 Register VPI: Can't send mbox\n");
5795 goto mbox_err_exit;
5796 }
5797 } else {
5798 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
5799 "0254 Register VPI: no memory\n");
5800 goto mbox_err_exit;
5801 }
5802 return;
5803
5804mbox_err_exit:
5805 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
5806 spin_lock_irq(shost->host_lock);
5807 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
5808 spin_unlock_irq(shost->host_lock);
5809 return;
5810}
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832static void
5833lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
5834 struct lpfc_iocbq *rspiocb)
5835{
5836 struct lpfc_vport *vport = cmdiocb->vport;
5837 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5838 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
5839 struct lpfc_nodelist *np;
5840 struct lpfc_nodelist *next_np;
5841 IOCB_t *irsp = &rspiocb->iocb;
5842 struct lpfc_iocbq *piocb;
5843
5844 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
5845 "0123 FDISC completes. x%x/x%x prevDID: x%x\n",
5846 irsp->ulpStatus, irsp->un.ulpWord[4],
5847 vport->fc_prevDID);
5848
5849
5850
5851
5852 list_for_each_entry(piocb, &phba->fabric_iocb_list, list) {
5853 lpfc_set_disctmo(piocb->vport);
5854 }
5855
5856 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
5857 "FDISC cmpl: status:x%x/x%x prevdid:x%x",
5858 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID);
5859
5860 if (irsp->ulpStatus) {
5861
5862 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
5863 goto out;
5864
5865 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
5866 "0126 FDISC failed. (%d/%d)\n",
5867 irsp->ulpStatus, irsp->un.ulpWord[4]);
5868 goto fdisc_failed;
5869 }
5870 if (vport->fc_vport->vport_state == FC_VPORT_INITIALIZING)
5871 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
5872 lpfc_nlp_put(ndlp);
5873
5874 lpfc_can_disctmo(vport);
5875 spin_lock_irq(shost->host_lock);
5876 vport->fc_flag |= FC_FABRIC;
5877 if (vport->phba->fc_topology == TOPOLOGY_LOOP)
5878 vport->fc_flag |= FC_PUBLIC_LOOP;
5879 spin_unlock_irq(shost->host_lock);
5880
5881 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
5882 lpfc_vport_set_state(vport, FC_VPORT_ACTIVE);
5883 if ((vport->fc_prevDID != vport->fc_myDID) &&
5884 !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
5885
5886
5887
5888
5889 list_for_each_entry_safe(np, next_np,
5890 &vport->fc_nodes, nlp_listp) {
5891 if (!NLP_CHK_NODE_ACT(ndlp) ||
5892 (np->nlp_state != NLP_STE_NPR_NODE) ||
5893 !(np->nlp_flag & NLP_NPR_ADISC))
5894 continue;
5895 spin_lock_irq(shost->host_lock);
5896 np->nlp_flag &= ~NLP_NPR_ADISC;
5897 spin_unlock_irq(shost->host_lock);
5898 lpfc_unreg_rpi(vport, np);
5899 }
5900 lpfc_mbx_unreg_vpi(vport);
5901 spin_lock_irq(shost->host_lock);
5902 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
5903 spin_unlock_irq(shost->host_lock);
5904 }
5905
5906 if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
5907 lpfc_register_new_vport(phba, vport, ndlp);
5908 else
5909 lpfc_do_scr_ns_plogi(phba, vport);
5910 goto out;
5911fdisc_failed:
5912 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
5913
5914 lpfc_can_disctmo(vport);
5915 lpfc_nlp_put(ndlp);
5916out:
5917 lpfc_els_free_iocb(phba, cmdiocb);
5918}
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940static int
5941lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
5942 uint8_t retry)
5943{
5944 struct lpfc_hba *phba = vport->phba;
5945 IOCB_t *icmd;
5946 struct lpfc_iocbq *elsiocb;
5947 struct serv_parm *sp;
5948 uint8_t *pcmd;
5949 uint16_t cmdsize;
5950 int did = ndlp->nlp_DID;
5951 int rc;
5952
5953 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
5954 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
5955 ELS_CMD_FDISC);
5956 if (!elsiocb) {
5957 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
5958 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
5959 "0255 Issue FDISC: no IOCB\n");
5960 return 1;
5961 }
5962
5963 icmd = &elsiocb->iocb;
5964 icmd->un.elsreq64.myID = 0;
5965 icmd->un.elsreq64.fl = 1;
5966
5967
5968 icmd->ulpCt_h = 1;
5969 icmd->ulpCt_l = 0;
5970
5971 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
5972 *((uint32_t *) (pcmd)) = ELS_CMD_FDISC;
5973 pcmd += sizeof(uint32_t);
5974 memcpy(pcmd, &vport->phba->pport->fc_sparam, sizeof(struct serv_parm));
5975 sp = (struct serv_parm *) pcmd;
5976
5977 sp->cmn.e_d_tov = 0;
5978 sp->cmn.w2.r_a_tov = 0;
5979 sp->cls1.classValid = 0;
5980 sp->cls2.seqDelivery = 1;
5981 sp->cls3.seqDelivery = 1;
5982
5983 pcmd += sizeof(uint32_t);
5984 pcmd += sizeof(uint32_t);
5985 pcmd += sizeof(uint32_t);
5986 pcmd += sizeof(uint32_t);
5987 memcpy(pcmd, &vport->fc_portname, 8);
5988 pcmd += sizeof(uint32_t);
5989 pcmd += sizeof(uint32_t);
5990 memcpy(pcmd, &vport->fc_nodename, 8);
5991
5992 lpfc_set_disctmo(vport);
5993
5994 phba->fc_stat.elsXmitFDISC++;
5995 elsiocb->iocb_cmpl = lpfc_cmpl_els_fdisc;
5996
5997 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
5998 "Issue FDISC: did:x%x",
5999 did, 0, 0);
6000
6001 rc = lpfc_issue_fabric_iocb(phba, elsiocb);
6002 if (rc == IOCB_ERROR) {
6003 lpfc_els_free_iocb(phba, elsiocb);
6004 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
6005 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
6006 "0256 Issue FDISC: Cannot send IOCB\n");
6007 return 1;
6008 }
6009 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
6010 vport->port_state = LPFC_FDISC;
6011 return 0;
6012}
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028static void
6029lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6030 struct lpfc_iocbq *rspiocb)
6031{
6032 struct lpfc_vport *vport = cmdiocb->vport;
6033 IOCB_t *irsp;
6034 struct lpfc_nodelist *ndlp;
6035 ndlp = (struct lpfc_nodelist *)cmdiocb->context1;
6036
6037 irsp = &rspiocb->iocb;
6038 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
6039 "LOGO npiv cmpl: status:x%x/x%x did:x%x",
6040 irsp->ulpStatus, irsp->un.ulpWord[4], irsp->un.rcvels.remoteID);
6041
6042 lpfc_els_free_iocb(phba, cmdiocb);
6043 vport->unreg_vpi_cmpl = VPORT_ERROR;
6044
6045
6046 lpfc_nlp_put(ndlp);
6047}
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065int
6066lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
6067{
6068 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
6069 struct lpfc_hba *phba = vport->phba;
6070 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
6071 IOCB_t *icmd;
6072 struct lpfc_iocbq *elsiocb;
6073 uint8_t *pcmd;
6074 uint16_t cmdsize;
6075
6076 cmdsize = 2 * sizeof(uint32_t) + sizeof(struct lpfc_name);
6077 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, 0, ndlp, ndlp->nlp_DID,
6078 ELS_CMD_LOGO);
6079 if (!elsiocb)
6080 return 1;
6081
6082 icmd = &elsiocb->iocb;
6083 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
6084 *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
6085 pcmd += sizeof(uint32_t);
6086
6087
6088 *((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID);
6089 pcmd += sizeof(uint32_t);
6090 memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name));
6091
6092 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
6093 "Issue LOGO npiv did:x%x flg:x%x",
6094 ndlp->nlp_DID, ndlp->nlp_flag, 0);
6095
6096 elsiocb->iocb_cmpl = lpfc_cmpl_els_npiv_logo;
6097 spin_lock_irq(shost->host_lock);
6098 ndlp->nlp_flag |= NLP_LOGO_SND;
6099 spin_unlock_irq(shost->host_lock);
6100 if (lpfc_sli_issue_iocb(phba, pring, elsiocb, 0) == IOCB_ERROR) {
6101 spin_lock_irq(shost->host_lock);
6102 ndlp->nlp_flag &= ~NLP_LOGO_SND;
6103 spin_unlock_irq(shost->host_lock);
6104 lpfc_els_free_iocb(phba, elsiocb);
6105 return 1;
6106 }
6107 return 0;
6108}
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121void
6122lpfc_fabric_block_timeout(unsigned long ptr)
6123{
6124 struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
6125 unsigned long iflags;
6126 uint32_t tmo_posted;
6127
6128 spin_lock_irqsave(&phba->pport->work_port_lock, iflags);
6129 tmo_posted = phba->pport->work_port_events & WORKER_FABRIC_BLOCK_TMO;
6130 if (!tmo_posted)
6131 phba->pport->work_port_events |= WORKER_FABRIC_BLOCK_TMO;
6132 spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags);
6133
6134 if (!tmo_posted)
6135 lpfc_worker_wake_up(phba);
6136 return;
6137}
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149static void
6150lpfc_resume_fabric_iocbs(struct lpfc_hba *phba)
6151{
6152 struct lpfc_iocbq *iocb;
6153 unsigned long iflags;
6154 int ret;
6155 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
6156 IOCB_t *cmd;
6157
6158repeat:
6159 iocb = NULL;
6160 spin_lock_irqsave(&phba->hbalock, iflags);
6161
6162 if (atomic_read(&phba->fabric_iocb_count) == 0) {
6163 list_remove_head(&phba->fabric_iocb_list, iocb, typeof(*iocb),
6164 list);
6165 if (iocb)
6166
6167 atomic_inc(&phba->fabric_iocb_count);
6168 }
6169 spin_unlock_irqrestore(&phba->hbalock, iflags);
6170 if (iocb) {
6171 iocb->fabric_iocb_cmpl = iocb->iocb_cmpl;
6172 iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb;
6173 iocb->iocb_flag |= LPFC_IO_FABRIC;
6174
6175 lpfc_debugfs_disc_trc(iocb->vport, LPFC_DISC_TRC_ELS_CMD,
6176 "Fabric sched1: ste:x%x",
6177 iocb->vport->port_state, 0, 0);
6178
6179 ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0);
6180
6181 if (ret == IOCB_ERROR) {
6182 iocb->iocb_cmpl = iocb->fabric_iocb_cmpl;
6183 iocb->fabric_iocb_cmpl = NULL;
6184 iocb->iocb_flag &= ~LPFC_IO_FABRIC;
6185 cmd = &iocb->iocb;
6186 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
6187 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
6188 iocb->iocb_cmpl(phba, iocb, iocb);
6189
6190 atomic_dec(&phba->fabric_iocb_count);
6191 goto repeat;
6192 }
6193 }
6194
6195 return;
6196}
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207void
6208lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba)
6209{
6210 clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
6211
6212 lpfc_resume_fabric_iocbs(phba);
6213 return;
6214}
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225static void
6226lpfc_block_fabric_iocbs(struct lpfc_hba *phba)
6227{
6228 int blocked;
6229
6230 blocked = test_and_set_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
6231
6232 if (!blocked)
6233 mod_timer(&phba->fabric_block_timer, jiffies + HZ/10 );
6234
6235 return;
6236}
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251static void
6252lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
6253 struct lpfc_iocbq *rspiocb)
6254{
6255 struct ls_rjt stat;
6256
6257 if ((cmdiocb->iocb_flag & LPFC_IO_FABRIC) != LPFC_IO_FABRIC)
6258 BUG();
6259
6260 switch (rspiocb->iocb.ulpStatus) {
6261 case IOSTAT_NPORT_RJT:
6262 case IOSTAT_FABRIC_RJT:
6263 if (rspiocb->iocb.un.ulpWord[4] & RJT_UNAVAIL_TEMP) {
6264 lpfc_block_fabric_iocbs(phba);
6265 }
6266 break;
6267
6268 case IOSTAT_NPORT_BSY:
6269 case IOSTAT_FABRIC_BSY:
6270 lpfc_block_fabric_iocbs(phba);
6271 break;
6272
6273 case IOSTAT_LS_RJT:
6274 stat.un.lsRjtError =
6275 be32_to_cpu(rspiocb->iocb.un.ulpWord[4]);
6276 if ((stat.un.b.lsRjtRsnCode == LSRJT_UNABLE_TPC) ||
6277 (stat.un.b.lsRjtRsnCode == LSRJT_LOGICAL_BSY))
6278 lpfc_block_fabric_iocbs(phba);
6279 break;
6280 }
6281
6282 if (atomic_read(&phba->fabric_iocb_count) == 0)
6283 BUG();
6284
6285 cmdiocb->iocb_cmpl = cmdiocb->fabric_iocb_cmpl;
6286 cmdiocb->fabric_iocb_cmpl = NULL;
6287 cmdiocb->iocb_flag &= ~LPFC_IO_FABRIC;
6288 cmdiocb->iocb_cmpl(phba, cmdiocb, rspiocb);
6289
6290 atomic_dec(&phba->fabric_iocb_count);
6291 if (!test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags)) {
6292
6293 lpfc_resume_fabric_iocbs(phba);
6294 }
6295}
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321static int
6322lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb)
6323{
6324 unsigned long iflags;
6325 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
6326 int ready;
6327 int ret;
6328
6329 if (atomic_read(&phba->fabric_iocb_count) > 1)
6330 BUG();
6331
6332 spin_lock_irqsave(&phba->hbalock, iflags);
6333 ready = atomic_read(&phba->fabric_iocb_count) == 0 &&
6334 !test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
6335
6336 if (ready)
6337
6338 atomic_inc(&phba->fabric_iocb_count);
6339 spin_unlock_irqrestore(&phba->hbalock, iflags);
6340 if (ready) {
6341 iocb->fabric_iocb_cmpl = iocb->iocb_cmpl;
6342 iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb;
6343 iocb->iocb_flag |= LPFC_IO_FABRIC;
6344
6345 lpfc_debugfs_disc_trc(iocb->vport, LPFC_DISC_TRC_ELS_CMD,
6346 "Fabric sched2: ste:x%x",
6347 iocb->vport->port_state, 0, 0);
6348
6349 ret = lpfc_sli_issue_iocb(phba, pring, iocb, 0);
6350
6351 if (ret == IOCB_ERROR) {
6352 iocb->iocb_cmpl = iocb->fabric_iocb_cmpl;
6353 iocb->fabric_iocb_cmpl = NULL;
6354 iocb->iocb_flag &= ~LPFC_IO_FABRIC;
6355 atomic_dec(&phba->fabric_iocb_count);
6356 }
6357 } else {
6358 spin_lock_irqsave(&phba->hbalock, iflags);
6359 list_add_tail(&iocb->list, &phba->fabric_iocb_list);
6360 spin_unlock_irqrestore(&phba->hbalock, iflags);
6361 ret = IOCB_SUCCESS;
6362 }
6363 return ret;
6364}
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377static void lpfc_fabric_abort_vport(struct lpfc_vport *vport)
6378{
6379 LIST_HEAD(completions);
6380 struct lpfc_hba *phba = vport->phba;
6381 struct lpfc_iocbq *tmp_iocb, *piocb;
6382 IOCB_t *cmd;
6383
6384 spin_lock_irq(&phba->hbalock);
6385 list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
6386 list) {
6387
6388 if (piocb->vport != vport)
6389 continue;
6390
6391 list_move_tail(&piocb->list, &completions);
6392 }
6393 spin_unlock_irq(&phba->hbalock);
6394
6395 while (!list_empty(&completions)) {
6396 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
6397 list_del_init(&piocb->list);
6398
6399 cmd = &piocb->iocb;
6400 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
6401 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
6402 (piocb->iocb_cmpl) (phba, piocb, piocb);
6403 }
6404}
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp)
6418{
6419 LIST_HEAD(completions);
6420 struct lpfc_hba *phba = ndlp->vport->phba;
6421 struct lpfc_iocbq *tmp_iocb, *piocb;
6422 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
6423 IOCB_t *cmd;
6424
6425 spin_lock_irq(&phba->hbalock);
6426 list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
6427 list) {
6428 if ((lpfc_check_sli_ndlp(phba, pring, piocb, ndlp))) {
6429
6430 list_move_tail(&piocb->list, &completions);
6431 }
6432 }
6433 spin_unlock_irq(&phba->hbalock);
6434
6435 while (!list_empty(&completions)) {
6436 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
6437 list_del_init(&piocb->list);
6438
6439 cmd = &piocb->iocb;
6440 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
6441 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
6442 (piocb->iocb_cmpl) (phba, piocb, piocb);
6443 }
6444}
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457void lpfc_fabric_abort_hba(struct lpfc_hba *phba)
6458{
6459 LIST_HEAD(completions);
6460 struct lpfc_iocbq *piocb;
6461 IOCB_t *cmd;
6462
6463 spin_lock_irq(&phba->hbalock);
6464 list_splice_init(&phba->fabric_iocb_list, &completions);
6465 spin_unlock_irq(&phba->hbalock);
6466
6467 while (!list_empty(&completions)) {
6468 piocb = list_get_first(&completions, struct lpfc_iocbq, list);
6469 list_del_init(&piocb->list);
6470
6471 cmd = &piocb->iocb;
6472 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
6473 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
6474 (piocb->iocb_cmpl) (phba, piocb, piocb);
6475 }
6476}