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