1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include <linux/blkdev.h>
23#include <linux/pci.h>
24#include <linux/interrupt.h>
25
26#include <scsi/scsi_device.h>
27#include <scsi/scsi_transport_fc.h>
28
29#include <scsi/scsi.h>
30
31#include "lpfc_hw4.h"
32#include "lpfc_hw.h"
33#include "lpfc_sli.h"
34#include "lpfc_sli4.h"
35#include "lpfc_nl.h"
36#include "lpfc_disc.h"
37#include "lpfc_scsi.h"
38#include "lpfc.h"
39#include "lpfc_logmsg.h"
40#include "lpfc_crtn.h"
41#include "lpfc_compat.h"
42
43
44
45
46
47
48
49
50
51
52
53
54
55int
56lpfc_dump_static_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb,
57 uint16_t offset)
58{
59 MAILBOX_t *mb;
60 struct lpfc_dmabuf *mp;
61
62 mb = &pmb->u.mb;
63
64
65 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
66 mb->mbxCommand = MBX_DUMP_MEMORY;
67 mb->un.varDmp.type = DMP_NV_PARAMS;
68 mb->un.varDmp.entry_index = offset;
69 mb->un.varDmp.region_id = DMP_REGION_VPORT;
70 mb->mbxOwner = OWN_HOST;
71
72
73 if (phba->sli_rev != LPFC_SLI_REV4) {
74 mb->un.varDmp.cv = 1;
75 mb->un.varDmp.word_cnt = DMP_RSP_SIZE/sizeof(uint32_t);
76 return 0;
77 }
78
79
80 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
81 if (mp)
82 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
83
84 if (!mp || !mp->virt) {
85 kfree(mp);
86 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
87 "2605 lpfc_dump_static_vport: memory"
88 " allocation failed\n");
89 return 1;
90 }
91 memset(mp->virt, 0, LPFC_BPL_SIZE);
92 INIT_LIST_HEAD(&mp->list);
93
94 pmb->context2 = (uint8_t *) mp;
95 mb->un.varWords[3] = putPaddrLow(mp->phys);
96 mb->un.varWords[4] = putPaddrHigh(mp->phys);
97 mb->un.varDmp.sli4_length = sizeof(struct static_vport_info);
98
99 return 0;
100}
101
102
103
104
105
106
107
108
109void
110lpfc_down_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
111{
112 MAILBOX_t *mb;
113 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
114 mb = &pmb->u.mb;
115 mb->mbxCommand = MBX_DOWN_LINK;
116 mb->mbxOwner = OWN_HOST;
117}
118
119
120
121
122
123
124
125
126
127
128
129
130
131void
132lpfc_dump_mem(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, uint16_t offset,
133 uint16_t region_id)
134{
135 MAILBOX_t *mb;
136 void *ctx;
137
138 mb = &pmb->u.mb;
139 ctx = pmb->context2;
140
141
142 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
143 mb->mbxCommand = MBX_DUMP_MEMORY;
144 mb->un.varDmp.cv = 1;
145 mb->un.varDmp.type = DMP_NV_PARAMS;
146 mb->un.varDmp.entry_index = offset;
147 mb->un.varDmp.region_id = region_id;
148 mb->un.varDmp.word_cnt = (DMP_RSP_SIZE / sizeof (uint32_t));
149 mb->un.varDmp.co = 0;
150 mb->un.varDmp.resp_offset = 0;
151 pmb->context2 = ctx;
152 mb->mbxOwner = OWN_HOST;
153 return;
154}
155
156
157
158
159
160
161
162
163
164void
165lpfc_dump_wakeup_param(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
166{
167 MAILBOX_t *mb;
168 void *ctx;
169
170 mb = &pmb->u.mb;
171
172 ctx = pmb->context2;
173
174
175 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
176 mb->mbxCommand = MBX_DUMP_MEMORY;
177 mb->mbxOwner = OWN_HOST;
178 mb->un.varDmp.cv = 1;
179 mb->un.varDmp.type = DMP_NV_PARAMS;
180 mb->un.varDmp.entry_index = 0;
181 mb->un.varDmp.region_id = WAKE_UP_PARMS_REGION_ID;
182 mb->un.varDmp.word_cnt = WAKE_UP_PARMS_WORD_SIZE;
183 mb->un.varDmp.co = 0;
184 mb->un.varDmp.resp_offset = 0;
185 pmb->context2 = ctx;
186 return;
187}
188
189
190
191
192
193
194
195
196
197
198
199
200void
201lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
202{
203 MAILBOX_t *mb;
204
205 mb = &pmb->u.mb;
206 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
207 mb->mbxCommand = MBX_READ_NV;
208 mb->mbxOwner = OWN_HOST;
209 return;
210}
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225void
226lpfc_config_async(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
227 uint32_t ring)
228{
229 MAILBOX_t *mb;
230
231 mb = &pmb->u.mb;
232 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
233 mb->mbxCommand = MBX_ASYNCEVT_ENABLE;
234 mb->un.varCfgAsyncEvent.ring = ring;
235 mb->mbxOwner = OWN_HOST;
236 return;
237}
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252void
253lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
254{
255 MAILBOX_t *mb;
256
257 mb = &pmb->u.mb;
258 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
259 mb->mbxCommand = MBX_HEARTBEAT;
260 mb->mbxOwner = OWN_HOST;
261 return;
262}
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284int
285lpfc_read_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb, struct lpfc_dmabuf *mp)
286{
287 MAILBOX_t *mb;
288 struct lpfc_sli *psli;
289
290 psli = &phba->sli;
291 mb = &pmb->u.mb;
292 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
293
294 INIT_LIST_HEAD(&mp->list);
295 mb->mbxCommand = MBX_READ_LA64;
296 mb->un.varReadLA.un.lilpBde64.tus.f.bdeSize = 128;
297 mb->un.varReadLA.un.lilpBde64.addrHigh = putPaddrHigh(mp->phys);
298 mb->un.varReadLA.un.lilpBde64.addrLow = putPaddrLow(mp->phys);
299
300
301
302
303 pmb->context1 = (uint8_t *) mp;
304 mb->mbxOwner = OWN_HOST;
305 return (0);
306}
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323void
324lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
325{
326 MAILBOX_t *mb;
327
328 mb = &pmb->u.mb;
329 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
330
331 mb->un.varClearLA.eventTag = phba->fc_eventTag;
332 mb->mbxCommand = MBX_CLEAR_LA;
333 mb->mbxOwner = OWN_HOST;
334 return;
335}
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351void
352lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
353{
354 struct lpfc_vport *vport = phba->pport;
355 MAILBOX_t *mb = &pmb->u.mb;
356 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
357
358
359
360
361 if (phba->cfg_cr_delay) {
362 mb->un.varCfgLnk.cr = 1;
363 mb->un.varCfgLnk.ci = 1;
364 mb->un.varCfgLnk.cr_delay = phba->cfg_cr_delay;
365 mb->un.varCfgLnk.cr_count = phba->cfg_cr_count;
366 }
367
368 mb->un.varCfgLnk.myId = vport->fc_myDID;
369 mb->un.varCfgLnk.edtov = phba->fc_edtov;
370 mb->un.varCfgLnk.arbtov = phba->fc_arbtov;
371 mb->un.varCfgLnk.ratov = phba->fc_ratov;
372 mb->un.varCfgLnk.rttov = phba->fc_rttov;
373 mb->un.varCfgLnk.altov = phba->fc_altov;
374 mb->un.varCfgLnk.crtov = phba->fc_crtov;
375 mb->un.varCfgLnk.citov = phba->fc_citov;
376
377 if (phba->cfg_ack0)
378 mb->un.varCfgLnk.ack0_enable = 1;
379
380 mb->mbxCommand = MBX_CONFIG_LINK;
381 mb->mbxOwner = OWN_HOST;
382 return;
383}
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398int
399lpfc_config_msi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
400{
401 MAILBOX_t *mb = &pmb->u.mb;
402 uint32_t attentionConditions[2];
403
404
405 if (phba->cfg_use_msi != 2) {
406 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
407 "0475 Not configured for supporting MSI-X "
408 "cfg_use_msi: 0x%x\n", phba->cfg_use_msi);
409 return -EINVAL;
410 }
411
412 if (phba->sli_rev < 3) {
413 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
414 "0476 HBA not supporting SLI-3 or later "
415 "SLI Revision: 0x%x\n", phba->sli_rev);
416 return -EINVAL;
417 }
418
419
420 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
421
422
423
424
425
426
427 attentionConditions[0] = (HA_R0ATT | HA_R1ATT | HA_R2ATT | HA_ERATT |
428 HA_LATT | HA_MBATT);
429 attentionConditions[1] = 0;
430
431 mb->un.varCfgMSI.attentionConditions[0] = attentionConditions[0];
432 mb->un.varCfgMSI.attentionConditions[1] = attentionConditions[1];
433
434
435
436
437#ifdef __BIG_ENDIAN_BITFIELD
438
439 mb->un.varCfgMSI.messageNumberByHA[HA_R0_POS] = 1;
440
441 mb->un.varCfgMSI.messageNumberByHA[HA_R1_POS] = 1;
442#else
443
444 mb->un.varCfgMSI.messageNumberByHA[HA_R0_POS^3] = 1;
445
446 mb->un.varCfgMSI.messageNumberByHA[HA_R1_POS^3] = 1;
447#endif
448
449 mb->un.varCfgMSI.autoClearHA[0] = attentionConditions[0];
450 mb->un.varCfgMSI.autoClearHA[1] = attentionConditions[1];
451
452
453 mb->un.varCfgMSI.autoClearHA[0] = 0;
454 mb->un.varCfgMSI.autoClearHA[1] = 0;
455
456
457 mb->mbxCommand = MBX_CONFIG_MSI;
458 mb->mbxOwner = OWN_HOST;
459
460 return 0;
461}
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477void
478lpfc_init_link(struct lpfc_hba * phba,
479 LPFC_MBOXQ_t * pmb, uint32_t topology, uint32_t linkspeed)
480{
481 lpfc_vpd_t *vpd;
482 struct lpfc_sli *psli;
483 MAILBOX_t *mb;
484
485 mb = &pmb->u.mb;
486 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
487
488 psli = &phba->sli;
489 switch (topology) {
490 case FLAGS_TOPOLOGY_MODE_LOOP_PT:
491 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
492 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
493 break;
494 case FLAGS_TOPOLOGY_MODE_PT_PT:
495 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
496 break;
497 case FLAGS_TOPOLOGY_MODE_LOOP:
498 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
499 break;
500 case FLAGS_TOPOLOGY_MODE_PT_LOOP:
501 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
502 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
503 break;
504 case FLAGS_LOCAL_LB:
505 mb->un.varInitLnk.link_flags = FLAGS_LOCAL_LB;
506 break;
507 }
508
509
510 mb->un.varInitLnk.link_flags |= FLAGS_IMED_ABORT;
511
512
513
514
515 vpd = &phba->vpd;
516 if (vpd->rev.feaLevelHigh >= 0x02){
517 switch(linkspeed){
518 case LINK_SPEED_1G:
519 case LINK_SPEED_2G:
520 case LINK_SPEED_4G:
521 case LINK_SPEED_8G:
522 mb->un.varInitLnk.link_flags |=
523 FLAGS_LINK_SPEED;
524 mb->un.varInitLnk.link_speed = linkspeed;
525 break;
526 case LINK_SPEED_AUTO:
527 default:
528 mb->un.varInitLnk.link_speed =
529 LINK_SPEED_AUTO;
530 break;
531 }
532
533 }
534 else
535 mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
536
537 mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK;
538 mb->mbxOwner = OWN_HOST;
539 mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA;
540 return;
541}
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564int
565lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
566{
567 struct lpfc_dmabuf *mp;
568 MAILBOX_t *mb;
569 struct lpfc_sli *psli;
570
571 psli = &phba->sli;
572 mb = &pmb->u.mb;
573 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
574
575 mb->mbxOwner = OWN_HOST;
576
577
578
579 mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
580 if (mp)
581 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
582 if (!mp || !mp->virt) {
583 kfree(mp);
584 mb->mbxCommand = MBX_READ_SPARM64;
585
586 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
587 "0301 READ_SPARAM: no buffers\n");
588 return (1);
589 }
590 INIT_LIST_HEAD(&mp->list);
591 mb->mbxCommand = MBX_READ_SPARM64;
592 mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
593 mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
594 mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
595 mb->un.varRdSparm.vpi = vpi + phba->vpi_base;
596
597
598 pmb->context1 = mp;
599
600 return (0);
601}
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618void
619lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
620 LPFC_MBOXQ_t * pmb)
621{
622 MAILBOX_t *mb;
623
624 mb = &pmb->u.mb;
625 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
626
627 mb->un.varUnregDID.did = did;
628 if (vpi != 0xffff)
629 vpi += phba->vpi_base;
630 mb->un.varUnregDID.vpi = vpi;
631
632 mb->mbxCommand = MBX_UNREG_D_ID;
633 mb->mbxOwner = OWN_HOST;
634 return;
635}
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650void
651lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
652{
653 MAILBOX_t *mb;
654
655 mb = &pmb->u.mb;
656 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
657
658 mb->mbxCommand = MBX_READ_CONFIG;
659 mb->mbxOwner = OWN_HOST;
660 return;
661}
662
663
664
665
666
667
668
669
670
671
672
673
674
675void
676lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
677{
678 MAILBOX_t *mb;
679
680 mb = &pmb->u.mb;
681 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
682
683 mb->mbxCommand = MBX_READ_LNK_STAT;
684 mb->mbxOwner = OWN_HOST;
685 return;
686}
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712int
713lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
714 uint8_t *param, LPFC_MBOXQ_t *pmb, uint32_t flag)
715{
716 MAILBOX_t *mb = &pmb->u.mb;
717 uint8_t *sparam;
718 struct lpfc_dmabuf *mp;
719
720 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
721
722 mb->un.varRegLogin.rpi = 0;
723 if (phba->sli_rev == LPFC_SLI_REV4) {
724 mb->un.varRegLogin.rpi = lpfc_sli4_alloc_rpi(phba);
725 if (mb->un.varRegLogin.rpi == LPFC_RPI_ALLOC_ERROR)
726 return 1;
727 }
728
729 mb->un.varRegLogin.vpi = vpi + phba->vpi_base;
730 mb->un.varRegLogin.did = did;
731 mb->un.varWords[30] = flag;
732
733 mb->mbxOwner = OWN_HOST;
734
735
736 mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
737 if (mp)
738 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
739 if (!mp || !mp->virt) {
740 kfree(mp);
741 mb->mbxCommand = MBX_REG_LOGIN64;
742
743 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
744 "0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, "
745 "flag x%x\n", vpi, did, flag);
746 return (1);
747 }
748 INIT_LIST_HEAD(&mp->list);
749 sparam = mp->virt;
750
751
752 memcpy(sparam, param, sizeof (struct serv_parm));
753
754
755 pmb->context1 = (uint8_t *) mp;
756
757 mb->mbxCommand = MBX_REG_LOGIN64;
758 mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
759 mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
760 mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
761
762 return (0);
763}
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779void
780lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
781 LPFC_MBOXQ_t * pmb)
782{
783 MAILBOX_t *mb;
784
785 mb = &pmb->u.mb;
786 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
787
788 mb->un.varUnregLogin.rpi = (uint16_t) rpi;
789 mb->un.varUnregLogin.rsvd1 = 0;
790 mb->un.varUnregLogin.vpi = vpi + phba->vpi_base;
791
792 mb->mbxCommand = MBX_UNREG_LOGIN;
793 mb->mbxOwner = OWN_HOST;
794
795 return;
796}
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813void
814lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb)
815{
816 MAILBOX_t *mb = &pmb->u.mb;
817
818 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
819
820 mb->un.varRegVpi.vpi = vport->vpi + vport->phba->vpi_base;
821 mb->un.varRegVpi.sid = vport->fc_myDID;
822 mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
823
824 mb->mbxCommand = MBX_REG_VPI;
825 mb->mbxOwner = OWN_HOST;
826 return;
827
828}
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846void
847lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
848{
849 MAILBOX_t *mb = &pmb->u.mb;
850 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
851
852 mb->un.varUnregVpi.vpi = vpi + phba->vpi_base;
853
854 mb->mbxCommand = MBX_UNREG_VPI;
855 mb->mbxOwner = OWN_HOST;
856 return;
857
858}
859
860
861
862
863
864
865
866
867static void
868lpfc_config_pcb_setup(struct lpfc_hba * phba)
869{
870 struct lpfc_sli *psli = &phba->sli;
871 struct lpfc_sli_ring *pring;
872 PCB_t *pcbp = phba->pcb;
873 dma_addr_t pdma_addr;
874 uint32_t offset;
875 uint32_t iocbCnt = 0;
876 int i;
877
878 pcbp->maxRing = (psli->num_rings - 1);
879
880 for (i = 0; i < psli->num_rings; i++) {
881 pring = &psli->ring[i];
882
883 pring->sizeCiocb = phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE:
884 SLI2_IOCB_CMD_SIZE;
885 pring->sizeRiocb = phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE:
886 SLI2_IOCB_RSP_SIZE;
887
888
889 if ((pring->numCiocb == 0) || (pring->numRiocb == 0)) {
890 pcbp->rdsc[i].cmdEntries = 0;
891 pcbp->rdsc[i].rspEntries = 0;
892 pcbp->rdsc[i].cmdAddrHigh = 0;
893 pcbp->rdsc[i].rspAddrHigh = 0;
894 pcbp->rdsc[i].cmdAddrLow = 0;
895 pcbp->rdsc[i].rspAddrLow = 0;
896 pring->cmdringaddr = NULL;
897 pring->rspringaddr = NULL;
898 continue;
899 }
900
901 pring->cmdringaddr = (void *)&phba->IOCBs[iocbCnt];
902 pcbp->rdsc[i].cmdEntries = pring->numCiocb;
903
904 offset = (uint8_t *) &phba->IOCBs[iocbCnt] -
905 (uint8_t *) phba->slim2p.virt;
906 pdma_addr = phba->slim2p.phys + offset;
907 pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
908 pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
909 iocbCnt += pring->numCiocb;
910
911
912 pring->rspringaddr = (void *) &phba->IOCBs[iocbCnt];
913
914 pcbp->rdsc[i].rspEntries = pring->numRiocb;
915 offset = (uint8_t *)&phba->IOCBs[iocbCnt] -
916 (uint8_t *)phba->slim2p.virt;
917 pdma_addr = phba->slim2p.phys + offset;
918 pcbp->rdsc[i].rspAddrHigh = putPaddrHigh(pdma_addr);
919 pcbp->rdsc[i].rspAddrLow = putPaddrLow(pdma_addr);
920 iocbCnt += pring->numRiocb;
921 }
922}
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938void
939lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
940{
941 MAILBOX_t *mb = &pmb->u.mb;
942 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
943 mb->un.varRdRev.cv = 1;
944 mb->un.varRdRev.v3req = 1;
945 mb->mbxCommand = MBX_READ_REV;
946 mb->mbxOwner = OWN_HOST;
947 return;
948}
949
950
951
952
953
954
955
956
957
958
959
960static void
961lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb,
962 struct lpfc_hbq_init *hbq_desc)
963{
964 hbqmb->profiles.profile2.seqlenbcnt = hbq_desc->seqlenbcnt;
965 hbqmb->profiles.profile2.maxlen = hbq_desc->maxlen;
966 hbqmb->profiles.profile2.seqlenoff = hbq_desc->seqlenoff;
967}
968
969
970
971
972
973
974
975
976
977
978
979static void
980lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb,
981 struct lpfc_hbq_init *hbq_desc)
982{
983 hbqmb->profiles.profile3.seqlenbcnt = hbq_desc->seqlenbcnt;
984 hbqmb->profiles.profile3.maxlen = hbq_desc->maxlen;
985 hbqmb->profiles.profile3.cmdcodeoff = hbq_desc->cmdcodeoff;
986 hbqmb->profiles.profile3.seqlenoff = hbq_desc->seqlenoff;
987 memcpy(&hbqmb->profiles.profile3.cmdmatch, hbq_desc->cmdmatch,
988 sizeof(hbqmb->profiles.profile3.cmdmatch));
989}
990
991
992
993
994
995
996
997
998
999
1000
1001
1002static void
1003lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb,
1004 struct lpfc_hbq_init *hbq_desc)
1005{
1006 hbqmb->profiles.profile5.seqlenbcnt = hbq_desc->seqlenbcnt;
1007 hbqmb->profiles.profile5.maxlen = hbq_desc->maxlen;
1008 hbqmb->profiles.profile5.cmdcodeoff = hbq_desc->cmdcodeoff;
1009 hbqmb->profiles.profile5.seqlenoff = hbq_desc->seqlenoff;
1010 memcpy(&hbqmb->profiles.profile5.cmdmatch, hbq_desc->cmdmatch,
1011 sizeof(hbqmb->profiles.profile5.cmdmatch));
1012}
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028void
1029lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id,
1030 struct lpfc_hbq_init *hbq_desc,
1031 uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb)
1032{
1033 int i;
1034 MAILBOX_t *mb = &pmb->u.mb;
1035 struct config_hbq_var *hbqmb = &mb->un.varCfgHbq;
1036
1037 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
1038 hbqmb->hbqId = id;
1039 hbqmb->entry_count = hbq_desc->entry_count;
1040 hbqmb->recvNotify = hbq_desc->rn;
1041
1042 hbqmb->numMask = hbq_desc->mask_count;
1043
1044 hbqmb->profile = hbq_desc->profile;
1045
1046
1047 hbqmb->ringMask = hbq_desc->ring_mask;
1048
1049
1050 hbqmb->headerLen = hbq_desc->headerLen;
1051
1052 hbqmb->logEntry = hbq_desc->logEntry;
1053
1054
1055
1056 hbqmb->hbqaddrLow = putPaddrLow(phba->hbqslimp.phys) +
1057 hbq_entry_index * sizeof(struct lpfc_hbq_entry);
1058 hbqmb->hbqaddrHigh = putPaddrHigh(phba->hbqslimp.phys);
1059
1060 mb->mbxCommand = MBX_CONFIG_HBQ;
1061 mb->mbxOwner = OWN_HOST;
1062
1063
1064
1065
1066 if (hbq_desc->profile == 2)
1067 lpfc_build_hbq_profile2(hbqmb, hbq_desc);
1068 else if (hbq_desc->profile == 3)
1069 lpfc_build_hbq_profile3(hbqmb, hbq_desc);
1070 else if (hbq_desc->profile == 5)
1071 lpfc_build_hbq_profile5(hbqmb, hbq_desc);
1072
1073
1074 if (!hbq_desc->mask_count)
1075 return;
1076
1077
1078 for (i = 0; i < hbq_desc->mask_count; i++) {
1079 hbqmb->hbqMasks[i].tmatch = hbq_desc->hbqMasks[i].tmatch;
1080 hbqmb->hbqMasks[i].tmask = hbq_desc->hbqMasks[i].tmask;
1081 hbqmb->hbqMasks[i].rctlmatch = hbq_desc->hbqMasks[i].rctlmatch;
1082 hbqmb->hbqMasks[i].rctlmask = hbq_desc->hbqMasks[i].rctlmask;
1083 }
1084
1085 return;
1086}
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105void
1106lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
1107{
1108 int i;
1109 MAILBOX_t *mb = &pmb->u.mb;
1110 struct lpfc_sli *psli;
1111 struct lpfc_sli_ring *pring;
1112
1113 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
1114
1115 mb->un.varCfgRing.ring = ring;
1116 mb->un.varCfgRing.maxOrigXchg = 0;
1117 mb->un.varCfgRing.maxRespXchg = 0;
1118 mb->un.varCfgRing.recvNotify = 1;
1119
1120 psli = &phba->sli;
1121 pring = &psli->ring[ring];
1122 mb->un.varCfgRing.numMask = pring->num_mask;
1123 mb->mbxCommand = MBX_CONFIG_RING;
1124 mb->mbxOwner = OWN_HOST;
1125
1126
1127 if (pring->prt[0].profile) {
1128 mb->un.varCfgRing.profile = pring->prt[0].profile;
1129 return;
1130 }
1131
1132
1133 for (i = 0; i < pring->num_mask; i++) {
1134 mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl;
1135 if (mb->un.varCfgRing.rrRegs[i].rval != FC_ELS_REQ)
1136 mb->un.varCfgRing.rrRegs[i].rmask = 0xff;
1137 else
1138 mb->un.varCfgRing.rrRegs[i].rmask = 0xfe;
1139 mb->un.varCfgRing.rrRegs[i].tval = pring->prt[i].type;
1140 mb->un.varCfgRing.rrRegs[i].tmask = 0xff;
1141 }
1142
1143 return;
1144}
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160void
1161lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1162{
1163 MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr;
1164 MAILBOX_t *mb = &pmb->u.mb;
1165 dma_addr_t pdma_addr;
1166 uint32_t bar_low, bar_high;
1167 size_t offset;
1168 struct lpfc_hgp hgp;
1169 int i;
1170 uint32_t pgp_offset;
1171
1172 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
1173 mb->mbxCommand = MBX_CONFIG_PORT;
1174 mb->mbxOwner = OWN_HOST;
1175
1176 mb->un.varCfgPort.pcbLen = sizeof(PCB_t);
1177
1178 offset = (uint8_t *)phba->pcb - (uint8_t *)phba->slim2p.virt;
1179 pdma_addr = phba->slim2p.phys + offset;
1180 mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
1181 mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
1182
1183
1184 mb->un.varCfgPort.hps = 1;
1185
1186
1187
1188 if (phba->sli_rev == LPFC_SLI_REV3 && phba->vpd.sli3Feat.cerbm) {
1189 if (phba->cfg_enable_bg)
1190 mb->un.varCfgPort.cbg = 1;
1191 mb->un.varCfgPort.cdss = 1;
1192 mb->un.varCfgPort.cerbm = 1;
1193 mb->un.varCfgPort.ccrp = 1;
1194 mb->un.varCfgPort.cinb = 1;
1195 mb->un.varCfgPort.max_hbq = lpfc_sli_hbq_count();
1196 if (phba->max_vpi && phba->cfg_enable_npiv &&
1197 phba->vpd.sli3Feat.cmv) {
1198 mb->un.varCfgPort.max_vpi = LPFC_MAX_VPI;
1199 mb->un.varCfgPort.cmv = 1;
1200 } else
1201 mb->un.varCfgPort.max_vpi = phba->max_vpi = 0;
1202 } else
1203 phba->sli_rev = LPFC_SLI_REV2;
1204 mb->un.varCfgPort.sli_mode = phba->sli_rev;
1205
1206
1207 phba->pcb->type = TYPE_NATIVE_SLI2;
1208 phba->pcb->feature = FEATURE_INITIAL_SLI2;
1209
1210
1211 phba->pcb->mailBoxSize = sizeof(MAILBOX_t);
1212 offset = (uint8_t *)phba->mbox - (uint8_t *)phba->slim2p.virt;
1213 pdma_addr = phba->slim2p.phys + offset;
1214 phba->pcb->mbAddrHigh = putPaddrHigh(pdma_addr);
1215 phba->pcb->mbAddrLow = putPaddrLow(pdma_addr);
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236 pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low);
1237 pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high);
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267 if (phba->sli_rev == 3) {
1268 phba->host_gp = &mb_slim->us.s3.host[0];
1269 phba->hbq_put = &mb_slim->us.s3.hbq_put[0];
1270 } else {
1271 phba->host_gp = &mb_slim->us.s2.host[0];
1272 phba->hbq_put = NULL;
1273 }
1274
1275
1276 phba->pcb->hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +
1277 (void __iomem *)phba->host_gp -
1278 (void __iomem *)phba->MBslimaddr;
1279 if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64)
1280 phba->pcb->hgpAddrHigh = bar_high;
1281 else
1282 phba->pcb->hgpAddrHigh = 0;
1283
1284 memset(&hgp, 0, sizeof(struct lpfc_hgp));
1285
1286 for (i=0; i < phba->sli.num_rings; i++) {
1287 lpfc_memcpy_to_slim(phba->host_gp + i, &hgp,
1288 sizeof(*phba->host_gp));
1289 }
1290
1291
1292 if (phba->sli_rev == 3)
1293 pgp_offset = offsetof(struct lpfc_sli2_slim,
1294 mbx.us.s3_pgp.port);
1295 else
1296 pgp_offset = offsetof(struct lpfc_sli2_slim, mbx.us.s2.port);
1297 pdma_addr = phba->slim2p.phys + pgp_offset;
1298 phba->pcb->pgpAddrHigh = putPaddrHigh(pdma_addr);
1299 phba->pcb->pgpAddrLow = putPaddrLow(pdma_addr);
1300
1301
1302 lpfc_config_pcb_setup(phba);
1303
1304
1305 if (lpfc_is_LC_HBA(phba->pcidev->device)) {
1306 uint32_t hbainit[5];
1307
1308 lpfc_hba_init(phba, hbainit);
1309
1310 memcpy(&mb->un.varCfgPort.hbainit, hbainit, 20);
1311 }
1312
1313
1314 lpfc_sli_pcimem_bcopy(phba->pcb, phba->pcb, sizeof(PCB_t));
1315}
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332void
1333lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
1334{
1335 MAILBOX_t *mb = &pmb->u.mb;
1336
1337 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
1338 mb->mbxCommand = MBX_KILL_BOARD;
1339 mb->mbxOwner = OWN_HOST;
1340 return;
1341}
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353void
1354lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
1355{
1356 struct lpfc_sli *psli;
1357
1358 psli = &phba->sli;
1359
1360 list_add_tail(&mbq->list, &psli->mboxq);
1361
1362 psli->mboxq_cnt++;
1363
1364 return;
1365}
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381LPFC_MBOXQ_t *
1382lpfc_mbox_get(struct lpfc_hba * phba)
1383{
1384 LPFC_MBOXQ_t *mbq = NULL;
1385 struct lpfc_sli *psli = &phba->sli;
1386
1387 list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list);
1388 if (mbq)
1389 psli->mboxq_cnt--;
1390
1391 return mbq;
1392}
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404void
1405__lpfc_mbox_cmpl_put(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbq)
1406{
1407 list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl);
1408}
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420void
1421lpfc_mbox_cmpl_put(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbq)
1422{
1423 unsigned long iflag;
1424
1425
1426 spin_lock_irqsave(&phba->hbalock, iflag);
1427 __lpfc_mbox_cmpl_put(phba, mbq);
1428 spin_unlock_irqrestore(&phba->hbalock, iflag);
1429 return;
1430}
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443int
1444lpfc_mbox_cmd_check(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1445{
1446
1447
1448
1449 if (mboxq->mbox_cmpl && mboxq->mbox_cmpl != lpfc_sli_def_mbox_cmpl &&
1450 mboxq->mbox_cmpl != lpfc_sli_wake_mbox_wait) {
1451 if (!mboxq->vport) {
1452 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_VPORT,
1453 "1814 Mbox x%x failed, no vport\n",
1454 mboxq->u.mb.mbxCommand);
1455 dump_stack();
1456 return -ENODEV;
1457 }
1458 }
1459 return 0;
1460}
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472int
1473lpfc_mbox_dev_check(struct lpfc_hba *phba)
1474{
1475
1476 if (unlikely(pci_channel_offline(phba->pcidev)))
1477 return -ENODEV;
1478
1479
1480 if (phba->link_state == LPFC_HBA_ERROR)
1481 return -ENODEV;
1482
1483 return 0;
1484}
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497int
1498lpfc_mbox_tmo_val(struct lpfc_hba *phba, int cmd)
1499{
1500 switch (cmd) {
1501 case MBX_WRITE_NV:
1502 case MBX_UPDATE_CFG:
1503 case MBX_DOWN_LOAD:
1504 case MBX_DEL_LD_ENTRY:
1505 case MBX_LOAD_AREA:
1506 case MBX_WRITE_WWN:
1507 case MBX_LOAD_EXP_ROM:
1508 return LPFC_MBOX_TMO_FLASH_CMD;
1509 case MBX_SLI4_CONFIG:
1510 return LPFC_MBOX_SLI4_CONFIG_TMO;
1511 }
1512 return LPFC_MBOX_TMO;
1513}
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525void
1526lpfc_sli4_mbx_sge_set(struct lpfcMboxq *mbox, uint32_t sgentry,
1527 dma_addr_t phyaddr, uint32_t length)
1528{
1529 struct lpfc_mbx_nembed_cmd *nembed_sge;
1530
1531 nembed_sge = (struct lpfc_mbx_nembed_cmd *)
1532 &mbox->u.mqe.un.nembed_cmd;
1533 nembed_sge->sge[sgentry].pa_lo = putPaddrLow(phyaddr);
1534 nembed_sge->sge[sgentry].pa_hi = putPaddrHigh(phyaddr);
1535 nembed_sge->sge[sgentry].length = length;
1536}
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546void
1547lpfc_sli4_mbx_sge_get(struct lpfcMboxq *mbox, uint32_t sgentry,
1548 struct lpfc_mbx_sge *sge)
1549{
1550 struct lpfc_mbx_nembed_cmd *nembed_sge;
1551
1552 nembed_sge = (struct lpfc_mbx_nembed_cmd *)
1553 &mbox->u.mqe.un.nembed_cmd;
1554 sge->pa_lo = nembed_sge->sge[sgentry].pa_lo;
1555 sge->pa_hi = nembed_sge->sge[sgentry].pa_hi;
1556 sge->length = nembed_sge->sge[sgentry].length;
1557}
1558
1559
1560
1561
1562
1563
1564
1565
1566void
1567lpfc_sli4_mbox_cmd_free(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
1568{
1569 struct lpfc_mbx_sli4_config *sli4_cfg;
1570 struct lpfc_mbx_sge sge;
1571 dma_addr_t phyaddr;
1572 uint32_t sgecount, sgentry;
1573
1574 sli4_cfg = &mbox->u.mqe.un.sli4_config;
1575
1576
1577 if (bf_get(lpfc_mbox_hdr_emb, &sli4_cfg->header.cfg_mhdr)) {
1578 mempool_free(mbox, phba->mbox_mem_pool);
1579 return;
1580 }
1581
1582
1583 sgecount = bf_get(lpfc_mbox_hdr_sge_cnt, &sli4_cfg->header.cfg_mhdr);
1584
1585 if (unlikely(!mbox->sge_array)) {
1586 mempool_free(mbox, phba->mbox_mem_pool);
1587 return;
1588 }
1589
1590 for (sgentry = 0; sgentry < sgecount; sgentry++) {
1591 lpfc_sli4_mbx_sge_get(mbox, sgentry, &sge);
1592 phyaddr = getPaddr(sge.pa_hi, sge.pa_lo);
1593 dma_free_coherent(&phba->pcidev->dev, PAGE_SIZE,
1594 mbox->sge_array->addr[sgentry], phyaddr);
1595 }
1596
1597 kfree(mbox->sge_array);
1598
1599 mempool_free(mbox, phba->mbox_mem_pool);
1600}
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616int
1617lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
1618 uint8_t subsystem, uint8_t opcode, uint32_t length, bool emb)
1619{
1620 struct lpfc_mbx_sli4_config *sli4_config;
1621 union lpfc_sli4_cfg_shdr *cfg_shdr = NULL;
1622 uint32_t alloc_len;
1623 uint32_t resid_len;
1624 uint32_t pagen, pcount;
1625 void *viraddr;
1626 dma_addr_t phyaddr;
1627
1628
1629 memset(mbox, 0, sizeof(*mbox));
1630 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_SLI4_CONFIG);
1631
1632
1633 sli4_config = &mbox->u.mqe.un.sli4_config;
1634
1635
1636 if (emb) {
1637
1638 bf_set(lpfc_mbox_hdr_emb, &sli4_config->header.cfg_mhdr, 1);
1639 sli4_config->header.cfg_mhdr.payload_length =
1640 LPFC_MBX_CMD_HDR_LENGTH + length;
1641
1642 bf_set(lpfc_mbox_hdr_opcode,
1643 &sli4_config->header.cfg_shdr.request, opcode);
1644 bf_set(lpfc_mbox_hdr_subsystem,
1645 &sli4_config->header.cfg_shdr.request, subsystem);
1646 sli4_config->header.cfg_shdr.request.request_length = length;
1647 return length;
1648 }
1649
1650
1651 pcount = (PAGE_ALIGN(length))/PAGE_SIZE;
1652 pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ?
1653 LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount;
1654
1655 mbox->sge_array = kmalloc(sizeof(struct lpfc_mbx_nembed_sge_virt),
1656 GFP_KERNEL);
1657 if (!mbox->sge_array)
1658 return 0;
1659
1660 for (pagen = 0, alloc_len = 0; pagen < pcount; pagen++) {
1661
1662
1663
1664
1665
1666 viraddr = dma_alloc_coherent(&phba->pcidev->dev, PAGE_SIZE,
1667 &phyaddr, GFP_KERNEL);
1668
1669 if (!viraddr)
1670 break;
1671 memset(viraddr, 0, PAGE_SIZE);
1672 mbox->sge_array->addr[pagen] = viraddr;
1673
1674 if (pagen == 0)
1675 cfg_shdr = (union lpfc_sli4_cfg_shdr *)viraddr;
1676 resid_len = length - alloc_len;
1677 if (resid_len > PAGE_SIZE) {
1678 lpfc_sli4_mbx_sge_set(mbox, pagen, phyaddr,
1679 PAGE_SIZE);
1680 alloc_len += PAGE_SIZE;
1681 } else {
1682 lpfc_sli4_mbx_sge_set(mbox, pagen, phyaddr,
1683 resid_len);
1684 alloc_len = length;
1685 }
1686 }
1687
1688
1689 sli4_config->header.cfg_mhdr.payload_length = alloc_len;
1690 bf_set(lpfc_mbox_hdr_sge_cnt, &sli4_config->header.cfg_mhdr, pagen);
1691
1692
1693 if (pagen > 0) {
1694 bf_set(lpfc_mbox_hdr_opcode, &cfg_shdr->request, opcode);
1695 bf_set(lpfc_mbox_hdr_subsystem, &cfg_shdr->request, subsystem);
1696 cfg_shdr->request.request_length =
1697 alloc_len - sizeof(union lpfc_sli4_cfg_shdr);
1698 }
1699
1700 lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr,
1701 sizeof(union lpfc_sli4_cfg_shdr));
1702
1703 return alloc_len;
1704}
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716uint8_t
1717lpfc_sli4_mbox_opcode_get(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
1718{
1719 struct lpfc_mbx_sli4_config *sli4_cfg;
1720 union lpfc_sli4_cfg_shdr *cfg_shdr;
1721
1722 if (mbox->u.mb.mbxCommand != MBX_SLI4_CONFIG)
1723 return 0;
1724 sli4_cfg = &mbox->u.mqe.un.sli4_config;
1725
1726
1727 if (bf_get(lpfc_mbox_hdr_emb, &sli4_cfg->header.cfg_mhdr)) {
1728 cfg_shdr = &mbox->u.mqe.un.sli4_config.header.cfg_shdr;
1729 return bf_get(lpfc_mbox_hdr_opcode, &cfg_shdr->request);
1730 }
1731
1732
1733 if (unlikely(!mbox->sge_array))
1734 return 0;
1735 cfg_shdr = (union lpfc_sli4_cfg_shdr *)mbox->sge_array->addr[0];
1736 return bf_get(lpfc_mbox_hdr_opcode, &cfg_shdr->request);
1737}
1738
1739
1740
1741
1742
1743
1744
1745
1746void
1747lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)
1748{
1749
1750 memset(mboxq, 0, sizeof(LPFC_MBOXQ_t));
1751 bf_set(lpfc_mqe_command, &mboxq->u.mqe, MBX_SLI4_REQ_FTRS);
1752
1753
1754 bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1);
1755
1756 if (phba->cfg_enable_fip)
1757 bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 0);
1758 else
1759 bf_set(lpfc_mbx_rq_ftr_rq_ifip, &mboxq->u.mqe.un.req_ftrs, 1);
1760
1761
1762 if (phba->cfg_enable_bg)
1763 bf_set(lpfc_mbx_rq_ftr_rq_dif, &mboxq->u.mqe.un.req_ftrs, 1);
1764
1765
1766 if (phba->max_vpi && phba->cfg_enable_npiv)
1767 bf_set(lpfc_mbx_rq_ftr_rq_npiv, &mboxq->u.mqe.un.req_ftrs, 1);
1768
1769 return;
1770}
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783void
1784lpfc_init_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
1785{
1786 struct lpfc_mbx_init_vfi *init_vfi;
1787
1788 memset(mbox, 0, sizeof(*mbox));
1789 init_vfi = &mbox->u.mqe.un.init_vfi;
1790 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VFI);
1791 bf_set(lpfc_init_vfi_vr, init_vfi, 1);
1792 bf_set(lpfc_init_vfi_vt, init_vfi, 1);
1793 bf_set(lpfc_init_vfi_vfi, init_vfi, vport->vfi + vport->phba->vfi_base);
1794 bf_set(lpfc_init_vfi_fcfi, init_vfi, vport->phba->fcf.fcfi);
1795}
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808void
1809lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys)
1810{
1811 struct lpfc_mbx_reg_vfi *reg_vfi;
1812
1813 memset(mbox, 0, sizeof(*mbox));
1814 reg_vfi = &mbox->u.mqe.un.reg_vfi;
1815 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_VFI);
1816 bf_set(lpfc_reg_vfi_vp, reg_vfi, 1);
1817 bf_set(lpfc_reg_vfi_vfi, reg_vfi, vport->vfi + vport->phba->vfi_base);
1818 bf_set(lpfc_reg_vfi_fcfi, reg_vfi, vport->phba->fcf.fcfi);
1819 bf_set(lpfc_reg_vfi_vpi, reg_vfi, vport->vpi + vport->phba->vpi_base);
1820 reg_vfi->bde.addrHigh = putPaddrHigh(phys);
1821 reg_vfi->bde.addrLow = putPaddrLow(phys);
1822 reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
1823 reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
1824 bf_set(lpfc_reg_vfi_nport_id, reg_vfi, vport->fc_myDID);
1825}
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839void
1840lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi)
1841{
1842 memset(mbox, 0, sizeof(*mbox));
1843 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI);
1844 bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi,
1845 vpi + phba->vpi_base);
1846 bf_set(lpfc_init_vpi_vfi, &mbox->u.mqe.un.init_vpi,
1847 phba->pport->vfi + phba->vfi_base);
1848}
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861void
1862lpfc_unreg_vfi(struct lpfcMboxq *mbox, uint16_t vfi)
1863{
1864 memset(mbox, 0, sizeof(*mbox));
1865 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI);
1866 bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi, vfi);
1867}
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877int
1878lpfc_dump_fcoe_param(struct lpfc_hba *phba,
1879 struct lpfcMboxq *mbox)
1880{
1881 struct lpfc_dmabuf *mp = NULL;
1882 MAILBOX_t *mb;
1883
1884 memset(mbox, 0, sizeof(*mbox));
1885 mb = &mbox->u.mb;
1886
1887 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
1888 if (mp)
1889 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
1890
1891 if (!mp || !mp->virt) {
1892 kfree(mp);
1893
1894 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
1895 "2569 lpfc_dump_fcoe_param: memory"
1896 " allocation failed\n");
1897 return 1;
1898 }
1899
1900 memset(mp->virt, 0, LPFC_BPL_SIZE);
1901 INIT_LIST_HEAD(&mp->list);
1902
1903
1904 mbox->context1 = (uint8_t *) mp;
1905
1906 mb->mbxCommand = MBX_DUMP_MEMORY;
1907 mb->un.varDmp.type = DMP_NV_PARAMS;
1908 mb->un.varDmp.region_id = DMP_REGION_23;
1909 mb->un.varDmp.sli4_length = DMP_RGN23_SIZE;
1910 mb->un.varWords[3] = putPaddrLow(mp->phys);
1911 mb->un.varWords[4] = putPaddrHigh(mp->phys);
1912 return 0;
1913}
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928void
1929lpfc_reg_fcfi(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
1930{
1931 struct lpfc_mbx_reg_fcfi *reg_fcfi;
1932
1933 memset(mbox, 0, sizeof(*mbox));
1934 reg_fcfi = &mbox->u.mqe.un.reg_fcfi;
1935 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_FCFI);
1936 bf_set(lpfc_reg_fcfi_rq_id0, reg_fcfi, phba->sli4_hba.hdr_rq->queue_id);
1937 bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi, REG_FCF_INVALID_QID);
1938 bf_set(lpfc_reg_fcfi_rq_id2, reg_fcfi, REG_FCF_INVALID_QID);
1939 bf_set(lpfc_reg_fcfi_rq_id3, reg_fcfi, REG_FCF_INVALID_QID);
1940 bf_set(lpfc_reg_fcfi_info_index, reg_fcfi, phba->fcf.fcf_indx);
1941
1942 bf_set(lpfc_reg_fcfi_mam, reg_fcfi,
1943 (~phba->fcf.addr_mode) & 0x3);
1944 if (phba->fcf.fcf_flag & FCF_VALID_VLAN) {
1945 bf_set(lpfc_reg_fcfi_vv, reg_fcfi, 1);
1946 bf_set(lpfc_reg_fcfi_vlan_tag, reg_fcfi, phba->fcf.vlan_id);
1947 }
1948}
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958void
1959lpfc_unreg_fcfi(struct lpfcMboxq *mbox, uint16_t fcfi)
1960{
1961 memset(mbox, 0, sizeof(*mbox));
1962 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_FCFI);
1963 bf_set(lpfc_unreg_fcfi, &mbox->u.mqe.un.unreg_fcfi, fcfi);
1964}
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974void
1975lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp)
1976{
1977 struct lpfc_mbx_resume_rpi *resume_rpi;
1978
1979 memset(mbox, 0, sizeof(*mbox));
1980 resume_rpi = &mbox->u.mqe.un.resume_rpi;
1981 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI);
1982 bf_set(lpfc_resume_rpi_index, resume_rpi, ndlp->nlp_rpi);
1983 bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI);
1984 resume_rpi->event_tag = ndlp->phba->fc_eventTag;
1985}
1986