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