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