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