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