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