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/slab.h>
25#include <linux/interrupt.h>
26
27#include <scsi/scsi.h>
28#include <scsi/scsi_device.h>
29#include <scsi/scsi_host.h>
30#include <scsi/scsi_transport_fc.h>
31
32
33#include "lpfc_hw4.h"
34#include "lpfc_hw.h"
35#include "lpfc_sli.h"
36#include "lpfc_sli4.h"
37#include "lpfc_nl.h"
38#include "lpfc_disc.h"
39#include "lpfc_scsi.h"
40#include "lpfc.h"
41#include "lpfc_logmsg.h"
42#include "lpfc_crtn.h"
43#include "lpfc_vport.h"
44#include "lpfc_debugfs.h"
45
46static int lpfc_els_retry(struct lpfc_hba *, struct lpfc_iocbq *,
47 struct lpfc_iocbq *);
48static void lpfc_cmpl_fabric_iocb(struct lpfc_hba *, struct lpfc_iocbq *,
49 struct lpfc_iocbq *);
50static void lpfc_fabric_abort_vport(struct lpfc_vport *vport);
51static int lpfc_issue_els_fdisc(struct lpfc_vport *vport,
52 struct lpfc_nodelist *ndlp, uint8_t retry);
53static int lpfc_issue_fabric_iocb(struct lpfc_hba *phba,
54 struct lpfc_iocbq *iocb);
55
56static int lpfc_max_els_tries = 3;
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80int
81lpfc_els_chk_latt(struct lpfc_vport *vport)
82{
83 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
84 struct lpfc_hba *phba = vport->phba;
85 uint32_t ha_copy;
86
87 if (vport->port_state >= LPFC_VPORT_READY ||
88 phba->link_state == LPFC_LINK_DOWN ||
89 phba->sli_rev > LPFC_SLI_REV3)
90 return 0;
91
92
93 if (lpfc_readl(phba->HAregaddr, &ha_copy))
94 return 1;
95
96 if (!(ha_copy & HA_LATT))
97 return 0;
98
99
100 lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
101 "0237 Pending Link Event during "
102 "Discovery: State x%x\n",
103 phba->pport->port_state);
104
105
106
107
108
109
110
111 spin_lock_irq(shost->host_lock);
112 vport->fc_flag |= FC_ABORT_DISCOVERY;
113 spin_unlock_irq(shost->host_lock);
114
115 if (phba->link_state != LPFC_CLEAR_LA)
116 lpfc_issue_clear_la(phba, vport);
117
118 return 1;
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
146
147
148
149struct lpfc_iocbq *
150lpfc_prep_els_iocb(struct lpfc_vport *vport, uint8_t expectRsp,
151 uint16_t cmdSize, uint8_t retry,
152 struct lpfc_nodelist *ndlp, uint32_t did,
153 uint32_t elscmd)
154{
155 struct lpfc_hba *phba = vport->phba;
156 struct lpfc_iocbq *elsiocb;
157 struct lpfc_dmabuf *pcmd, *prsp, *pbuflist;
158 struct ulp_bde64 *bpl;
159 IOCB_t *icmd;
160
161
162 if (!lpfc_is_link_up(phba))
163 return NULL;
164
165
166 elsiocb = lpfc_sli_get_iocbq(phba);
167
168 if (elsiocb == NULL)
169 return NULL;
170
171
172
173
174
175 if ((did == Fabric_DID) &&
176 (phba->hba_flag & HBA_FIP_SUPPORT) &&
177 ((elscmd == ELS_CMD_FLOGI) ||
178 (elscmd == ELS_CMD_FDISC) ||
179 (elscmd == ELS_CMD_LOGO)))
180 switch (elscmd) {
181 case ELS_CMD_FLOGI:
182 elsiocb->iocb_flag |=
183 ((LPFC_ELS_ID_FLOGI << LPFC_FIP_ELS_ID_SHIFT)
184 & LPFC_FIP_ELS_ID_MASK);
185 break;
186 case ELS_CMD_FDISC:
187 elsiocb->iocb_flag |=
188 ((LPFC_ELS_ID_FDISC << LPFC_FIP_ELS_ID_SHIFT)
189 & LPFC_FIP_ELS_ID_MASK);
190 break;
191 case ELS_CMD_LOGO:
192 elsiocb->iocb_flag |=
193 ((LPFC_ELS_ID_LOGO << LPFC_FIP_ELS_ID_SHIFT)
194 & LPFC_FIP_ELS_ID_MASK);
195 break;
196 }
197 else
198 elsiocb->iocb_flag &= ~LPFC_FIP_ELS_ID_MASK;
199
200 icmd = &elsiocb->iocb;
201
202
203
204 pcmd = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
205 if (pcmd)
206 pcmd->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &pcmd->phys);
207 if (!pcmd || !pcmd->virt)
208 goto els_iocb_free_pcmb_exit;
209
210 INIT_LIST_HEAD(&pcmd->list);
211
212
213 if (expectRsp) {
214 prsp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
215 if (prsp)
216 prsp->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
217 &prsp->phys);
218 if (!prsp || !prsp->virt)
219 goto els_iocb_free_prsp_exit;
220 INIT_LIST_HEAD(&prsp->list);
221 } else
222 prsp = NULL;
223
224
225 pbuflist = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
226 if (pbuflist)
227 pbuflist->virt = lpfc_mbuf_alloc(phba, MEM_PRI,
228 &pbuflist->phys);
229 if (!pbuflist || !pbuflist->virt)
230 goto els_iocb_free_pbuf_exit;
231
232 INIT_LIST_HEAD(&pbuflist->list);
233
234 if (expectRsp) {
235 icmd->un.elsreq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
236 icmd->un.elsreq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
237 icmd->un.elsreq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
238 icmd->un.elsreq64.bdl.bdeSize = (2 * sizeof(struct ulp_bde64));
239
240 icmd->un.elsreq64.remoteID = did;
241 icmd->ulpCommand = CMD_ELS_REQUEST64_CR;
242 if (elscmd == ELS_CMD_FLOGI)
243 icmd->ulpTimeout = FF_DEF_RATOV * 2;
244 else
245 icmd->ulpTimeout = phba->fc_ratov * 2;
246 } else {
247 icmd->un.xseq64.bdl.addrHigh = putPaddrHigh(pbuflist->phys);
248 icmd->un.xseq64.bdl.addrLow = putPaddrLow(pbuflist->phys);
249 icmd->un.xseq64.bdl.bdeFlags = BUFF_TYPE_BLP_64;
250 icmd->un.xseq64.bdl.bdeSize = sizeof(struct ulp_bde64);
251 icmd->un.xseq64.xmit_els_remoteID = did;
252 icmd->ulpCommand = CMD_XMIT_ELS_RSP64_CX;
253 }
254 icmd->ulpBdeCount = 1;
255 icmd->ulpLe = 1;
256 icmd->ulpClass = CLASS3;
257
258
259
260
261
262
263 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) ||
264 ((phba->sli_rev == LPFC_SLI_REV4) &&
265 (vport->fc_flag & FC_PT2PT))) {
266
267 if (expectRsp) {
268 icmd->un.elsreq64.myID = vport->fc_myDID;
269
270
271 icmd->ulpContext = phba->vpi_ids[vport->vpi];
272 }
273
274 icmd->ulpCt_h = 0;
275
276 if (elscmd == ELS_CMD_ECHO)
277 icmd->ulpCt_l = 0;
278 else
279 icmd->ulpCt_l = 1;
280 }
281
282 bpl = (struct ulp_bde64 *) pbuflist->virt;
283 bpl->addrLow = le32_to_cpu(putPaddrLow(pcmd->phys));
284 bpl->addrHigh = le32_to_cpu(putPaddrHigh(pcmd->phys));
285 bpl->tus.f.bdeSize = cmdSize;
286 bpl->tus.f.bdeFlags = 0;
287 bpl->tus.w = le32_to_cpu(bpl->tus.w);
288
289 if (expectRsp) {
290 bpl++;
291 bpl->addrLow = le32_to_cpu(putPaddrLow(prsp->phys));
292 bpl->addrHigh = le32_to_cpu(putPaddrHigh(prsp->phys));
293 bpl->tus.f.bdeSize = FCELSSIZE;
294 bpl->tus.f.bdeFlags = BUFF_TYPE_BDE_64;
295 bpl->tus.w = le32_to_cpu(bpl->tus.w);
296 }
297
298
299 elsiocb->context1 = lpfc_nlp_get(ndlp);
300 if (!elsiocb->context1)
301 goto els_iocb_free_pbuf_exit;
302 elsiocb->context2 = pcmd;
303 elsiocb->context3 = pbuflist;
304 elsiocb->retry = retry;
305 elsiocb->vport = vport;
306 elsiocb->drvrTimeout = (phba->fc_ratov << 1) + LPFC_DRVR_TIMEOUT;
307
308 if (prsp) {
309 list_add(&prsp->list, &pcmd->list);
310 }
311 if (expectRsp) {
312
313 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
314 "0116 Xmit ELS command x%x to remote "
315 "NPORT x%x I/O tag: x%x, port state:x%x"
316 " fc_flag:x%x\n",
317 elscmd, did, elsiocb->iotag,
318 vport->port_state,
319 vport->fc_flag);
320 } else {
321
322 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
323 "0117 Xmit ELS response x%x to remote "
324 "NPORT x%x I/O tag: x%x, size: x%x "
325 "port_state x%x fc_flag x%x\n",
326 elscmd, ndlp->nlp_DID, elsiocb->iotag,
327 cmdSize, vport->port_state,
328 vport->fc_flag);
329 }
330 return elsiocb;
331
332els_iocb_free_pbuf_exit:
333 if (expectRsp)
334 lpfc_mbuf_free(phba, prsp->virt, prsp->phys);
335 kfree(pbuflist);
336
337els_iocb_free_prsp_exit:
338 lpfc_mbuf_free(phba, pcmd->virt, pcmd->phys);
339 kfree(prsp);
340
341els_iocb_free_pcmb_exit:
342 kfree(pcmd);
343 lpfc_sli_release_iocbq(phba, elsiocb);
344 return NULL;
345}
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363int
364lpfc_issue_fabric_reglogin(struct lpfc_vport *vport)
365{
366 struct lpfc_hba *phba = vport->phba;
367 LPFC_MBOXQ_t *mbox;
368 struct lpfc_dmabuf *mp;
369 struct lpfc_nodelist *ndlp;
370 struct serv_parm *sp;
371 int rc;
372 int err = 0;
373
374 sp = &phba->fc_fabparam;
375 ndlp = lpfc_findnode_did(vport, Fabric_DID);
376 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
377 err = 1;
378 goto fail;
379 }
380
381 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
382 if (!mbox) {
383 err = 2;
384 goto fail;
385 }
386
387 vport->port_state = LPFC_FABRIC_CFG_LINK;
388 lpfc_config_link(phba, mbox);
389 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
390 mbox->vport = vport;
391
392 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
393 if (rc == MBX_NOT_FINISHED) {
394 err = 3;
395 goto fail_free_mbox;
396 }
397
398 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
399 if (!mbox) {
400 err = 4;
401 goto fail;
402 }
403 rc = lpfc_reg_rpi(phba, vport->vpi, Fabric_DID, (uint8_t *)sp, mbox,
404 ndlp->nlp_rpi);
405 if (rc) {
406 err = 5;
407 goto fail_free_mbox;
408 }
409
410 mbox->mbox_cmpl = lpfc_mbx_cmpl_fabric_reg_login;
411 mbox->vport = vport;
412
413
414
415 mbox->context2 = lpfc_nlp_get(ndlp);
416
417 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
418 if (rc == MBX_NOT_FINISHED) {
419 err = 6;
420 goto fail_issue_reg_login;
421 }
422
423 return 0;
424
425fail_issue_reg_login:
426
427
428
429 lpfc_nlp_put(ndlp);
430 mp = (struct lpfc_dmabuf *) mbox->context1;
431 lpfc_mbuf_free(phba, mp->virt, mp->phys);
432 kfree(mp);
433fail_free_mbox:
434 mempool_free(mbox, phba->mbox_mem_pool);
435
436fail:
437 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
438 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
439 "0249 Cannot issue Register Fabric login: Err %d\n", err);
440 return -ENXIO;
441}
442
443
444
445
446
447
448
449
450
451
452
453
454int
455lpfc_issue_reg_vfi(struct lpfc_vport *vport)
456{
457 struct lpfc_hba *phba = vport->phba;
458 LPFC_MBOXQ_t *mboxq;
459 struct lpfc_nodelist *ndlp;
460 struct serv_parm *sp;
461 struct lpfc_dmabuf *dmabuf;
462 int rc = 0;
463
464 sp = &phba->fc_fabparam;
465
466 if ((phba->sli_rev == LPFC_SLI_REV4) &&
467 !(phba->link_flag & LS_LOOPBACK_MODE) &&
468 !(vport->fc_flag & FC_PT2PT)) {
469 ndlp = lpfc_findnode_did(vport, Fabric_DID);
470 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
471 rc = -ENODEV;
472 goto fail;
473 }
474 }
475
476 dmabuf = kzalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
477 if (!dmabuf) {
478 rc = -ENOMEM;
479 goto fail;
480 }
481 dmabuf->virt = lpfc_mbuf_alloc(phba, MEM_PRI, &dmabuf->phys);
482 if (!dmabuf->virt) {
483 rc = -ENOMEM;
484 goto fail_free_dmabuf;
485 }
486
487 mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
488 if (!mboxq) {
489 rc = -ENOMEM;
490 goto fail_free_coherent;
491 }
492 vport->port_state = LPFC_FABRIC_CFG_LINK;
493 memcpy(dmabuf->virt, &phba->fc_fabparam, sizeof(vport->fc_sparam));
494 lpfc_reg_vfi(mboxq, vport, dmabuf->phys);
495
496 mboxq->mbox_cmpl = lpfc_mbx_cmpl_reg_vfi;
497 mboxq->vport = vport;
498 mboxq->context1 = dmabuf;
499 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
500 if (rc == MBX_NOT_FINISHED) {
501 rc = -ENXIO;
502 goto fail_free_mbox;
503 }
504 return 0;
505
506fail_free_mbox:
507 mempool_free(mboxq, phba->mbox_mem_pool);
508fail_free_coherent:
509 lpfc_mbuf_free(phba, dmabuf->virt, dmabuf->phys);
510fail_free_dmabuf:
511 kfree(dmabuf);
512fail:
513 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
514 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
515 "0289 Issue Register VFI failed: Err %d\n", rc);
516 return rc;
517}
518
519
520
521
522
523
524
525
526
527
528
529
530int
531lpfc_issue_unreg_vfi(struct lpfc_vport *vport)
532{
533 struct lpfc_hba *phba = vport->phba;
534 struct Scsi_Host *shost;
535 LPFC_MBOXQ_t *mboxq;
536 int rc;
537
538 mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
539 if (!mboxq) {
540 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
541 "2556 UNREG_VFI mbox allocation failed"
542 "HBA state x%x\n", phba->pport->port_state);
543 return -ENOMEM;
544 }
545
546 lpfc_unreg_vfi(mboxq, vport);
547 mboxq->vport = vport;
548 mboxq->mbox_cmpl = lpfc_unregister_vfi_cmpl;
549
550 rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_NOWAIT);
551 if (rc == MBX_NOT_FINISHED) {
552 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY|LOG_MBOX,
553 "2557 UNREG_VFI issue mbox failed rc x%x "
554 "HBA state x%x\n",
555 rc, phba->pport->port_state);
556 mempool_free(mboxq, phba->mbox_mem_pool);
557 return -EIO;
558 }
559
560 shost = lpfc_shost_from_vport(vport);
561 spin_lock_irq(shost->host_lock);
562 vport->fc_flag &= ~FC_VFI_REGISTERED;
563 spin_unlock_irq(shost->host_lock);
564 return 0;
565}
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585static uint8_t
586lpfc_check_clean_addr_bit(struct lpfc_vport *vport,
587 struct serv_parm *sp)
588{
589 uint8_t fabric_param_changed = 0;
590 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
591
592 if ((vport->fc_prevDID != vport->fc_myDID) ||
593 memcmp(&vport->fabric_portname, &sp->portName,
594 sizeof(struct lpfc_name)) ||
595 memcmp(&vport->fabric_nodename, &sp->nodeName,
596 sizeof(struct lpfc_name)))
597 fabric_param_changed = 1;
598
599
600
601
602
603
604
605
606
607
608
609 if (fabric_param_changed && !sp->cmn.clean_address_bit &&
610 (vport->fc_prevDID || lpfc_delay_discovery)) {
611 spin_lock_irq(shost->host_lock);
612 vport->fc_flag |= FC_DISC_DELAYED;
613 spin_unlock_irq(shost->host_lock);
614 }
615
616 return fabric_param_changed;
617}
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640static int
641lpfc_cmpl_els_flogi_fabric(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
642 struct serv_parm *sp, IOCB_t *irsp)
643{
644 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
645 struct lpfc_hba *phba = vport->phba;
646 struct lpfc_nodelist *np;
647 struct lpfc_nodelist *next_np;
648 uint8_t fabric_param_changed;
649
650 spin_lock_irq(shost->host_lock);
651 vport->fc_flag |= FC_FABRIC;
652 spin_unlock_irq(shost->host_lock);
653
654 phba->fc_edtov = be32_to_cpu(sp->cmn.e_d_tov);
655 if (sp->cmn.edtovResolution)
656 phba->fc_edtov = (phba->fc_edtov + 999999) / 1000000;
657
658 phba->fc_edtovResol = sp->cmn.edtovResolution;
659 phba->fc_ratov = (be32_to_cpu(sp->cmn.w2.r_a_tov) + 999) / 1000;
660
661 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
662 spin_lock_irq(shost->host_lock);
663 vport->fc_flag |= FC_PUBLIC_LOOP;
664 spin_unlock_irq(shost->host_lock);
665 }
666
667 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
668 memcpy(&ndlp->nlp_portname, &sp->portName, sizeof(struct lpfc_name));
669 memcpy(&ndlp->nlp_nodename, &sp->nodeName, sizeof(struct lpfc_name));
670 ndlp->nlp_class_sup = 0;
671 if (sp->cls1.classValid)
672 ndlp->nlp_class_sup |= FC_COS_CLASS1;
673 if (sp->cls2.classValid)
674 ndlp->nlp_class_sup |= FC_COS_CLASS2;
675 if (sp->cls3.classValid)
676 ndlp->nlp_class_sup |= FC_COS_CLASS3;
677 if (sp->cls4.classValid)
678 ndlp->nlp_class_sup |= FC_COS_CLASS4;
679 ndlp->nlp_maxframe = ((sp->cmn.bbRcvSizeMsb & 0x0F) << 8) |
680 sp->cmn.bbRcvSizeLsb;
681
682 fabric_param_changed = lpfc_check_clean_addr_bit(vport, sp);
683 memcpy(&vport->fabric_portname, &sp->portName,
684 sizeof(struct lpfc_name));
685 memcpy(&vport->fabric_nodename, &sp->nodeName,
686 sizeof(struct lpfc_name));
687 memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
688
689 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
690 if (sp->cmn.response_multiple_NPort) {
691 lpfc_printf_vlog(vport, KERN_WARNING,
692 LOG_ELS | LOG_VPORT,
693 "1816 FLOGI NPIV supported, "
694 "response data 0x%x\n",
695 sp->cmn.response_multiple_NPort);
696 spin_lock_irq(&phba->hbalock);
697 phba->link_flag |= LS_NPIV_FAB_SUPPORTED;
698 spin_unlock_irq(&phba->hbalock);
699 } else {
700
701
702 lpfc_printf_vlog(vport, KERN_WARNING,
703 LOG_ELS | LOG_VPORT,
704 "1817 Fabric does not support NPIV "
705 "- configuring single port mode.\n");
706 spin_lock_irq(&phba->hbalock);
707 phba->link_flag &= ~LS_NPIV_FAB_SUPPORTED;
708 spin_unlock_irq(&phba->hbalock);
709 }
710 }
711
712
713
714
715
716 if (phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) {
717
718 if ((phba->sli_rev == LPFC_SLI_REV4) && fabric_param_changed)
719 lpfc_unregister_fcf_prep(phba);
720
721
722 if (vport->fc_flag & FC_VFI_REGISTERED)
723 lpfc_issue_reg_vfi(vport);
724 }
725
726 if (fabric_param_changed &&
727 !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
728
729
730
731
732 list_for_each_entry_safe(np, next_np,
733 &vport->fc_nodes, nlp_listp) {
734 if (!NLP_CHK_NODE_ACT(np))
735 continue;
736 if ((np->nlp_state != NLP_STE_NPR_NODE) ||
737 !(np->nlp_flag & NLP_NPR_ADISC))
738 continue;
739 spin_lock_irq(shost->host_lock);
740 np->nlp_flag &= ~NLP_NPR_ADISC;
741 spin_unlock_irq(shost->host_lock);
742 lpfc_unreg_rpi(vport, np);
743 }
744 lpfc_cleanup_pending_mbox(vport);
745
746 if (phba->sli_rev == LPFC_SLI_REV4) {
747 lpfc_sli4_unreg_all_rpis(vport);
748 lpfc_mbx_unreg_vpi(vport);
749 spin_lock_irq(shost->host_lock);
750 vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
751 spin_unlock_irq(shost->host_lock);
752 }
753
754
755
756
757
758 spin_lock_irq(shost->host_lock);
759 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
760 spin_unlock_irq(shost->host_lock);
761 } else if ((phba->sli_rev == LPFC_SLI_REV4) &&
762 !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
763
764
765
766
767 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
768 lpfc_register_new_vport(phba, vport, ndlp);
769 return 0;
770 }
771
772 if (phba->sli_rev < LPFC_SLI_REV4) {
773 lpfc_nlp_set_state(vport, ndlp, NLP_STE_REG_LOGIN_ISSUE);
774 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED &&
775 vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
776 lpfc_register_new_vport(phba, vport, ndlp);
777 else
778 lpfc_issue_fabric_reglogin(vport);
779 } else {
780 ndlp->nlp_type |= NLP_FABRIC;
781 lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNMAPPED_NODE);
782 if ((!(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) &&
783 (vport->vpi_state & LPFC_VPI_REGISTERED)) {
784 lpfc_start_fdiscs(phba);
785 lpfc_do_scr_ns_plogi(phba, vport);
786 } else if (vport->fc_flag & FC_VFI_REGISTERED)
787 lpfc_issue_init_vpi(vport);
788 else {
789 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
790 "3135 Need register VFI: (x%x/%x)\n",
791 vport->fc_prevDID, vport->fc_myDID);
792 lpfc_issue_reg_vfi(vport);
793 }
794 }
795 return 0;
796}
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818static int
819lpfc_cmpl_els_flogi_nport(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
820 struct serv_parm *sp)
821{
822 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
823 struct lpfc_hba *phba = vport->phba;
824 LPFC_MBOXQ_t *mbox;
825 int rc;
826
827 spin_lock_irq(shost->host_lock);
828 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
829 spin_unlock_irq(shost->host_lock);
830
831 phba->fc_edtov = FF_DEF_EDTOV;
832 phba->fc_ratov = FF_DEF_RATOV;
833 rc = memcmp(&vport->fc_portname, &sp->portName,
834 sizeof(vport->fc_portname));
835 memcpy(&phba->fc_fabparam, sp, sizeof(struct serv_parm));
836
837 if (rc >= 0) {
838
839 spin_lock_irq(shost->host_lock);
840 vport->fc_flag |= FC_PT2PT_PLOGI;
841 spin_unlock_irq(shost->host_lock);
842
843
844
845
846
847
848
849 if (rc)
850 vport->fc_myDID = PT2PT_LocalID;
851
852 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
853 if (!mbox)
854 goto fail;
855
856 lpfc_config_link(phba, mbox);
857
858 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
859 mbox->vport = vport;
860 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
861 if (rc == MBX_NOT_FINISHED) {
862 mempool_free(mbox, phba->mbox_mem_pool);
863 goto fail;
864 }
865
866
867
868
869
870
871
872
873 if ((phba->sli_rev == LPFC_SLI_REV4) && rc)
874 lpfc_issue_reg_vfi(vport);
875
876
877
878
879 lpfc_nlp_put(ndlp);
880
881 ndlp = lpfc_findnode_did(vport, PT2PT_RemoteID);
882 if (!ndlp) {
883
884
885
886
887 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
888 if (!ndlp)
889 goto fail;
890 lpfc_nlp_init(vport, ndlp, PT2PT_RemoteID);
891 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
892 ndlp = lpfc_enable_node(vport, ndlp,
893 NLP_STE_UNUSED_NODE);
894 if(!ndlp)
895 goto fail;
896 }
897
898 memcpy(&ndlp->nlp_portname, &sp->portName,
899 sizeof(struct lpfc_name));
900 memcpy(&ndlp->nlp_nodename, &sp->nodeName,
901 sizeof(struct lpfc_name));
902
903 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
904 spin_lock_irq(shost->host_lock);
905 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
906 spin_unlock_irq(shost->host_lock);
907 } else
908
909
910
911
912 lpfc_nlp_put(ndlp);
913
914
915 phba->sli3_options &= ~LPFC_SLI3_NPIV_ENABLED;
916
917 spin_lock_irq(shost->host_lock);
918 vport->fc_flag |= FC_PT2PT;
919 spin_unlock_irq(shost->host_lock);
920
921 if ((phba->sli_rev == LPFC_SLI_REV4) && phba->fc_topology_changed) {
922 lpfc_unregister_fcf_prep(phba);
923
924
925
926
927
928
929
930
931 spin_lock_irq(shost->host_lock);
932 vport->fc_flag &= ~FC_VFI_REGISTERED;
933 spin_unlock_irq(shost->host_lock);
934 phba->fc_topology_changed = 0;
935 lpfc_issue_reg_vfi(vport);
936 }
937
938
939 lpfc_disc_start(vport);
940 return 0;
941fail:
942 return -ENXIO;
943}
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968static void
969lpfc_cmpl_els_flogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
970 struct lpfc_iocbq *rspiocb)
971{
972 struct lpfc_vport *vport = cmdiocb->vport;
973 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
974 IOCB_t *irsp = &rspiocb->iocb;
975 struct lpfc_nodelist *ndlp = cmdiocb->context1;
976 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
977 struct serv_parm *sp;
978 uint16_t fcf_index;
979 int rc;
980
981
982 if (lpfc_els_chk_latt(vport)) {
983
984
985
986 lpfc_nlp_put(ndlp);
987 goto out;
988 }
989
990 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
991 "FLOGI cmpl: status:x%x/x%x state:x%x",
992 irsp->ulpStatus, irsp->un.ulpWord[4],
993 vport->port_state);
994
995 if (irsp->ulpStatus) {
996
997
998
999
1000 if ((phba->hba_flag & HBA_FIP_SUPPORT) &&
1001 (phba->fcf.fcf_flag & FCF_DISCOVERY)) {
1002 if (phba->link_state < LPFC_LINK_UP)
1003 goto stop_rr_fcf_flogi;
1004 if ((phba->fcoe_cvl_eventtag_attn ==
1005 phba->fcoe_cvl_eventtag) &&
1006 (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) &&
1007 ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) ==
1008 IOERR_SLI_ABORTED))
1009 goto stop_rr_fcf_flogi;
1010 else
1011 phba->fcoe_cvl_eventtag_attn =
1012 phba->fcoe_cvl_eventtag;
1013 lpfc_printf_log(phba, KERN_WARNING, LOG_FIP | LOG_ELS,
1014 "2611 FLOGI failed on FCF (x%x), "
1015 "status:x%x/x%x, tmo:x%x, perform "
1016 "roundrobin FCF failover\n",
1017 phba->fcf.current_rec.fcf_indx,
1018 irsp->ulpStatus, irsp->un.ulpWord[4],
1019 irsp->ulpTimeout);
1020 lpfc_sli4_set_fcf_flogi_fail(phba,
1021 phba->fcf.current_rec.fcf_indx);
1022 fcf_index = lpfc_sli4_fcf_rr_next_index_get(phba);
1023 rc = lpfc_sli4_fcf_rr_next_proc(vport, fcf_index);
1024 if (rc)
1025 goto out;
1026 }
1027
1028stop_rr_fcf_flogi:
1029
1030 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1031 "2858 FLOGI failure Status:x%x/x%x TMO:x%x\n",
1032 irsp->ulpStatus, irsp->un.ulpWord[4],
1033 irsp->ulpTimeout);
1034
1035
1036 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
1037 goto out;
1038
1039
1040 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1041 "0100 FLOGI failure Status:x%x/x%x TMO:x%x\n",
1042 irsp->ulpStatus, irsp->un.ulpWord[4],
1043 irsp->ulpTimeout);
1044
1045
1046 spin_lock_irq(shost->host_lock);
1047 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
1048 spin_unlock_irq(shost->host_lock);
1049
1050
1051
1052
1053
1054 if (phba->alpa_map[0] == 0)
1055 vport->cfg_discovery_threads = LPFC_MAX_DISC_THREADS;
1056 if ((phba->sli_rev == LPFC_SLI_REV4) &&
1057 (!(vport->fc_flag & FC_VFI_REGISTERED) ||
1058 (vport->fc_prevDID != vport->fc_myDID) ||
1059 phba->fc_topology_changed)) {
1060 if (vport->fc_flag & FC_VFI_REGISTERED) {
1061 if (phba->fc_topology_changed) {
1062 lpfc_unregister_fcf_prep(phba);
1063 spin_lock_irq(shost->host_lock);
1064 vport->fc_flag &= ~FC_VFI_REGISTERED;
1065 spin_unlock_irq(shost->host_lock);
1066 phba->fc_topology_changed = 0;
1067 } else {
1068 lpfc_sli4_unreg_all_rpis(vport);
1069 }
1070 }
1071 lpfc_issue_reg_vfi(vport);
1072 lpfc_nlp_put(ndlp);
1073 goto out;
1074 }
1075 goto flogifail;
1076 }
1077 spin_lock_irq(shost->host_lock);
1078 vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
1079 vport->fc_flag &= ~FC_VPORT_LOGO_RCVD;
1080 spin_unlock_irq(shost->host_lock);
1081
1082
1083
1084
1085
1086 prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
1087 if (!prsp)
1088 goto out;
1089 sp = prsp->virt + sizeof(uint32_t);
1090
1091
1092 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1093 "0101 FLOGI completes successfully, I/O tag:x%x, "
1094 "Data: x%x x%x x%x x%x x%x x%x\n", cmdiocb->iotag,
1095 irsp->un.ulpWord[4], sp->cmn.e_d_tov,
1096 sp->cmn.w2.r_a_tov, sp->cmn.edtovResolution,
1097 vport->port_state, vport->fc_flag);
1098
1099 if (vport->port_state == LPFC_FLOGI) {
1100
1101
1102
1103
1104 if (sp->cmn.fPort)
1105 rc = lpfc_cmpl_els_flogi_fabric(vport, ndlp, sp, irsp);
1106 else if (!(phba->hba_flag & HBA_FCOE_MODE))
1107 rc = lpfc_cmpl_els_flogi_nport(vport, ndlp, sp);
1108 else {
1109 lpfc_printf_vlog(vport, KERN_ERR,
1110 LOG_FIP | LOG_ELS,
1111 "2831 FLOGI response with cleared Fabric "
1112 "bit fcf_index 0x%x "
1113 "Switch Name %02x%02x%02x%02x%02x%02x%02x%02x "
1114 "Fabric Name "
1115 "%02x%02x%02x%02x%02x%02x%02x%02x\n",
1116 phba->fcf.current_rec.fcf_indx,
1117 phba->fcf.current_rec.switch_name[0],
1118 phba->fcf.current_rec.switch_name[1],
1119 phba->fcf.current_rec.switch_name[2],
1120 phba->fcf.current_rec.switch_name[3],
1121 phba->fcf.current_rec.switch_name[4],
1122 phba->fcf.current_rec.switch_name[5],
1123 phba->fcf.current_rec.switch_name[6],
1124 phba->fcf.current_rec.switch_name[7],
1125 phba->fcf.current_rec.fabric_name[0],
1126 phba->fcf.current_rec.fabric_name[1],
1127 phba->fcf.current_rec.fabric_name[2],
1128 phba->fcf.current_rec.fabric_name[3],
1129 phba->fcf.current_rec.fabric_name[4],
1130 phba->fcf.current_rec.fabric_name[5],
1131 phba->fcf.current_rec.fabric_name[6],
1132 phba->fcf.current_rec.fabric_name[7]);
1133 lpfc_nlp_put(ndlp);
1134 spin_lock_irq(&phba->hbalock);
1135 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
1136 phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
1137 spin_unlock_irq(&phba->hbalock);
1138 goto out;
1139 }
1140 if (!rc) {
1141
1142 if (phba->hba_flag & HBA_FIP_SUPPORT)
1143 lpfc_printf_vlog(vport, KERN_INFO, LOG_FIP |
1144 LOG_ELS,
1145 "2769 FLOGI to FCF (x%x) "
1146 "completed successfully\n",
1147 phba->fcf.current_rec.fcf_indx);
1148 spin_lock_irq(&phba->hbalock);
1149 phba->fcf.fcf_flag &= ~FCF_DISCOVERY;
1150 phba->hba_flag &= ~(FCF_RR_INPROG | HBA_DEVLOSS_TMO);
1151 spin_unlock_irq(&phba->hbalock);
1152 goto out;
1153 }
1154 }
1155
1156flogifail:
1157 lpfc_nlp_put(ndlp);
1158
1159 if (!lpfc_error_lost_link(irsp)) {
1160
1161 lpfc_disc_list_loopmap(vport);
1162
1163
1164 lpfc_disc_start(vport);
1165 } else if (((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
1166 (((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
1167 IOERR_SLI_ABORTED) &&
1168 ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
1169 IOERR_SLI_DOWN))) &&
1170 (phba->link_state != LPFC_CLEAR_LA)) {
1171
1172 lpfc_issue_clear_la(phba, vport);
1173 }
1174out:
1175 lpfc_els_free_iocb(phba, cmdiocb);
1176}
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200static int
1201lpfc_issue_els_flogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
1202 uint8_t retry)
1203{
1204 struct lpfc_hba *phba = vport->phba;
1205 struct serv_parm *sp;
1206 IOCB_t *icmd;
1207 struct lpfc_iocbq *elsiocb;
1208 struct lpfc_sli_ring *pring;
1209 uint8_t *pcmd;
1210 uint16_t cmdsize;
1211 uint32_t tmo;
1212 int rc;
1213
1214 pring = &phba->sli.ring[LPFC_ELS_RING];
1215
1216 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
1217 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
1218 ndlp->nlp_DID, ELS_CMD_FLOGI);
1219
1220 if (!elsiocb)
1221 return 1;
1222
1223 icmd = &elsiocb->iocb;
1224 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1225
1226
1227 *((uint32_t *) (pcmd)) = ELS_CMD_FLOGI;
1228 pcmd += sizeof(uint32_t);
1229 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
1230 sp = (struct serv_parm *) pcmd;
1231
1232
1233 sp->cmn.e_d_tov = 0;
1234 sp->cmn.w2.r_a_tov = 0;
1235 sp->cmn.virtual_fabric_support = 0;
1236 sp->cls1.classValid = 0;
1237 if (sp->cmn.fcphLow < FC_PH3)
1238 sp->cmn.fcphLow = FC_PH3;
1239 if (sp->cmn.fcphHigh < FC_PH3)
1240 sp->cmn.fcphHigh = FC_PH3;
1241
1242 if (phba->sli_rev == LPFC_SLI_REV4) {
1243 if (bf_get(lpfc_sli_intf_if_type, &phba->sli4_hba.sli_intf) ==
1244 LPFC_SLI_INTF_IF_TYPE_0) {
1245 elsiocb->iocb.ulpCt_h = ((SLI4_CT_FCFI >> 1) & 1);
1246 elsiocb->iocb.ulpCt_l = (SLI4_CT_FCFI & 1);
1247
1248
1249 elsiocb->iocb.ulpContext = phba->fcf.fcfi;
1250 }
1251
1252 sp->cls2.classValid = 0;
1253 sp->cls2.seqDelivery = 0;
1254 } else {
1255
1256 sp->cls2.seqDelivery = (sp->cls2.classValid) ? 1 : 0;
1257 sp->cls3.seqDelivery = (sp->cls3.classValid) ? 1 : 0;
1258 if (phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) {
1259 sp->cmn.request_multiple_Nport = 1;
1260
1261 icmd->ulpCt_h = 1;
1262 icmd->ulpCt_l = 0;
1263 } else
1264 sp->cmn.request_multiple_Nport = 0;
1265 }
1266
1267 if (phba->fc_topology != LPFC_TOPOLOGY_LOOP) {
1268 icmd->un.elsreq64.myID = 0;
1269 icmd->un.elsreq64.fl = 1;
1270 }
1271
1272 tmo = phba->fc_ratov;
1273 phba->fc_ratov = LPFC_DISC_FLOGI_TMO;
1274 lpfc_set_disctmo(vport);
1275 phba->fc_ratov = tmo;
1276
1277 phba->fc_stat.elsXmitFLOGI++;
1278 elsiocb->iocb_cmpl = lpfc_cmpl_els_flogi;
1279
1280 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1281 "Issue FLOGI: opt:x%x",
1282 phba->sli3_options, 0, 0);
1283
1284 rc = lpfc_issue_fabric_iocb(phba, elsiocb);
1285 if (rc == IOCB_ERROR) {
1286 lpfc_els_free_iocb(phba, elsiocb);
1287 return 1;
1288 }
1289 return 0;
1290}
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306int
1307lpfc_els_abort_flogi(struct lpfc_hba *phba)
1308{
1309 struct lpfc_sli_ring *pring;
1310 struct lpfc_iocbq *iocb, *next_iocb;
1311 struct lpfc_nodelist *ndlp;
1312 IOCB_t *icmd;
1313
1314
1315 lpfc_printf_log(phba, KERN_INFO, LOG_DISCOVERY,
1316 "0201 Abort outstanding I/O on NPort x%x\n",
1317 Fabric_DID);
1318
1319 pring = &phba->sli.ring[LPFC_ELS_RING];
1320
1321
1322
1323
1324
1325 spin_lock_irq(&phba->hbalock);
1326 list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) {
1327 icmd = &iocb->iocb;
1328 if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR) {
1329 ndlp = (struct lpfc_nodelist *)(iocb->context1);
1330 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
1331 (ndlp->nlp_DID == Fabric_DID))
1332 lpfc_sli_issue_abort_iotag(phba, pring, iocb);
1333 }
1334 }
1335 spin_unlock_irq(&phba->hbalock);
1336
1337 return 0;
1338}
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356int
1357lpfc_initial_flogi(struct lpfc_vport *vport)
1358{
1359 struct lpfc_hba *phba = vport->phba;
1360 struct lpfc_nodelist *ndlp;
1361
1362 vport->port_state = LPFC_FLOGI;
1363 lpfc_set_disctmo(vport);
1364
1365
1366 ndlp = lpfc_findnode_did(vport, Fabric_DID);
1367 if (!ndlp) {
1368
1369 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
1370 if (!ndlp)
1371 return 0;
1372 lpfc_nlp_init(vport, ndlp, Fabric_DID);
1373
1374 ndlp->nlp_type |= NLP_FABRIC;
1375
1376 lpfc_enqueue_node(vport, ndlp);
1377 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
1378
1379 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
1380 if (!ndlp)
1381 return 0;
1382 }
1383
1384 if (lpfc_issue_els_flogi(vport, ndlp, 0)) {
1385
1386
1387
1388 lpfc_nlp_put(ndlp);
1389 return 0;
1390 }
1391 return 1;
1392}
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410int
1411lpfc_initial_fdisc(struct lpfc_vport *vport)
1412{
1413 struct lpfc_hba *phba = vport->phba;
1414 struct lpfc_nodelist *ndlp;
1415
1416
1417 ndlp = lpfc_findnode_did(vport, Fabric_DID);
1418 if (!ndlp) {
1419
1420 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
1421 if (!ndlp)
1422 return 0;
1423 lpfc_nlp_init(vport, ndlp, Fabric_DID);
1424
1425 lpfc_enqueue_node(vport, ndlp);
1426 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
1427
1428 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
1429 if (!ndlp)
1430 return 0;
1431 }
1432
1433 if (lpfc_issue_els_fdisc(vport, ndlp, 0)) {
1434
1435
1436
1437 lpfc_nlp_put(ndlp);
1438 return 0;
1439 }
1440 return 1;
1441}
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454void
1455lpfc_more_plogi(struct lpfc_vport *vport)
1456{
1457 int sentplogi;
1458
1459 if (vport->num_disc_nodes)
1460 vport->num_disc_nodes--;
1461
1462
1463 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
1464 "0232 Continue discovery with %d PLOGIs to go "
1465 "Data: x%x x%x x%x\n",
1466 vport->num_disc_nodes, vport->fc_plogi_cnt,
1467 vport->fc_flag, vport->port_state);
1468
1469 if (vport->fc_flag & FC_NLP_MORE)
1470
1471 sentplogi = lpfc_els_disc_plogi(vport);
1472
1473 return;
1474}
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507static struct lpfc_nodelist *
1508lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
1509 struct lpfc_nodelist *ndlp)
1510{
1511 struct lpfc_vport *vport = ndlp->vport;
1512 struct lpfc_nodelist *new_ndlp;
1513 struct lpfc_rport_data *rdata;
1514 struct fc_rport *rport;
1515 struct serv_parm *sp;
1516 uint8_t name[sizeof(struct lpfc_name)];
1517 uint32_t rc, keepDID = 0;
1518 int put_node;
1519 int put_rport;
1520 unsigned long *active_rrqs_xri_bitmap = NULL;
1521
1522
1523
1524
1525 if (ndlp->nlp_type & NLP_FABRIC)
1526 return ndlp;
1527
1528 sp = (struct serv_parm *) ((uint8_t *) prsp + sizeof(uint32_t));
1529 memset(name, 0, sizeof(struct lpfc_name));
1530
1531
1532
1533
1534 new_ndlp = lpfc_findnode_wwpn(vport, &sp->portName);
1535
1536 if (new_ndlp == ndlp && NLP_CHK_NODE_ACT(new_ndlp))
1537 return ndlp;
1538 if (phba->sli_rev == LPFC_SLI_REV4) {
1539 active_rrqs_xri_bitmap = mempool_alloc(phba->active_rrq_pool,
1540 GFP_KERNEL);
1541 if (active_rrqs_xri_bitmap)
1542 memset(active_rrqs_xri_bitmap, 0,
1543 phba->cfg_rrq_xri_bitmap_sz);
1544 }
1545
1546 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1547 "3178 PLOGI confirm: ndlp %p x%x: new_ndlp %p\n",
1548 ndlp, ndlp->nlp_DID, new_ndlp);
1549
1550 if (!new_ndlp) {
1551 rc = memcmp(&ndlp->nlp_portname, name,
1552 sizeof(struct lpfc_name));
1553 if (!rc) {
1554 if (active_rrqs_xri_bitmap)
1555 mempool_free(active_rrqs_xri_bitmap,
1556 phba->active_rrq_pool);
1557 return ndlp;
1558 }
1559 new_ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_ATOMIC);
1560 if (!new_ndlp) {
1561 if (active_rrqs_xri_bitmap)
1562 mempool_free(active_rrqs_xri_bitmap,
1563 phba->active_rrq_pool);
1564 return ndlp;
1565 }
1566 lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
1567 } else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
1568 rc = memcmp(&ndlp->nlp_portname, name,
1569 sizeof(struct lpfc_name));
1570 if (!rc) {
1571 if (active_rrqs_xri_bitmap)
1572 mempool_free(active_rrqs_xri_bitmap,
1573 phba->active_rrq_pool);
1574 return ndlp;
1575 }
1576 new_ndlp = lpfc_enable_node(vport, new_ndlp,
1577 NLP_STE_UNUSED_NODE);
1578 if (!new_ndlp) {
1579 if (active_rrqs_xri_bitmap)
1580 mempool_free(active_rrqs_xri_bitmap,
1581 phba->active_rrq_pool);
1582 return ndlp;
1583 }
1584 keepDID = new_ndlp->nlp_DID;
1585 if ((phba->sli_rev == LPFC_SLI_REV4) && active_rrqs_xri_bitmap)
1586 memcpy(active_rrqs_xri_bitmap,
1587 new_ndlp->active_rrqs_xri_bitmap,
1588 phba->cfg_rrq_xri_bitmap_sz);
1589 } else {
1590 keepDID = new_ndlp->nlp_DID;
1591 if (phba->sli_rev == LPFC_SLI_REV4 &&
1592 active_rrqs_xri_bitmap)
1593 memcpy(active_rrqs_xri_bitmap,
1594 new_ndlp->active_rrqs_xri_bitmap,
1595 phba->cfg_rrq_xri_bitmap_sz);
1596 }
1597
1598 lpfc_unreg_rpi(vport, new_ndlp);
1599 new_ndlp->nlp_DID = ndlp->nlp_DID;
1600 new_ndlp->nlp_prev_state = ndlp->nlp_prev_state;
1601 if (phba->sli_rev == LPFC_SLI_REV4)
1602 memcpy(new_ndlp->active_rrqs_xri_bitmap,
1603 ndlp->active_rrqs_xri_bitmap,
1604 phba->cfg_rrq_xri_bitmap_sz);
1605
1606 if (ndlp->nlp_flag & NLP_NPR_2B_DISC)
1607 new_ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1608 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1609
1610
1611 lpfc_nlp_set_state(vport, new_ndlp, ndlp->nlp_state);
1612
1613
1614 if (memcmp(&ndlp->nlp_portname, name, sizeof(struct lpfc_name)) == 0) {
1615
1616
1617
1618 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1619 "3179 PLOGI confirm NEW: %x %x\n",
1620 new_ndlp->nlp_DID, keepDID);
1621
1622
1623 rport = ndlp->rport;
1624 if (rport) {
1625 rdata = rport->dd_data;
1626 if (rdata->pnode == ndlp) {
1627 lpfc_nlp_put(ndlp);
1628 ndlp->rport = NULL;
1629 rdata->pnode = lpfc_nlp_get(new_ndlp);
1630 new_ndlp->rport = rport;
1631 }
1632 new_ndlp->nlp_type = ndlp->nlp_type;
1633 }
1634
1635
1636
1637
1638 if (ndlp->nlp_DID == 0) {
1639 spin_lock_irq(&phba->ndlp_lock);
1640 NLP_SET_FREE_REQ(ndlp);
1641 spin_unlock_irq(&phba->ndlp_lock);
1642 }
1643
1644
1645 ndlp->nlp_DID = keepDID;
1646 if (phba->sli_rev == LPFC_SLI_REV4 &&
1647 active_rrqs_xri_bitmap)
1648 memcpy(ndlp->active_rrqs_xri_bitmap,
1649 active_rrqs_xri_bitmap,
1650 phba->cfg_rrq_xri_bitmap_sz);
1651 lpfc_drop_node(vport, ndlp);
1652 }
1653 else {
1654 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1655 "3180 PLOGI confirm SWAP: %x %x\n",
1656 new_ndlp->nlp_DID, keepDID);
1657
1658 lpfc_unreg_rpi(vport, ndlp);
1659
1660
1661 ndlp->nlp_DID = keepDID;
1662 if (phba->sli_rev == LPFC_SLI_REV4 &&
1663 active_rrqs_xri_bitmap)
1664 memcpy(ndlp->active_rrqs_xri_bitmap,
1665 active_rrqs_xri_bitmap,
1666 phba->cfg_rrq_xri_bitmap_sz);
1667
1668
1669
1670
1671
1672
1673 new_ndlp->nlp_state = ndlp->nlp_state;
1674
1675
1676
1677
1678
1679 if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
1680 (ndlp->nlp_state == NLP_STE_MAPPED_NODE))
1681 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
1682
1683
1684 rport = ndlp->rport;
1685 if (rport) {
1686 rdata = rport->dd_data;
1687 put_node = rdata->pnode != NULL;
1688 put_rport = ndlp->rport != NULL;
1689 rdata->pnode = NULL;
1690 ndlp->rport = NULL;
1691 if (put_node)
1692 lpfc_nlp_put(ndlp);
1693 if (put_rport)
1694 put_device(&rport->dev);
1695 }
1696 }
1697 if (phba->sli_rev == LPFC_SLI_REV4 &&
1698 active_rrqs_xri_bitmap)
1699 mempool_free(active_rrqs_xri_bitmap,
1700 phba->active_rrq_pool);
1701 return new_ndlp;
1702}
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715void
1716lpfc_end_rscn(struct lpfc_vport *vport)
1717{
1718 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1719
1720 if (vport->fc_flag & FC_RSCN_MODE) {
1721
1722
1723
1724
1725 if (vport->fc_rscn_id_cnt ||
1726 (vport->fc_flag & FC_RSCN_DISCOVERY) != 0)
1727 lpfc_els_handle_rscn(vport);
1728 else {
1729 spin_lock_irq(shost->host_lock);
1730 vport->fc_flag &= ~FC_RSCN_MODE;
1731 spin_unlock_irq(shost->host_lock);
1732 }
1733 }
1734}
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748static void
1749lpfc_cmpl_els_rrq(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1750 struct lpfc_iocbq *rspiocb)
1751{
1752 struct lpfc_vport *vport = cmdiocb->vport;
1753 IOCB_t *irsp;
1754 struct lpfc_nodelist *ndlp;
1755 struct lpfc_node_rrq *rrq;
1756
1757
1758 rrq = cmdiocb->context_un.rrq;
1759 cmdiocb->context_un.rsp_iocb = rspiocb;
1760
1761 irsp = &rspiocb->iocb;
1762 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1763 "RRQ cmpl: status:x%x/x%x did:x%x",
1764 irsp->ulpStatus, irsp->un.ulpWord[4],
1765 irsp->un.elsreq64.remoteID);
1766
1767 ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
1768 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || ndlp != rrq->ndlp) {
1769 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1770 "2882 RRQ completes to NPort x%x "
1771 "with no ndlp. Data: x%x x%x x%x\n",
1772 irsp->un.elsreq64.remoteID,
1773 irsp->ulpStatus, irsp->un.ulpWord[4],
1774 irsp->ulpIoTag);
1775 goto out;
1776 }
1777
1778
1779 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1780 "2880 RRQ completes to NPort x%x "
1781 "Data: x%x x%x x%x x%x x%x\n",
1782 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
1783 irsp->ulpTimeout, rrq->xritag, rrq->rxid);
1784
1785 if (irsp->ulpStatus) {
1786
1787
1788 if (irsp->ulpStatus != IOSTAT_LS_RJT ||
1789 (((irsp->un.ulpWord[4]) >> 16 != LSRJT_INVALID_CMD) &&
1790 ((irsp->un.ulpWord[4]) >> 16 != LSRJT_UNABLE_TPC)) ||
1791 (phba)->pport->cfg_log_verbose & LOG_ELS)
1792 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1793 "2881 RRQ failure DID:%06X Status:x%x/x%x\n",
1794 ndlp->nlp_DID, irsp->ulpStatus,
1795 irsp->un.ulpWord[4]);
1796 }
1797out:
1798 if (rrq)
1799 lpfc_clr_rrq_active(phba, rrq->xritag, rrq);
1800 lpfc_els_free_iocb(phba, cmdiocb);
1801 return;
1802}
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823static void
1824lpfc_cmpl_els_plogi(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
1825 struct lpfc_iocbq *rspiocb)
1826{
1827 struct lpfc_vport *vport = cmdiocb->vport;
1828 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
1829 IOCB_t *irsp;
1830 struct lpfc_nodelist *ndlp;
1831 struct lpfc_dmabuf *prsp;
1832 int disc, rc;
1833
1834
1835 cmdiocb->context_un.rsp_iocb = rspiocb;
1836
1837 irsp = &rspiocb->iocb;
1838 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
1839 "PLOGI cmpl: status:x%x/x%x did:x%x",
1840 irsp->ulpStatus, irsp->un.ulpWord[4],
1841 irsp->un.elsreq64.remoteID);
1842
1843 ndlp = lpfc_findnode_did(vport, irsp->un.elsreq64.remoteID);
1844 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
1845 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1846 "0136 PLOGI completes to NPort x%x "
1847 "with no ndlp. Data: x%x x%x x%x\n",
1848 irsp->un.elsreq64.remoteID,
1849 irsp->ulpStatus, irsp->un.ulpWord[4],
1850 irsp->ulpIoTag);
1851 goto out;
1852 }
1853
1854
1855
1856
1857 spin_lock_irq(shost->host_lock);
1858 disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
1859 ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
1860 spin_unlock_irq(shost->host_lock);
1861 rc = 0;
1862
1863
1864 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
1865 "0102 PLOGI completes to NPort x%x "
1866 "Data: x%x x%x x%x x%x x%x\n",
1867 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
1868 irsp->ulpTimeout, disc, vport->num_disc_nodes);
1869
1870 if (lpfc_els_chk_latt(vport)) {
1871 spin_lock_irq(shost->host_lock);
1872 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1873 spin_unlock_irq(shost->host_lock);
1874 goto out;
1875 }
1876
1877 if (irsp->ulpStatus) {
1878
1879 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
1880
1881 if (disc) {
1882 spin_lock_irq(shost->host_lock);
1883 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
1884 spin_unlock_irq(shost->host_lock);
1885 }
1886 goto out;
1887 }
1888
1889 if (irsp->ulpStatus != IOSTAT_LS_RJT ||
1890 (((irsp->un.ulpWord[4]) >> 16 != LSRJT_INVALID_CMD) &&
1891 ((irsp->un.ulpWord[4]) >> 16 != LSRJT_UNABLE_TPC)) ||
1892 (phba)->pport->cfg_log_verbose & LOG_ELS)
1893 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
1894 "2753 PLOGI failure DID:%06X Status:x%x/x%x\n",
1895 ndlp->nlp_DID, irsp->ulpStatus,
1896 irsp->un.ulpWord[4]);
1897
1898 if (lpfc_error_lost_link(irsp))
1899 rc = NLP_STE_FREED_NODE;
1900 else
1901 rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1902 NLP_EVT_CMPL_PLOGI);
1903 } else {
1904
1905 prsp = list_entry(((struct lpfc_dmabuf *)
1906 cmdiocb->context2)->list.next,
1907 struct lpfc_dmabuf, list);
1908 ndlp = lpfc_plogi_confirm_nport(phba, prsp->virt, ndlp);
1909 rc = lpfc_disc_state_machine(vport, ndlp, cmdiocb,
1910 NLP_EVT_CMPL_PLOGI);
1911 }
1912
1913 if (disc && vport->num_disc_nodes) {
1914
1915 lpfc_more_plogi(vport);
1916
1917 if (vport->num_disc_nodes == 0) {
1918 spin_lock_irq(shost->host_lock);
1919 vport->fc_flag &= ~FC_NDISC_ACTIVE;
1920 spin_unlock_irq(shost->host_lock);
1921
1922 lpfc_can_disctmo(vport);
1923 lpfc_end_rscn(vport);
1924 }
1925 }
1926
1927out:
1928 lpfc_els_free_iocb(phba, cmdiocb);
1929 return;
1930}
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953int
1954lpfc_issue_els_plogi(struct lpfc_vport *vport, uint32_t did, uint8_t retry)
1955{
1956 struct lpfc_hba *phba = vport->phba;
1957 struct serv_parm *sp;
1958 IOCB_t *icmd;
1959 struct lpfc_nodelist *ndlp;
1960 struct lpfc_iocbq *elsiocb;
1961 struct lpfc_sli *psli;
1962 uint8_t *pcmd;
1963 uint16_t cmdsize;
1964 int ret;
1965
1966 psli = &phba->sli;
1967
1968 ndlp = lpfc_findnode_did(vport, did);
1969 if (ndlp && !NLP_CHK_NODE_ACT(ndlp))
1970 ndlp = NULL;
1971
1972
1973 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
1974 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
1975 ELS_CMD_PLOGI);
1976 if (!elsiocb)
1977 return 1;
1978
1979 icmd = &elsiocb->iocb;
1980 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
1981
1982
1983 *((uint32_t *) (pcmd)) = ELS_CMD_PLOGI;
1984 pcmd += sizeof(uint32_t);
1985 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
1986 sp = (struct serv_parm *) pcmd;
1987
1988
1989
1990
1991
1992 if ((vport->fc_flag & FC_FABRIC) && !(vport->fc_flag & FC_PUBLIC_LOOP))
1993 sp->cmn.altBbCredit = 1;
1994
1995 if (sp->cmn.fcphLow < FC_PH_4_3)
1996 sp->cmn.fcphLow = FC_PH_4_3;
1997
1998 if (sp->cmn.fcphHigh < FC_PH3)
1999 sp->cmn.fcphHigh = FC_PH3;
2000
2001 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2002 "Issue PLOGI: did:x%x",
2003 did, 0, 0);
2004
2005 phba->fc_stat.elsXmitPLOGI++;
2006 elsiocb->iocb_cmpl = lpfc_cmpl_els_plogi;
2007 ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
2008
2009 if (ret == IOCB_ERROR) {
2010 lpfc_els_free_iocb(phba, elsiocb);
2011 return 1;
2012 }
2013 return 0;
2014}
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029static void
2030lpfc_cmpl_els_prli(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2031 struct lpfc_iocbq *rspiocb)
2032{
2033 struct lpfc_vport *vport = cmdiocb->vport;
2034 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2035 IOCB_t *irsp;
2036 struct lpfc_sli *psli;
2037 struct lpfc_nodelist *ndlp;
2038
2039 psli = &phba->sli;
2040
2041 cmdiocb->context_un.rsp_iocb = rspiocb;
2042
2043 irsp = &(rspiocb->iocb);
2044 ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2045 spin_lock_irq(shost->host_lock);
2046 ndlp->nlp_flag &= ~NLP_PRLI_SND;
2047 spin_unlock_irq(shost->host_lock);
2048
2049 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2050 "PRLI cmpl: status:x%x/x%x did:x%x",
2051 irsp->ulpStatus, irsp->un.ulpWord[4],
2052 ndlp->nlp_DID);
2053
2054 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2055 "0103 PRLI completes to NPort x%x "
2056 "Data: x%x x%x x%x x%x\n",
2057 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
2058 irsp->ulpTimeout, vport->num_disc_nodes);
2059
2060 vport->fc_prli_sent--;
2061
2062 if (lpfc_els_chk_latt(vport))
2063 goto out;
2064
2065 if (irsp->ulpStatus) {
2066
2067 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
2068
2069 goto out;
2070 }
2071
2072 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
2073 "2754 PRLI failure DID:%06X Status:x%x/x%x\n",
2074 ndlp->nlp_DID, irsp->ulpStatus,
2075 irsp->un.ulpWord[4]);
2076
2077 if (lpfc_error_lost_link(irsp))
2078 goto out;
2079 else
2080 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
2081 NLP_EVT_CMPL_PRLI);
2082 } else
2083
2084 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
2085 NLP_EVT_CMPL_PRLI);
2086out:
2087 lpfc_els_free_iocb(phba, cmdiocb);
2088 return;
2089}
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112int
2113lpfc_issue_els_prli(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2114 uint8_t retry)
2115{
2116 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2117 struct lpfc_hba *phba = vport->phba;
2118 PRLI *npr;
2119 IOCB_t *icmd;
2120 struct lpfc_iocbq *elsiocb;
2121 uint8_t *pcmd;
2122 uint16_t cmdsize;
2123
2124 cmdsize = (sizeof(uint32_t) + sizeof(PRLI));
2125 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
2126 ndlp->nlp_DID, ELS_CMD_PRLI);
2127 if (!elsiocb)
2128 return 1;
2129
2130 icmd = &elsiocb->iocb;
2131 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2132
2133
2134 memset(pcmd, 0, (sizeof(PRLI) + sizeof(uint32_t)));
2135 *((uint32_t *) (pcmd)) = ELS_CMD_PRLI;
2136 pcmd += sizeof(uint32_t);
2137
2138
2139 npr = (PRLI *) pcmd;
2140
2141
2142
2143
2144 if (phba->vpd.rev.feaLevelHigh >= 0x02) {
2145 npr->ConfmComplAllowed = 1;
2146 npr->Retry = 1;
2147 npr->TaskRetryIdReq = 1;
2148 }
2149 npr->estabImagePair = 1;
2150 npr->readXferRdyDis = 1;
2151 if (vport->cfg_first_burst_size)
2152 npr->writeXferRdyDis = 1;
2153
2154
2155 npr->prliType = PRLI_FCP_TYPE;
2156 npr->initiatorFunc = 1;
2157
2158 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2159 "Issue PRLI: did:x%x",
2160 ndlp->nlp_DID, 0, 0);
2161
2162 phba->fc_stat.elsXmitPRLI++;
2163 elsiocb->iocb_cmpl = lpfc_cmpl_els_prli;
2164 spin_lock_irq(shost->host_lock);
2165 ndlp->nlp_flag |= NLP_PRLI_SND;
2166 spin_unlock_irq(shost->host_lock);
2167 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
2168 IOCB_ERROR) {
2169 spin_lock_irq(shost->host_lock);
2170 ndlp->nlp_flag &= ~NLP_PRLI_SND;
2171 spin_unlock_irq(shost->host_lock);
2172 lpfc_els_free_iocb(phba, elsiocb);
2173 return 1;
2174 }
2175 vport->fc_prli_sent++;
2176 return 0;
2177}
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191static void
2192lpfc_rscn_disc(struct lpfc_vport *vport)
2193{
2194 lpfc_can_disctmo(vport);
2195
2196
2197
2198 if (vport->fc_npr_cnt)
2199 if (lpfc_els_disc_plogi(vport))
2200 return;
2201
2202 lpfc_end_rscn(vport);
2203}
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215static void
2216lpfc_adisc_done(struct lpfc_vport *vport)
2217{
2218 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2219 struct lpfc_hba *phba = vport->phba;
2220
2221
2222
2223
2224
2225 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
2226 !(vport->fc_flag & FC_RSCN_MODE) &&
2227 (phba->sli_rev < LPFC_SLI_REV4)) {
2228
2229
2230
2231
2232
2233
2234
2235
2236 lpfc_issue_clear_la(phba, vport);
2237 lpfc_issue_reg_vpi(phba, vport);
2238 return;
2239 }
2240
2241
2242
2243
2244 if (vport->port_state < LPFC_VPORT_READY) {
2245
2246 if (vport->port_type == LPFC_PHYSICAL_PORT)
2247 lpfc_issue_clear_la(phba, vport);
2248 if (!(vport->fc_flag & FC_ABORT_DISCOVERY)) {
2249 vport->num_disc_nodes = 0;
2250
2251 if (vport->fc_npr_cnt)
2252 lpfc_els_disc_plogi(vport);
2253 if (!vport->num_disc_nodes) {
2254 spin_lock_irq(shost->host_lock);
2255 vport->fc_flag &= ~FC_NDISC_ACTIVE;
2256 spin_unlock_irq(shost->host_lock);
2257 lpfc_can_disctmo(vport);
2258 lpfc_end_rscn(vport);
2259 }
2260 }
2261 vport->port_state = LPFC_VPORT_READY;
2262 } else
2263 lpfc_rscn_disc(vport);
2264}
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275void
2276lpfc_more_adisc(struct lpfc_vport *vport)
2277{
2278 if (vport->num_disc_nodes)
2279 vport->num_disc_nodes--;
2280
2281 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
2282 "0210 Continue discovery with %d ADISCs to go "
2283 "Data: x%x x%x x%x\n",
2284 vport->num_disc_nodes, vport->fc_adisc_cnt,
2285 vport->fc_flag, vport->port_state);
2286
2287 if (vport->fc_flag & FC_NLP_MORE) {
2288 lpfc_set_disctmo(vport);
2289
2290 lpfc_els_disc_adisc(vport);
2291 }
2292 if (!vport->num_disc_nodes)
2293 lpfc_adisc_done(vport);
2294 return;
2295}
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313static void
2314lpfc_cmpl_els_adisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2315 struct lpfc_iocbq *rspiocb)
2316{
2317 struct lpfc_vport *vport = cmdiocb->vport;
2318 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2319 IOCB_t *irsp;
2320 struct lpfc_nodelist *ndlp;
2321 int disc;
2322
2323
2324 cmdiocb->context_un.rsp_iocb = rspiocb;
2325
2326 irsp = &(rspiocb->iocb);
2327 ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2328
2329 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2330 "ADISC cmpl: status:x%x/x%x did:x%x",
2331 irsp->ulpStatus, irsp->un.ulpWord[4],
2332 ndlp->nlp_DID);
2333
2334
2335
2336
2337 spin_lock_irq(shost->host_lock);
2338 disc = (ndlp->nlp_flag & NLP_NPR_2B_DISC);
2339 ndlp->nlp_flag &= ~(NLP_ADISC_SND | NLP_NPR_2B_DISC);
2340 spin_unlock_irq(shost->host_lock);
2341
2342 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2343 "0104 ADISC completes to NPort x%x "
2344 "Data: x%x x%x x%x x%x x%x\n",
2345 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
2346 irsp->ulpTimeout, disc, vport->num_disc_nodes);
2347
2348 if (lpfc_els_chk_latt(vport)) {
2349 spin_lock_irq(shost->host_lock);
2350 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2351 spin_unlock_irq(shost->host_lock);
2352 goto out;
2353 }
2354
2355 if (irsp->ulpStatus) {
2356
2357 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
2358
2359 if (disc) {
2360 spin_lock_irq(shost->host_lock);
2361 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2362 spin_unlock_irq(shost->host_lock);
2363 lpfc_set_disctmo(vport);
2364 }
2365 goto out;
2366 }
2367
2368 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
2369 "2755 ADISC failure DID:%06X Status:x%x/x%x\n",
2370 ndlp->nlp_DID, irsp->ulpStatus,
2371 irsp->un.ulpWord[4]);
2372
2373 if (!lpfc_error_lost_link(irsp))
2374 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
2375 NLP_EVT_CMPL_ADISC);
2376 } else
2377
2378 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
2379 NLP_EVT_CMPL_ADISC);
2380
2381
2382 if (disc && vport->num_disc_nodes)
2383 lpfc_more_adisc(vport);
2384out:
2385 lpfc_els_free_iocb(phba, cmdiocb);
2386 return;
2387}
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409int
2410lpfc_issue_els_adisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2411 uint8_t retry)
2412{
2413 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2414 struct lpfc_hba *phba = vport->phba;
2415 ADISC *ap;
2416 IOCB_t *icmd;
2417 struct lpfc_iocbq *elsiocb;
2418 uint8_t *pcmd;
2419 uint16_t cmdsize;
2420
2421 cmdsize = (sizeof(uint32_t) + sizeof(ADISC));
2422 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
2423 ndlp->nlp_DID, ELS_CMD_ADISC);
2424 if (!elsiocb)
2425 return 1;
2426
2427 icmd = &elsiocb->iocb;
2428 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2429
2430
2431 *((uint32_t *) (pcmd)) = ELS_CMD_ADISC;
2432 pcmd += sizeof(uint32_t);
2433
2434
2435 ap = (ADISC *) pcmd;
2436 ap->hardAL_PA = phba->fc_pref_ALPA;
2437 memcpy(&ap->portName, &vport->fc_portname, sizeof(struct lpfc_name));
2438 memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
2439 ap->DID = be32_to_cpu(vport->fc_myDID);
2440
2441 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2442 "Issue ADISC: did:x%x",
2443 ndlp->nlp_DID, 0, 0);
2444
2445 phba->fc_stat.elsXmitADISC++;
2446 elsiocb->iocb_cmpl = lpfc_cmpl_els_adisc;
2447 spin_lock_irq(shost->host_lock);
2448 ndlp->nlp_flag |= NLP_ADISC_SND;
2449 spin_unlock_irq(shost->host_lock);
2450 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
2451 IOCB_ERROR) {
2452 spin_lock_irq(shost->host_lock);
2453 ndlp->nlp_flag &= ~NLP_ADISC_SND;
2454 spin_unlock_irq(shost->host_lock);
2455 lpfc_els_free_iocb(phba, elsiocb);
2456 return 1;
2457 }
2458 return 0;
2459}
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473static void
2474lpfc_cmpl_els_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2475 struct lpfc_iocbq *rspiocb)
2476{
2477 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
2478 struct lpfc_vport *vport = ndlp->vport;
2479 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2480 IOCB_t *irsp;
2481 struct lpfc_sli *psli;
2482 struct lpfcMboxq *mbox;
2483 unsigned long flags;
2484 uint32_t skip_recovery = 0;
2485
2486 psli = &phba->sli;
2487
2488 cmdiocb->context_un.rsp_iocb = rspiocb;
2489
2490 irsp = &(rspiocb->iocb);
2491 spin_lock_irq(shost->host_lock);
2492 ndlp->nlp_flag &= ~NLP_LOGO_SND;
2493 spin_unlock_irq(shost->host_lock);
2494
2495 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2496 "LOGO cmpl: status:x%x/x%x did:x%x",
2497 irsp->ulpStatus, irsp->un.ulpWord[4],
2498 ndlp->nlp_DID);
2499
2500
2501 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2502 "0105 LOGO completes to NPort x%x "
2503 "Data: x%x x%x x%x x%x\n",
2504 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
2505 irsp->ulpTimeout, vport->num_disc_nodes);
2506
2507 if (lpfc_els_chk_latt(vport)) {
2508 skip_recovery = 1;
2509 goto out;
2510 }
2511
2512
2513 if (ndlp->nlp_flag & NLP_TARGET_REMOVE) {
2514
2515
2516
2517 lpfc_disc_state_machine(vport, ndlp, cmdiocb,
2518 NLP_EVT_DEVICE_RM);
2519 skip_recovery = 1;
2520 goto out;
2521 }
2522
2523 if (irsp->ulpStatus) {
2524
2525 if (lpfc_els_retry(phba, cmdiocb, rspiocb)) {
2526
2527 skip_recovery = 1;
2528 goto out;
2529 }
2530
2531 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
2532 "2756 LOGO failure DID:%06X Status:x%x/x%x\n",
2533 ndlp->nlp_DID, irsp->ulpStatus,
2534 irsp->un.ulpWord[4]);
2535
2536 if (lpfc_error_lost_link(irsp)) {
2537 skip_recovery = 1;
2538 goto out;
2539 }
2540 }
2541
2542
2543 lpfc_disc_state_machine(vport, ndlp, cmdiocb, NLP_EVT_CMPL_LOGO);
2544
2545out:
2546 lpfc_els_free_iocb(phba, cmdiocb);
2547
2548 if ((vport->fc_flag & FC_PT2PT) &&
2549 !(vport->fc_flag & FC_PT2PT_PLOGI)) {
2550 phba->pport->fc_myDID = 0;
2551 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
2552 if (mbox) {
2553 lpfc_config_link(phba, mbox);
2554 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
2555 mbox->vport = vport;
2556 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) ==
2557 MBX_NOT_FINISHED) {
2558 mempool_free(mbox, phba->mbox_mem_pool);
2559 skip_recovery = 1;
2560 }
2561 }
2562 }
2563
2564
2565
2566
2567
2568
2569 if ((ndlp->nlp_type & NLP_FCP_TARGET) && (skip_recovery == 0)) {
2570 lpfc_cancel_retry_delay_tmo(vport, ndlp);
2571 spin_lock_irqsave(shost->host_lock, flags);
2572 ndlp->nlp_flag |= NLP_NPR_2B_DISC;
2573 spin_unlock_irqrestore(shost->host_lock, flags);
2574
2575 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2576 "3187 LOGO completes to NPort x%x: Start "
2577 "Recovery Data: x%x x%x x%x x%x\n",
2578 ndlp->nlp_DID, irsp->ulpStatus,
2579 irsp->un.ulpWord[4], irsp->ulpTimeout,
2580 vport->num_disc_nodes);
2581 lpfc_disc_start(vport);
2582 }
2583 return;
2584}
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606int
2607lpfc_issue_els_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
2608 uint8_t retry)
2609{
2610 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2611 struct lpfc_hba *phba = vport->phba;
2612 IOCB_t *icmd;
2613 struct lpfc_iocbq *elsiocb;
2614 uint8_t *pcmd;
2615 uint16_t cmdsize;
2616 int rc;
2617
2618 spin_lock_irq(shost->host_lock);
2619 if (ndlp->nlp_flag & NLP_LOGO_SND) {
2620 spin_unlock_irq(shost->host_lock);
2621 return 0;
2622 }
2623 spin_unlock_irq(shost->host_lock);
2624
2625 cmdsize = (2 * sizeof(uint32_t)) + sizeof(struct lpfc_name);
2626 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
2627 ndlp->nlp_DID, ELS_CMD_LOGO);
2628 if (!elsiocb)
2629 return 1;
2630
2631 icmd = &elsiocb->iocb;
2632 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2633 *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
2634 pcmd += sizeof(uint32_t);
2635
2636
2637 *((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID);
2638 pcmd += sizeof(uint32_t);
2639 memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name));
2640
2641 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2642 "Issue LOGO: did:x%x",
2643 ndlp->nlp_DID, 0, 0);
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653 spin_lock_irq(shost->host_lock);
2654 ndlp->nlp_flag |= NLP_ISSUE_LOGO;
2655 spin_unlock_irq(shost->host_lock);
2656 if (lpfc_unreg_rpi(vport, ndlp)) {
2657 lpfc_els_free_iocb(phba, elsiocb);
2658 return 0;
2659 }
2660
2661 phba->fc_stat.elsXmitLOGO++;
2662 elsiocb->iocb_cmpl = lpfc_cmpl_els_logo;
2663 spin_lock_irq(shost->host_lock);
2664 ndlp->nlp_flag |= NLP_LOGO_SND;
2665 ndlp->nlp_flag &= ~NLP_ISSUE_LOGO;
2666 spin_unlock_irq(shost->host_lock);
2667 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
2668
2669 if (rc == IOCB_ERROR) {
2670 spin_lock_irq(shost->host_lock);
2671 ndlp->nlp_flag &= ~NLP_LOGO_SND;
2672 spin_unlock_irq(shost->host_lock);
2673 lpfc_els_free_iocb(phba, elsiocb);
2674 return 1;
2675 }
2676 return 0;
2677}
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695static void
2696lpfc_cmpl_els_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
2697 struct lpfc_iocbq *rspiocb)
2698{
2699 struct lpfc_vport *vport = cmdiocb->vport;
2700 IOCB_t *irsp;
2701
2702 irsp = &rspiocb->iocb;
2703
2704 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2705 "ELS cmd cmpl: status:x%x/x%x did:x%x",
2706 irsp->ulpStatus, irsp->un.ulpWord[4],
2707 irsp->un.elsreq64.remoteID);
2708
2709 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
2710 "0106 ELS cmd tag x%x completes Data: x%x x%x x%x\n",
2711 irsp->ulpIoTag, irsp->ulpStatus,
2712 irsp->un.ulpWord[4], irsp->ulpTimeout);
2713
2714 lpfc_els_chk_latt(vport);
2715 lpfc_els_free_iocb(phba, cmdiocb);
2716 return;
2717}
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741int
2742lpfc_issue_els_scr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
2743{
2744 struct lpfc_hba *phba = vport->phba;
2745 IOCB_t *icmd;
2746 struct lpfc_iocbq *elsiocb;
2747 struct lpfc_sli *psli;
2748 uint8_t *pcmd;
2749 uint16_t cmdsize;
2750 struct lpfc_nodelist *ndlp;
2751
2752 psli = &phba->sli;
2753 cmdsize = (sizeof(uint32_t) + sizeof(SCR));
2754
2755 ndlp = lpfc_findnode_did(vport, nportid);
2756 if (!ndlp) {
2757 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
2758 if (!ndlp)
2759 return 1;
2760 lpfc_nlp_init(vport, ndlp, nportid);
2761 lpfc_enqueue_node(vport, ndlp);
2762 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
2763 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
2764 if (!ndlp)
2765 return 1;
2766 }
2767
2768 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
2769 ndlp->nlp_DID, ELS_CMD_SCR);
2770
2771 if (!elsiocb) {
2772
2773
2774
2775 lpfc_nlp_put(ndlp);
2776 return 1;
2777 }
2778
2779 icmd = &elsiocb->iocb;
2780 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2781
2782 *((uint32_t *) (pcmd)) = ELS_CMD_SCR;
2783 pcmd += sizeof(uint32_t);
2784
2785
2786 memset(pcmd, 0, sizeof(SCR));
2787 ((SCR *) pcmd)->Function = SCR_FUNC_FULL;
2788
2789 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2790 "Issue SCR: did:x%x",
2791 ndlp->nlp_DID, 0, 0);
2792
2793 phba->fc_stat.elsXmitSCR++;
2794 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
2795 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
2796 IOCB_ERROR) {
2797
2798
2799
2800
2801 lpfc_nlp_put(ndlp);
2802 lpfc_els_free_iocb(phba, elsiocb);
2803 return 1;
2804 }
2805
2806
2807
2808
2809 lpfc_nlp_put(ndlp);
2810 return 0;
2811}
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835static int
2836lpfc_issue_els_farpr(struct lpfc_vport *vport, uint32_t nportid, uint8_t retry)
2837{
2838 struct lpfc_hba *phba = vport->phba;
2839 IOCB_t *icmd;
2840 struct lpfc_iocbq *elsiocb;
2841 struct lpfc_sli *psli;
2842 FARP *fp;
2843 uint8_t *pcmd;
2844 uint32_t *lp;
2845 uint16_t cmdsize;
2846 struct lpfc_nodelist *ondlp;
2847 struct lpfc_nodelist *ndlp;
2848
2849 psli = &phba->sli;
2850 cmdsize = (sizeof(uint32_t) + sizeof(FARP));
2851
2852 ndlp = lpfc_findnode_did(vport, nportid);
2853 if (!ndlp) {
2854 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
2855 if (!ndlp)
2856 return 1;
2857 lpfc_nlp_init(vport, ndlp, nportid);
2858 lpfc_enqueue_node(vport, ndlp);
2859 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
2860 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
2861 if (!ndlp)
2862 return 1;
2863 }
2864
2865 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp,
2866 ndlp->nlp_DID, ELS_CMD_RNID);
2867 if (!elsiocb) {
2868
2869
2870
2871 lpfc_nlp_put(ndlp);
2872 return 1;
2873 }
2874
2875 icmd = &elsiocb->iocb;
2876 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
2877
2878 *((uint32_t *) (pcmd)) = ELS_CMD_FARPR;
2879 pcmd += sizeof(uint32_t);
2880
2881
2882 fp = (FARP *) (pcmd);
2883 memset(fp, 0, sizeof(FARP));
2884 lp = (uint32_t *) pcmd;
2885 *lp++ = be32_to_cpu(nportid);
2886 *lp++ = be32_to_cpu(vport->fc_myDID);
2887 fp->Rflags = 0;
2888 fp->Mflags = (FARP_MATCH_PORT | FARP_MATCH_NODE);
2889
2890 memcpy(&fp->RportName, &vport->fc_portname, sizeof(struct lpfc_name));
2891 memcpy(&fp->RnodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
2892 ondlp = lpfc_findnode_did(vport, nportid);
2893 if (ondlp && NLP_CHK_NODE_ACT(ondlp)) {
2894 memcpy(&fp->OportName, &ondlp->nlp_portname,
2895 sizeof(struct lpfc_name));
2896 memcpy(&fp->OnodeName, &ondlp->nlp_nodename,
2897 sizeof(struct lpfc_name));
2898 }
2899
2900 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
2901 "Issue FARPR: did:x%x",
2902 ndlp->nlp_DID, 0, 0);
2903
2904 phba->fc_stat.elsXmitFARPR++;
2905 elsiocb->iocb_cmpl = lpfc_cmpl_els_cmd;
2906 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
2907 IOCB_ERROR) {
2908
2909
2910
2911
2912 lpfc_nlp_put(ndlp);
2913 lpfc_els_free_iocb(phba, elsiocb);
2914 return 1;
2915 }
2916
2917
2918
2919 lpfc_nlp_put(ndlp);
2920 return 0;
2921}
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935void
2936lpfc_cancel_retry_delay_tmo(struct lpfc_vport *vport, struct lpfc_nodelist *nlp)
2937{
2938 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
2939 struct lpfc_work_evt *evtp;
2940
2941 if (!(nlp->nlp_flag & NLP_DELAY_TMO))
2942 return;
2943 spin_lock_irq(shost->host_lock);
2944 nlp->nlp_flag &= ~NLP_DELAY_TMO;
2945 spin_unlock_irq(shost->host_lock);
2946 del_timer_sync(&nlp->nlp_delayfunc);
2947 nlp->nlp_last_elscmd = 0;
2948 if (!list_empty(&nlp->els_retry_evt.evt_listp)) {
2949 list_del_init(&nlp->els_retry_evt.evt_listp);
2950
2951 evtp = &nlp->els_retry_evt;
2952 lpfc_nlp_put((struct lpfc_nodelist *)evtp->evt_arg1);
2953 }
2954 if (nlp->nlp_flag & NLP_NPR_2B_DISC) {
2955 spin_lock_irq(shost->host_lock);
2956 nlp->nlp_flag &= ~NLP_NPR_2B_DISC;
2957 spin_unlock_irq(shost->host_lock);
2958 if (vport->num_disc_nodes) {
2959 if (vport->port_state < LPFC_VPORT_READY) {
2960
2961 lpfc_more_adisc(vport);
2962 } else {
2963
2964 lpfc_more_plogi(vport);
2965 if (vport->num_disc_nodes == 0) {
2966 spin_lock_irq(shost->host_lock);
2967 vport->fc_flag &= ~FC_NDISC_ACTIVE;
2968 spin_unlock_irq(shost->host_lock);
2969 lpfc_can_disctmo(vport);
2970 lpfc_end_rscn(vport);
2971 }
2972 }
2973 }
2974 }
2975 return;
2976}
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992void
2993lpfc_els_retry_delay(unsigned long ptr)
2994{
2995 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) ptr;
2996 struct lpfc_vport *vport = ndlp->vport;
2997 struct lpfc_hba *phba = vport->phba;
2998 unsigned long flags;
2999 struct lpfc_work_evt *evtp = &ndlp->els_retry_evt;
3000
3001 spin_lock_irqsave(&phba->hbalock, flags);
3002 if (!list_empty(&evtp->evt_listp)) {
3003 spin_unlock_irqrestore(&phba->hbalock, flags);
3004 return;
3005 }
3006
3007
3008
3009
3010 evtp->evt_arg1 = lpfc_nlp_get(ndlp);
3011 if (evtp->evt_arg1) {
3012 evtp->evt = LPFC_EVT_ELS_RETRY;
3013 list_add_tail(&evtp->evt_listp, &phba->work_list);
3014 lpfc_worker_wake_up(phba);
3015 }
3016 spin_unlock_irqrestore(&phba->hbalock, flags);
3017 return;
3018}
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029void
3030lpfc_els_retry_delay_handler(struct lpfc_nodelist *ndlp)
3031{
3032 struct lpfc_vport *vport = ndlp->vport;
3033 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3034 uint32_t cmd, retry;
3035
3036 spin_lock_irq(shost->host_lock);
3037 cmd = ndlp->nlp_last_elscmd;
3038 ndlp->nlp_last_elscmd = 0;
3039
3040 if (!(ndlp->nlp_flag & NLP_DELAY_TMO)) {
3041 spin_unlock_irq(shost->host_lock);
3042 return;
3043 }
3044
3045 ndlp->nlp_flag &= ~NLP_DELAY_TMO;
3046 spin_unlock_irq(shost->host_lock);
3047
3048
3049
3050
3051
3052 del_timer_sync(&ndlp->nlp_delayfunc);
3053 retry = ndlp->nlp_retry;
3054 ndlp->nlp_retry = 0;
3055
3056 switch (cmd) {
3057 case ELS_CMD_FLOGI:
3058 lpfc_issue_els_flogi(vport, ndlp, retry);
3059 break;
3060 case ELS_CMD_PLOGI:
3061 if (!lpfc_issue_els_plogi(vport, ndlp->nlp_DID, retry)) {
3062 ndlp->nlp_prev_state = ndlp->nlp_state;
3063 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
3064 }
3065 break;
3066 case ELS_CMD_ADISC:
3067 if (!lpfc_issue_els_adisc(vport, ndlp, retry)) {
3068 ndlp->nlp_prev_state = ndlp->nlp_state;
3069 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
3070 }
3071 break;
3072 case ELS_CMD_PRLI:
3073 if (!lpfc_issue_els_prli(vport, ndlp, retry)) {
3074 ndlp->nlp_prev_state = ndlp->nlp_state;
3075 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
3076 }
3077 break;
3078 case ELS_CMD_LOGO:
3079 if (!lpfc_issue_els_logo(vport, ndlp, retry)) {
3080 ndlp->nlp_prev_state = ndlp->nlp_state;
3081 lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
3082 }
3083 break;
3084 case ELS_CMD_FDISC:
3085 if (!(vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI))
3086 lpfc_issue_els_fdisc(vport, ndlp, retry);
3087 break;
3088 }
3089 return;
3090}
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113static int
3114lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
3115 struct lpfc_iocbq *rspiocb)
3116{
3117 struct lpfc_vport *vport = cmdiocb->vport;
3118 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3119 IOCB_t *irsp = &rspiocb->iocb;
3120 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
3121 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
3122 uint32_t *elscmd;
3123 struct ls_rjt stat;
3124 int retry = 0, maxretry = lpfc_max_els_tries, delay = 0;
3125 int logerr = 0;
3126 uint32_t cmd = 0;
3127 uint32_t did;
3128
3129
3130
3131
3132
3133
3134 if (pcmd && pcmd->virt) {
3135 elscmd = (uint32_t *) (pcmd->virt);
3136 cmd = *elscmd++;
3137 }
3138
3139 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
3140 did = ndlp->nlp_DID;
3141 else {
3142
3143 did = irsp->un.elsreq64.remoteID;
3144 ndlp = lpfc_findnode_did(vport, did);
3145 if ((!ndlp || !NLP_CHK_NODE_ACT(ndlp))
3146 && (cmd != ELS_CMD_PLOGI))
3147 return 1;
3148 }
3149
3150 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
3151 "Retry ELS: wd7:x%x wd4:x%x did:x%x",
3152 *(((uint32_t *) irsp) + 7), irsp->un.ulpWord[4], ndlp->nlp_DID);
3153
3154 switch (irsp->ulpStatus) {
3155 case IOSTAT_FCP_RSP_ERROR:
3156 break;
3157 case IOSTAT_REMOTE_STOP:
3158 if (phba->sli_rev == LPFC_SLI_REV4) {
3159
3160
3161
3162
3163 lpfc_set_rrq_active(phba, ndlp,
3164 cmdiocb->sli4_lxritag, 0, 0);
3165 }
3166 break;
3167 case IOSTAT_LOCAL_REJECT:
3168 switch ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK)) {
3169 case IOERR_LOOP_OPEN_FAILURE:
3170 if (cmd == ELS_CMD_FLOGI) {
3171 if (PCI_DEVICE_ID_HORNET ==
3172 phba->pcidev->device) {
3173 phba->fc_topology = LPFC_TOPOLOGY_LOOP;
3174 phba->pport->fc_myDID = 0;
3175 phba->alpa_map[0] = 0;
3176 phba->alpa_map[1] = 0;
3177 }
3178 }
3179 if (cmd == ELS_CMD_PLOGI && cmdiocb->retry == 0)
3180 delay = 1000;
3181 retry = 1;
3182 break;
3183
3184 case IOERR_ILLEGAL_COMMAND:
3185 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
3186 "0124 Retry illegal cmd x%x "
3187 "retry:x%x delay:x%x\n",
3188 cmd, cmdiocb->retry, delay);
3189 retry = 1;
3190
3191 maxretry = 8;
3192 if (cmdiocb->retry > 2)
3193 delay = 1000;
3194 break;
3195
3196 case IOERR_NO_RESOURCES:
3197 logerr = 1;
3198 retry = 1;
3199 if (cmdiocb->retry > 100)
3200 delay = 100;
3201 maxretry = 250;
3202 break;
3203
3204 case IOERR_ILLEGAL_FRAME:
3205 delay = 100;
3206 retry = 1;
3207 break;
3208
3209 case IOERR_SEQUENCE_TIMEOUT:
3210 case IOERR_INVALID_RPI:
3211 if (cmd == ELS_CMD_PLOGI &&
3212 did == NameServer_DID) {
3213
3214
3215 maxretry = 0;
3216 delay = 100;
3217 }
3218 retry = 1;
3219 break;
3220 }
3221 break;
3222
3223 case IOSTAT_NPORT_RJT:
3224 case IOSTAT_FABRIC_RJT:
3225 if (irsp->un.ulpWord[4] & RJT_UNAVAIL_TEMP) {
3226 retry = 1;
3227 break;
3228 }
3229 break;
3230
3231 case IOSTAT_NPORT_BSY:
3232 case IOSTAT_FABRIC_BSY:
3233 logerr = 1;
3234 retry = 1;
3235 break;
3236
3237 case IOSTAT_LS_RJT:
3238 stat.un.lsRjtError = be32_to_cpu(irsp->un.ulpWord[4]);
3239
3240
3241
3242 switch (stat.un.b.lsRjtRsnCode) {
3243 case LSRJT_UNABLE_TPC:
3244 if (stat.un.b.lsRjtRsnCodeExp ==
3245 LSEXP_CMD_IN_PROGRESS) {
3246 if (cmd == ELS_CMD_PLOGI) {
3247 delay = 1000;
3248 maxretry = 48;
3249 }
3250 retry = 1;
3251 break;
3252 }
3253 if (stat.un.b.lsRjtRsnCodeExp ==
3254 LSEXP_CANT_GIVE_DATA) {
3255 if (cmd == ELS_CMD_PLOGI) {
3256 delay = 1000;
3257 maxretry = 48;
3258 }
3259 retry = 1;
3260 break;
3261 }
3262 if ((cmd == ELS_CMD_PLOGI) ||
3263 (cmd == ELS_CMD_PRLI)) {
3264 delay = 1000;
3265 maxretry = lpfc_max_els_tries + 1;
3266 retry = 1;
3267 break;
3268 }
3269 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
3270 (cmd == ELS_CMD_FDISC) &&
3271 (stat.un.b.lsRjtRsnCodeExp == LSEXP_OUT_OF_RESOURCE)){
3272 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
3273 "0125 FDISC Failed (x%x). "
3274 "Fabric out of resources\n",
3275 stat.un.lsRjtError);
3276 lpfc_vport_set_state(vport,
3277 FC_VPORT_NO_FABRIC_RSCS);
3278 }
3279 break;
3280
3281 case LSRJT_LOGICAL_BSY:
3282 if ((cmd == ELS_CMD_PLOGI) ||
3283 (cmd == ELS_CMD_PRLI)) {
3284 delay = 1000;
3285 maxretry = 48;
3286 } else if (cmd == ELS_CMD_FDISC) {
3287
3288 maxretry = 48;
3289 if (cmdiocb->retry >= 32)
3290 delay = 1000;
3291 }
3292 retry = 1;
3293 break;
3294
3295 case LSRJT_LOGICAL_ERR:
3296
3297
3298
3299
3300 if (cmd == ELS_CMD_FDISC &&
3301 stat.un.b.lsRjtRsnCodeExp == LSEXP_PORT_LOGIN_REQ) {
3302 maxretry = 3;
3303 delay = 1000;
3304 retry = 1;
3305 break;
3306 }
3307 case LSRJT_PROTOCOL_ERR:
3308 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
3309 (cmd == ELS_CMD_FDISC) &&
3310 ((stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_PNAME) ||
3311 (stat.un.b.lsRjtRsnCodeExp == LSEXP_INVALID_NPORT_ID))
3312 ) {
3313 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
3314 "0122 FDISC Failed (x%x). "
3315 "Fabric Detected Bad WWN\n",
3316 stat.un.lsRjtError);
3317 lpfc_vport_set_state(vport,
3318 FC_VPORT_FABRIC_REJ_WWN);
3319 }
3320 break;
3321 }
3322 break;
3323
3324 case IOSTAT_INTERMED_RSP:
3325 case IOSTAT_BA_RJT:
3326 break;
3327
3328 default:
3329 break;
3330 }
3331
3332 if (did == FDMI_DID)
3333 retry = 1;
3334
3335 if ((cmd == ELS_CMD_FLOGI) &&
3336 (phba->fc_topology != LPFC_TOPOLOGY_LOOP) &&
3337 !lpfc_error_lost_link(irsp)) {
3338
3339 retry = 1;
3340
3341 maxretry = 0;
3342 if (cmdiocb->retry >= 100)
3343 delay = 5000;
3344 else if (cmdiocb->retry >= 32)
3345 delay = 1000;
3346 } else if ((cmd == ELS_CMD_FDISC) && !lpfc_error_lost_link(irsp)) {
3347
3348 retry = 1;
3349 maxretry = vport->cfg_devloss_tmo;
3350 delay = 1000;
3351 }
3352
3353 cmdiocb->retry++;
3354 if (maxretry && (cmdiocb->retry >= maxretry)) {
3355 phba->fc_stat.elsRetryExceeded++;
3356 retry = 0;
3357 }
3358
3359 if ((vport->load_flag & FC_UNLOADING) != 0)
3360 retry = 0;
3361
3362 if (retry) {
3363 if ((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_FDISC)) {
3364
3365 if (phba->fcf.fcf_flag & FCF_DISCOVERY) {
3366 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3367 "2849 Stop retry ELS command "
3368 "x%x to remote NPORT x%x, "
3369 "Data: x%x x%x\n", cmd, did,
3370 cmdiocb->retry, delay);
3371 return 0;
3372 }
3373 }
3374
3375
3376 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3377 "0107 Retry ELS command x%x to remote "
3378 "NPORT x%x Data: x%x x%x\n",
3379 cmd, did, cmdiocb->retry, delay);
3380
3381 if (((cmd == ELS_CMD_PLOGI) || (cmd == ELS_CMD_ADISC)) &&
3382 ((irsp->ulpStatus != IOSTAT_LOCAL_REJECT) ||
3383 ((irsp->un.ulpWord[4] & IOERR_PARAM_MASK) !=
3384 IOERR_NO_RESOURCES))) {
3385
3386
3387
3388 if (timer_pending(&vport->fc_disctmo) ||
3389 (vport->fc_flag & FC_RSCN_MODE))
3390 lpfc_set_disctmo(vport);
3391 }
3392
3393 phba->fc_stat.elsXmitRetry++;
3394 if (ndlp && NLP_CHK_NODE_ACT(ndlp) && delay) {
3395 phba->fc_stat.elsDelayRetry++;
3396 ndlp->nlp_retry = cmdiocb->retry;
3397
3398
3399 mod_timer(&ndlp->nlp_delayfunc,
3400 jiffies + msecs_to_jiffies(delay));
3401 spin_lock_irq(shost->host_lock);
3402 ndlp->nlp_flag |= NLP_DELAY_TMO;
3403 spin_unlock_irq(shost->host_lock);
3404
3405 ndlp->nlp_prev_state = ndlp->nlp_state;
3406 if (cmd == ELS_CMD_PRLI)
3407 lpfc_nlp_set_state(vport, ndlp,
3408 NLP_STE_PRLI_ISSUE);
3409 else
3410 lpfc_nlp_set_state(vport, ndlp,
3411 NLP_STE_NPR_NODE);
3412 ndlp->nlp_last_elscmd = cmd;
3413
3414 return 1;
3415 }
3416 switch (cmd) {
3417 case ELS_CMD_FLOGI:
3418 lpfc_issue_els_flogi(vport, ndlp, cmdiocb->retry);
3419 return 1;
3420 case ELS_CMD_FDISC:
3421 lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry);
3422 return 1;
3423 case ELS_CMD_PLOGI:
3424 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
3425 ndlp->nlp_prev_state = ndlp->nlp_state;
3426 lpfc_nlp_set_state(vport, ndlp,
3427 NLP_STE_PLOGI_ISSUE);
3428 }
3429 lpfc_issue_els_plogi(vport, did, cmdiocb->retry);
3430 return 1;
3431 case ELS_CMD_ADISC:
3432 ndlp->nlp_prev_state = ndlp->nlp_state;
3433 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
3434 lpfc_issue_els_adisc(vport, ndlp, cmdiocb->retry);
3435 return 1;
3436 case ELS_CMD_PRLI:
3437 ndlp->nlp_prev_state = ndlp->nlp_state;
3438 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PRLI_ISSUE);
3439 lpfc_issue_els_prli(vport, ndlp, cmdiocb->retry);
3440 return 1;
3441 case ELS_CMD_LOGO:
3442 ndlp->nlp_prev_state = ndlp->nlp_state;
3443 lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
3444 lpfc_issue_els_logo(vport, ndlp, cmdiocb->retry);
3445 return 1;
3446 }
3447 }
3448
3449 if (logerr) {
3450 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
3451 "0137 No retry ELS command x%x to remote "
3452 "NPORT x%x: Out of Resources: Error:x%x/%x\n",
3453 cmd, did, irsp->ulpStatus,
3454 irsp->un.ulpWord[4]);
3455 }
3456 else {
3457 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3458 "0108 No retry ELS command x%x to remote "
3459 "NPORT x%x Retried:%d Error:x%x/%x\n",
3460 cmd, did, cmdiocb->retry, irsp->ulpStatus,
3461 irsp->un.ulpWord[4]);
3462 }
3463 return 0;
3464}
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480static int
3481lpfc_els_free_data(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr1)
3482{
3483 struct lpfc_dmabuf *buf_ptr;
3484
3485
3486 if (!list_empty(&buf_ptr1->list)) {
3487 list_remove_head(&buf_ptr1->list, buf_ptr,
3488 struct lpfc_dmabuf,
3489 list);
3490 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
3491 kfree(buf_ptr);
3492 }
3493 lpfc_mbuf_free(phba, buf_ptr1->virt, buf_ptr1->phys);
3494 kfree(buf_ptr1);
3495 return 0;
3496}
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510static int
3511lpfc_els_free_bpl(struct lpfc_hba *phba, struct lpfc_dmabuf *buf_ptr)
3512{
3513 lpfc_mbuf_free(phba, buf_ptr->virt, buf_ptr->phys);
3514 kfree(buf_ptr);
3515 return 0;
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
3543
3544
3545int
3546lpfc_els_free_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *elsiocb)
3547{
3548 struct lpfc_dmabuf *buf_ptr, *buf_ptr1;
3549 struct lpfc_nodelist *ndlp;
3550
3551 ndlp = (struct lpfc_nodelist *)elsiocb->context1;
3552 if (ndlp) {
3553 if (ndlp->nlp_flag & NLP_DEFER_RM) {
3554 lpfc_nlp_put(ndlp);
3555
3556
3557
3558
3559 if (!lpfc_nlp_not_used(ndlp)) {
3560
3561
3562
3563 ndlp->nlp_flag &= ~NLP_DEFER_RM;
3564 }
3565 }
3566 else
3567 lpfc_nlp_put(ndlp);
3568 elsiocb->context1 = NULL;
3569 }
3570
3571 if (elsiocb->context2) {
3572 if (elsiocb->iocb_flag & LPFC_DELAY_MEM_FREE) {
3573
3574
3575
3576
3577 elsiocb->iocb_flag &= ~LPFC_DELAY_MEM_FREE;
3578 buf_ptr = elsiocb->context2;
3579 elsiocb->context2 = NULL;
3580 if (buf_ptr) {
3581 buf_ptr1 = NULL;
3582 spin_lock_irq(&phba->hbalock);
3583 if (!list_empty(&buf_ptr->list)) {
3584 list_remove_head(&buf_ptr->list,
3585 buf_ptr1, struct lpfc_dmabuf,
3586 list);
3587 INIT_LIST_HEAD(&buf_ptr1->list);
3588 list_add_tail(&buf_ptr1->list,
3589 &phba->elsbuf);
3590 phba->elsbuf_cnt++;
3591 }
3592 INIT_LIST_HEAD(&buf_ptr->list);
3593 list_add_tail(&buf_ptr->list, &phba->elsbuf);
3594 phba->elsbuf_cnt++;
3595 spin_unlock_irq(&phba->hbalock);
3596 }
3597 } else {
3598 buf_ptr1 = (struct lpfc_dmabuf *) elsiocb->context2;
3599 lpfc_els_free_data(phba, buf_ptr1);
3600 }
3601 }
3602
3603 if (elsiocb->context3) {
3604 buf_ptr = (struct lpfc_dmabuf *) elsiocb->context3;
3605 lpfc_els_free_bpl(phba, buf_ptr);
3606 }
3607 lpfc_sli_release_iocbq(phba, elsiocb);
3608 return 0;
3609}
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628static void
3629lpfc_cmpl_els_logo_acc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
3630 struct lpfc_iocbq *rspiocb)
3631{
3632 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
3633 struct lpfc_vport *vport = cmdiocb->vport;
3634 IOCB_t *irsp;
3635
3636 irsp = &rspiocb->iocb;
3637 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3638 "ACC LOGO cmpl: status:x%x/x%x did:x%x",
3639 irsp->ulpStatus, irsp->un.ulpWord[4], ndlp->nlp_DID);
3640
3641 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3642 "0109 ACC to LOGO completes to NPort x%x "
3643 "Data: x%x x%x x%x\n",
3644 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
3645 ndlp->nlp_rpi);
3646
3647 if (ndlp->nlp_state == NLP_STE_NPR_NODE) {
3648
3649 if (!lpfc_nlp_not_used(ndlp)) {
3650
3651
3652
3653 lpfc_unreg_rpi(vport, ndlp);
3654 } else {
3655
3656
3657
3658 cmdiocb->context1 = NULL;
3659 }
3660 }
3661
3662
3663
3664
3665
3666 lpfc_els_free_iocb(phba, cmdiocb);
3667
3668
3669
3670
3671
3672 if (ndlp->nlp_type & NLP_FABRIC)
3673 lpfc_nlp_put(ndlp);
3674
3675 return;
3676}
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691void
3692lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
3693{
3694 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (pmb->context1);
3695 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
3696
3697 pmb->context1 = NULL;
3698 pmb->context2 = NULL;
3699
3700 lpfc_mbuf_free(phba, mp->virt, mp->phys);
3701 kfree(mp);
3702 mempool_free(pmb, phba->mbox_mem_pool);
3703 if (ndlp) {
3704 if (NLP_CHK_NODE_ACT(ndlp)) {
3705 lpfc_nlp_put(ndlp);
3706
3707
3708
3709
3710 lpfc_nlp_not_used(ndlp);
3711 } else {
3712 lpfc_drop_node(ndlp->vport, ndlp);
3713 }
3714 }
3715
3716 return;
3717}
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735static void
3736lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
3737 struct lpfc_iocbq *rspiocb)
3738{
3739 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
3740 struct lpfc_vport *vport = ndlp ? ndlp->vport : NULL;
3741 struct Scsi_Host *shost = vport ? lpfc_shost_from_vport(vport) : NULL;
3742 IOCB_t *irsp;
3743 uint8_t *pcmd;
3744 LPFC_MBOXQ_t *mbox = NULL;
3745 struct lpfc_dmabuf *mp = NULL;
3746 uint32_t ls_rjt = 0;
3747
3748 irsp = &rspiocb->iocb;
3749
3750 if (cmdiocb->context_un.mbox)
3751 mbox = cmdiocb->context_un.mbox;
3752
3753
3754
3755
3756 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
3757 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
3758 (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
3759
3760
3761
3762 if (!(ndlp->nlp_flag & NLP_RM_DFLT_RPI))
3763 ls_rjt = 1;
3764 }
3765
3766
3767 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) {
3768 if (mbox) {
3769 mp = (struct lpfc_dmabuf *) mbox->context1;
3770 if (mp) {
3771 lpfc_mbuf_free(phba, mp->virt, mp->phys);
3772 kfree(mp);
3773 }
3774 mempool_free(mbox, phba->mbox_mem_pool);
3775 }
3776 if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
3777 (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
3778 if (lpfc_nlp_not_used(ndlp)) {
3779 ndlp = NULL;
3780
3781
3782
3783
3784 cmdiocb->context1 = NULL;
3785 }
3786 goto out;
3787 }
3788
3789 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3790 "ELS rsp cmpl: status:x%x/x%x did:x%x",
3791 irsp->ulpStatus, irsp->un.ulpWord[4],
3792 cmdiocb->iocb.un.elsreq64.remoteID);
3793
3794 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
3795 "0110 ELS response tag x%x completes "
3796 "Data: x%x x%x x%x x%x x%x x%x x%x\n",
3797 cmdiocb->iocb.ulpIoTag, rspiocb->iocb.ulpStatus,
3798 rspiocb->iocb.un.ulpWord[4], rspiocb->iocb.ulpTimeout,
3799 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
3800 ndlp->nlp_rpi);
3801 if (mbox) {
3802 if ((rspiocb->iocb.ulpStatus == 0)
3803 && (ndlp->nlp_flag & NLP_ACC_REGLOGIN)) {
3804 lpfc_unreg_rpi(vport, ndlp);
3805
3806
3807
3808 mbox->context2 = lpfc_nlp_get(ndlp);
3809 mbox->vport = vport;
3810 if (ndlp->nlp_flag & NLP_RM_DFLT_RPI) {
3811 mbox->mbox_flag |= LPFC_MBX_IMED_UNREG;
3812 mbox->mbox_cmpl = lpfc_mbx_cmpl_dflt_rpi;
3813 }
3814 else {
3815 mbox->mbox_cmpl = lpfc_mbx_cmpl_reg_login;
3816 ndlp->nlp_prev_state = ndlp->nlp_state;
3817 lpfc_nlp_set_state(vport, ndlp,
3818 NLP_STE_REG_LOGIN_ISSUE);
3819 }
3820 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
3821 != MBX_NOT_FINISHED)
3822 goto out;
3823 else
3824
3825
3826
3827 lpfc_nlp_put(ndlp);
3828
3829
3830 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
3831 "0138 ELS rsp: Cannot issue reg_login for x%x "
3832 "Data: x%x x%x x%x\n",
3833 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
3834 ndlp->nlp_rpi);
3835
3836 if (lpfc_nlp_not_used(ndlp)) {
3837 ndlp = NULL;
3838
3839
3840
3841
3842 cmdiocb->context1 = NULL;
3843 }
3844 } else {
3845
3846 if (!lpfc_error_lost_link(irsp) &&
3847 ndlp->nlp_flag & NLP_ACC_REGLOGIN) {
3848 if (lpfc_nlp_not_used(ndlp)) {
3849 ndlp = NULL;
3850
3851
3852
3853
3854
3855 cmdiocb->context1 = NULL;
3856 }
3857 }
3858 }
3859 mp = (struct lpfc_dmabuf *) mbox->context1;
3860 if (mp) {
3861 lpfc_mbuf_free(phba, mp->virt, mp->phys);
3862 kfree(mp);
3863 }
3864 mempool_free(mbox, phba->mbox_mem_pool);
3865 }
3866out:
3867 if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
3868 spin_lock_irq(shost->host_lock);
3869 ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI);
3870 spin_unlock_irq(shost->host_lock);
3871
3872
3873
3874
3875
3876
3877 if (ls_rjt)
3878 if (lpfc_nlp_not_used(ndlp))
3879
3880
3881
3882
3883 cmdiocb->context1 = NULL;
3884 }
3885
3886 lpfc_els_free_iocb(phba, cmdiocb);
3887 return;
3888}
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915int
3916lpfc_els_rsp_acc(struct lpfc_vport *vport, uint32_t flag,
3917 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
3918 LPFC_MBOXQ_t *mbox)
3919{
3920 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
3921 struct lpfc_hba *phba = vport->phba;
3922 IOCB_t *icmd;
3923 IOCB_t *oldcmd;
3924 struct lpfc_iocbq *elsiocb;
3925 struct lpfc_sli *psli;
3926 uint8_t *pcmd;
3927 uint16_t cmdsize;
3928 int rc;
3929 ELS_PKT *els_pkt_ptr;
3930
3931 psli = &phba->sli;
3932 oldcmd = &oldiocb->iocb;
3933
3934 switch (flag) {
3935 case ELS_CMD_ACC:
3936 cmdsize = sizeof(uint32_t);
3937 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
3938 ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
3939 if (!elsiocb) {
3940 spin_lock_irq(shost->host_lock);
3941 ndlp->nlp_flag &= ~NLP_LOGO_ACC;
3942 spin_unlock_irq(shost->host_lock);
3943 return 1;
3944 }
3945
3946 icmd = &elsiocb->iocb;
3947 icmd->ulpContext = oldcmd->ulpContext;
3948 icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
3949 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3950 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
3951 pcmd += sizeof(uint32_t);
3952
3953 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3954 "Issue ACC: did:x%x flg:x%x",
3955 ndlp->nlp_DID, ndlp->nlp_flag, 0);
3956 break;
3957 case ELS_CMD_PLOGI:
3958 cmdsize = (sizeof(struct serv_parm) + sizeof(uint32_t));
3959 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
3960 ndlp, ndlp->nlp_DID, ELS_CMD_ACC);
3961 if (!elsiocb)
3962 return 1;
3963
3964 icmd = &elsiocb->iocb;
3965 icmd->ulpContext = oldcmd->ulpContext;
3966 icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
3967 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3968
3969 if (mbox)
3970 elsiocb->context_un.mbox = mbox;
3971
3972 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
3973 pcmd += sizeof(uint32_t);
3974 memcpy(pcmd, &vport->fc_sparam, sizeof(struct serv_parm));
3975
3976 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3977 "Issue ACC PLOGI: did:x%x flg:x%x",
3978 ndlp->nlp_DID, ndlp->nlp_flag, 0);
3979 break;
3980 case ELS_CMD_PRLO:
3981 cmdsize = sizeof(uint32_t) + sizeof(PRLO);
3982 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry,
3983 ndlp, ndlp->nlp_DID, ELS_CMD_PRLO);
3984 if (!elsiocb)
3985 return 1;
3986
3987 icmd = &elsiocb->iocb;
3988 icmd->ulpContext = oldcmd->ulpContext;
3989 icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
3990 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
3991
3992 memcpy(pcmd, ((struct lpfc_dmabuf *) oldiocb->context2)->virt,
3993 sizeof(uint32_t) + sizeof(PRLO));
3994 *((uint32_t *) (pcmd)) = ELS_CMD_PRLO_ACC;
3995 els_pkt_ptr = (ELS_PKT *) pcmd;
3996 els_pkt_ptr->un.prlo.acceptRspCode = PRLO_REQ_EXECUTED;
3997
3998 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
3999 "Issue ACC PRLO: did:x%x flg:x%x",
4000 ndlp->nlp_DID, ndlp->nlp_flag, 0);
4001 break;
4002 default:
4003 return 1;
4004 }
4005
4006 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4007 "0128 Xmit ELS ACC response tag x%x, XRI: x%x, "
4008 "DID: x%x, nlp_flag: x%x nlp_state: x%x RPI: x%x "
4009 "fc_flag x%x\n",
4010 elsiocb->iotag, elsiocb->iocb.ulpContext,
4011 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
4012 ndlp->nlp_rpi, vport->fc_flag);
4013 if (ndlp->nlp_flag & NLP_LOGO_ACC) {
4014 spin_lock_irq(shost->host_lock);
4015 ndlp->nlp_flag &= ~NLP_LOGO_ACC;
4016 spin_unlock_irq(shost->host_lock);
4017 elsiocb->iocb_cmpl = lpfc_cmpl_els_logo_acc;
4018 } else {
4019 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
4020 }
4021
4022 phba->fc_stat.elsXmitACC++;
4023 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
4024 if (rc == IOCB_ERROR) {
4025 lpfc_els_free_iocb(phba, elsiocb);
4026 return 1;
4027 }
4028 return 0;
4029}
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053int
4054lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError,
4055 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp,
4056 LPFC_MBOXQ_t *mbox)
4057{
4058 struct lpfc_hba *phba = vport->phba;
4059 IOCB_t *icmd;
4060 IOCB_t *oldcmd;
4061 struct lpfc_iocbq *elsiocb;
4062 struct lpfc_sli *psli;
4063 uint8_t *pcmd;
4064 uint16_t cmdsize;
4065 int rc;
4066
4067 psli = &phba->sli;
4068 cmdsize = 2 * sizeof(uint32_t);
4069 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
4070 ndlp->nlp_DID, ELS_CMD_LS_RJT);
4071 if (!elsiocb)
4072 return 1;
4073
4074 icmd = &elsiocb->iocb;
4075 oldcmd = &oldiocb->iocb;
4076 icmd->ulpContext = oldcmd->ulpContext;
4077 icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
4078 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4079
4080 *((uint32_t *) (pcmd)) = ELS_CMD_LS_RJT;
4081 pcmd += sizeof(uint32_t);
4082 *((uint32_t *) (pcmd)) = rejectError;
4083
4084 if (mbox)
4085 elsiocb->context_un.mbox = mbox;
4086
4087
4088 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4089 "0129 Xmit ELS RJT x%x response tag x%x "
4090 "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
4091 "rpi x%x\n",
4092 rejectError, elsiocb->iotag,
4093 elsiocb->iocb.ulpContext, ndlp->nlp_DID,
4094 ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi);
4095 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
4096 "Issue LS_RJT: did:x%x flg:x%x err:x%x",
4097 ndlp->nlp_DID, ndlp->nlp_flag, rejectError);
4098
4099 phba->fc_stat.elsXmitLSRJT++;
4100 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
4101 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
4102
4103 if (rc == IOCB_ERROR) {
4104 lpfc_els_free_iocb(phba, elsiocb);
4105 return 1;
4106 }
4107 return 0;
4108}
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129int
4130lpfc_els_rsp_adisc_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
4131 struct lpfc_nodelist *ndlp)
4132{
4133 struct lpfc_hba *phba = vport->phba;
4134 ADISC *ap;
4135 IOCB_t *icmd, *oldcmd;
4136 struct lpfc_iocbq *elsiocb;
4137 uint8_t *pcmd;
4138 uint16_t cmdsize;
4139 int rc;
4140
4141 cmdsize = sizeof(uint32_t) + sizeof(ADISC);
4142 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
4143 ndlp->nlp_DID, ELS_CMD_ACC);
4144 if (!elsiocb)
4145 return 1;
4146
4147 icmd = &elsiocb->iocb;
4148 oldcmd = &oldiocb->iocb;
4149 icmd->ulpContext = oldcmd->ulpContext;
4150 icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
4151
4152
4153 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4154 "0130 Xmit ADISC ACC response iotag x%x xri: "
4155 "x%x, did x%x, nlp_flag x%x, nlp_state x%x rpi x%x\n",
4156 elsiocb->iotag, elsiocb->iocb.ulpContext,
4157 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
4158 ndlp->nlp_rpi);
4159 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4160
4161 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
4162 pcmd += sizeof(uint32_t);
4163
4164 ap = (ADISC *) (pcmd);
4165 ap->hardAL_PA = phba->fc_pref_ALPA;
4166 memcpy(&ap->portName, &vport->fc_portname, sizeof(struct lpfc_name));
4167 memcpy(&ap->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
4168 ap->DID = be32_to_cpu(vport->fc_myDID);
4169
4170 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
4171 "Issue ACC ADISC: did:x%x flg:x%x",
4172 ndlp->nlp_DID, ndlp->nlp_flag, 0);
4173
4174 phba->fc_stat.elsXmitACC++;
4175 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
4176 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
4177 if (rc == IOCB_ERROR) {
4178 lpfc_els_free_iocb(phba, elsiocb);
4179 return 1;
4180 }
4181 return 0;
4182}
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203int
4204lpfc_els_rsp_prli_acc(struct lpfc_vport *vport, struct lpfc_iocbq *oldiocb,
4205 struct lpfc_nodelist *ndlp)
4206{
4207 struct lpfc_hba *phba = vport->phba;
4208 PRLI *npr;
4209 lpfc_vpd_t *vpd;
4210 IOCB_t *icmd;
4211 IOCB_t *oldcmd;
4212 struct lpfc_iocbq *elsiocb;
4213 struct lpfc_sli *psli;
4214 uint8_t *pcmd;
4215 uint16_t cmdsize;
4216 int rc;
4217
4218 psli = &phba->sli;
4219
4220 cmdsize = sizeof(uint32_t) + sizeof(PRLI);
4221 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
4222 ndlp->nlp_DID, (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK)));
4223 if (!elsiocb)
4224 return 1;
4225
4226 icmd = &elsiocb->iocb;
4227 oldcmd = &oldiocb->iocb;
4228 icmd->ulpContext = oldcmd->ulpContext;
4229 icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
4230
4231
4232 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4233 "0131 Xmit PRLI ACC response tag x%x xri x%x, "
4234 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
4235 elsiocb->iotag, elsiocb->iocb.ulpContext,
4236 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
4237 ndlp->nlp_rpi);
4238 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4239
4240 *((uint32_t *) (pcmd)) = (ELS_CMD_ACC | (ELS_CMD_PRLI & ~ELS_RSP_MASK));
4241 pcmd += sizeof(uint32_t);
4242
4243
4244 memset(pcmd, 0, sizeof(PRLI));
4245
4246 npr = (PRLI *) pcmd;
4247 vpd = &phba->vpd;
4248
4249
4250
4251
4252 if ((ndlp->nlp_type & NLP_FCP_TARGET) &&
4253 (vpd->rev.feaLevelHigh >= 0x02)) {
4254 npr->ConfmComplAllowed = 1;
4255 npr->Retry = 1;
4256 npr->TaskRetryIdReq = 1;
4257 }
4258
4259 npr->acceptRspCode = PRLI_REQ_EXECUTED;
4260 npr->estabImagePair = 1;
4261 npr->readXferRdyDis = 1;
4262 npr->ConfmComplAllowed = 1;
4263
4264 npr->prliType = PRLI_FCP_TYPE;
4265 npr->initiatorFunc = 1;
4266
4267 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
4268 "Issue ACC PRLI: did:x%x flg:x%x",
4269 ndlp->nlp_DID, ndlp->nlp_flag, 0);
4270
4271 phba->fc_stat.elsXmitACC++;
4272 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
4273
4274 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
4275 if (rc == IOCB_ERROR) {
4276 lpfc_els_free_iocb(phba, elsiocb);
4277 return 1;
4278 }
4279 return 0;
4280}
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308static int
4309lpfc_els_rsp_rnid_acc(struct lpfc_vport *vport, uint8_t format,
4310 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
4311{
4312 struct lpfc_hba *phba = vport->phba;
4313 RNID *rn;
4314 IOCB_t *icmd, *oldcmd;
4315 struct lpfc_iocbq *elsiocb;
4316 struct lpfc_sli *psli;
4317 uint8_t *pcmd;
4318 uint16_t cmdsize;
4319 int rc;
4320
4321 psli = &phba->sli;
4322 cmdsize = sizeof(uint32_t) + sizeof(uint32_t)
4323 + (2 * sizeof(struct lpfc_name));
4324 if (format)
4325 cmdsize += sizeof(RNID_TOP_DISC);
4326
4327 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
4328 ndlp->nlp_DID, ELS_CMD_ACC);
4329 if (!elsiocb)
4330 return 1;
4331
4332 icmd = &elsiocb->iocb;
4333 oldcmd = &oldiocb->iocb;
4334 icmd->ulpContext = oldcmd->ulpContext;
4335 icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
4336
4337
4338 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4339 "0132 Xmit RNID ACC response tag x%x xri x%x\n",
4340 elsiocb->iotag, elsiocb->iocb.ulpContext);
4341 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4342 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
4343 pcmd += sizeof(uint32_t);
4344
4345 memset(pcmd, 0, sizeof(RNID));
4346 rn = (RNID *) (pcmd);
4347 rn->Format = format;
4348 rn->CommonLen = (2 * sizeof(struct lpfc_name));
4349 memcpy(&rn->portName, &vport->fc_portname, sizeof(struct lpfc_name));
4350 memcpy(&rn->nodeName, &vport->fc_nodename, sizeof(struct lpfc_name));
4351 switch (format) {
4352 case 0:
4353 rn->SpecificLen = 0;
4354 break;
4355 case RNID_TOPOLOGY_DISC:
4356 rn->SpecificLen = sizeof(RNID_TOP_DISC);
4357 memcpy(&rn->un.topologyDisc.portName,
4358 &vport->fc_portname, sizeof(struct lpfc_name));
4359 rn->un.topologyDisc.unitType = RNID_HBA;
4360 rn->un.topologyDisc.physPort = 0;
4361 rn->un.topologyDisc.attachedNodes = 0;
4362 break;
4363 default:
4364 rn->CommonLen = 0;
4365 rn->SpecificLen = 0;
4366 break;
4367 }
4368
4369 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
4370 "Issue ACC RNID: did:x%x flg:x%x",
4371 ndlp->nlp_DID, ndlp->nlp_flag, 0);
4372
4373 phba->fc_stat.elsXmitACC++;
4374 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
4375
4376 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
4377 if (rc == IOCB_ERROR) {
4378 lpfc_els_free_iocb(phba, elsiocb);
4379 return 1;
4380 }
4381 return 0;
4382}
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392static void
4393lpfc_els_clear_rrq(struct lpfc_vport *vport,
4394 struct lpfc_iocbq *iocb, struct lpfc_nodelist *ndlp)
4395{
4396 struct lpfc_hba *phba = vport->phba;
4397 uint8_t *pcmd;
4398 struct RRQ *rrq;
4399 uint16_t rxid;
4400 uint16_t xri;
4401 struct lpfc_node_rrq *prrq;
4402
4403
4404 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) iocb->context2)->virt);
4405 pcmd += sizeof(uint32_t);
4406 rrq = (struct RRQ *)pcmd;
4407 rrq->rrq_exchg = be32_to_cpu(rrq->rrq_exchg);
4408 rxid = bf_get(rrq_rxid, rrq);
4409
4410 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4411 "2883 Clear RRQ for SID:x%x OXID:x%x RXID:x%x"
4412 " x%x x%x\n",
4413 be32_to_cpu(bf_get(rrq_did, rrq)),
4414 bf_get(rrq_oxid, rrq),
4415 rxid,
4416 iocb->iotag, iocb->iocb.ulpContext);
4417
4418 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
4419 "Clear RRQ: did:x%x flg:x%x exchg:x%.08x",
4420 ndlp->nlp_DID, ndlp->nlp_flag, rrq->rrq_exchg);
4421 if (vport->fc_myDID == be32_to_cpu(bf_get(rrq_did, rrq)))
4422 xri = bf_get(rrq_oxid, rrq);
4423 else
4424 xri = rxid;
4425 prrq = lpfc_get_active_rrq(vport, xri, ndlp->nlp_DID);
4426 if (prrq)
4427 lpfc_clr_rrq_active(phba, xri, prrq);
4428 return;
4429}
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442static int
4443lpfc_els_rsp_echo_acc(struct lpfc_vport *vport, uint8_t *data,
4444 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
4445{
4446 struct lpfc_hba *phba = vport->phba;
4447 struct lpfc_iocbq *elsiocb;
4448 struct lpfc_sli *psli;
4449 uint8_t *pcmd;
4450 uint16_t cmdsize;
4451 int rc;
4452
4453 psli = &phba->sli;
4454 cmdsize = oldiocb->iocb.unsli3.rcvsli3.acc_len;
4455
4456
4457
4458
4459 if (cmdsize > LPFC_BPL_SIZE)
4460 cmdsize = LPFC_BPL_SIZE;
4461 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
4462 ndlp->nlp_DID, ELS_CMD_ACC);
4463 if (!elsiocb)
4464 return 1;
4465
4466 elsiocb->iocb.ulpContext = oldiocb->iocb.ulpContext;
4467 elsiocb->iocb.unsli3.rcvsli3.ox_id = oldiocb->iocb.unsli3.rcvsli3.ox_id;
4468
4469
4470 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
4471 "2876 Xmit ECHO ACC response tag x%x xri x%x\n",
4472 elsiocb->iotag, elsiocb->iocb.ulpContext);
4473 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
4474 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
4475 pcmd += sizeof(uint32_t);
4476 memcpy(pcmd, data, cmdsize - sizeof(uint32_t));
4477
4478 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP,
4479 "Issue ACC ECHO: did:x%x flg:x%x",
4480 ndlp->nlp_DID, ndlp->nlp_flag, 0);
4481
4482 phba->fc_stat.elsXmitACC++;
4483 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
4484
4485 rc = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
4486 if (rc == IOCB_ERROR) {
4487 lpfc_els_free_iocb(phba, elsiocb);
4488 return 1;
4489 }
4490 return 0;
4491}
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512int
4513lpfc_els_disc_adisc(struct lpfc_vport *vport)
4514{
4515 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
4516 struct lpfc_nodelist *ndlp, *next_ndlp;
4517 int sentadisc = 0;
4518
4519
4520 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
4521 if (!NLP_CHK_NODE_ACT(ndlp))
4522 continue;
4523 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
4524 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
4525 (ndlp->nlp_flag & NLP_NPR_ADISC) != 0) {
4526 spin_lock_irq(shost->host_lock);
4527 ndlp->nlp_flag &= ~NLP_NPR_ADISC;
4528 spin_unlock_irq(shost->host_lock);
4529 ndlp->nlp_prev_state = ndlp->nlp_state;
4530 lpfc_nlp_set_state(vport, ndlp, NLP_STE_ADISC_ISSUE);
4531 lpfc_issue_els_adisc(vport, ndlp, 0);
4532 sentadisc++;
4533 vport->num_disc_nodes++;
4534 if (vport->num_disc_nodes >=
4535 vport->cfg_discovery_threads) {
4536 spin_lock_irq(shost->host_lock);
4537 vport->fc_flag |= FC_NLP_MORE;
4538 spin_unlock_irq(shost->host_lock);
4539 break;
4540 }
4541 }
4542 }
4543 if (sentadisc == 0) {
4544 spin_lock_irq(shost->host_lock);
4545 vport->fc_flag &= ~FC_NLP_MORE;
4546 spin_unlock_irq(shost->host_lock);
4547 }
4548 return sentadisc;
4549}
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570int
4571lpfc_els_disc_plogi(struct lpfc_vport *vport)
4572{
4573 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
4574 struct lpfc_nodelist *ndlp, *next_ndlp;
4575 int sentplogi = 0;
4576
4577
4578 list_for_each_entry_safe(ndlp, next_ndlp, &vport->fc_nodes, nlp_listp) {
4579 if (!NLP_CHK_NODE_ACT(ndlp))
4580 continue;
4581 if (ndlp->nlp_state == NLP_STE_NPR_NODE &&
4582 (ndlp->nlp_flag & NLP_NPR_2B_DISC) != 0 &&
4583 (ndlp->nlp_flag & NLP_DELAY_TMO) == 0 &&
4584 (ndlp->nlp_flag & NLP_NPR_ADISC) == 0) {
4585 ndlp->nlp_prev_state = ndlp->nlp_state;
4586 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
4587 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
4588 sentplogi++;
4589 vport->num_disc_nodes++;
4590 if (vport->num_disc_nodes >=
4591 vport->cfg_discovery_threads) {
4592 spin_lock_irq(shost->host_lock);
4593 vport->fc_flag |= FC_NLP_MORE;
4594 spin_unlock_irq(shost->host_lock);
4595 break;
4596 }
4597 }
4598 }
4599 if (sentplogi) {
4600 lpfc_set_disctmo(vport);
4601 }
4602 else {
4603 spin_lock_irq(shost->host_lock);
4604 vport->fc_flag &= ~FC_NLP_MORE;
4605 spin_unlock_irq(shost->host_lock);
4606 }
4607 return sentplogi;
4608}
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619void
4620lpfc_els_flush_rscn(struct lpfc_vport *vport)
4621{
4622 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
4623 struct lpfc_hba *phba = vport->phba;
4624 int i;
4625
4626 spin_lock_irq(shost->host_lock);
4627 if (vport->fc_rscn_flush) {
4628
4629 spin_unlock_irq(shost->host_lock);
4630 return;
4631 }
4632
4633 vport->fc_rscn_flush = 1;
4634 spin_unlock_irq(shost->host_lock);
4635
4636 for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
4637 lpfc_in_buf_free(phba, vport->fc_rscn_id_list[i]);
4638 vport->fc_rscn_id_list[i] = NULL;
4639 }
4640 spin_lock_irq(shost->host_lock);
4641 vport->fc_rscn_id_cnt = 0;
4642 vport->fc_flag &= ~(FC_RSCN_MODE | FC_RSCN_DISCOVERY);
4643 spin_unlock_irq(shost->host_lock);
4644 lpfc_can_disctmo(vport);
4645
4646 vport->fc_rscn_flush = 0;
4647}
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661int
4662lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did)
4663{
4664 D_ID ns_did;
4665 D_ID rscn_did;
4666 uint32_t *lp;
4667 uint32_t payload_len, i;
4668 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
4669
4670 ns_did.un.word = did;
4671
4672
4673 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
4674 return 0;
4675
4676
4677 if (vport->fc_flag & FC_RSCN_DISCOVERY)
4678 return did;
4679
4680 spin_lock_irq(shost->host_lock);
4681 if (vport->fc_rscn_flush) {
4682
4683 spin_unlock_irq(shost->host_lock);
4684 return 0;
4685 }
4686
4687 vport->fc_rscn_flush = 1;
4688 spin_unlock_irq(shost->host_lock);
4689 for (i = 0; i < vport->fc_rscn_id_cnt; i++) {
4690 lp = vport->fc_rscn_id_list[i]->virt;
4691 payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK);
4692 payload_len -= sizeof(uint32_t);
4693 while (payload_len) {
4694 rscn_did.un.word = be32_to_cpu(*lp++);
4695 payload_len -= sizeof(uint32_t);
4696 switch (rscn_did.un.b.resv & RSCN_ADDRESS_FORMAT_MASK) {
4697 case RSCN_ADDRESS_FORMAT_PORT:
4698 if ((ns_did.un.b.domain == rscn_did.un.b.domain)
4699 && (ns_did.un.b.area == rscn_did.un.b.area)
4700 && (ns_did.un.b.id == rscn_did.un.b.id))
4701 goto return_did_out;
4702 break;
4703 case RSCN_ADDRESS_FORMAT_AREA:
4704 if ((ns_did.un.b.domain == rscn_did.un.b.domain)
4705 && (ns_did.un.b.area == rscn_did.un.b.area))
4706 goto return_did_out;
4707 break;
4708 case RSCN_ADDRESS_FORMAT_DOMAIN:
4709 if (ns_did.un.b.domain == rscn_did.un.b.domain)
4710 goto return_did_out;
4711 break;
4712 case RSCN_ADDRESS_FORMAT_FABRIC:
4713 goto return_did_out;
4714 }
4715 }
4716 }
4717
4718 vport->fc_rscn_flush = 0;
4719 return 0;
4720return_did_out:
4721
4722 vport->fc_rscn_flush = 0;
4723 return did;
4724}
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737static int
4738lpfc_rscn_recovery_check(struct lpfc_vport *vport)
4739{
4740 struct lpfc_nodelist *ndlp = NULL;
4741
4742
4743 list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
4744 if (!NLP_CHK_NODE_ACT(ndlp) ||
4745 (ndlp->nlp_state == NLP_STE_UNUSED_NODE) ||
4746 !lpfc_rscn_payload_check(vport, ndlp->nlp_DID))
4747 continue;
4748 lpfc_disc_state_machine(vport, ndlp, NULL,
4749 NLP_EVT_DEVICE_RECOVERY);
4750 lpfc_cancel_retry_delay_tmo(vport, ndlp);
4751 }
4752 return 0;
4753}
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763static void
4764lpfc_send_rscn_event(struct lpfc_vport *vport,
4765 struct lpfc_iocbq *cmdiocb)
4766{
4767 struct lpfc_dmabuf *pcmd;
4768 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
4769 uint32_t *payload_ptr;
4770 uint32_t payload_len;
4771 struct lpfc_rscn_event_header *rscn_event_data;
4772
4773 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
4774 payload_ptr = (uint32_t *) pcmd->virt;
4775 payload_len = be32_to_cpu(*payload_ptr & ~ELS_CMD_MASK);
4776
4777 rscn_event_data = kmalloc(sizeof(struct lpfc_rscn_event_header) +
4778 payload_len, GFP_KERNEL);
4779 if (!rscn_event_data) {
4780 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
4781 "0147 Failed to allocate memory for RSCN event\n");
4782 return;
4783 }
4784 rscn_event_data->event_type = FC_REG_RSCN_EVENT;
4785 rscn_event_data->payload_length = payload_len;
4786 memcpy(rscn_event_data->rscn_payload, payload_ptr,
4787 payload_len);
4788
4789 fc_host_post_vendor_event(shost,
4790 fc_get_event_number(),
4791 sizeof(struct lpfc_els_event_header) + payload_len,
4792 (char *)rscn_event_data,
4793 LPFC_NL_VENDOR_ID);
4794
4795 kfree(rscn_event_data);
4796}
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820static int
4821lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
4822 struct lpfc_nodelist *ndlp)
4823{
4824 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
4825 struct lpfc_hba *phba = vport->phba;
4826 struct lpfc_dmabuf *pcmd;
4827 uint32_t *lp, *datap;
4828 IOCB_t *icmd;
4829 uint32_t payload_len, length, nportid, *cmd;
4830 int rscn_cnt;
4831 int rscn_id = 0, hba_id = 0;
4832 int i;
4833
4834 icmd = &cmdiocb->iocb;
4835 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
4836 lp = (uint32_t *) pcmd->virt;
4837
4838 payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK);
4839 payload_len -= sizeof(uint32_t);
4840
4841 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
4842 "0214 RSCN received Data: x%x x%x x%x x%x\n",
4843 vport->fc_flag, payload_len, *lp,
4844 vport->fc_rscn_id_cnt);
4845
4846
4847 lpfc_send_rscn_event(vport, cmdiocb);
4848
4849 for (i = 0; i < payload_len/sizeof(uint32_t); i++)
4850 fc_host_post_event(shost, fc_get_event_number(),
4851 FCH_EVT_RSCN, lp[i]);
4852
4853
4854
4855
4856 if (vport->port_state <= LPFC_NS_QRY) {
4857 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
4858 "RCV RSCN ignore: did:x%x/ste:x%x flg:x%x",
4859 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
4860
4861 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4862 return 0;
4863 }
4864
4865
4866
4867
4868 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
4869 !(vport->cfg_peer_port_login)) {
4870 i = payload_len;
4871 datap = lp;
4872 while (i > 0) {
4873 nportid = *datap++;
4874 nportid = ((be32_to_cpu(nportid)) & Mask_DID);
4875 i -= sizeof(uint32_t);
4876 rscn_id++;
4877 if (lpfc_find_vport_by_did(phba, nportid))
4878 hba_id++;
4879 }
4880 if (rscn_id == hba_id) {
4881
4882 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
4883 "0219 Ignore RSCN "
4884 "Data: x%x x%x x%x x%x\n",
4885 vport->fc_flag, payload_len,
4886 *lp, vport->fc_rscn_id_cnt);
4887 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
4888 "RCV RSCN vport: did:x%x/ste:x%x flg:x%x",
4889 ndlp->nlp_DID, vport->port_state,
4890 ndlp->nlp_flag);
4891
4892 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb,
4893 ndlp, NULL);
4894 return 0;
4895 }
4896 }
4897
4898 spin_lock_irq(shost->host_lock);
4899 if (vport->fc_rscn_flush) {
4900
4901 vport->fc_flag |= FC_RSCN_DISCOVERY;
4902 spin_unlock_irq(shost->host_lock);
4903
4904 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4905 return 0;
4906 }
4907
4908 vport->fc_rscn_flush = 1;
4909 spin_unlock_irq(shost->host_lock);
4910
4911 rscn_cnt = vport->fc_rscn_id_cnt;
4912
4913
4914
4915 if (vport->fc_flag & (FC_RSCN_MODE | FC_NDISC_ACTIVE)) {
4916 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
4917 "RCV RSCN defer: did:x%x/ste:x%x flg:x%x",
4918 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
4919
4920 spin_lock_irq(shost->host_lock);
4921 vport->fc_flag |= FC_RSCN_DEFERRED;
4922 if ((rscn_cnt < FC_MAX_HOLD_RSCN) &&
4923 !(vport->fc_flag & FC_RSCN_DISCOVERY)) {
4924 vport->fc_flag |= FC_RSCN_MODE;
4925 spin_unlock_irq(shost->host_lock);
4926 if (rscn_cnt) {
4927 cmd = vport->fc_rscn_id_list[rscn_cnt-1]->virt;
4928 length = be32_to_cpu(*cmd & ~ELS_CMD_MASK);
4929 }
4930 if ((rscn_cnt) &&
4931 (payload_len + length <= LPFC_BPL_SIZE)) {
4932 *cmd &= ELS_CMD_MASK;
4933 *cmd |= cpu_to_be32(payload_len + length);
4934 memcpy(((uint8_t *)cmd) + length, lp,
4935 payload_len);
4936 } else {
4937 vport->fc_rscn_id_list[rscn_cnt] = pcmd;
4938 vport->fc_rscn_id_cnt++;
4939
4940
4941
4942 cmdiocb->context2 = NULL;
4943 }
4944
4945 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
4946 "0235 Deferred RSCN "
4947 "Data: x%x x%x x%x\n",
4948 vport->fc_rscn_id_cnt, vport->fc_flag,
4949 vport->port_state);
4950 } else {
4951 vport->fc_flag |= FC_RSCN_DISCOVERY;
4952 spin_unlock_irq(shost->host_lock);
4953
4954 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
4955 "0234 ReDiscovery RSCN "
4956 "Data: x%x x%x x%x\n",
4957 vport->fc_rscn_id_cnt, vport->fc_flag,
4958 vport->port_state);
4959 }
4960
4961 vport->fc_rscn_flush = 0;
4962
4963 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4964
4965 lpfc_rscn_recovery_check(vport);
4966 spin_lock_irq(shost->host_lock);
4967 vport->fc_flag &= ~FC_RSCN_DEFERRED;
4968 spin_unlock_irq(shost->host_lock);
4969 return 0;
4970 }
4971 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
4972 "RCV RSCN: did:x%x/ste:x%x flg:x%x",
4973 ndlp->nlp_DID, vport->port_state, ndlp->nlp_flag);
4974
4975 spin_lock_irq(shost->host_lock);
4976 vport->fc_flag |= FC_RSCN_MODE;
4977 spin_unlock_irq(shost->host_lock);
4978 vport->fc_rscn_id_list[vport->fc_rscn_id_cnt++] = pcmd;
4979
4980 vport->fc_rscn_flush = 0;
4981
4982
4983
4984
4985 cmdiocb->context2 = NULL;
4986 lpfc_set_disctmo(vport);
4987
4988 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
4989
4990 lpfc_rscn_recovery_check(vport);
4991 return lpfc_els_handle_rscn(vport);
4992}
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010int
5011lpfc_els_handle_rscn(struct lpfc_vport *vport)
5012{
5013 struct lpfc_nodelist *ndlp;
5014 struct lpfc_hba *phba = vport->phba;
5015
5016
5017 if (vport->load_flag & FC_UNLOADING) {
5018 lpfc_els_flush_rscn(vport);
5019 return 0;
5020 }
5021
5022
5023 lpfc_set_disctmo(vport);
5024
5025
5026 lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
5027 "0215 RSCN processed Data: x%x x%x x%x x%x\n",
5028 vport->fc_flag, 0, vport->fc_rscn_id_cnt,
5029 vport->port_state);
5030
5031
5032 vport->fc_ns_retry = 0;
5033 vport->num_disc_nodes = 0;
5034
5035 ndlp = lpfc_findnode_did(vport, NameServer_DID);
5036 if (ndlp && NLP_CHK_NODE_ACT(ndlp)
5037 && ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) {
5038
5039 if (lpfc_ns_cmd(vport, SLI_CTNS_GID_FT, 0, 0) == 0)
5040
5041
5042 return 1;
5043 } else {
5044
5045
5046 ndlp = lpfc_findnode_did(vport, NameServer_DID);
5047 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
5048
5049
5050 return 1;
5051
5052 if (ndlp) {
5053 ndlp = lpfc_enable_node(vport, ndlp,
5054 NLP_STE_PLOGI_ISSUE);
5055 if (!ndlp) {
5056 lpfc_els_flush_rscn(vport);
5057 return 0;
5058 }
5059 ndlp->nlp_prev_state = NLP_STE_UNUSED_NODE;
5060 } else {
5061 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
5062 if (!ndlp) {
5063 lpfc_els_flush_rscn(vport);
5064 return 0;
5065 }
5066 lpfc_nlp_init(vport, ndlp, NameServer_DID);
5067 ndlp->nlp_prev_state = ndlp->nlp_state;
5068 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
5069 }
5070 ndlp->nlp_type |= NLP_FABRIC;
5071 lpfc_issue_els_plogi(vport, NameServer_DID, 0);
5072
5073
5074
5075 return 1;
5076 }
5077
5078 lpfc_els_flush_rscn(vport);
5079 return 0;
5080}
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107static int
5108lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5109 struct lpfc_nodelist *ndlp)
5110{
5111 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
5112 struct lpfc_hba *phba = vport->phba;
5113 struct lpfc_dmabuf *pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
5114 uint32_t *lp = (uint32_t *) pcmd->virt;
5115 IOCB_t *icmd = &cmdiocb->iocb;
5116 struct serv_parm *sp;
5117 LPFC_MBOXQ_t *mbox;
5118 struct ls_rjt stat;
5119 uint32_t cmd, did;
5120 int rc;
5121 uint32_t fc_flag = 0;
5122 uint32_t port_state = 0;
5123
5124 cmd = *lp++;
5125 sp = (struct serv_parm *) lp;
5126
5127
5128
5129 lpfc_set_disctmo(vport);
5130
5131 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
5132
5133 did = icmd->un.elsreq64.remoteID;
5134
5135
5136
5137 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
5138 "0113 An FLOGI ELS command x%x was "
5139 "received from DID x%x in Loop Mode\n",
5140 cmd, did);
5141 return 1;
5142 }
5143
5144 if ((lpfc_check_sparm(vport, ndlp, sp, CLASS3, 1))) {
5145
5146
5147
5148
5149 rc = memcmp(&vport->fc_portname, &sp->portName,
5150 sizeof(struct lpfc_name));
5151
5152 if (!rc) {
5153 if (phba->sli_rev < LPFC_SLI_REV4) {
5154 mbox = mempool_alloc(phba->mbox_mem_pool,
5155 GFP_KERNEL);
5156 if (!mbox)
5157 return 1;
5158 lpfc_linkdown(phba);
5159 lpfc_init_link(phba, mbox,
5160 phba->cfg_topology,
5161 phba->cfg_link_speed);
5162 mbox->u.mb.un.varInitLnk.lipsr_AL_PA = 0;
5163 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
5164 mbox->vport = vport;
5165 rc = lpfc_sli_issue_mbox(phba, mbox,
5166 MBX_NOWAIT);
5167 lpfc_set_loopback_flag(phba);
5168 if (rc == MBX_NOT_FINISHED)
5169 mempool_free(mbox, phba->mbox_mem_pool);
5170 return 1;
5171 } else {
5172
5173
5174
5175 lpfc_els_abort_flogi(phba);
5176 return 0;
5177 }
5178 } else if (rc > 0) {
5179 spin_lock_irq(shost->host_lock);
5180 vport->fc_flag |= FC_PT2PT_PLOGI;
5181 spin_unlock_irq(shost->host_lock);
5182
5183
5184
5185
5186
5187
5188 vport->fc_myDID = PT2PT_LocalID;
5189 } else
5190 vport->fc_myDID = PT2PT_RemoteID;
5191
5192
5193
5194
5195
5196 spin_lock_irq(shost->host_lock);
5197 fc_flag = vport->fc_flag;
5198 port_state = vport->port_state;
5199 vport->fc_flag |= FC_PT2PT;
5200 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
5201 vport->port_state = LPFC_FLOGI;
5202 spin_unlock_irq(shost->host_lock);
5203 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
5204 "3311 Rcv Flogi PS x%x new PS x%x "
5205 "fc_flag x%x new fc_flag x%x\n",
5206 port_state, vport->port_state,
5207 fc_flag, vport->fc_flag);
5208
5209
5210
5211
5212
5213
5214 did = vport->fc_myDID;
5215 vport->fc_myDID = Fabric_DID;
5216
5217 } else {
5218
5219 stat.un.b.lsRjtRsvd0 = 0;
5220 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
5221 stat.un.b.lsRjtRsnCodeExp = LSEXP_SPARM_OPTIONS;
5222 stat.un.b.vendorUnique = 0;
5223
5224
5225
5226
5227
5228
5229 did = vport->fc_myDID;
5230 vport->fc_myDID = Fabric_DID;
5231
5232 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
5233 NULL);
5234
5235
5236 vport->fc_myDID = did;
5237
5238 return 1;
5239 }
5240
5241
5242 lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, NULL);
5243
5244
5245 vport->fc_myDID = did;
5246
5247 if (!(vport->fc_flag & FC_PT2PT_PLOGI)) {
5248
5249 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
5250 if (!mbox)
5251 goto fail;
5252
5253 lpfc_config_link(phba, mbox);
5254
5255 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
5256 mbox->vport = vport;
5257 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
5258 if (rc == MBX_NOT_FINISHED) {
5259 mempool_free(mbox, phba->mbox_mem_pool);
5260 goto fail;
5261 }
5262 }
5263
5264 return 0;
5265fail:
5266 return 1;
5267}
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285static int
5286lpfc_els_rcv_rnid(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5287 struct lpfc_nodelist *ndlp)
5288{
5289 struct lpfc_dmabuf *pcmd;
5290 uint32_t *lp;
5291 IOCB_t *icmd;
5292 RNID *rn;
5293 struct ls_rjt stat;
5294 uint32_t cmd;
5295
5296 icmd = &cmdiocb->iocb;
5297 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
5298 lp = (uint32_t *) pcmd->virt;
5299
5300 cmd = *lp++;
5301 rn = (RNID *) lp;
5302
5303
5304
5305 switch (rn->Format) {
5306 case 0:
5307 case RNID_TOPOLOGY_DISC:
5308
5309 lpfc_els_rsp_rnid_acc(vport, rn->Format, cmdiocb, ndlp);
5310 break;
5311 default:
5312
5313 stat.un.b.lsRjtRsvd0 = 0;
5314 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
5315 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
5316 stat.un.b.vendorUnique = 0;
5317 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
5318 NULL);
5319 }
5320 return 0;
5321}
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332static int
5333lpfc_els_rcv_echo(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5334 struct lpfc_nodelist *ndlp)
5335{
5336 uint8_t *pcmd;
5337
5338 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
5339
5340
5341 pcmd += sizeof(uint32_t);
5342
5343 lpfc_els_rsp_echo_acc(vport, pcmd, cmdiocb, ndlp);
5344 return 0;
5345}
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360static int
5361lpfc_els_rcv_lirr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5362 struct lpfc_nodelist *ndlp)
5363{
5364 struct ls_rjt stat;
5365
5366
5367 stat.un.b.lsRjtRsvd0 = 0;
5368 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
5369 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
5370 stat.un.b.vendorUnique = 0;
5371 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
5372 return 0;
5373}
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391static void
5392lpfc_els_rcv_rrq(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5393 struct lpfc_nodelist *ndlp)
5394{
5395 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
5396 if (vport->phba->sli_rev == LPFC_SLI_REV4)
5397 lpfc_els_clear_rrq(vport, cmdiocb, ndlp);
5398}
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419static void
5420lpfc_els_rsp_rls_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5421{
5422 MAILBOX_t *mb;
5423 IOCB_t *icmd;
5424 struct RLS_RSP *rls_rsp;
5425 uint8_t *pcmd;
5426 struct lpfc_iocbq *elsiocb;
5427 struct lpfc_nodelist *ndlp;
5428 uint16_t oxid;
5429 uint16_t rxid;
5430 uint32_t cmdsize;
5431
5432 mb = &pmb->u.mb;
5433
5434 ndlp = (struct lpfc_nodelist *) pmb->context2;
5435 rxid = (uint16_t) ((unsigned long)(pmb->context1) & 0xffff);
5436 oxid = (uint16_t) (((unsigned long)(pmb->context1) >> 16) & 0xffff);
5437 pmb->context1 = NULL;
5438 pmb->context2 = NULL;
5439
5440 if (mb->mbxStatus) {
5441 mempool_free(pmb, phba->mbox_mem_pool);
5442 return;
5443 }
5444
5445 cmdsize = sizeof(struct RLS_RSP) + sizeof(uint32_t);
5446 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
5447 lpfc_max_els_tries, ndlp,
5448 ndlp->nlp_DID, ELS_CMD_ACC);
5449
5450
5451 lpfc_nlp_put(ndlp);
5452
5453 if (!elsiocb) {
5454 mempool_free(pmb, phba->mbox_mem_pool);
5455 return;
5456 }
5457
5458 icmd = &elsiocb->iocb;
5459 icmd->ulpContext = rxid;
5460 icmd->unsli3.rcvsli3.ox_id = oxid;
5461
5462 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
5463 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
5464 pcmd += sizeof(uint32_t);
5465 rls_rsp = (struct RLS_RSP *)pcmd;
5466
5467 rls_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt);
5468 rls_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt);
5469 rls_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt);
5470 rls_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt);
5471 rls_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord);
5472 rls_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt);
5473 mempool_free(pmb, phba->mbox_mem_pool);
5474
5475 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
5476 "2874 Xmit ELS RLS ACC response tag x%x xri x%x, "
5477 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
5478 elsiocb->iotag, elsiocb->iocb.ulpContext,
5479 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
5480 ndlp->nlp_rpi);
5481 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
5482 phba->fc_stat.elsXmitACC++;
5483 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
5484 lpfc_els_free_iocb(phba, elsiocb);
5485}
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506static void
5507lpfc_els_rsp_rps_acc(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
5508{
5509 MAILBOX_t *mb;
5510 IOCB_t *icmd;
5511 RPS_RSP *rps_rsp;
5512 uint8_t *pcmd;
5513 struct lpfc_iocbq *elsiocb;
5514 struct lpfc_nodelist *ndlp;
5515 uint16_t status;
5516 uint16_t oxid;
5517 uint16_t rxid;
5518 uint32_t cmdsize;
5519
5520 mb = &pmb->u.mb;
5521
5522 ndlp = (struct lpfc_nodelist *) pmb->context2;
5523 rxid = (uint16_t) ((unsigned long)(pmb->context1) & 0xffff);
5524 oxid = (uint16_t) (((unsigned long)(pmb->context1) >> 16) & 0xffff);
5525 pmb->context1 = NULL;
5526 pmb->context2 = NULL;
5527
5528 if (mb->mbxStatus) {
5529 mempool_free(pmb, phba->mbox_mem_pool);
5530 return;
5531 }
5532
5533 cmdsize = sizeof(RPS_RSP) + sizeof(uint32_t);
5534 mempool_free(pmb, phba->mbox_mem_pool);
5535 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
5536 lpfc_max_els_tries, ndlp,
5537 ndlp->nlp_DID, ELS_CMD_ACC);
5538
5539
5540 lpfc_nlp_put(ndlp);
5541
5542 if (!elsiocb)
5543 return;
5544
5545 icmd = &elsiocb->iocb;
5546 icmd->ulpContext = rxid;
5547 icmd->unsli3.rcvsli3.ox_id = oxid;
5548
5549 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
5550 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
5551 pcmd += sizeof(uint32_t);
5552 rps_rsp = (RPS_RSP *)pcmd;
5553
5554 if (phba->fc_topology != LPFC_TOPOLOGY_LOOP)
5555 status = 0x10;
5556 else
5557 status = 0x8;
5558 if (phba->pport->fc_flag & FC_FABRIC)
5559 status |= 0x4;
5560
5561 rps_rsp->rsvd1 = 0;
5562 rps_rsp->portStatus = cpu_to_be16(status);
5563 rps_rsp->linkFailureCnt = cpu_to_be32(mb->un.varRdLnk.linkFailureCnt);
5564 rps_rsp->lossSyncCnt = cpu_to_be32(mb->un.varRdLnk.lossSyncCnt);
5565 rps_rsp->lossSignalCnt = cpu_to_be32(mb->un.varRdLnk.lossSignalCnt);
5566 rps_rsp->primSeqErrCnt = cpu_to_be32(mb->un.varRdLnk.primSeqErrCnt);
5567 rps_rsp->invalidXmitWord = cpu_to_be32(mb->un.varRdLnk.invalidXmitWord);
5568 rps_rsp->crcCnt = cpu_to_be32(mb->un.varRdLnk.crcCnt);
5569
5570 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
5571 "0118 Xmit ELS RPS ACC response tag x%x xri x%x, "
5572 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x\n",
5573 elsiocb->iotag, elsiocb->iocb.ulpContext,
5574 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
5575 ndlp->nlp_rpi);
5576 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
5577 phba->fc_stat.elsXmitACC++;
5578 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
5579 lpfc_els_free_iocb(phba, elsiocb);
5580 return;
5581}
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601static int
5602lpfc_els_rcv_rls(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5603 struct lpfc_nodelist *ndlp)
5604{
5605 struct lpfc_hba *phba = vport->phba;
5606 LPFC_MBOXQ_t *mbox;
5607 struct lpfc_dmabuf *pcmd;
5608 struct ls_rjt stat;
5609
5610 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
5611 (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
5612
5613 goto reject_out;
5614
5615 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
5616
5617 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
5618 if (mbox) {
5619 lpfc_read_lnk_stat(phba, mbox);
5620 mbox->context1 = (void *)((unsigned long)
5621 ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) |
5622 cmdiocb->iocb.ulpContext));
5623 mbox->context2 = lpfc_nlp_get(ndlp);
5624 mbox->vport = vport;
5625 mbox->mbox_cmpl = lpfc_els_rsp_rls_acc;
5626 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
5627 != MBX_NOT_FINISHED)
5628
5629 return 0;
5630
5631
5632
5633 lpfc_nlp_put(ndlp);
5634 mempool_free(mbox, phba->mbox_mem_pool);
5635 }
5636reject_out:
5637
5638 stat.un.b.lsRjtRsvd0 = 0;
5639 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
5640 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
5641 stat.un.b.vendorUnique = 0;
5642 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
5643 return 0;
5644}
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667static int
5668lpfc_els_rcv_rtv(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5669 struct lpfc_nodelist *ndlp)
5670{
5671 struct lpfc_hba *phba = vport->phba;
5672 struct ls_rjt stat;
5673 struct RTV_RSP *rtv_rsp;
5674 uint8_t *pcmd;
5675 struct lpfc_iocbq *elsiocb;
5676 uint32_t cmdsize;
5677
5678
5679 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
5680 (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
5681
5682 goto reject_out;
5683
5684 cmdsize = sizeof(struct RTV_RSP) + sizeof(uint32_t);
5685 elsiocb = lpfc_prep_els_iocb(phba->pport, 0, cmdsize,
5686 lpfc_max_els_tries, ndlp,
5687 ndlp->nlp_DID, ELS_CMD_ACC);
5688
5689 if (!elsiocb)
5690 return 1;
5691
5692 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
5693 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
5694 pcmd += sizeof(uint32_t);
5695
5696
5697 elsiocb->iocb.ulpContext = cmdiocb->iocb.ulpContext;
5698 elsiocb->iocb.unsli3.rcvsli3.ox_id = cmdiocb->iocb.unsli3.rcvsli3.ox_id;
5699
5700 rtv_rsp = (struct RTV_RSP *)pcmd;
5701
5702
5703 rtv_rsp->ratov = cpu_to_be32(phba->fc_ratov * 1000);
5704 rtv_rsp->edtov = cpu_to_be32(phba->fc_edtov);
5705 bf_set(qtov_edtovres, rtv_rsp, phba->fc_edtovResol ? 1 : 0);
5706 bf_set(qtov_rttov, rtv_rsp, 0);
5707 rtv_rsp->qtov = cpu_to_be32(rtv_rsp->qtov);
5708
5709
5710 lpfc_printf_vlog(ndlp->vport, KERN_INFO, LOG_ELS,
5711 "2875 Xmit ELS RTV ACC response tag x%x xri x%x, "
5712 "did x%x, nlp_flag x%x, nlp_state x%x, rpi x%x, "
5713 "Data: x%x x%x x%x\n",
5714 elsiocb->iotag, elsiocb->iocb.ulpContext,
5715 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
5716 ndlp->nlp_rpi,
5717 rtv_rsp->ratov, rtv_rsp->edtov, rtv_rsp->qtov);
5718 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
5719 phba->fc_stat.elsXmitACC++;
5720 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) == IOCB_ERROR)
5721 lpfc_els_free_iocb(phba, elsiocb);
5722 return 0;
5723
5724reject_out:
5725
5726 stat.un.b.lsRjtRsvd0 = 0;
5727 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
5728 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
5729 stat.un.b.vendorUnique = 0;
5730 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
5731 return 0;
5732}
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751static int
5752lpfc_els_rcv_rps(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5753 struct lpfc_nodelist *ndlp)
5754{
5755 struct lpfc_hba *phba = vport->phba;
5756 uint32_t *lp;
5757 uint8_t flag;
5758 LPFC_MBOXQ_t *mbox;
5759 struct lpfc_dmabuf *pcmd;
5760 RPS *rps;
5761 struct ls_rjt stat;
5762
5763 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
5764 (ndlp->nlp_state != NLP_STE_MAPPED_NODE))
5765
5766 goto reject_out;
5767
5768 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
5769 lp = (uint32_t *) pcmd->virt;
5770 flag = (be32_to_cpu(*lp++) & 0xf);
5771 rps = (RPS *) lp;
5772
5773 if ((flag == 0) ||
5774 ((flag == 1) && (be32_to_cpu(rps->un.portNum) == 0)) ||
5775 ((flag == 2) && (memcmp(&rps->un.portName, &vport->fc_portname,
5776 sizeof(struct lpfc_name)) == 0))) {
5777
5778 printk("Fix me....\n");
5779 dump_stack();
5780 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_ATOMIC);
5781 if (mbox) {
5782 lpfc_read_lnk_stat(phba, mbox);
5783 mbox->context1 = (void *)((unsigned long)
5784 ((cmdiocb->iocb.unsli3.rcvsli3.ox_id << 16) |
5785 cmdiocb->iocb.ulpContext));
5786 mbox->context2 = lpfc_nlp_get(ndlp);
5787 mbox->vport = vport;
5788 mbox->mbox_cmpl = lpfc_els_rsp_rps_acc;
5789 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
5790 != MBX_NOT_FINISHED)
5791
5792 return 0;
5793
5794
5795
5796 lpfc_nlp_put(ndlp);
5797 mempool_free(mbox, phba->mbox_mem_pool);
5798 }
5799 }
5800
5801reject_out:
5802
5803 stat.un.b.lsRjtRsvd0 = 0;
5804 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
5805 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
5806 stat.un.b.vendorUnique = 0;
5807 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp, NULL);
5808 return 0;
5809}
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824static int
5825lpfc_issue_els_rrq(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
5826 uint32_t did, struct lpfc_node_rrq *rrq)
5827{
5828 struct lpfc_hba *phba = vport->phba;
5829 struct RRQ *els_rrq;
5830 IOCB_t *icmd;
5831 struct lpfc_iocbq *elsiocb;
5832 uint8_t *pcmd;
5833 uint16_t cmdsize;
5834 int ret;
5835
5836
5837 if (ndlp != rrq->ndlp)
5838 ndlp = rrq->ndlp;
5839 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
5840 return 1;
5841
5842
5843 cmdsize = (sizeof(uint32_t) + sizeof(struct RRQ));
5844 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, 0, ndlp, did,
5845 ELS_CMD_RRQ);
5846 if (!elsiocb)
5847 return 1;
5848
5849 icmd = &elsiocb->iocb;
5850 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
5851
5852
5853 *((uint32_t *) (pcmd)) = ELS_CMD_RRQ;
5854 pcmd += sizeof(uint32_t);
5855 els_rrq = (struct RRQ *) pcmd;
5856
5857 bf_set(rrq_oxid, els_rrq, phba->sli4_hba.xri_ids[rrq->xritag]);
5858 bf_set(rrq_rxid, els_rrq, rrq->rxid);
5859 bf_set(rrq_did, els_rrq, vport->fc_myDID);
5860 els_rrq->rrq = cpu_to_be32(els_rrq->rrq);
5861 els_rrq->rrq_exchg = cpu_to_be32(els_rrq->rrq_exchg);
5862
5863
5864 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
5865 "Issue RRQ: did:x%x",
5866 did, rrq->xritag, rrq->rxid);
5867 elsiocb->context_un.rrq = rrq;
5868 elsiocb->iocb_cmpl = lpfc_cmpl_els_rrq;
5869 ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0);
5870
5871 if (ret == IOCB_ERROR) {
5872 lpfc_els_free_iocb(phba, elsiocb);
5873 return 1;
5874 }
5875 return 0;
5876}
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890int
5891lpfc_send_rrq(struct lpfc_hba *phba, struct lpfc_node_rrq *rrq)
5892{
5893 struct lpfc_nodelist *ndlp = lpfc_findnode_did(rrq->vport,
5894 rrq->nlp_DID);
5895 if (lpfc_test_rrq_active(phba, ndlp, rrq->xritag))
5896 return lpfc_issue_els_rrq(rrq->vport, ndlp,
5897 rrq->nlp_DID, rrq);
5898 else
5899 return 1;
5900}
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921static int
5922lpfc_els_rsp_rpl_acc(struct lpfc_vport *vport, uint16_t cmdsize,
5923 struct lpfc_iocbq *oldiocb, struct lpfc_nodelist *ndlp)
5924{
5925 struct lpfc_hba *phba = vport->phba;
5926 IOCB_t *icmd, *oldcmd;
5927 RPL_RSP rpl_rsp;
5928 struct lpfc_iocbq *elsiocb;
5929 uint8_t *pcmd;
5930
5931 elsiocb = lpfc_prep_els_iocb(vport, 0, cmdsize, oldiocb->retry, ndlp,
5932 ndlp->nlp_DID, ELS_CMD_ACC);
5933
5934 if (!elsiocb)
5935 return 1;
5936
5937 icmd = &elsiocb->iocb;
5938 oldcmd = &oldiocb->iocb;
5939 icmd->ulpContext = oldcmd->ulpContext;
5940 icmd->unsli3.rcvsli3.ox_id = oldcmd->unsli3.rcvsli3.ox_id;
5941
5942 pcmd = (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
5943 *((uint32_t *) (pcmd)) = ELS_CMD_ACC;
5944 pcmd += sizeof(uint16_t);
5945 *((uint16_t *)(pcmd)) = be16_to_cpu(cmdsize);
5946 pcmd += sizeof(uint16_t);
5947
5948
5949 rpl_rsp.listLen = be32_to_cpu(1);
5950 rpl_rsp.index = 0;
5951 rpl_rsp.port_num_blk.portNum = 0;
5952 rpl_rsp.port_num_blk.portID = be32_to_cpu(vport->fc_myDID);
5953 memcpy(&rpl_rsp.port_num_blk.portName, &vport->fc_portname,
5954 sizeof(struct lpfc_name));
5955 memcpy(pcmd, &rpl_rsp, cmdsize - sizeof(uint32_t));
5956
5957 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
5958 "0120 Xmit ELS RPL ACC response tag x%x "
5959 "xri x%x, did x%x, nlp_flag x%x, nlp_state x%x, "
5960 "rpi x%x\n",
5961 elsiocb->iotag, elsiocb->iocb.ulpContext,
5962 ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state,
5963 ndlp->nlp_rpi);
5964 elsiocb->iocb_cmpl = lpfc_cmpl_els_rsp;
5965 phba->fc_stat.elsXmitACC++;
5966 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
5967 IOCB_ERROR) {
5968 lpfc_els_free_iocb(phba, elsiocb);
5969 return 1;
5970 }
5971 return 0;
5972}
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990static int
5991lpfc_els_rcv_rpl(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
5992 struct lpfc_nodelist *ndlp)
5993{
5994 struct lpfc_dmabuf *pcmd;
5995 uint32_t *lp;
5996 uint32_t maxsize;
5997 uint16_t cmdsize;
5998 RPL *rpl;
5999 struct ls_rjt stat;
6000
6001 if ((ndlp->nlp_state != NLP_STE_UNMAPPED_NODE) &&
6002 (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
6003
6004 stat.un.b.lsRjtRsvd0 = 0;
6005 stat.un.b.lsRjtRsnCode = LSRJT_UNABLE_TPC;
6006 stat.un.b.lsRjtRsnCodeExp = LSEXP_CANT_GIVE_DATA;
6007 stat.un.b.vendorUnique = 0;
6008 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, cmdiocb, ndlp,
6009 NULL);
6010
6011 return 0;
6012 }
6013
6014 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
6015 lp = (uint32_t *) pcmd->virt;
6016 rpl = (RPL *) (lp + 1);
6017 maxsize = be32_to_cpu(rpl->maxsize);
6018
6019
6020 if ((rpl->index == 0) &&
6021 ((maxsize == 0) ||
6022 ((maxsize * sizeof(uint32_t)) >= sizeof(RPL_RSP)))) {
6023 cmdsize = sizeof(uint32_t) + sizeof(RPL_RSP);
6024 } else {
6025 cmdsize = sizeof(uint32_t) + maxsize * sizeof(uint32_t);
6026 }
6027 lpfc_els_rsp_rpl_acc(vport, cmdsize, cmdiocb, ndlp);
6028
6029 return 0;
6030}
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056static int
6057lpfc_els_rcv_farp(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
6058 struct lpfc_nodelist *ndlp)
6059{
6060 struct lpfc_dmabuf *pcmd;
6061 uint32_t *lp;
6062 IOCB_t *icmd;
6063 FARP *fp;
6064 uint32_t cmd, cnt, did;
6065
6066 icmd = &cmdiocb->iocb;
6067 did = icmd->un.elsreq64.remoteID;
6068 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
6069 lp = (uint32_t *) pcmd->virt;
6070
6071 cmd = *lp++;
6072 fp = (FARP *) lp;
6073
6074 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
6075 "0601 FARP-REQ received from DID x%x\n", did);
6076
6077 if (fp->Mflags & ~(FARP_MATCH_NODE | FARP_MATCH_PORT)) {
6078 return 0;
6079 }
6080
6081 cnt = 0;
6082
6083 if (fp->Mflags & FARP_MATCH_PORT) {
6084 if (memcmp(&fp->RportName, &vport->fc_portname,
6085 sizeof(struct lpfc_name)) == 0)
6086 cnt = 1;
6087 }
6088
6089
6090 if (fp->Mflags & FARP_MATCH_NODE) {
6091 if (memcmp(&fp->RnodeName, &vport->fc_nodename,
6092 sizeof(struct lpfc_name)) == 0)
6093 cnt = 1;
6094 }
6095
6096 if (cnt) {
6097 if ((ndlp->nlp_state == NLP_STE_UNMAPPED_NODE) ||
6098 (ndlp->nlp_state == NLP_STE_MAPPED_NODE)) {
6099
6100 if (fp->Rflags & FARP_REQUEST_PLOGI) {
6101 ndlp->nlp_prev_state = ndlp->nlp_state;
6102 lpfc_nlp_set_state(vport, ndlp,
6103 NLP_STE_PLOGI_ISSUE);
6104 lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0);
6105 }
6106
6107
6108 if (fp->Rflags & FARP_REQUEST_FARPR)
6109 lpfc_issue_els_farpr(vport, did, 0);
6110 }
6111 }
6112 return 0;
6113}
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129static int
6130lpfc_els_rcv_farpr(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
6131 struct lpfc_nodelist *ndlp)
6132{
6133 struct lpfc_dmabuf *pcmd;
6134 uint32_t *lp;
6135 IOCB_t *icmd;
6136 uint32_t cmd, did;
6137
6138 icmd = &cmdiocb->iocb;
6139 did = icmd->un.elsreq64.remoteID;
6140 pcmd = (struct lpfc_dmabuf *) cmdiocb->context2;
6141 lp = (uint32_t *) pcmd->virt;
6142
6143 cmd = *lp++;
6144
6145 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
6146 "0600 FARP-RSP received from DID x%x\n", did);
6147
6148 lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
6149
6150 return 0;
6151}
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172static int
6173lpfc_els_rcv_fan(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
6174 struct lpfc_nodelist *fan_ndlp)
6175{
6176 struct lpfc_hba *phba = vport->phba;
6177 uint32_t *lp;
6178 FAN *fp;
6179
6180 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0265 FAN received\n");
6181 lp = (uint32_t *)((struct lpfc_dmabuf *)cmdiocb->context2)->virt;
6182 fp = (FAN *) ++lp;
6183
6184 if ((vport == phba->pport) &&
6185 (vport->port_state == LPFC_LOCAL_CFG_LINK)) {
6186 if ((memcmp(&phba->fc_fabparam.nodeName, &fp->FnodeName,
6187 sizeof(struct lpfc_name))) ||
6188 (memcmp(&phba->fc_fabparam.portName, &fp->FportName,
6189 sizeof(struct lpfc_name)))) {
6190
6191 lpfc_issue_init_vfi(vport);
6192 } else {
6193
6194 vport->fc_myDID = vport->fc_prevDID;
6195 if (phba->sli_rev < LPFC_SLI_REV4)
6196 lpfc_issue_fabric_reglogin(vport);
6197 else {
6198 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
6199 "3138 Need register VFI: (x%x/%x)\n",
6200 vport->fc_prevDID, vport->fc_myDID);
6201 lpfc_issue_reg_vfi(vport);
6202 }
6203 }
6204 }
6205 return 0;
6206}
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218void
6219lpfc_els_timeout(unsigned long ptr)
6220{
6221 struct lpfc_vport *vport = (struct lpfc_vport *) ptr;
6222 struct lpfc_hba *phba = vport->phba;
6223 uint32_t tmo_posted;
6224 unsigned long iflag;
6225
6226 spin_lock_irqsave(&vport->work_port_lock, iflag);
6227 tmo_posted = vport->work_port_events & WORKER_ELS_TMO;
6228 if ((!tmo_posted) && (!(vport->load_flag & FC_UNLOADING)))
6229 vport->work_port_events |= WORKER_ELS_TMO;
6230 spin_unlock_irqrestore(&vport->work_port_lock, iflag);
6231
6232 if ((!tmo_posted) && (!(vport->load_flag & FC_UNLOADING)))
6233 lpfc_worker_wake_up(phba);
6234 return;
6235}
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247void
6248lpfc_els_timeout_handler(struct lpfc_vport *vport)
6249{
6250 struct lpfc_hba *phba = vport->phba;
6251 struct lpfc_sli_ring *pring;
6252 struct lpfc_iocbq *tmp_iocb, *piocb;
6253 IOCB_t *cmd = NULL;
6254 struct lpfc_dmabuf *pcmd;
6255 uint32_t els_command = 0;
6256 uint32_t timeout;
6257 uint32_t remote_ID = 0xffffffff;
6258 LIST_HEAD(abort_list);
6259
6260
6261 timeout = (uint32_t)(phba->fc_ratov << 1);
6262
6263 pring = &phba->sli.ring[LPFC_ELS_RING];
6264 if ((phba->pport->load_flag & FC_UNLOADING))
6265 return;
6266 spin_lock_irq(&phba->hbalock);
6267 if (phba->sli_rev == LPFC_SLI_REV4)
6268 spin_lock(&pring->ring_lock);
6269
6270 if ((phba->pport->load_flag & FC_UNLOADING)) {
6271 if (phba->sli_rev == LPFC_SLI_REV4)
6272 spin_unlock(&pring->ring_lock);
6273 spin_unlock_irq(&phba->hbalock);
6274 return;
6275 }
6276
6277 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
6278 cmd = &piocb->iocb;
6279
6280 if ((piocb->iocb_flag & LPFC_IO_LIBDFC) != 0 ||
6281 piocb->iocb.ulpCommand == CMD_ABORT_XRI_CN ||
6282 piocb->iocb.ulpCommand == CMD_CLOSE_XRI_CN)
6283 continue;
6284
6285 if (piocb->vport != vport)
6286 continue;
6287
6288 pcmd = (struct lpfc_dmabuf *) piocb->context2;
6289 if (pcmd)
6290 els_command = *(uint32_t *) (pcmd->virt);
6291
6292 if (els_command == ELS_CMD_FARP ||
6293 els_command == ELS_CMD_FARPR ||
6294 els_command == ELS_CMD_FDISC)
6295 continue;
6296
6297 if (piocb->drvrTimeout > 0) {
6298 if (piocb->drvrTimeout >= timeout)
6299 piocb->drvrTimeout -= timeout;
6300 else
6301 piocb->drvrTimeout = 0;
6302 continue;
6303 }
6304
6305 remote_ID = 0xffffffff;
6306 if (cmd->ulpCommand != CMD_GEN_REQUEST64_CR)
6307 remote_ID = cmd->un.elsreq64.remoteID;
6308 else {
6309 struct lpfc_nodelist *ndlp;
6310 ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext);
6311 if (ndlp && NLP_CHK_NODE_ACT(ndlp))
6312 remote_ID = ndlp->nlp_DID;
6313 }
6314 list_add_tail(&piocb->dlist, &abort_list);
6315 }
6316 if (phba->sli_rev == LPFC_SLI_REV4)
6317 spin_unlock(&pring->ring_lock);
6318 spin_unlock_irq(&phba->hbalock);
6319
6320 list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) {
6321 cmd = &piocb->iocb;
6322 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
6323 "0127 ELS timeout Data: x%x x%x x%x "
6324 "x%x\n", els_command,
6325 remote_ID, cmd->ulpCommand, cmd->ulpIoTag);
6326 spin_lock_irq(&phba->hbalock);
6327 list_del_init(&piocb->dlist);
6328 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
6329 spin_unlock_irq(&phba->hbalock);
6330 }
6331
6332 if (!list_empty(&phba->sli.ring[LPFC_ELS_RING].txcmplq))
6333 if (!(phba->pport->load_flag & FC_UNLOADING))
6334 mod_timer(&vport->els_tmofunc,
6335 jiffies + msecs_to_jiffies(1000 * timeout));
6336}
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358void
6359lpfc_els_flush_cmd(struct lpfc_vport *vport)
6360{
6361 LIST_HEAD(abort_list);
6362 struct lpfc_hba *phba = vport->phba;
6363 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
6364 struct lpfc_iocbq *tmp_iocb, *piocb;
6365 IOCB_t *cmd = NULL;
6366
6367 lpfc_fabric_abort_vport(vport);
6368
6369
6370
6371
6372
6373
6374 spin_lock_irq(&phba->hbalock);
6375 if (phba->sli_rev == LPFC_SLI_REV4)
6376 spin_lock(&pring->ring_lock);
6377
6378 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txcmplq, list) {
6379 if (piocb->iocb_flag & LPFC_IO_LIBDFC)
6380 continue;
6381
6382 if (piocb->vport != vport)
6383 continue;
6384 list_add_tail(&piocb->dlist, &abort_list);
6385 }
6386 if (phba->sli_rev == LPFC_SLI_REV4)
6387 spin_unlock(&pring->ring_lock);
6388 spin_unlock_irq(&phba->hbalock);
6389
6390 list_for_each_entry_safe(piocb, tmp_iocb, &abort_list, dlist) {
6391 spin_lock_irq(&phba->hbalock);
6392 list_del_init(&piocb->dlist);
6393 lpfc_sli_issue_abort_iotag(phba, pring, piocb);
6394 spin_unlock_irq(&phba->hbalock);
6395 }
6396 if (!list_empty(&abort_list))
6397 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
6398 "3387 abort list for txq not empty\n");
6399 INIT_LIST_HEAD(&abort_list);
6400
6401 spin_lock_irq(&phba->hbalock);
6402 if (phba->sli_rev == LPFC_SLI_REV4)
6403 spin_lock(&pring->ring_lock);
6404
6405 list_for_each_entry_safe(piocb, tmp_iocb, &pring->txq, list) {
6406 cmd = &piocb->iocb;
6407
6408 if (piocb->iocb_flag & LPFC_IO_LIBDFC) {
6409 continue;
6410 }
6411
6412
6413 if (cmd->ulpCommand == CMD_QUE_RING_BUF_CN ||
6414 cmd->ulpCommand == CMD_QUE_RING_BUF64_CN ||
6415 cmd->ulpCommand == CMD_CLOSE_XRI_CN ||
6416 cmd->ulpCommand == CMD_ABORT_XRI_CN)
6417 continue;
6418
6419 if (piocb->vport != vport)
6420 continue;
6421
6422 list_del_init(&piocb->list);
6423 list_add_tail(&piocb->list, &abort_list);
6424 }
6425 if (phba->sli_rev == LPFC_SLI_REV4)
6426 spin_unlock(&pring->ring_lock);
6427 spin_unlock_irq(&phba->hbalock);
6428
6429
6430 lpfc_sli_cancel_iocbs(phba, &abort_list,
6431 IOSTAT_LOCAL_REJECT, IOERR_SLI_ABORTED);
6432
6433 return;
6434}
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453void
6454lpfc_els_flush_all_cmd(struct lpfc_hba *phba)
6455{
6456 struct lpfc_vport *vport;
6457 list_for_each_entry(vport, &phba->port_list, listentry)
6458 lpfc_els_flush_cmd(vport);
6459
6460 return;
6461}
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472void
6473lpfc_send_els_failure_event(struct lpfc_hba *phba,
6474 struct lpfc_iocbq *cmdiocbp,
6475 struct lpfc_iocbq *rspiocbp)
6476{
6477 struct lpfc_vport *vport = cmdiocbp->vport;
6478 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
6479 struct lpfc_lsrjt_event lsrjt_event;
6480 struct lpfc_fabric_event_header fabric_event;
6481 struct ls_rjt stat;
6482 struct lpfc_nodelist *ndlp;
6483 uint32_t *pcmd;
6484
6485 ndlp = cmdiocbp->context1;
6486 if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
6487 return;
6488
6489 if (rspiocbp->iocb.ulpStatus == IOSTAT_LS_RJT) {
6490 lsrjt_event.header.event_type = FC_REG_ELS_EVENT;
6491 lsrjt_event.header.subcategory = LPFC_EVENT_LSRJT_RCV;
6492 memcpy(lsrjt_event.header.wwpn, &ndlp->nlp_portname,
6493 sizeof(struct lpfc_name));
6494 memcpy(lsrjt_event.header.wwnn, &ndlp->nlp_nodename,
6495 sizeof(struct lpfc_name));
6496 pcmd = (uint32_t *) (((struct lpfc_dmabuf *)
6497 cmdiocbp->context2)->virt);
6498 lsrjt_event.command = (pcmd != NULL) ? *pcmd : 0;
6499 stat.un.lsRjtError = be32_to_cpu(rspiocbp->iocb.un.ulpWord[4]);
6500 lsrjt_event.reason_code = stat.un.b.lsRjtRsnCode;
6501 lsrjt_event.explanation = stat.un.b.lsRjtRsnCodeExp;
6502 fc_host_post_vendor_event(shost,
6503 fc_get_event_number(),
6504 sizeof(lsrjt_event),
6505 (char *)&lsrjt_event,
6506 LPFC_NL_VENDOR_ID);
6507 return;
6508 }
6509 if ((rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY) ||
6510 (rspiocbp->iocb.ulpStatus == IOSTAT_FABRIC_BSY)) {
6511 fabric_event.event_type = FC_REG_FABRIC_EVENT;
6512 if (rspiocbp->iocb.ulpStatus == IOSTAT_NPORT_BSY)
6513 fabric_event.subcategory = LPFC_EVENT_PORT_BUSY;
6514 else
6515 fabric_event.subcategory = LPFC_EVENT_FABRIC_BUSY;
6516 memcpy(fabric_event.wwpn, &ndlp->nlp_portname,
6517 sizeof(struct lpfc_name));
6518 memcpy(fabric_event.wwnn, &ndlp->nlp_nodename,
6519 sizeof(struct lpfc_name));
6520 fc_host_post_vendor_event(shost,
6521 fc_get_event_number(),
6522 sizeof(fabric_event),
6523 (char *)&fabric_event,
6524 LPFC_NL_VENDOR_ID);
6525 return;
6526 }
6527
6528}
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539static void
6540lpfc_send_els_event(struct lpfc_vport *vport,
6541 struct lpfc_nodelist *ndlp,
6542 uint32_t *payload)
6543{
6544 struct lpfc_els_event_header *els_data = NULL;
6545 struct lpfc_logo_event *logo_data = NULL;
6546 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
6547
6548 if (*payload == ELS_CMD_LOGO) {
6549 logo_data = kmalloc(sizeof(struct lpfc_logo_event), GFP_KERNEL);
6550 if (!logo_data) {
6551 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
6552 "0148 Failed to allocate memory "
6553 "for LOGO event\n");
6554 return;
6555 }
6556 els_data = &logo_data->header;
6557 } else {
6558 els_data = kmalloc(sizeof(struct lpfc_els_event_header),
6559 GFP_KERNEL);
6560 if (!els_data) {
6561 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
6562 "0149 Failed to allocate memory "
6563 "for ELS event\n");
6564 return;
6565 }
6566 }
6567 els_data->event_type = FC_REG_ELS_EVENT;
6568 switch (*payload) {
6569 case ELS_CMD_PLOGI:
6570 els_data->subcategory = LPFC_EVENT_PLOGI_RCV;
6571 break;
6572 case ELS_CMD_PRLO:
6573 els_data->subcategory = LPFC_EVENT_PRLO_RCV;
6574 break;
6575 case ELS_CMD_ADISC:
6576 els_data->subcategory = LPFC_EVENT_ADISC_RCV;
6577 break;
6578 case ELS_CMD_LOGO:
6579 els_data->subcategory = LPFC_EVENT_LOGO_RCV;
6580
6581 memcpy(logo_data->logo_wwpn, &payload[2],
6582 sizeof(struct lpfc_name));
6583 break;
6584 default:
6585 kfree(els_data);
6586 return;
6587 }
6588 memcpy(els_data->wwpn, &ndlp->nlp_portname, sizeof(struct lpfc_name));
6589 memcpy(els_data->wwnn, &ndlp->nlp_nodename, sizeof(struct lpfc_name));
6590 if (*payload == ELS_CMD_LOGO) {
6591 fc_host_post_vendor_event(shost,
6592 fc_get_event_number(),
6593 sizeof(struct lpfc_logo_event),
6594 (char *)logo_data,
6595 LPFC_NL_VENDOR_ID);
6596 kfree(logo_data);
6597 } else {
6598 fc_host_post_vendor_event(shost,
6599 fc_get_event_number(),
6600 sizeof(struct lpfc_els_event_header),
6601 (char *)els_data,
6602 LPFC_NL_VENDOR_ID);
6603 kfree(els_data);
6604 }
6605
6606 return;
6607}
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624static void
6625lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
6626 struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb)
6627{
6628 struct Scsi_Host *shost;
6629 struct lpfc_nodelist *ndlp;
6630 struct ls_rjt stat;
6631 uint32_t *payload;
6632 uint32_t cmd, did, newnode;
6633 uint8_t rjt_exp, rjt_err = 0;
6634 IOCB_t *icmd = &elsiocb->iocb;
6635
6636 if (!vport || !(elsiocb->context2))
6637 goto dropit;
6638
6639 newnode = 0;
6640 payload = ((struct lpfc_dmabuf *)elsiocb->context2)->virt;
6641 cmd = *payload;
6642 if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) == 0)
6643 lpfc_post_buffer(phba, pring, 1);
6644
6645 did = icmd->un.rcvels.remoteID;
6646 if (icmd->ulpStatus) {
6647 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6648 "RCV Unsol ELS: status:x%x/x%x did:x%x",
6649 icmd->ulpStatus, icmd->un.ulpWord[4], did);
6650 goto dropit;
6651 }
6652
6653
6654 if (lpfc_els_chk_latt(vport))
6655 goto dropit;
6656
6657
6658 if (vport->load_flag & FC_UNLOADING)
6659 goto dropit;
6660
6661
6662 if ((vport->fc_flag & FC_DISC_DELAYED) &&
6663 (cmd != ELS_CMD_PLOGI))
6664 goto dropit;
6665
6666 ndlp = lpfc_findnode_did(vport, did);
6667 if (!ndlp) {
6668
6669 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
6670 if (!ndlp)
6671 goto dropit;
6672
6673 lpfc_nlp_init(vport, ndlp, did);
6674 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
6675 newnode = 1;
6676 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
6677 ndlp->nlp_type |= NLP_FABRIC;
6678 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
6679 ndlp = lpfc_enable_node(vport, ndlp,
6680 NLP_STE_UNUSED_NODE);
6681 if (!ndlp)
6682 goto dropit;
6683 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
6684 newnode = 1;
6685 if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
6686 ndlp->nlp_type |= NLP_FABRIC;
6687 } else if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
6688
6689 ndlp = lpfc_nlp_get(ndlp);
6690 if (!ndlp)
6691 goto dropit;
6692 lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
6693 newnode = 1;
6694 }
6695
6696 phba->fc_stat.elsRcvFrame++;
6697
6698
6699
6700
6701
6702 if (ndlp->nlp_add_flag & NLP_IN_DEV_LOSS)
6703 goto dropit;
6704
6705 elsiocb->context1 = lpfc_nlp_get(ndlp);
6706 elsiocb->vport = vport;
6707
6708 if ((cmd & ELS_CMD_MASK) == ELS_CMD_RSCN) {
6709 cmd &= ELS_CMD_MASK;
6710 }
6711
6712 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
6713 "0112 ELS command x%x received from NPORT x%x "
6714 "Data: x%x x%x x%x x%x\n",
6715 cmd, did, vport->port_state, vport->fc_flag,
6716 vport->fc_myDID, vport->fc_prevDID);
6717 switch (cmd) {
6718 case ELS_CMD_PLOGI:
6719 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6720 "RCV PLOGI: did:x%x/ste:x%x flg:x%x",
6721 did, vport->port_state, ndlp->nlp_flag);
6722
6723 phba->fc_stat.elsRcvPLOGI++;
6724 ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp);
6725 if (phba->sli_rev == LPFC_SLI_REV4 &&
6726 (phba->pport->fc_flag & FC_PT2PT)) {
6727 vport->fc_prevDID = vport->fc_myDID;
6728
6729
6730
6731
6732 vport->fc_myDID = elsiocb->iocb.un.rcvels.parmRo;
6733 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
6734 "3312 Remote port assigned DID x%x "
6735 "%x\n", vport->fc_myDID,
6736 vport->fc_prevDID);
6737 }
6738
6739 lpfc_send_els_event(vport, ndlp, payload);
6740
6741
6742 if (vport->fc_flag & FC_DISC_DELAYED) {
6743 rjt_err = LSRJT_UNABLE_TPC;
6744 rjt_exp = LSEXP_NOTHING_MORE;
6745 break;
6746 }
6747 shost = lpfc_shost_from_vport(vport);
6748 if (vport->port_state < LPFC_DISC_AUTH) {
6749 if (!(phba->pport->fc_flag & FC_PT2PT) ||
6750 (phba->pport->fc_flag & FC_PT2PT_PLOGI)) {
6751 rjt_err = LSRJT_UNABLE_TPC;
6752 rjt_exp = LSEXP_NOTHING_MORE;
6753 break;
6754 }
6755
6756
6757
6758
6759 if (phba->sli_rev == LPFC_SLI_REV4 &&
6760 (phba->fc_topology_changed ||
6761 vport->fc_myDID != vport->fc_prevDID)) {
6762 lpfc_unregister_fcf_prep(phba);
6763 spin_lock_irq(shost->host_lock);
6764 vport->fc_flag &= ~FC_VFI_REGISTERED;
6765 spin_unlock_irq(shost->host_lock);
6766 phba->fc_topology_changed = 0;
6767 lpfc_issue_reg_vfi(vport);
6768 }
6769 }
6770
6771 spin_lock_irq(shost->host_lock);
6772 ndlp->nlp_flag &= ~NLP_TARGET_REMOVE;
6773 spin_unlock_irq(shost->host_lock);
6774
6775 lpfc_disc_state_machine(vport, ndlp, elsiocb,
6776 NLP_EVT_RCV_PLOGI);
6777
6778 break;
6779 case ELS_CMD_FLOGI:
6780 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6781 "RCV FLOGI: did:x%x/ste:x%x flg:x%x",
6782 did, vport->port_state, ndlp->nlp_flag);
6783
6784 phba->fc_stat.elsRcvFLOGI++;
6785 lpfc_els_rcv_flogi(vport, elsiocb, ndlp);
6786 if (newnode)
6787 lpfc_nlp_put(ndlp);
6788 break;
6789 case ELS_CMD_LOGO:
6790 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6791 "RCV LOGO: did:x%x/ste:x%x flg:x%x",
6792 did, vport->port_state, ndlp->nlp_flag);
6793
6794 phba->fc_stat.elsRcvLOGO++;
6795 lpfc_send_els_event(vport, ndlp, payload);
6796 if (vport->port_state < LPFC_DISC_AUTH) {
6797 rjt_err = LSRJT_UNABLE_TPC;
6798 rjt_exp = LSEXP_NOTHING_MORE;
6799 break;
6800 }
6801 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_LOGO);
6802 break;
6803 case ELS_CMD_PRLO:
6804 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6805 "RCV PRLO: did:x%x/ste:x%x flg:x%x",
6806 did, vport->port_state, ndlp->nlp_flag);
6807
6808 phba->fc_stat.elsRcvPRLO++;
6809 lpfc_send_els_event(vport, ndlp, payload);
6810 if (vport->port_state < LPFC_DISC_AUTH) {
6811 rjt_err = LSRJT_UNABLE_TPC;
6812 rjt_exp = LSEXP_NOTHING_MORE;
6813 break;
6814 }
6815 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLO);
6816 break;
6817 case ELS_CMD_RSCN:
6818 phba->fc_stat.elsRcvRSCN++;
6819 lpfc_els_rcv_rscn(vport, elsiocb, ndlp);
6820 if (newnode)
6821 lpfc_nlp_put(ndlp);
6822 break;
6823 case ELS_CMD_ADISC:
6824 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6825 "RCV ADISC: did:x%x/ste:x%x flg:x%x",
6826 did, vport->port_state, ndlp->nlp_flag);
6827
6828 lpfc_send_els_event(vport, ndlp, payload);
6829 phba->fc_stat.elsRcvADISC++;
6830 if (vport->port_state < LPFC_DISC_AUTH) {
6831 rjt_err = LSRJT_UNABLE_TPC;
6832 rjt_exp = LSEXP_NOTHING_MORE;
6833 break;
6834 }
6835 lpfc_disc_state_machine(vport, ndlp, elsiocb,
6836 NLP_EVT_RCV_ADISC);
6837 break;
6838 case ELS_CMD_PDISC:
6839 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6840 "RCV PDISC: did:x%x/ste:x%x flg:x%x",
6841 did, vport->port_state, ndlp->nlp_flag);
6842
6843 phba->fc_stat.elsRcvPDISC++;
6844 if (vport->port_state < LPFC_DISC_AUTH) {
6845 rjt_err = LSRJT_UNABLE_TPC;
6846 rjt_exp = LSEXP_NOTHING_MORE;
6847 break;
6848 }
6849 lpfc_disc_state_machine(vport, ndlp, elsiocb,
6850 NLP_EVT_RCV_PDISC);
6851 break;
6852 case ELS_CMD_FARPR:
6853 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6854 "RCV FARPR: did:x%x/ste:x%x flg:x%x",
6855 did, vport->port_state, ndlp->nlp_flag);
6856
6857 phba->fc_stat.elsRcvFARPR++;
6858 lpfc_els_rcv_farpr(vport, elsiocb, ndlp);
6859 break;
6860 case ELS_CMD_FARP:
6861 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6862 "RCV FARP: did:x%x/ste:x%x flg:x%x",
6863 did, vport->port_state, ndlp->nlp_flag);
6864
6865 phba->fc_stat.elsRcvFARP++;
6866 lpfc_els_rcv_farp(vport, elsiocb, ndlp);
6867 break;
6868 case ELS_CMD_FAN:
6869 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6870 "RCV FAN: did:x%x/ste:x%x flg:x%x",
6871 did, vport->port_state, ndlp->nlp_flag);
6872
6873 phba->fc_stat.elsRcvFAN++;
6874 lpfc_els_rcv_fan(vport, elsiocb, ndlp);
6875 break;
6876 case ELS_CMD_PRLI:
6877 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6878 "RCV PRLI: did:x%x/ste:x%x flg:x%x",
6879 did, vport->port_state, ndlp->nlp_flag);
6880
6881 phba->fc_stat.elsRcvPRLI++;
6882 if (vport->port_state < LPFC_DISC_AUTH) {
6883 rjt_err = LSRJT_UNABLE_TPC;
6884 rjt_exp = LSEXP_NOTHING_MORE;
6885 break;
6886 }
6887 lpfc_disc_state_machine(vport, ndlp, elsiocb, NLP_EVT_RCV_PRLI);
6888 break;
6889 case ELS_CMD_LIRR:
6890 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6891 "RCV LIRR: did:x%x/ste:x%x flg:x%x",
6892 did, vport->port_state, ndlp->nlp_flag);
6893
6894 phba->fc_stat.elsRcvLIRR++;
6895 lpfc_els_rcv_lirr(vport, elsiocb, ndlp);
6896 if (newnode)
6897 lpfc_nlp_put(ndlp);
6898 break;
6899 case ELS_CMD_RLS:
6900 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6901 "RCV RLS: did:x%x/ste:x%x flg:x%x",
6902 did, vport->port_state, ndlp->nlp_flag);
6903
6904 phba->fc_stat.elsRcvRLS++;
6905 lpfc_els_rcv_rls(vport, elsiocb, ndlp);
6906 if (newnode)
6907 lpfc_nlp_put(ndlp);
6908 break;
6909 case ELS_CMD_RPS:
6910 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6911 "RCV RPS: did:x%x/ste:x%x flg:x%x",
6912 did, vport->port_state, ndlp->nlp_flag);
6913
6914 phba->fc_stat.elsRcvRPS++;
6915 lpfc_els_rcv_rps(vport, elsiocb, ndlp);
6916 if (newnode)
6917 lpfc_nlp_put(ndlp);
6918 break;
6919 case ELS_CMD_RPL:
6920 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6921 "RCV RPL: did:x%x/ste:x%x flg:x%x",
6922 did, vport->port_state, ndlp->nlp_flag);
6923
6924 phba->fc_stat.elsRcvRPL++;
6925 lpfc_els_rcv_rpl(vport, elsiocb, ndlp);
6926 if (newnode)
6927 lpfc_nlp_put(ndlp);
6928 break;
6929 case ELS_CMD_RNID:
6930 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6931 "RCV RNID: did:x%x/ste:x%x flg:x%x",
6932 did, vport->port_state, ndlp->nlp_flag);
6933
6934 phba->fc_stat.elsRcvRNID++;
6935 lpfc_els_rcv_rnid(vport, elsiocb, ndlp);
6936 if (newnode)
6937 lpfc_nlp_put(ndlp);
6938 break;
6939 case ELS_CMD_RTV:
6940 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6941 "RCV RTV: did:x%x/ste:x%x flg:x%x",
6942 did, vport->port_state, ndlp->nlp_flag);
6943 phba->fc_stat.elsRcvRTV++;
6944 lpfc_els_rcv_rtv(vport, elsiocb, ndlp);
6945 if (newnode)
6946 lpfc_nlp_put(ndlp);
6947 break;
6948 case ELS_CMD_RRQ:
6949 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6950 "RCV RRQ: did:x%x/ste:x%x flg:x%x",
6951 did, vport->port_state, ndlp->nlp_flag);
6952
6953 phba->fc_stat.elsRcvRRQ++;
6954 lpfc_els_rcv_rrq(vport, elsiocb, ndlp);
6955 if (newnode)
6956 lpfc_nlp_put(ndlp);
6957 break;
6958 case ELS_CMD_ECHO:
6959 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6960 "RCV ECHO: did:x%x/ste:x%x flg:x%x",
6961 did, vport->port_state, ndlp->nlp_flag);
6962
6963 phba->fc_stat.elsRcvECHO++;
6964 lpfc_els_rcv_echo(vport, elsiocb, ndlp);
6965 if (newnode)
6966 lpfc_nlp_put(ndlp);
6967 break;
6968 case ELS_CMD_REC:
6969
6970 rjt_err = LSRJT_UNABLE_TPC;
6971 rjt_exp = LSEXP_INVALID_OX_RX;
6972 break;
6973 default:
6974 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_UNSOL,
6975 "RCV ELS cmd: cmd:x%x did:x%x/ste:x%x",
6976 cmd, did, vport->port_state);
6977
6978
6979 rjt_err = LSRJT_CMD_UNSUPPORTED;
6980 rjt_exp = LSEXP_NOTHING_MORE;
6981
6982
6983 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
6984 "0115 Unknown ELS command x%x "
6985 "received from NPORT x%x\n", cmd, did);
6986 if (newnode)
6987 lpfc_nlp_put(ndlp);
6988 break;
6989 }
6990
6991
6992 if (rjt_err) {
6993 memset(&stat, 0, sizeof(stat));
6994 stat.un.b.lsRjtRsnCode = rjt_err;
6995 stat.un.b.lsRjtRsnCodeExp = rjt_exp;
6996 lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp,
6997 NULL);
6998 }
6999
7000 lpfc_nlp_put(elsiocb->context1);
7001 elsiocb->context1 = NULL;
7002 return;
7003
7004dropit:
7005 if (vport && !(vport->load_flag & FC_UNLOADING))
7006 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
7007 "0111 Dropping received ELS cmd "
7008 "Data: x%x x%x x%x\n",
7009 icmd->ulpStatus, icmd->un.ulpWord[4], icmd->ulpTimeout);
7010 phba->fc_stat.elsRcvDrop++;
7011}
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025void
7026lpfc_els_unsol_event(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
7027 struct lpfc_iocbq *elsiocb)
7028{
7029 struct lpfc_vport *vport = phba->pport;
7030 IOCB_t *icmd = &elsiocb->iocb;
7031 dma_addr_t paddr;
7032 struct lpfc_dmabuf *bdeBuf1 = elsiocb->context2;
7033 struct lpfc_dmabuf *bdeBuf2 = elsiocb->context3;
7034
7035 elsiocb->context1 = NULL;
7036 elsiocb->context2 = NULL;
7037 elsiocb->context3 = NULL;
7038
7039 if (icmd->ulpStatus == IOSTAT_NEED_BUFFER) {
7040 lpfc_sli_hbqbuf_add_hbqs(phba, LPFC_ELS_HBQ);
7041 } else if (icmd->ulpStatus == IOSTAT_LOCAL_REJECT &&
7042 (icmd->un.ulpWord[4] & IOERR_PARAM_MASK) ==
7043 IOERR_RCV_BUFFER_WAITING) {
7044 phba->fc_stat.NoRcvBuf++;
7045
7046 if (!(phba->sli3_options & LPFC_SLI3_HBQ_ENABLED))
7047 lpfc_post_buffer(phba, pring, 0);
7048 return;
7049 }
7050
7051 if ((phba->sli3_options & LPFC_SLI3_NPIV_ENABLED) &&
7052 (icmd->ulpCommand == CMD_IOCB_RCV_ELS64_CX ||
7053 icmd->ulpCommand == CMD_IOCB_RCV_SEQ64_CX)) {
7054 if (icmd->unsli3.rcvsli3.vpi == 0xffff)
7055 vport = phba->pport;
7056 else
7057 vport = lpfc_find_vport_by_vpid(phba,
7058 icmd->unsli3.rcvsli3.vpi);
7059 }
7060
7061
7062
7063
7064 if (icmd->ulpBdeCount == 0)
7065 return;
7066
7067
7068
7069
7070 if (phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) {
7071 elsiocb->context2 = bdeBuf1;
7072 } else {
7073 paddr = getPaddr(icmd->un.cont64[0].addrHigh,
7074 icmd->un.cont64[0].addrLow);
7075 elsiocb->context2 = lpfc_sli_ringpostbuf_get(phba, pring,
7076 paddr);
7077 }
7078
7079 lpfc_els_unsol_buffer(phba, pring, vport, elsiocb);
7080
7081
7082
7083
7084 if (elsiocb->context2) {
7085 lpfc_in_buf_free(phba, (struct lpfc_dmabuf *)elsiocb->context2);
7086 elsiocb->context2 = NULL;
7087 }
7088
7089
7090 if ((phba->sli3_options & LPFC_SLI3_HBQ_ENABLED) &&
7091 icmd->ulpBdeCount == 2) {
7092 elsiocb->context2 = bdeBuf2;
7093 lpfc_els_unsol_buffer(phba, pring, vport, elsiocb);
7094
7095 if (elsiocb->context2) {
7096 lpfc_in_buf_free(phba, elsiocb->context2);
7097 elsiocb->context2 = NULL;
7098 }
7099 }
7100}
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115void
7116lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
7117{
7118 struct lpfc_nodelist *ndlp, *ndlp_fdmi;
7119 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
7120
7121
7122
7123
7124
7125
7126 spin_lock_irq(shost->host_lock);
7127 if (vport->fc_flag & FC_DISC_DELAYED) {
7128 spin_unlock_irq(shost->host_lock);
7129 lpfc_printf_log(phba, KERN_ERR, LOG_DISCOVERY,
7130 "3334 Delay fc port discovery for %d seconds\n",
7131 phba->fc_ratov);
7132 mod_timer(&vport->delayed_disc_tmo,
7133 jiffies + msecs_to_jiffies(1000 * phba->fc_ratov));
7134 return;
7135 }
7136 spin_unlock_irq(shost->host_lock);
7137
7138 ndlp = lpfc_findnode_did(vport, NameServer_DID);
7139 if (!ndlp) {
7140 ndlp = mempool_alloc(phba->nlp_mem_pool, GFP_KERNEL);
7141 if (!ndlp) {
7142 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
7143 lpfc_disc_start(vport);
7144 return;
7145 }
7146 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
7147 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
7148 "0251 NameServer login: no memory\n");
7149 return;
7150 }
7151 lpfc_nlp_init(vport, ndlp, NameServer_DID);
7152 } else if (!NLP_CHK_NODE_ACT(ndlp)) {
7153 ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
7154 if (!ndlp) {
7155 if (phba->fc_topology == LPFC_TOPOLOGY_LOOP) {
7156 lpfc_disc_start(vport);
7157 return;
7158 }
7159 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
7160 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
7161 "0348 NameServer login: node freed\n");
7162 return;
7163 }
7164 }
7165 ndlp->nlp_type |= NLP_FABRIC;
7166
7167 lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
7168
7169 if (lpfc_issue_els_plogi(vport, ndlp->nlp_DID, 0)) {
7170 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
7171 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
7172 "0252 Cannot issue NameServer login\n");
7173 return;
7174 }
7175
7176 if (vport->cfg_fdmi_on) {
7177
7178
7179
7180
7181 ndlp_fdmi = lpfc_findnode_did(vport, FDMI_DID);
7182 if (!ndlp_fdmi) {
7183 ndlp_fdmi = mempool_alloc(phba->nlp_mem_pool,
7184 GFP_KERNEL);
7185 if (ndlp_fdmi) {
7186 lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
7187 ndlp_fdmi->nlp_type |= NLP_FABRIC;
7188 } else
7189 return;
7190 }
7191 if (!NLP_CHK_NODE_ACT(ndlp_fdmi))
7192 ndlp_fdmi = lpfc_enable_node(vport,
7193 ndlp_fdmi,
7194 NLP_STE_NPR_NODE);
7195
7196 if (ndlp_fdmi) {
7197 lpfc_nlp_set_state(vport, ndlp_fdmi,
7198 NLP_STE_PLOGI_ISSUE);
7199 lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID, 0);
7200 }
7201 }
7202}
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216static void
7217lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
7218{
7219 struct lpfc_vport *vport = pmb->vport;
7220 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
7221 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) pmb->context2;
7222 MAILBOX_t *mb = &pmb->u.mb;
7223 int rc;
7224
7225 spin_lock_irq(shost->host_lock);
7226 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
7227 spin_unlock_irq(shost->host_lock);
7228
7229 if (mb->mbxStatus) {
7230 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
7231 "0915 Register VPI failed : Status: x%x"
7232 " upd bit: x%x \n", mb->mbxStatus,
7233 mb->un.varRegVpi.upd);
7234 if (phba->sli_rev == LPFC_SLI_REV4 &&
7235 mb->un.varRegVpi.upd)
7236 goto mbox_err_exit ;
7237
7238 switch (mb->mbxStatus) {
7239 case 0x11:
7240 case 0x9603:
7241 case 0x9602:
7242
7243 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
7244 spin_lock_irq(shost->host_lock);
7245 vport->fc_flag &= ~(FC_FABRIC | FC_PUBLIC_LOOP);
7246 spin_unlock_irq(shost->host_lock);
7247 lpfc_can_disctmo(vport);
7248 break;
7249
7250 case 0x20:
7251 spin_lock_irq(shost->host_lock);
7252 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
7253 spin_unlock_irq(shost->host_lock);
7254 lpfc_init_vpi(phba, pmb, vport->vpi);
7255 pmb->vport = vport;
7256 pmb->mbox_cmpl = lpfc_init_vpi_cmpl;
7257 rc = lpfc_sli_issue_mbox(phba, pmb,
7258 MBX_NOWAIT);
7259 if (rc == MBX_NOT_FINISHED) {
7260 lpfc_printf_vlog(vport,
7261 KERN_ERR, LOG_MBOX,
7262 "2732 Failed to issue INIT_VPI"
7263 " mailbox command\n");
7264 } else {
7265 lpfc_nlp_put(ndlp);
7266 return;
7267 }
7268
7269 default:
7270
7271 if (phba->sli_rev == LPFC_SLI_REV4)
7272 lpfc_sli4_unreg_all_rpis(vport);
7273 lpfc_mbx_unreg_vpi(vport);
7274 spin_lock_irq(shost->host_lock);
7275 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
7276 spin_unlock_irq(shost->host_lock);
7277 if (vport->port_type == LPFC_PHYSICAL_PORT
7278 && !(vport->fc_flag & FC_LOGO_RCVD_DID_CHNG))
7279 lpfc_issue_init_vfi(vport);
7280 else
7281 lpfc_initial_fdisc(vport);
7282 break;
7283 }
7284 } else {
7285 spin_lock_irq(shost->host_lock);
7286 vport->vpi_state |= LPFC_VPI_REGISTERED;
7287 spin_unlock_irq(shost->host_lock);
7288 if (vport == phba->pport) {
7289 if (phba->sli_rev < LPFC_SLI_REV4)
7290 lpfc_issue_fabric_reglogin(vport);
7291 else {
7292
7293
7294
7295
7296 if (vport->port_state != LPFC_FDISC)
7297 lpfc_start_fdiscs(phba);
7298 lpfc_do_scr_ns_plogi(phba, vport);
7299 }
7300 } else
7301 lpfc_do_scr_ns_plogi(phba, vport);
7302 }
7303mbox_err_exit:
7304
7305
7306
7307 lpfc_nlp_put(ndlp);
7308
7309 mempool_free(pmb, phba->mbox_mem_pool);
7310 return;
7311}
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322void
7323lpfc_register_new_vport(struct lpfc_hba *phba, struct lpfc_vport *vport,
7324 struct lpfc_nodelist *ndlp)
7325{
7326 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
7327 LPFC_MBOXQ_t *mbox;
7328
7329 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
7330 if (mbox) {
7331 lpfc_reg_vpi(vport, mbox);
7332 mbox->vport = vport;
7333 mbox->context2 = lpfc_nlp_get(ndlp);
7334 mbox->mbox_cmpl = lpfc_cmpl_reg_new_vport;
7335 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT)
7336 == MBX_NOT_FINISHED) {
7337
7338
7339
7340 lpfc_nlp_put(ndlp);
7341 mempool_free(mbox, phba->mbox_mem_pool);
7342
7343 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
7344 "0253 Register VPI: Can't send mbox\n");
7345 goto mbox_err_exit;
7346 }
7347 } else {
7348 lpfc_printf_vlog(vport, KERN_ERR, LOG_MBOX,
7349 "0254 Register VPI: no memory\n");
7350 goto mbox_err_exit;
7351 }
7352 return;
7353
7354mbox_err_exit:
7355 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
7356 spin_lock_irq(shost->host_lock);
7357 vport->fc_flag &= ~FC_VPORT_NEEDS_REG_VPI;
7358 spin_unlock_irq(shost->host_lock);
7359 return;
7360}
7361
7362
7363
7364
7365
7366
7367
7368void
7369lpfc_cancel_all_vport_retry_delay_timer(struct lpfc_hba *phba)
7370{
7371 struct lpfc_vport **vports;
7372 struct lpfc_nodelist *ndlp;
7373 uint32_t link_state;
7374 int i;
7375
7376
7377 link_state = phba->link_state;
7378 lpfc_linkdown(phba);
7379 phba->link_state = link_state;
7380
7381 vports = lpfc_create_vport_work_array(phba);
7382
7383 if (vports) {
7384 for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) {
7385 ndlp = lpfc_findnode_did(vports[i], Fabric_DID);
7386 if (ndlp)
7387 lpfc_cancel_retry_delay_tmo(vports[i], ndlp);
7388 lpfc_els_flush_cmd(vports[i]);
7389 }
7390 lpfc_destroy_vport_work_array(phba, vports);
7391 }
7392}
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402void
7403lpfc_retry_pport_discovery(struct lpfc_hba *phba)
7404{
7405 struct lpfc_nodelist *ndlp;
7406 struct Scsi_Host *shost;
7407
7408
7409 lpfc_cancel_all_vport_retry_delay_timer(phba);
7410
7411
7412 ndlp = lpfc_findnode_did(phba->pport, Fabric_DID);
7413 if (!ndlp)
7414 return;
7415
7416 shost = lpfc_shost_from_vport(phba->pport);
7417 mod_timer(&ndlp->nlp_delayfunc, jiffies + msecs_to_jiffies(1000));
7418 spin_lock_irq(shost->host_lock);
7419 ndlp->nlp_flag |= NLP_DELAY_TMO;
7420 spin_unlock_irq(shost->host_lock);
7421 ndlp->nlp_last_elscmd = ELS_CMD_FLOGI;
7422 phba->pport->port_state = LPFC_FLOGI;
7423 return;
7424}
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435static int
7436lpfc_fabric_login_reqd(struct lpfc_hba *phba,
7437 struct lpfc_iocbq *cmdiocb,
7438 struct lpfc_iocbq *rspiocb)
7439{
7440
7441 if ((rspiocb->iocb.ulpStatus != IOSTAT_FABRIC_RJT) ||
7442 (rspiocb->iocb.un.ulpWord[4] != RJT_LOGIN_REQUIRED))
7443 return 0;
7444 else
7445 return 1;
7446}
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468static void
7469lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
7470 struct lpfc_iocbq *rspiocb)
7471{
7472 struct lpfc_vport *vport = cmdiocb->vport;
7473 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
7474 struct lpfc_nodelist *ndlp = (struct lpfc_nodelist *) cmdiocb->context1;
7475 struct lpfc_nodelist *np;
7476 struct lpfc_nodelist *next_np;
7477 IOCB_t *irsp = &rspiocb->iocb;
7478 struct lpfc_iocbq *piocb;
7479 struct lpfc_dmabuf *pcmd = cmdiocb->context2, *prsp;
7480 struct serv_parm *sp;
7481 uint8_t fabric_param_changed;
7482
7483 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
7484 "0123 FDISC completes. x%x/x%x prevDID: x%x\n",
7485 irsp->ulpStatus, irsp->un.ulpWord[4],
7486 vport->fc_prevDID);
7487
7488
7489
7490
7491 list_for_each_entry(piocb, &phba->fabric_iocb_list, list) {
7492 lpfc_set_disctmo(piocb->vport);
7493 }
7494
7495 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
7496 "FDISC cmpl: status:x%x/x%x prevdid:x%x",
7497 irsp->ulpStatus, irsp->un.ulpWord[4], vport->fc_prevDID);
7498
7499 if (irsp->ulpStatus) {
7500
7501 if (lpfc_fabric_login_reqd(phba, cmdiocb, rspiocb)) {
7502 lpfc_retry_pport_discovery(phba);
7503 goto out;
7504 }
7505
7506
7507 if (lpfc_els_retry(phba, cmdiocb, rspiocb))
7508 goto out;
7509
7510 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
7511 "0126 FDISC failed. (x%x/x%x)\n",
7512 irsp->ulpStatus, irsp->un.ulpWord[4]);
7513 goto fdisc_failed;
7514 }
7515 spin_lock_irq(shost->host_lock);
7516 vport->fc_flag &= ~FC_VPORT_CVL_RCVD;
7517 vport->fc_flag &= ~FC_VPORT_LOGO_RCVD;
7518 vport->fc_flag |= FC_FABRIC;
7519 if (vport->phba->fc_topology == LPFC_TOPOLOGY_LOOP)
7520 vport->fc_flag |= FC_PUBLIC_LOOP;
7521 spin_unlock_irq(shost->host_lock);
7522
7523 vport->fc_myDID = irsp->un.ulpWord[4] & Mask_DID;
7524 lpfc_vport_set_state(vport, FC_VPORT_ACTIVE);
7525 prsp = list_get_first(&pcmd->list, struct lpfc_dmabuf, list);
7526 if (!prsp)
7527 goto out;
7528 sp = prsp->virt + sizeof(uint32_t);
7529 fabric_param_changed = lpfc_check_clean_addr_bit(vport, sp);
7530 memcpy(&vport->fabric_portname, &sp->portName,
7531 sizeof(struct lpfc_name));
7532 memcpy(&vport->fabric_nodename, &sp->nodeName,
7533 sizeof(struct lpfc_name));
7534 if (fabric_param_changed &&
7535 !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
7536
7537
7538
7539
7540 list_for_each_entry_safe(np, next_np,
7541 &vport->fc_nodes, nlp_listp) {
7542 if (!NLP_CHK_NODE_ACT(ndlp) ||
7543 (np->nlp_state != NLP_STE_NPR_NODE) ||
7544 !(np->nlp_flag & NLP_NPR_ADISC))
7545 continue;
7546 spin_lock_irq(shost->host_lock);
7547 np->nlp_flag &= ~NLP_NPR_ADISC;
7548 spin_unlock_irq(shost->host_lock);
7549 lpfc_unreg_rpi(vport, np);
7550 }
7551 lpfc_cleanup_pending_mbox(vport);
7552
7553 if (phba->sli_rev == LPFC_SLI_REV4)
7554 lpfc_sli4_unreg_all_rpis(vport);
7555
7556 lpfc_mbx_unreg_vpi(vport);
7557 spin_lock_irq(shost->host_lock);
7558 vport->fc_flag |= FC_VPORT_NEEDS_REG_VPI;
7559 if (phba->sli_rev == LPFC_SLI_REV4)
7560 vport->fc_flag |= FC_VPORT_NEEDS_INIT_VPI;
7561 else
7562 vport->fc_flag |= FC_LOGO_RCVD_DID_CHNG;
7563 spin_unlock_irq(shost->host_lock);
7564 } else if ((phba->sli_rev == LPFC_SLI_REV4) &&
7565 !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)) {
7566
7567
7568
7569
7570 lpfc_register_new_vport(phba, vport, ndlp);
7571 goto out;
7572 }
7573
7574 if (vport->fc_flag & FC_VPORT_NEEDS_INIT_VPI)
7575 lpfc_issue_init_vpi(vport);
7576 else if (vport->fc_flag & FC_VPORT_NEEDS_REG_VPI)
7577 lpfc_register_new_vport(phba, vport, ndlp);
7578 else
7579 lpfc_do_scr_ns_plogi(phba, vport);
7580 goto out;
7581fdisc_failed:
7582 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
7583
7584 lpfc_can_disctmo(vport);
7585 lpfc_nlp_put(ndlp);
7586out:
7587 lpfc_els_free_iocb(phba, cmdiocb);
7588}
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610static int
7611lpfc_issue_els_fdisc(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
7612 uint8_t retry)
7613{
7614 struct lpfc_hba *phba = vport->phba;
7615 IOCB_t *icmd;
7616 struct lpfc_iocbq *elsiocb;
7617 struct serv_parm *sp;
7618 uint8_t *pcmd;
7619 uint16_t cmdsize;
7620 int did = ndlp->nlp_DID;
7621 int rc;
7622
7623 vport->port_state = LPFC_FDISC;
7624 vport->fc_myDID = 0;
7625 cmdsize = (sizeof(uint32_t) + sizeof(struct serv_parm));
7626 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, retry, ndlp, did,
7627 ELS_CMD_FDISC);
7628 if (!elsiocb) {
7629 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
7630 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
7631 "0255 Issue FDISC: no IOCB\n");
7632 return 1;
7633 }
7634
7635 icmd = &elsiocb->iocb;
7636 icmd->un.elsreq64.myID = 0;
7637 icmd->un.elsreq64.fl = 1;
7638
7639
7640
7641
7642
7643 if (phba->sli_rev == LPFC_SLI_REV3) {
7644 icmd->ulpCt_h = 1;
7645 icmd->ulpCt_l = 0;
7646 }
7647
7648 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
7649 *((uint32_t *) (pcmd)) = ELS_CMD_FDISC;
7650 pcmd += sizeof(uint32_t);
7651 memcpy(pcmd, &vport->phba->pport->fc_sparam, sizeof(struct serv_parm));
7652 sp = (struct serv_parm *) pcmd;
7653
7654 sp->cmn.e_d_tov = 0;
7655 sp->cmn.w2.r_a_tov = 0;
7656 sp->cmn.virtual_fabric_support = 0;
7657 sp->cls1.classValid = 0;
7658 sp->cls2.seqDelivery = 1;
7659 sp->cls3.seqDelivery = 1;
7660
7661 pcmd += sizeof(uint32_t);
7662 pcmd += sizeof(uint32_t);
7663 pcmd += sizeof(uint32_t);
7664 pcmd += sizeof(uint32_t);
7665 memcpy(pcmd, &vport->fc_portname, 8);
7666 pcmd += sizeof(uint32_t);
7667 pcmd += sizeof(uint32_t);
7668 memcpy(pcmd, &vport->fc_nodename, 8);
7669
7670 lpfc_set_disctmo(vport);
7671
7672 phba->fc_stat.elsXmitFDISC++;
7673 elsiocb->iocb_cmpl = lpfc_cmpl_els_fdisc;
7674
7675 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
7676 "Issue FDISC: did:x%x",
7677 did, 0, 0);
7678
7679 rc = lpfc_issue_fabric_iocb(phba, elsiocb);
7680 if (rc == IOCB_ERROR) {
7681 lpfc_els_free_iocb(phba, elsiocb);
7682 lpfc_vport_set_state(vport, FC_VPORT_FAILED);
7683 lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
7684 "0256 Issue FDISC: Cannot send IOCB\n");
7685 return 1;
7686 }
7687 lpfc_vport_set_state(vport, FC_VPORT_INITIALIZING);
7688 return 0;
7689}
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705static void
7706lpfc_cmpl_els_npiv_logo(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
7707 struct lpfc_iocbq *rspiocb)
7708{
7709 struct lpfc_vport *vport = cmdiocb->vport;
7710 IOCB_t *irsp;
7711 struct lpfc_nodelist *ndlp;
7712 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
7713
7714 ndlp = (struct lpfc_nodelist *)cmdiocb->context1;
7715 irsp = &rspiocb->iocb;
7716 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
7717 "LOGO npiv cmpl: status:x%x/x%x did:x%x",
7718 irsp->ulpStatus, irsp->un.ulpWord[4], irsp->un.rcvels.remoteID);
7719
7720 lpfc_els_free_iocb(phba, cmdiocb);
7721 vport->unreg_vpi_cmpl = VPORT_ERROR;
7722
7723
7724 lpfc_nlp_put(ndlp);
7725
7726
7727 lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS,
7728 "2928 NPIV LOGO completes to NPort x%x "
7729 "Data: x%x x%x x%x x%x\n",
7730 ndlp->nlp_DID, irsp->ulpStatus, irsp->un.ulpWord[4],
7731 irsp->ulpTimeout, vport->num_disc_nodes);
7732
7733 if (irsp->ulpStatus == IOSTAT_SUCCESS) {
7734 spin_lock_irq(shost->host_lock);
7735 vport->fc_flag &= ~FC_FABRIC;
7736 spin_unlock_irq(shost->host_lock);
7737 }
7738}
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756int
7757lpfc_issue_els_npiv_logo(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
7758{
7759 struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
7760 struct lpfc_hba *phba = vport->phba;
7761 IOCB_t *icmd;
7762 struct lpfc_iocbq *elsiocb;
7763 uint8_t *pcmd;
7764 uint16_t cmdsize;
7765
7766 cmdsize = 2 * sizeof(uint32_t) + sizeof(struct lpfc_name);
7767 elsiocb = lpfc_prep_els_iocb(vport, 1, cmdsize, 0, ndlp, ndlp->nlp_DID,
7768 ELS_CMD_LOGO);
7769 if (!elsiocb)
7770 return 1;
7771
7772 icmd = &elsiocb->iocb;
7773 pcmd = (uint8_t *) (((struct lpfc_dmabuf *) elsiocb->context2)->virt);
7774 *((uint32_t *) (pcmd)) = ELS_CMD_LOGO;
7775 pcmd += sizeof(uint32_t);
7776
7777
7778 *((uint32_t *) (pcmd)) = be32_to_cpu(vport->fc_myDID);
7779 pcmd += sizeof(uint32_t);
7780 memcpy(pcmd, &vport->fc_portname, sizeof(struct lpfc_name));
7781
7782 lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_CMD,
7783 "Issue LOGO npiv did:x%x flg:x%x",
7784 ndlp->nlp_DID, ndlp->nlp_flag, 0);
7785
7786 elsiocb->iocb_cmpl = lpfc_cmpl_els_npiv_logo;
7787 spin_lock_irq(shost->host_lock);
7788 ndlp->nlp_flag |= NLP_LOGO_SND;
7789 spin_unlock_irq(shost->host_lock);
7790 if (lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, elsiocb, 0) ==
7791 IOCB_ERROR) {
7792 spin_lock_irq(shost->host_lock);
7793 ndlp->nlp_flag &= ~NLP_LOGO_SND;
7794 spin_unlock_irq(shost->host_lock);
7795 lpfc_els_free_iocb(phba, elsiocb);
7796 return 1;
7797 }
7798 return 0;
7799}
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812void
7813lpfc_fabric_block_timeout(unsigned long ptr)
7814{
7815 struct lpfc_hba *phba = (struct lpfc_hba *) ptr;
7816 unsigned long iflags;
7817 uint32_t tmo_posted;
7818
7819 spin_lock_irqsave(&phba->pport->work_port_lock, iflags);
7820 tmo_posted = phba->pport->work_port_events & WORKER_FABRIC_BLOCK_TMO;
7821 if (!tmo_posted)
7822 phba->pport->work_port_events |= WORKER_FABRIC_BLOCK_TMO;
7823 spin_unlock_irqrestore(&phba->pport->work_port_lock, iflags);
7824
7825 if (!tmo_posted)
7826 lpfc_worker_wake_up(phba);
7827 return;
7828}
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840static void
7841lpfc_resume_fabric_iocbs(struct lpfc_hba *phba)
7842{
7843 struct lpfc_iocbq *iocb;
7844 unsigned long iflags;
7845 int ret;
7846 IOCB_t *cmd;
7847
7848repeat:
7849 iocb = NULL;
7850 spin_lock_irqsave(&phba->hbalock, iflags);
7851
7852 if (atomic_read(&phba->fabric_iocb_count) == 0) {
7853 list_remove_head(&phba->fabric_iocb_list, iocb, typeof(*iocb),
7854 list);
7855 if (iocb)
7856
7857 atomic_inc(&phba->fabric_iocb_count);
7858 }
7859 spin_unlock_irqrestore(&phba->hbalock, iflags);
7860 if (iocb) {
7861 iocb->fabric_iocb_cmpl = iocb->iocb_cmpl;
7862 iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb;
7863 iocb->iocb_flag |= LPFC_IO_FABRIC;
7864
7865 lpfc_debugfs_disc_trc(iocb->vport, LPFC_DISC_TRC_ELS_CMD,
7866 "Fabric sched1: ste:x%x",
7867 iocb->vport->port_state, 0, 0);
7868
7869 ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, iocb, 0);
7870
7871 if (ret == IOCB_ERROR) {
7872 iocb->iocb_cmpl = iocb->fabric_iocb_cmpl;
7873 iocb->fabric_iocb_cmpl = NULL;
7874 iocb->iocb_flag &= ~LPFC_IO_FABRIC;
7875 cmd = &iocb->iocb;
7876 cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
7877 cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
7878 iocb->iocb_cmpl(phba, iocb, iocb);
7879
7880 atomic_dec(&phba->fabric_iocb_count);
7881 goto repeat;
7882 }
7883 }
7884
7885 return;
7886}
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897void
7898lpfc_unblock_fabric_iocbs(struct lpfc_hba *phba)
7899{
7900 clear_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
7901
7902 lpfc_resume_fabric_iocbs(phba);
7903 return;
7904}
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915static void
7916lpfc_block_fabric_iocbs(struct lpfc_hba *phba)
7917{
7918 int blocked;
7919
7920 blocked = test_and_set_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
7921
7922 if (!blocked)
7923 mod_timer(&phba->fabric_block_timer,
7924 jiffies + msecs_to_jiffies(100));
7925
7926 return;
7927}
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942static void
7943lpfc_cmpl_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
7944 struct lpfc_iocbq *rspiocb)
7945{
7946 struct ls_rjt stat;
7947
7948 if ((cmdiocb->iocb_flag & LPFC_IO_FABRIC) != LPFC_IO_FABRIC)
7949 BUG();
7950
7951 switch (rspiocb->iocb.ulpStatus) {
7952 case IOSTAT_NPORT_RJT:
7953 case IOSTAT_FABRIC_RJT:
7954 if (rspiocb->iocb.un.ulpWord[4] & RJT_UNAVAIL_TEMP) {
7955 lpfc_block_fabric_iocbs(phba);
7956 }
7957 break;
7958
7959 case IOSTAT_NPORT_BSY:
7960 case IOSTAT_FABRIC_BSY:
7961 lpfc_block_fabric_iocbs(phba);
7962 break;
7963
7964 case IOSTAT_LS_RJT:
7965 stat.un.lsRjtError =
7966 be32_to_cpu(rspiocb->iocb.un.ulpWord[4]);
7967 if ((stat.un.b.lsRjtRsnCode == LSRJT_UNABLE_TPC) ||
7968 (stat.un.b.lsRjtRsnCode == LSRJT_LOGICAL_BSY))
7969 lpfc_block_fabric_iocbs(phba);
7970 break;
7971 }
7972
7973 if (atomic_read(&phba->fabric_iocb_count) == 0)
7974 BUG();
7975
7976 cmdiocb->iocb_cmpl = cmdiocb->fabric_iocb_cmpl;
7977 cmdiocb->fabric_iocb_cmpl = NULL;
7978 cmdiocb->iocb_flag &= ~LPFC_IO_FABRIC;
7979 cmdiocb->iocb_cmpl(phba, cmdiocb, rspiocb);
7980
7981 atomic_dec(&phba->fabric_iocb_count);
7982 if (!test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags)) {
7983
7984 lpfc_resume_fabric_iocbs(phba);
7985 }
7986}
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012static int
8013lpfc_issue_fabric_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *iocb)
8014{
8015 unsigned long iflags;
8016 int ready;
8017 int ret;
8018
8019 if (atomic_read(&phba->fabric_iocb_count) > 1)
8020 BUG();
8021
8022 spin_lock_irqsave(&phba->hbalock, iflags);
8023 ready = atomic_read(&phba->fabric_iocb_count) == 0 &&
8024 !test_bit(FABRIC_COMANDS_BLOCKED, &phba->bit_flags);
8025
8026 if (ready)
8027
8028 atomic_inc(&phba->fabric_iocb_count);
8029 spin_unlock_irqrestore(&phba->hbalock, iflags);
8030 if (ready) {
8031 iocb->fabric_iocb_cmpl = iocb->iocb_cmpl;
8032 iocb->iocb_cmpl = lpfc_cmpl_fabric_iocb;
8033 iocb->iocb_flag |= LPFC_IO_FABRIC;
8034
8035 lpfc_debugfs_disc_trc(iocb->vport, LPFC_DISC_TRC_ELS_CMD,
8036 "Fabric sched2: ste:x%x",
8037 iocb->vport->port_state, 0, 0);
8038
8039 ret = lpfc_sli_issue_iocb(phba, LPFC_ELS_RING, iocb, 0);
8040
8041 if (ret == IOCB_ERROR) {
8042 iocb->iocb_cmpl = iocb->fabric_iocb_cmpl;
8043 iocb->fabric_iocb_cmpl = NULL;
8044 iocb->iocb_flag &= ~LPFC_IO_FABRIC;
8045 atomic_dec(&phba->fabric_iocb_count);
8046 }
8047 } else {
8048 spin_lock_irqsave(&phba->hbalock, iflags);
8049 list_add_tail(&iocb->list, &phba->fabric_iocb_list);
8050 spin_unlock_irqrestore(&phba->hbalock, iflags);
8051 ret = IOCB_SUCCESS;
8052 }
8053 return ret;
8054}
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067static void lpfc_fabric_abort_vport(struct lpfc_vport *vport)
8068{
8069 LIST_HEAD(completions);
8070 struct lpfc_hba *phba = vport->phba;
8071 struct lpfc_iocbq *tmp_iocb, *piocb;
8072
8073 spin_lock_irq(&phba->hbalock);
8074 list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
8075 list) {
8076
8077 if (piocb->vport != vport)
8078 continue;
8079
8080 list_move_tail(&piocb->list, &completions);
8081 }
8082 spin_unlock_irq(&phba->hbalock);
8083
8084
8085 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
8086 IOERR_SLI_ABORTED);
8087}
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100void lpfc_fabric_abort_nport(struct lpfc_nodelist *ndlp)
8101{
8102 LIST_HEAD(completions);
8103 struct lpfc_hba *phba = ndlp->phba;
8104 struct lpfc_iocbq *tmp_iocb, *piocb;
8105 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
8106
8107 spin_lock_irq(&phba->hbalock);
8108 list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
8109 list) {
8110 if ((lpfc_check_sli_ndlp(phba, pring, piocb, ndlp))) {
8111
8112 list_move_tail(&piocb->list, &completions);
8113 }
8114 }
8115 spin_unlock_irq(&phba->hbalock);
8116
8117
8118 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
8119 IOERR_SLI_ABORTED);
8120}
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133void lpfc_fabric_abort_hba(struct lpfc_hba *phba)
8134{
8135 LIST_HEAD(completions);
8136
8137 spin_lock_irq(&phba->hbalock);
8138 list_splice_init(&phba->fabric_iocb_list, &completions);
8139 spin_unlock_irq(&phba->hbalock);
8140
8141
8142 lpfc_sli_cancel_iocbs(phba, &completions, IOSTAT_LOCAL_REJECT,
8143 IOERR_SLI_ABORTED);
8144}
8145
8146
8147
8148
8149
8150
8151
8152
8153void
8154lpfc_sli4_vport_delete_els_xri_aborted(struct lpfc_vport *vport)
8155{
8156 struct lpfc_hba *phba = vport->phba;
8157 struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
8158 unsigned long iflag = 0;
8159
8160 spin_lock_irqsave(&phba->hbalock, iflag);
8161 spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
8162 list_for_each_entry_safe(sglq_entry, sglq_next,
8163 &phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
8164 if (sglq_entry->ndlp && sglq_entry->ndlp->vport == vport)
8165 sglq_entry->ndlp = NULL;
8166 }
8167 spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
8168 spin_unlock_irqrestore(&phba->hbalock, iflag);
8169 return;
8170}
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180void
8181lpfc_sli4_els_xri_aborted(struct lpfc_hba *phba,
8182 struct sli4_wcqe_xri_aborted *axri)
8183{
8184 uint16_t xri = bf_get(lpfc_wcqe_xa_xri, axri);
8185 uint16_t rxid = bf_get(lpfc_wcqe_xa_remote_xid, axri);
8186 uint16_t lxri = 0;
8187
8188 struct lpfc_sglq *sglq_entry = NULL, *sglq_next = NULL;
8189 unsigned long iflag = 0;
8190 struct lpfc_nodelist *ndlp;
8191 struct lpfc_sli_ring *pring = &phba->sli.ring[LPFC_ELS_RING];
8192
8193 spin_lock_irqsave(&phba->hbalock, iflag);
8194 spin_lock(&phba->sli4_hba.abts_sgl_list_lock);
8195 list_for_each_entry_safe(sglq_entry, sglq_next,
8196 &phba->sli4_hba.lpfc_abts_els_sgl_list, list) {
8197 if (sglq_entry->sli4_xritag == xri) {
8198 list_del(&sglq_entry->list);
8199 ndlp = sglq_entry->ndlp;
8200 sglq_entry->ndlp = NULL;
8201 spin_lock(&pring->ring_lock);
8202 list_add_tail(&sglq_entry->list,
8203 &phba->sli4_hba.lpfc_sgl_list);
8204 sglq_entry->state = SGL_FREED;
8205 spin_unlock(&pring->ring_lock);
8206 spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
8207 spin_unlock_irqrestore(&phba->hbalock, iflag);
8208 lpfc_set_rrq_active(phba, ndlp,
8209 sglq_entry->sli4_lxritag,
8210 rxid, 1);
8211
8212
8213 if (!(list_empty(&pring->txq)))
8214 lpfc_worker_wake_up(phba);
8215 return;
8216 }
8217 }
8218 spin_unlock(&phba->sli4_hba.abts_sgl_list_lock);
8219 lxri = lpfc_sli4_xri_inrange(phba, xri);
8220 if (lxri == NO_XRI) {
8221 spin_unlock_irqrestore(&phba->hbalock, iflag);
8222 return;
8223 }
8224 spin_lock(&pring->ring_lock);
8225 sglq_entry = __lpfc_get_active_sglq(phba, lxri);
8226 if (!sglq_entry || (sglq_entry->sli4_xritag != xri)) {
8227 spin_unlock(&pring->ring_lock);
8228 spin_unlock_irqrestore(&phba->hbalock, iflag);
8229 return;
8230 }
8231 sglq_entry->state = SGL_XRI_ABORTED;
8232 spin_unlock(&pring->ring_lock);
8233 spin_unlock_irqrestore(&phba->hbalock, iflag);
8234 return;
8235}
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246void
8247lpfc_sli_abts_recover_port(struct lpfc_vport *vport,
8248 struct lpfc_nodelist *ndlp)
8249{
8250 struct Scsi_Host *shost;
8251 struct lpfc_hba *phba;
8252 unsigned long flags = 0;
8253
8254 shost = lpfc_shost_from_vport(vport);
8255 phba = vport->phba;
8256 if (ndlp->nlp_state != NLP_STE_MAPPED_NODE) {
8257 lpfc_printf_log(phba, KERN_INFO,
8258 LOG_SLI, "3093 No rport recovery needed. "
8259 "rport in state 0x%x\n", ndlp->nlp_state);
8260 return;
8261 }
8262 lpfc_printf_log(phba, KERN_INFO, LOG_SLI,
8263 "3094 Start rport recovery on shost id 0x%x "
8264 "fc_id 0x%06x vpi 0x%x rpi 0x%x state 0x%x "
8265 "flags 0x%x\n",
8266 shost->host_no, ndlp->nlp_DID,
8267 vport->vpi, ndlp->nlp_rpi, ndlp->nlp_state,
8268 ndlp->nlp_flag);
8269
8270
8271
8272
8273 spin_lock_irqsave(shost->host_lock, flags);
8274 ndlp->nlp_fcp_info &= ~NLP_FCP_2_DEVICE;
8275 spin_unlock_irqrestore(shost->host_lock, flags);
8276 lpfc_issue_els_logo(vport, ndlp, 0);
8277 lpfc_nlp_set_state(vport, ndlp, NLP_STE_LOGO_ISSUE);
8278}
8279
8280