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