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