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_device.h>
30#include <scsi/scsi_transport_fc.h>
31#include <scsi/scsi.h>
32#include <scsi/fc/fc_fs.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_compat.h"
45
46
47
48
49
50
51
52
53
54
55
56
57
58int
59lpfc_dump_static_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb,
60 uint16_t offset)
61{
62 MAILBOX_t *mb;
63 struct lpfc_dmabuf *mp;
64
65 mb = &pmb->u.mb;
66
67
68 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
69 mb->mbxCommand = MBX_DUMP_MEMORY;
70 mb->un.varDmp.type = DMP_NV_PARAMS;
71 mb->un.varDmp.entry_index = offset;
72 mb->un.varDmp.region_id = DMP_REGION_VPORT;
73 mb->mbxOwner = OWN_HOST;
74
75
76 if (phba->sli_rev != LPFC_SLI_REV4) {
77 mb->un.varDmp.cv = 1;
78 mb->un.varDmp.word_cnt = DMP_RSP_SIZE/sizeof(uint32_t);
79 return 0;
80 }
81
82
83 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
84 if (mp)
85 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
86
87 if (!mp || !mp->virt) {
88 kfree(mp);
89 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
90 "2605 lpfc_dump_static_vport: memory"
91 " allocation failed\n");
92 return 1;
93 }
94 memset(mp->virt, 0, LPFC_BPL_SIZE);
95 INIT_LIST_HEAD(&mp->list);
96
97 pmb->context1 = (uint8_t *)mp;
98 mb->un.varWords[3] = putPaddrLow(mp->phys);
99 mb->un.varWords[4] = putPaddrHigh(mp->phys);
100 mb->un.varDmp.sli4_length = sizeof(struct static_vport_info);
101
102 return 0;
103}
104
105
106
107
108
109
110
111
112void
113lpfc_down_link(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
114{
115 MAILBOX_t *mb;
116 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
117 mb = &pmb->u.mb;
118 mb->mbxCommand = MBX_DOWN_LINK;
119 mb->mbxOwner = OWN_HOST;
120}
121
122
123
124
125
126
127
128
129
130
131
132
133
134void
135lpfc_dump_mem(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, uint16_t offset,
136 uint16_t region_id)
137{
138 MAILBOX_t *mb;
139 void *ctx;
140
141 mb = &pmb->u.mb;
142 ctx = pmb->context2;
143
144
145 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
146 mb->mbxCommand = MBX_DUMP_MEMORY;
147 mb->un.varDmp.cv = 1;
148 mb->un.varDmp.type = DMP_NV_PARAMS;
149 mb->un.varDmp.entry_index = offset;
150 mb->un.varDmp.region_id = region_id;
151 mb->un.varDmp.word_cnt = (DMP_RSP_SIZE / sizeof (uint32_t));
152 mb->un.varDmp.co = 0;
153 mb->un.varDmp.resp_offset = 0;
154 pmb->context2 = ctx;
155 mb->mbxOwner = OWN_HOST;
156 return;
157}
158
159
160
161
162
163
164
165
166
167void
168lpfc_dump_wakeup_param(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
169{
170 MAILBOX_t *mb;
171 void *ctx;
172
173 mb = &pmb->u.mb;
174
175 ctx = pmb->context2;
176
177
178 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
179 mb->mbxCommand = MBX_DUMP_MEMORY;
180 mb->mbxOwner = OWN_HOST;
181 mb->un.varDmp.cv = 1;
182 mb->un.varDmp.type = DMP_NV_PARAMS;
183 if (phba->sli_rev < LPFC_SLI_REV4)
184 mb->un.varDmp.entry_index = 0;
185 mb->un.varDmp.region_id = WAKE_UP_PARMS_REGION_ID;
186 mb->un.varDmp.word_cnt = WAKE_UP_PARMS_WORD_SIZE;
187 mb->un.varDmp.co = 0;
188 mb->un.varDmp.resp_offset = 0;
189 pmb->context2 = ctx;
190 return;
191}
192
193
194
195
196
197
198
199
200
201
202
203
204void
205lpfc_read_nv(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
206{
207 MAILBOX_t *mb;
208
209 mb = &pmb->u.mb;
210 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
211 mb->mbxCommand = MBX_READ_NV;
212 mb->mbxOwner = OWN_HOST;
213 return;
214}
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229void
230lpfc_config_async(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb,
231 uint32_t ring)
232{
233 MAILBOX_t *mb;
234
235 mb = &pmb->u.mb;
236 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
237 mb->mbxCommand = MBX_ASYNCEVT_ENABLE;
238 mb->un.varCfgAsyncEvent.ring = ring;
239 mb->mbxOwner = OWN_HOST;
240 return;
241}
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256void
257lpfc_heart_beat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
258{
259 MAILBOX_t *mb;
260
261 mb = &pmb->u.mb;
262 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
263 mb->mbxCommand = MBX_HEARTBEAT;
264 mb->mbxOwner = OWN_HOST;
265 return;
266}
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289int
290lpfc_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb,
291 struct lpfc_dmabuf *mp)
292{
293 MAILBOX_t *mb;
294
295 mb = &pmb->u.mb;
296 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
297
298 INIT_LIST_HEAD(&mp->list);
299 mb->mbxCommand = MBX_READ_TOPOLOGY;
300 mb->un.varReadTop.lilpBde64.tus.f.bdeSize = LPFC_ALPA_MAP_SIZE;
301 mb->un.varReadTop.lilpBde64.addrHigh = putPaddrHigh(mp->phys);
302 mb->un.varReadTop.lilpBde64.addrLow = putPaddrLow(mp->phys);
303
304
305
306
307 pmb->context1 = (uint8_t *)mp;
308 mb->mbxOwner = OWN_HOST;
309 return (0);
310}
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327void
328lpfc_clear_la(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
329{
330 MAILBOX_t *mb;
331
332 mb = &pmb->u.mb;
333 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
334
335 mb->un.varClearLA.eventTag = phba->fc_eventTag;
336 mb->mbxCommand = MBX_CLEAR_LA;
337 mb->mbxOwner = OWN_HOST;
338 return;
339}
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355void
356lpfc_config_link(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
357{
358 struct lpfc_vport *vport = phba->pport;
359 MAILBOX_t *mb = &pmb->u.mb;
360 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
361
362
363
364
365 if (phba->cfg_cr_delay && (phba->sli_rev < LPFC_SLI_REV4)) {
366 mb->un.varCfgLnk.cr = 1;
367 mb->un.varCfgLnk.ci = 1;
368 mb->un.varCfgLnk.cr_delay = phba->cfg_cr_delay;
369 mb->un.varCfgLnk.cr_count = phba->cfg_cr_count;
370 }
371
372 mb->un.varCfgLnk.myId = vport->fc_myDID;
373 mb->un.varCfgLnk.edtov = phba->fc_edtov;
374 mb->un.varCfgLnk.arbtov = phba->fc_arbtov;
375 mb->un.varCfgLnk.ratov = phba->fc_ratov;
376 mb->un.varCfgLnk.rttov = phba->fc_rttov;
377 mb->un.varCfgLnk.altov = phba->fc_altov;
378 mb->un.varCfgLnk.crtov = phba->fc_crtov;
379 mb->un.varCfgLnk.cscn = 0;
380 if (phba->bbcredit_support && phba->cfg_enable_bbcr) {
381 mb->un.varCfgLnk.cscn = 1;
382 mb->un.varCfgLnk.bbscn = bf_get(lpfc_bbscn_def,
383 &phba->sli4_hba.bbscn_params);
384 }
385
386 if (phba->cfg_ack0 && (phba->sli_rev < LPFC_SLI_REV4))
387 mb->un.varCfgLnk.ack0_enable = 1;
388
389 mb->mbxCommand = MBX_CONFIG_LINK;
390 mb->mbxOwner = OWN_HOST;
391 return;
392}
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407int
408lpfc_config_msi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
409{
410 MAILBOX_t *mb = &pmb->u.mb;
411 uint32_t attentionConditions[2];
412
413
414 if (phba->cfg_use_msi != 2) {
415 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
416 "0475 Not configured for supporting MSI-X "
417 "cfg_use_msi: 0x%x\n", phba->cfg_use_msi);
418 return -EINVAL;
419 }
420
421 if (phba->sli_rev < 3) {
422 lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
423 "0476 HBA not supporting SLI-3 or later "
424 "SLI Revision: 0x%x\n", phba->sli_rev);
425 return -EINVAL;
426 }
427
428
429 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
430
431
432
433
434
435
436 attentionConditions[0] = (HA_R0ATT | HA_R1ATT | HA_R2ATT | HA_ERATT |
437 HA_LATT | HA_MBATT);
438 attentionConditions[1] = 0;
439
440 mb->un.varCfgMSI.attentionConditions[0] = attentionConditions[0];
441 mb->un.varCfgMSI.attentionConditions[1] = attentionConditions[1];
442
443
444
445
446#ifdef __BIG_ENDIAN_BITFIELD
447
448 mb->un.varCfgMSI.messageNumberByHA[HA_R0_POS] = 1;
449
450 mb->un.varCfgMSI.messageNumberByHA[HA_R1_POS] = 1;
451#else
452
453 mb->un.varCfgMSI.messageNumberByHA[HA_R0_POS^3] = 1;
454
455 mb->un.varCfgMSI.messageNumberByHA[HA_R1_POS^3] = 1;
456#endif
457
458 mb->un.varCfgMSI.autoClearHA[0] = attentionConditions[0];
459 mb->un.varCfgMSI.autoClearHA[1] = attentionConditions[1];
460
461
462 mb->un.varCfgMSI.autoClearHA[0] = 0;
463 mb->un.varCfgMSI.autoClearHA[1] = 0;
464
465
466 mb->mbxCommand = MBX_CONFIG_MSI;
467 mb->mbxOwner = OWN_HOST;
468
469 return 0;
470}
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486void
487lpfc_init_link(struct lpfc_hba * phba,
488 LPFC_MBOXQ_t * pmb, uint32_t topology, uint32_t linkspeed)
489{
490 lpfc_vpd_t *vpd;
491 MAILBOX_t *mb;
492
493 mb = &pmb->u.mb;
494 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
495
496 switch (topology) {
497 case FLAGS_TOPOLOGY_MODE_LOOP_PT:
498 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
499 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
500 break;
501 case FLAGS_TOPOLOGY_MODE_PT_PT:
502 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
503 break;
504 case FLAGS_TOPOLOGY_MODE_LOOP:
505 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_LOOP;
506 break;
507 case FLAGS_TOPOLOGY_MODE_PT_LOOP:
508 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
509 mb->un.varInitLnk.link_flags |= FLAGS_TOPOLOGY_FAILOVER;
510 break;
511 case FLAGS_LOCAL_LB:
512 mb->un.varInitLnk.link_flags = FLAGS_LOCAL_LB;
513 break;
514 }
515
516 if (phba->pcidev->device == PCI_DEVICE_ID_LANCER_G6_FC &&
517 mb->un.varInitLnk.link_flags & FLAGS_TOPOLOGY_MODE_LOOP) {
518
519 mb->un.varInitLnk.link_flags = FLAGS_TOPOLOGY_MODE_PT_PT;
520 phba->cfg_topology = FLAGS_TOPOLOGY_MODE_PT_PT;
521 }
522
523
524 mb->un.varInitLnk.link_flags |= FLAGS_IMED_ABORT;
525
526
527
528
529 vpd = &phba->vpd;
530 if (vpd->rev.feaLevelHigh >= 0x02){
531 switch(linkspeed){
532 case LPFC_USER_LINK_SPEED_1G:
533 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
534 mb->un.varInitLnk.link_speed = LINK_SPEED_1G;
535 break;
536 case LPFC_USER_LINK_SPEED_2G:
537 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
538 mb->un.varInitLnk.link_speed = LINK_SPEED_2G;
539 break;
540 case LPFC_USER_LINK_SPEED_4G:
541 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
542 mb->un.varInitLnk.link_speed = LINK_SPEED_4G;
543 break;
544 case LPFC_USER_LINK_SPEED_8G:
545 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
546 mb->un.varInitLnk.link_speed = LINK_SPEED_8G;
547 break;
548 case LPFC_USER_LINK_SPEED_10G:
549 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
550 mb->un.varInitLnk.link_speed = LINK_SPEED_10G;
551 break;
552 case LPFC_USER_LINK_SPEED_16G:
553 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
554 mb->un.varInitLnk.link_speed = LINK_SPEED_16G;
555 break;
556 case LPFC_USER_LINK_SPEED_32G:
557 mb->un.varInitLnk.link_flags |= FLAGS_LINK_SPEED;
558 mb->un.varInitLnk.link_speed = LINK_SPEED_32G;
559 break;
560 case LPFC_USER_LINK_SPEED_AUTO:
561 default:
562 mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
563 break;
564 }
565
566 }
567 else
568 mb->un.varInitLnk.link_speed = LINK_SPEED_AUTO;
569
570 mb->mbxCommand = (volatile uint8_t)MBX_INIT_LINK;
571 mb->mbxOwner = OWN_HOST;
572 mb->un.varInitLnk.fabric_AL_PA = phba->fc_pref_ALPA;
573 return;
574}
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597int
598lpfc_read_sparam(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb, int vpi)
599{
600 struct lpfc_dmabuf *mp;
601 MAILBOX_t *mb;
602
603 mb = &pmb->u.mb;
604 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
605
606 mb->mbxOwner = OWN_HOST;
607
608
609
610 mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
611 if (mp)
612 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
613 if (!mp || !mp->virt) {
614 kfree(mp);
615 mb->mbxCommand = MBX_READ_SPARM64;
616
617 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
618 "0301 READ_SPARAM: no buffers\n");
619 return (1);
620 }
621 INIT_LIST_HEAD(&mp->list);
622 mb->mbxCommand = MBX_READ_SPARM64;
623 mb->un.varRdSparm.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
624 mb->un.varRdSparm.un.sp64.addrHigh = putPaddrHigh(mp->phys);
625 mb->un.varRdSparm.un.sp64.addrLow = putPaddrLow(mp->phys);
626 if (phba->sli_rev >= LPFC_SLI_REV3)
627 mb->un.varRdSparm.vpi = phba->vpi_ids[vpi];
628
629
630 pmb->context1 = mp;
631
632 return (0);
633}
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650void
651lpfc_unreg_did(struct lpfc_hba * phba, uint16_t vpi, uint32_t did,
652 LPFC_MBOXQ_t * pmb)
653{
654 MAILBOX_t *mb;
655
656 mb = &pmb->u.mb;
657 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
658
659 mb->un.varUnregDID.did = did;
660 mb->un.varUnregDID.vpi = vpi;
661 if ((vpi != 0xffff) &&
662 (phba->sli_rev == LPFC_SLI_REV4))
663 mb->un.varUnregDID.vpi = phba->vpi_ids[vpi];
664
665 mb->mbxCommand = MBX_UNREG_D_ID;
666 mb->mbxOwner = OWN_HOST;
667 return;
668}
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683void
684lpfc_read_config(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
685{
686 MAILBOX_t *mb;
687
688 mb = &pmb->u.mb;
689 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
690
691 mb->mbxCommand = MBX_READ_CONFIG;
692 mb->mbxOwner = OWN_HOST;
693 return;
694}
695
696
697
698
699
700
701
702
703
704
705
706
707
708void
709lpfc_read_lnk_stat(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
710{
711 MAILBOX_t *mb;
712
713 mb = &pmb->u.mb;
714 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
715
716 mb->mbxCommand = MBX_READ_LNK_STAT;
717 mb->mbxOwner = OWN_HOST;
718 return;
719}
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745int
746lpfc_reg_rpi(struct lpfc_hba *phba, uint16_t vpi, uint32_t did,
747 uint8_t *param, LPFC_MBOXQ_t *pmb, uint16_t rpi)
748{
749 MAILBOX_t *mb = &pmb->u.mb;
750 uint8_t *sparam;
751 struct lpfc_dmabuf *mp;
752
753 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
754
755 mb->un.varRegLogin.rpi = 0;
756 if (phba->sli_rev == LPFC_SLI_REV4)
757 mb->un.varRegLogin.rpi = phba->sli4_hba.rpi_ids[rpi];
758 if (phba->sli_rev >= LPFC_SLI_REV3)
759 mb->un.varRegLogin.vpi = phba->vpi_ids[vpi];
760 mb->un.varRegLogin.did = did;
761 mb->mbxOwner = OWN_HOST;
762
763 mp = kmalloc(sizeof (struct lpfc_dmabuf), GFP_KERNEL);
764 if (mp)
765 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
766 if (!mp || !mp->virt) {
767 kfree(mp);
768 mb->mbxCommand = MBX_REG_LOGIN64;
769
770 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
771 "0302 REG_LOGIN: no buffers, VPI:%d DID:x%x, "
772 "rpi x%x\n", vpi, did, rpi);
773 return 1;
774 }
775 INIT_LIST_HEAD(&mp->list);
776 sparam = mp->virt;
777
778
779 memcpy(sparam, param, sizeof (struct serv_parm));
780
781
782 pmb->context1 = (uint8_t *) mp;
783
784 mb->mbxCommand = MBX_REG_LOGIN64;
785 mb->un.varRegLogin.un.sp64.tus.f.bdeSize = sizeof (struct serv_parm);
786 mb->un.varRegLogin.un.sp64.addrHigh = putPaddrHigh(mp->phys);
787 mb->un.varRegLogin.un.sp64.addrLow = putPaddrLow(mp->phys);
788
789 return 0;
790}
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809void
810lpfc_unreg_login(struct lpfc_hba *phba, uint16_t vpi, uint32_t rpi,
811 LPFC_MBOXQ_t * pmb)
812{
813 MAILBOX_t *mb;
814
815 mb = &pmb->u.mb;
816 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
817
818 mb->un.varUnregLogin.rpi = rpi;
819 mb->un.varUnregLogin.rsvd1 = 0;
820 if (phba->sli_rev >= LPFC_SLI_REV3)
821 mb->un.varUnregLogin.vpi = phba->vpi_ids[vpi];
822
823 mb->mbxCommand = MBX_UNREG_LOGIN;
824 mb->mbxOwner = OWN_HOST;
825
826 return;
827}
828
829
830
831
832
833
834
835
836void
837lpfc_sli4_unreg_all_rpis(struct lpfc_vport *vport)
838{
839 struct lpfc_hba *phba = vport->phba;
840 LPFC_MBOXQ_t *mbox;
841 int rc;
842
843 mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
844 if (mbox) {
845
846
847
848
849
850
851
852 lpfc_unreg_login(phba, vport->vpi, phba->vpi_ids[vport->vpi],
853 mbox);
854 mbox->u.mb.un.varUnregLogin.rsvd1 = 0x4000;
855 mbox->vport = vport;
856 mbox->mbox_cmpl = lpfc_sli_def_mbox_cmpl;
857 mbox->context1 = NULL;
858 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
859 if (rc == MBX_NOT_FINISHED)
860 mempool_free(mbox, phba->mbox_mem_pool);
861 }
862}
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879void
880lpfc_reg_vpi(struct lpfc_vport *vport, LPFC_MBOXQ_t *pmb)
881{
882 MAILBOX_t *mb = &pmb->u.mb;
883 struct lpfc_hba *phba = vport->phba;
884
885 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
886
887
888
889 if ((phba->sli_rev == LPFC_SLI_REV4) &&
890 !(vport->fc_flag & FC_VPORT_NEEDS_REG_VPI))
891 mb->un.varRegVpi.upd = 1;
892
893 mb->un.varRegVpi.vpi = phba->vpi_ids[vport->vpi];
894 mb->un.varRegVpi.sid = vport->fc_myDID;
895 if (phba->sli_rev == LPFC_SLI_REV4)
896 mb->un.varRegVpi.vfi = phba->sli4_hba.vfi_ids[vport->vfi];
897 else
898 mb->un.varRegVpi.vfi = vport->vfi + vport->phba->vfi_base;
899 memcpy(mb->un.varRegVpi.wwn, &vport->fc_portname,
900 sizeof(struct lpfc_name));
901 mb->un.varRegVpi.wwn[0] = cpu_to_le32(mb->un.varRegVpi.wwn[0]);
902 mb->un.varRegVpi.wwn[1] = cpu_to_le32(mb->un.varRegVpi.wwn[1]);
903
904 mb->mbxCommand = MBX_REG_VPI;
905 mb->mbxOwner = OWN_HOST;
906 return;
907
908}
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926void
927lpfc_unreg_vpi(struct lpfc_hba *phba, uint16_t vpi, LPFC_MBOXQ_t *pmb)
928{
929 MAILBOX_t *mb = &pmb->u.mb;
930 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
931
932 if (phba->sli_rev == LPFC_SLI_REV3)
933 mb->un.varUnregVpi.vpi = phba->vpi_ids[vpi];
934 else if (phba->sli_rev >= LPFC_SLI_REV4)
935 mb->un.varUnregVpi.sli4_vpi = phba->vpi_ids[vpi];
936
937 mb->mbxCommand = MBX_UNREG_VPI;
938 mb->mbxOwner = OWN_HOST;
939 return;
940
941}
942
943
944
945
946
947
948
949
950static void
951lpfc_config_pcb_setup(struct lpfc_hba * phba)
952{
953 struct lpfc_sli *psli = &phba->sli;
954 struct lpfc_sli_ring *pring;
955 PCB_t *pcbp = phba->pcb;
956 dma_addr_t pdma_addr;
957 uint32_t offset;
958 uint32_t iocbCnt = 0;
959 int i;
960
961 pcbp->maxRing = (psli->num_rings - 1);
962
963 for (i = 0; i < psli->num_rings; i++) {
964 pring = &psli->sli3_ring[i];
965
966 pring->sli.sli3.sizeCiocb =
967 phba->sli_rev == 3 ? SLI3_IOCB_CMD_SIZE :
968 SLI2_IOCB_CMD_SIZE;
969 pring->sli.sli3.sizeRiocb =
970 phba->sli_rev == 3 ? SLI3_IOCB_RSP_SIZE :
971 SLI2_IOCB_RSP_SIZE;
972
973
974 if ((pring->sli.sli3.numCiocb == 0) ||
975 (pring->sli.sli3.numRiocb == 0)) {
976 pcbp->rdsc[i].cmdEntries = 0;
977 pcbp->rdsc[i].rspEntries = 0;
978 pcbp->rdsc[i].cmdAddrHigh = 0;
979 pcbp->rdsc[i].rspAddrHigh = 0;
980 pcbp->rdsc[i].cmdAddrLow = 0;
981 pcbp->rdsc[i].rspAddrLow = 0;
982 pring->sli.sli3.cmdringaddr = NULL;
983 pring->sli.sli3.rspringaddr = NULL;
984 continue;
985 }
986
987 pring->sli.sli3.cmdringaddr = (void *)&phba->IOCBs[iocbCnt];
988 pcbp->rdsc[i].cmdEntries = pring->sli.sli3.numCiocb;
989
990 offset = (uint8_t *) &phba->IOCBs[iocbCnt] -
991 (uint8_t *) phba->slim2p.virt;
992 pdma_addr = phba->slim2p.phys + offset;
993 pcbp->rdsc[i].cmdAddrHigh = putPaddrHigh(pdma_addr);
994 pcbp->rdsc[i].cmdAddrLow = putPaddrLow(pdma_addr);
995 iocbCnt += pring->sli.sli3.numCiocb;
996
997
998 pring->sli.sli3.rspringaddr = (void *) &phba->IOCBs[iocbCnt];
999
1000 pcbp->rdsc[i].rspEntries = pring->sli.sli3.numRiocb;
1001 offset = (uint8_t *)&phba->IOCBs[iocbCnt] -
1002 (uint8_t *)phba->slim2p.virt;
1003 pdma_addr = phba->slim2p.phys + offset;
1004 pcbp->rdsc[i].rspAddrHigh = putPaddrHigh(pdma_addr);
1005 pcbp->rdsc[i].rspAddrLow = putPaddrLow(pdma_addr);
1006 iocbCnt += pring->sli.sli3.numRiocb;
1007 }
1008}
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024void
1025lpfc_read_rev(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
1026{
1027 MAILBOX_t *mb = &pmb->u.mb;
1028 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
1029 mb->un.varRdRev.cv = 1;
1030 mb->un.varRdRev.v3req = 1;
1031 mb->mbxCommand = MBX_READ_REV;
1032 mb->mbxOwner = OWN_HOST;
1033 return;
1034}
1035
1036void
1037lpfc_sli4_swap_str(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1038{
1039 MAILBOX_t *mb = &pmb->u.mb;
1040 struct lpfc_mqe *mqe;
1041
1042 switch (mb->mbxCommand) {
1043 case MBX_READ_REV:
1044 mqe = &pmb->u.mqe;
1045 lpfc_sli_pcimem_bcopy(mqe->un.read_rev.fw_name,
1046 mqe->un.read_rev.fw_name, 16);
1047 lpfc_sli_pcimem_bcopy(mqe->un.read_rev.ulp_fw_name,
1048 mqe->un.read_rev.ulp_fw_name, 16);
1049 break;
1050 default:
1051 break;
1052 }
1053 return;
1054}
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066static void
1067lpfc_build_hbq_profile2(struct config_hbq_var *hbqmb,
1068 struct lpfc_hbq_init *hbq_desc)
1069{
1070 hbqmb->profiles.profile2.seqlenbcnt = hbq_desc->seqlenbcnt;
1071 hbqmb->profiles.profile2.maxlen = hbq_desc->maxlen;
1072 hbqmb->profiles.profile2.seqlenoff = hbq_desc->seqlenoff;
1073}
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085static void
1086lpfc_build_hbq_profile3(struct config_hbq_var *hbqmb,
1087 struct lpfc_hbq_init *hbq_desc)
1088{
1089 hbqmb->profiles.profile3.seqlenbcnt = hbq_desc->seqlenbcnt;
1090 hbqmb->profiles.profile3.maxlen = hbq_desc->maxlen;
1091 hbqmb->profiles.profile3.cmdcodeoff = hbq_desc->cmdcodeoff;
1092 hbqmb->profiles.profile3.seqlenoff = hbq_desc->seqlenoff;
1093 memcpy(&hbqmb->profiles.profile3.cmdmatch, hbq_desc->cmdmatch,
1094 sizeof(hbqmb->profiles.profile3.cmdmatch));
1095}
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108static void
1109lpfc_build_hbq_profile5(struct config_hbq_var *hbqmb,
1110 struct lpfc_hbq_init *hbq_desc)
1111{
1112 hbqmb->profiles.profile5.seqlenbcnt = hbq_desc->seqlenbcnt;
1113 hbqmb->profiles.profile5.maxlen = hbq_desc->maxlen;
1114 hbqmb->profiles.profile5.cmdcodeoff = hbq_desc->cmdcodeoff;
1115 hbqmb->profiles.profile5.seqlenoff = hbq_desc->seqlenoff;
1116 memcpy(&hbqmb->profiles.profile5.cmdmatch, hbq_desc->cmdmatch,
1117 sizeof(hbqmb->profiles.profile5.cmdmatch));
1118}
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134void
1135lpfc_config_hbq(struct lpfc_hba *phba, uint32_t id,
1136 struct lpfc_hbq_init *hbq_desc,
1137 uint32_t hbq_entry_index, LPFC_MBOXQ_t *pmb)
1138{
1139 int i;
1140 MAILBOX_t *mb = &pmb->u.mb;
1141 struct config_hbq_var *hbqmb = &mb->un.varCfgHbq;
1142
1143 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
1144 hbqmb->hbqId = id;
1145 hbqmb->entry_count = hbq_desc->entry_count;
1146 hbqmb->recvNotify = hbq_desc->rn;
1147
1148 hbqmb->numMask = hbq_desc->mask_count;
1149
1150 hbqmb->profile = hbq_desc->profile;
1151
1152
1153 hbqmb->ringMask = hbq_desc->ring_mask;
1154
1155
1156 hbqmb->headerLen = hbq_desc->headerLen;
1157
1158 hbqmb->logEntry = hbq_desc->logEntry;
1159
1160
1161
1162 hbqmb->hbqaddrLow = putPaddrLow(phba->hbqslimp.phys) +
1163 hbq_entry_index * sizeof(struct lpfc_hbq_entry);
1164 hbqmb->hbqaddrHigh = putPaddrHigh(phba->hbqslimp.phys);
1165
1166 mb->mbxCommand = MBX_CONFIG_HBQ;
1167 mb->mbxOwner = OWN_HOST;
1168
1169
1170
1171
1172 if (hbq_desc->profile == 2)
1173 lpfc_build_hbq_profile2(hbqmb, hbq_desc);
1174 else if (hbq_desc->profile == 3)
1175 lpfc_build_hbq_profile3(hbqmb, hbq_desc);
1176 else if (hbq_desc->profile == 5)
1177 lpfc_build_hbq_profile5(hbqmb, hbq_desc);
1178
1179
1180 if (!hbq_desc->mask_count)
1181 return;
1182
1183
1184 for (i = 0; i < hbq_desc->mask_count; i++) {
1185 hbqmb->hbqMasks[i].tmatch = hbq_desc->hbqMasks[i].tmatch;
1186 hbqmb->hbqMasks[i].tmask = hbq_desc->hbqMasks[i].tmask;
1187 hbqmb->hbqMasks[i].rctlmatch = hbq_desc->hbqMasks[i].rctlmatch;
1188 hbqmb->hbqMasks[i].rctlmask = hbq_desc->hbqMasks[i].rctlmask;
1189 }
1190
1191 return;
1192}
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211void
1212lpfc_config_ring(struct lpfc_hba * phba, int ring, LPFC_MBOXQ_t * pmb)
1213{
1214 int i;
1215 MAILBOX_t *mb = &pmb->u.mb;
1216 struct lpfc_sli *psli;
1217 struct lpfc_sli_ring *pring;
1218
1219 memset(pmb, 0, sizeof (LPFC_MBOXQ_t));
1220
1221 mb->un.varCfgRing.ring = ring;
1222 mb->un.varCfgRing.maxOrigXchg = 0;
1223 mb->un.varCfgRing.maxRespXchg = 0;
1224 mb->un.varCfgRing.recvNotify = 1;
1225
1226 psli = &phba->sli;
1227 pring = &psli->sli3_ring[ring];
1228 mb->un.varCfgRing.numMask = pring->num_mask;
1229 mb->mbxCommand = MBX_CONFIG_RING;
1230 mb->mbxOwner = OWN_HOST;
1231
1232
1233 if (pring->prt[0].profile) {
1234 mb->un.varCfgRing.profile = pring->prt[0].profile;
1235 return;
1236 }
1237
1238
1239 for (i = 0; i < pring->num_mask; i++) {
1240 mb->un.varCfgRing.rrRegs[i].rval = pring->prt[i].rctl;
1241 if (mb->un.varCfgRing.rrRegs[i].rval != FC_RCTL_ELS_REQ)
1242 mb->un.varCfgRing.rrRegs[i].rmask = 0xff;
1243 else
1244 mb->un.varCfgRing.rrRegs[i].rmask = 0xfe;
1245 mb->un.varCfgRing.rrRegs[i].tval = pring->prt[i].type;
1246 mb->un.varCfgRing.rrRegs[i].tmask = 0xff;
1247 }
1248
1249 return;
1250}
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266void
1267lpfc_config_port(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
1268{
1269 MAILBOX_t __iomem *mb_slim = (MAILBOX_t __iomem *) phba->MBslimaddr;
1270 MAILBOX_t *mb = &pmb->u.mb;
1271 dma_addr_t pdma_addr;
1272 uint32_t bar_low, bar_high;
1273 size_t offset;
1274 struct lpfc_hgp hgp;
1275 int i;
1276 uint32_t pgp_offset;
1277
1278 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
1279 mb->mbxCommand = MBX_CONFIG_PORT;
1280 mb->mbxOwner = OWN_HOST;
1281
1282 mb->un.varCfgPort.pcbLen = sizeof(PCB_t);
1283
1284 offset = (uint8_t *)phba->pcb - (uint8_t *)phba->slim2p.virt;
1285 pdma_addr = phba->slim2p.phys + offset;
1286 mb->un.varCfgPort.pcbLow = putPaddrLow(pdma_addr);
1287 mb->un.varCfgPort.pcbHigh = putPaddrHigh(pdma_addr);
1288
1289
1290 mb->un.varCfgPort.hps = 1;
1291
1292
1293
1294 if (phba->sli_rev == LPFC_SLI_REV3 && phba->vpd.sli3Feat.cerbm) {
1295 if (phba->cfg_enable_bg)
1296 mb->un.varCfgPort.cbg = 1;
1297 if (phba->cfg_enable_dss)
1298 mb->un.varCfgPort.cdss = 1;
1299 mb->un.varCfgPort.cerbm = 1;
1300 mb->un.varCfgPort.ccrp = 1;
1301 mb->un.varCfgPort.max_hbq = lpfc_sli_hbq_count();
1302 if (phba->max_vpi && phba->cfg_enable_npiv &&
1303 phba->vpd.sli3Feat.cmv) {
1304 mb->un.varCfgPort.max_vpi = LPFC_MAX_VPI;
1305 mb->un.varCfgPort.cmv = 1;
1306 } else
1307 mb->un.varCfgPort.max_vpi = phba->max_vpi = 0;
1308 } else
1309 phba->sli_rev = LPFC_SLI_REV2;
1310 mb->un.varCfgPort.sli_mode = phba->sli_rev;
1311
1312
1313 if (phba->sli_rev == LPFC_SLI_REV3)
1314 mb->un.varCfgPort.casabt = 1;
1315
1316
1317 phba->pcb->type = TYPE_NATIVE_SLI2;
1318 phba->pcb->feature = FEATURE_INITIAL_SLI2;
1319
1320
1321 phba->pcb->mailBoxSize = sizeof(MAILBOX_t) + MAILBOX_EXT_SIZE;
1322 offset = (uint8_t *)phba->mbox - (uint8_t *)phba->slim2p.virt;
1323 pdma_addr = phba->slim2p.phys + offset;
1324 phba->pcb->mbAddrHigh = putPaddrHigh(pdma_addr);
1325 phba->pcb->mbAddrLow = putPaddrLow(pdma_addr);
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346 pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_0, &bar_low);
1347 pci_read_config_dword(phba->pcidev, PCI_BASE_ADDRESS_1, &bar_high);
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377 if (phba->cfg_hostmem_hgp && phba->sli_rev != 3) {
1378 phba->host_gp = &phba->mbox->us.s2.host[0];
1379 phba->hbq_put = NULL;
1380 offset = (uint8_t *)&phba->mbox->us.s2.host -
1381 (uint8_t *)phba->slim2p.virt;
1382 pdma_addr = phba->slim2p.phys + offset;
1383 phba->pcb->hgpAddrHigh = putPaddrHigh(pdma_addr);
1384 phba->pcb->hgpAddrLow = putPaddrLow(pdma_addr);
1385 } else {
1386
1387 mb->un.varCfgPort.hps = 1;
1388
1389 if (phba->sli_rev == 3) {
1390 phba->host_gp = &mb_slim->us.s3.host[0];
1391 phba->hbq_put = &mb_slim->us.s3.hbq_put[0];
1392 } else {
1393 phba->host_gp = &mb_slim->us.s2.host[0];
1394 phba->hbq_put = NULL;
1395 }
1396
1397
1398 phba->pcb->hgpAddrLow = (bar_low & PCI_BASE_ADDRESS_MEM_MASK) +
1399 (void __iomem *)phba->host_gp -
1400 (void __iomem *)phba->MBslimaddr;
1401 if (bar_low & PCI_BASE_ADDRESS_MEM_TYPE_64)
1402 phba->pcb->hgpAddrHigh = bar_high;
1403 else
1404 phba->pcb->hgpAddrHigh = 0;
1405
1406 memset(&hgp, 0, sizeof(struct lpfc_hgp));
1407
1408 for (i = 0; i < phba->sli.num_rings; i++) {
1409 lpfc_memcpy_to_slim(phba->host_gp + i, &hgp,
1410 sizeof(*phba->host_gp));
1411 }
1412 }
1413
1414
1415 if (phba->sli_rev == 3)
1416 pgp_offset = offsetof(struct lpfc_sli2_slim,
1417 mbx.us.s3_pgp.port);
1418 else
1419 pgp_offset = offsetof(struct lpfc_sli2_slim, mbx.us.s2.port);
1420 pdma_addr = phba->slim2p.phys + pgp_offset;
1421 phba->pcb->pgpAddrHigh = putPaddrHigh(pdma_addr);
1422 phba->pcb->pgpAddrLow = putPaddrLow(pdma_addr);
1423
1424
1425 lpfc_config_pcb_setup(phba);
1426
1427
1428 if (lpfc_is_LC_HBA(phba->pcidev->device)) {
1429 uint32_t hbainit[5];
1430
1431 lpfc_hba_init(phba, hbainit);
1432
1433 memcpy(&mb->un.varCfgPort.hbainit, hbainit, 20);
1434 }
1435
1436
1437 lpfc_sli_pcimem_bcopy(phba->pcb, phba->pcb, sizeof(PCB_t));
1438}
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455void
1456lpfc_kill_board(struct lpfc_hba * phba, LPFC_MBOXQ_t * pmb)
1457{
1458 MAILBOX_t *mb = &pmb->u.mb;
1459
1460 memset(pmb, 0, sizeof(LPFC_MBOXQ_t));
1461 mb->mbxCommand = MBX_KILL_BOARD;
1462 mb->mbxOwner = OWN_HOST;
1463 return;
1464}
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476void
1477lpfc_mbox_put(struct lpfc_hba * phba, LPFC_MBOXQ_t * mbq)
1478{
1479 struct lpfc_sli *psli;
1480
1481 psli = &phba->sli;
1482
1483 list_add_tail(&mbq->list, &psli->mboxq);
1484
1485 psli->mboxq_cnt++;
1486
1487 return;
1488}
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504LPFC_MBOXQ_t *
1505lpfc_mbox_get(struct lpfc_hba * phba)
1506{
1507 LPFC_MBOXQ_t *mbq = NULL;
1508 struct lpfc_sli *psli = &phba->sli;
1509
1510 list_remove_head((&psli->mboxq), mbq, LPFC_MBOXQ_t, list);
1511 if (mbq)
1512 psli->mboxq_cnt--;
1513
1514 return mbq;
1515}
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527void
1528__lpfc_mbox_cmpl_put(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbq)
1529{
1530 list_add_tail(&mbq->list, &phba->sli.mboxq_cmpl);
1531}
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543void
1544lpfc_mbox_cmpl_put(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbq)
1545{
1546 unsigned long iflag;
1547
1548
1549 spin_lock_irqsave(&phba->hbalock, iflag);
1550 __lpfc_mbox_cmpl_put(phba, mbq);
1551 spin_unlock_irqrestore(&phba->hbalock, iflag);
1552 return;
1553}
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566int
1567lpfc_mbox_cmd_check(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1568{
1569
1570
1571
1572 if (mboxq->mbox_cmpl && mboxq->mbox_cmpl != lpfc_sli_def_mbox_cmpl &&
1573 mboxq->mbox_cmpl != lpfc_sli_wake_mbox_wait) {
1574 if (!mboxq->vport) {
1575 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_VPORT,
1576 "1814 Mbox x%x failed, no vport\n",
1577 mboxq->u.mb.mbxCommand);
1578 dump_stack();
1579 return -ENODEV;
1580 }
1581 }
1582 return 0;
1583}
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595int
1596lpfc_mbox_dev_check(struct lpfc_hba *phba)
1597{
1598
1599 if (unlikely(pci_channel_offline(phba->pcidev)))
1600 return -ENODEV;
1601
1602
1603 if (phba->link_state == LPFC_HBA_ERROR)
1604 return -ENODEV;
1605
1606 return 0;
1607}
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620int
1621lpfc_mbox_tmo_val(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
1622{
1623 MAILBOX_t *mbox = &mboxq->u.mb;
1624 uint8_t subsys, opcode;
1625
1626 switch (mbox->mbxCommand) {
1627 case MBX_WRITE_NV:
1628 case MBX_DUMP_MEMORY:
1629 case MBX_UPDATE_CFG:
1630 case MBX_DOWN_LOAD:
1631 case MBX_DEL_LD_ENTRY:
1632 case MBX_WRITE_VPARMS:
1633 case MBX_LOAD_AREA:
1634 case MBX_WRITE_WWN:
1635 case MBX_LOAD_EXP_ROM:
1636 case MBX_ACCESS_VDATA:
1637 return LPFC_MBOX_TMO_FLASH_CMD;
1638 case MBX_SLI4_CONFIG:
1639 subsys = lpfc_sli_config_mbox_subsys_get(phba, mboxq);
1640 opcode = lpfc_sli_config_mbox_opcode_get(phba, mboxq);
1641 if (subsys == LPFC_MBOX_SUBSYSTEM_COMMON) {
1642 switch (opcode) {
1643 case LPFC_MBOX_OPCODE_READ_OBJECT:
1644 case LPFC_MBOX_OPCODE_WRITE_OBJECT:
1645 case LPFC_MBOX_OPCODE_READ_OBJECT_LIST:
1646 case LPFC_MBOX_OPCODE_DELETE_OBJECT:
1647 case LPFC_MBOX_OPCODE_GET_PROFILE_LIST:
1648 case LPFC_MBOX_OPCODE_SET_ACT_PROFILE:
1649 case LPFC_MBOX_OPCODE_GET_PROFILE_CONFIG:
1650 case LPFC_MBOX_OPCODE_SET_PROFILE_CONFIG:
1651 case LPFC_MBOX_OPCODE_GET_FACTORY_PROFILE_CONFIG:
1652 case LPFC_MBOX_OPCODE_GET_PROFILE_CAPACITIES:
1653 case LPFC_MBOX_OPCODE_SEND_ACTIVATION:
1654 case LPFC_MBOX_OPCODE_RESET_LICENSES:
1655 case LPFC_MBOX_OPCODE_SET_BOOT_CONFIG:
1656 case LPFC_MBOX_OPCODE_GET_VPD_DATA:
1657 case LPFC_MBOX_OPCODE_SET_PHYSICAL_LINK_CONFIG:
1658 return LPFC_MBOX_SLI4_CONFIG_EXTENDED_TMO;
1659 }
1660 }
1661 if (subsys == LPFC_MBOX_SUBSYSTEM_FCOE) {
1662 switch (opcode) {
1663 case LPFC_MBOX_OPCODE_FCOE_SET_FCLINK_SETTINGS:
1664 return LPFC_MBOX_SLI4_CONFIG_EXTENDED_TMO;
1665 }
1666 }
1667 return LPFC_MBOX_SLI4_CONFIG_TMO;
1668 }
1669 return LPFC_MBOX_TMO;
1670}
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682void
1683lpfc_sli4_mbx_sge_set(struct lpfcMboxq *mbox, uint32_t sgentry,
1684 dma_addr_t phyaddr, uint32_t length)
1685{
1686 struct lpfc_mbx_nembed_cmd *nembed_sge;
1687
1688 nembed_sge = (struct lpfc_mbx_nembed_cmd *)
1689 &mbox->u.mqe.un.nembed_cmd;
1690 nembed_sge->sge[sgentry].pa_lo = putPaddrLow(phyaddr);
1691 nembed_sge->sge[sgentry].pa_hi = putPaddrHigh(phyaddr);
1692 nembed_sge->sge[sgentry].length = length;
1693}
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703void
1704lpfc_sli4_mbx_sge_get(struct lpfcMboxq *mbox, uint32_t sgentry,
1705 struct lpfc_mbx_sge *sge)
1706{
1707 struct lpfc_mbx_nembed_cmd *nembed_sge;
1708
1709 nembed_sge = (struct lpfc_mbx_nembed_cmd *)
1710 &mbox->u.mqe.un.nembed_cmd;
1711 sge->pa_lo = nembed_sge->sge[sgentry].pa_lo;
1712 sge->pa_hi = nembed_sge->sge[sgentry].pa_hi;
1713 sge->length = nembed_sge->sge[sgentry].length;
1714}
1715
1716
1717
1718
1719
1720
1721
1722
1723void
1724lpfc_sli4_mbox_cmd_free(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
1725{
1726 struct lpfc_mbx_sli4_config *sli4_cfg;
1727 struct lpfc_mbx_sge sge;
1728 dma_addr_t phyaddr;
1729 uint32_t sgecount, sgentry;
1730
1731 sli4_cfg = &mbox->u.mqe.un.sli4_config;
1732
1733
1734 if (bf_get(lpfc_mbox_hdr_emb, &sli4_cfg->header.cfg_mhdr)) {
1735 mempool_free(mbox, phba->mbox_mem_pool);
1736 return;
1737 }
1738
1739
1740 sgecount = bf_get(lpfc_mbox_hdr_sge_cnt, &sli4_cfg->header.cfg_mhdr);
1741
1742 if (unlikely(!mbox->sge_array)) {
1743 mempool_free(mbox, phba->mbox_mem_pool);
1744 return;
1745 }
1746
1747 for (sgentry = 0; sgentry < sgecount; sgentry++) {
1748 lpfc_sli4_mbx_sge_get(mbox, sgentry, &sge);
1749 phyaddr = getPaddr(sge.pa_hi, sge.pa_lo);
1750 dma_free_coherent(&phba->pcidev->dev, SLI4_PAGE_SIZE,
1751 mbox->sge_array->addr[sgentry], phyaddr);
1752 }
1753
1754 kfree(mbox->sge_array);
1755
1756 mempool_free(mbox, phba->mbox_mem_pool);
1757}
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773int
1774lpfc_sli4_config(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
1775 uint8_t subsystem, uint8_t opcode, uint32_t length, bool emb)
1776{
1777 struct lpfc_mbx_sli4_config *sli4_config;
1778 union lpfc_sli4_cfg_shdr *cfg_shdr = NULL;
1779 uint32_t alloc_len;
1780 uint32_t resid_len;
1781 uint32_t pagen, pcount;
1782 void *viraddr;
1783 dma_addr_t phyaddr;
1784
1785
1786 memset(mbox, 0, sizeof(*mbox));
1787 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_SLI4_CONFIG);
1788
1789
1790 sli4_config = &mbox->u.mqe.un.sli4_config;
1791
1792
1793 if (emb) {
1794
1795 bf_set(lpfc_mbox_hdr_emb, &sli4_config->header.cfg_mhdr, 1);
1796 sli4_config->header.cfg_mhdr.payload_length = length;
1797
1798 bf_set(lpfc_mbox_hdr_opcode,
1799 &sli4_config->header.cfg_shdr.request, opcode);
1800 bf_set(lpfc_mbox_hdr_subsystem,
1801 &sli4_config->header.cfg_shdr.request, subsystem);
1802 sli4_config->header.cfg_shdr.request.request_length =
1803 length - LPFC_MBX_CMD_HDR_LENGTH;
1804 return length;
1805 }
1806
1807
1808 pcount = (SLI4_PAGE_ALIGN(length))/SLI4_PAGE_SIZE;
1809 pcount = (pcount > LPFC_SLI4_MBX_SGE_MAX_PAGES) ?
1810 LPFC_SLI4_MBX_SGE_MAX_PAGES : pcount;
1811
1812 mbox->sge_array = kzalloc(sizeof(struct lpfc_mbx_nembed_sge_virt),
1813 GFP_KERNEL);
1814 if (!mbox->sge_array) {
1815 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1816 "2527 Failed to allocate non-embedded SGE "
1817 "array.\n");
1818 return 0;
1819 }
1820 for (pagen = 0, alloc_len = 0; pagen < pcount; pagen++) {
1821
1822
1823
1824
1825
1826 viraddr = dma_zalloc_coherent(&phba->pcidev->dev,
1827 SLI4_PAGE_SIZE, &phyaddr,
1828 GFP_KERNEL);
1829
1830 if (!viraddr)
1831 break;
1832 mbox->sge_array->addr[pagen] = viraddr;
1833
1834 if (pagen == 0)
1835 cfg_shdr = (union lpfc_sli4_cfg_shdr *)viraddr;
1836 resid_len = length - alloc_len;
1837 if (resid_len > SLI4_PAGE_SIZE) {
1838 lpfc_sli4_mbx_sge_set(mbox, pagen, phyaddr,
1839 SLI4_PAGE_SIZE);
1840 alloc_len += SLI4_PAGE_SIZE;
1841 } else {
1842 lpfc_sli4_mbx_sge_set(mbox, pagen, phyaddr,
1843 resid_len);
1844 alloc_len = length;
1845 }
1846 }
1847
1848
1849 sli4_config->header.cfg_mhdr.payload_length = alloc_len;
1850 bf_set(lpfc_mbox_hdr_sge_cnt, &sli4_config->header.cfg_mhdr, pagen);
1851
1852
1853 if (pagen > 0) {
1854 bf_set(lpfc_mbox_hdr_opcode, &cfg_shdr->request, opcode);
1855 bf_set(lpfc_mbox_hdr_subsystem, &cfg_shdr->request, subsystem);
1856 cfg_shdr->request.request_length =
1857 alloc_len - sizeof(union lpfc_sli4_cfg_shdr);
1858 }
1859
1860 if (cfg_shdr)
1861 lpfc_sli_pcimem_bcopy(cfg_shdr, cfg_shdr,
1862 sizeof(union lpfc_sli4_cfg_shdr));
1863 return alloc_len;
1864}
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881int
1882lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *phba, struct lpfcMboxq *mbox,
1883 uint16_t exts_count, uint16_t rsrc_type, bool emb)
1884{
1885 uint8_t opcode = 0;
1886 struct lpfc_mbx_nembed_rsrc_extent *n_rsrc_extnt = NULL;
1887 void *virtaddr = NULL;
1888
1889
1890 if (emb == LPFC_SLI4_MBX_NEMBED) {
1891
1892 virtaddr = mbox->sge_array->addr[0];
1893 if (virtaddr == NULL)
1894 return 1;
1895 n_rsrc_extnt = (struct lpfc_mbx_nembed_rsrc_extent *) virtaddr;
1896 }
1897
1898
1899
1900
1901
1902 if (emb == LPFC_SLI4_MBX_EMBED)
1903 bf_set(lpfc_mbx_alloc_rsrc_extents_type,
1904 &mbox->u.mqe.un.alloc_rsrc_extents.u.req,
1905 rsrc_type);
1906 else {
1907
1908 bf_set(lpfc_mbx_alloc_rsrc_extents_type,
1909 n_rsrc_extnt, rsrc_type);
1910 lpfc_sli_pcimem_bcopy(&n_rsrc_extnt->word4,
1911 &n_rsrc_extnt->word4,
1912 sizeof(uint32_t));
1913 }
1914
1915
1916 opcode = lpfc_sli_config_mbox_opcode_get(phba, mbox);
1917 switch (opcode) {
1918 case LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT:
1919 if (emb == LPFC_SLI4_MBX_EMBED)
1920 bf_set(lpfc_mbx_alloc_rsrc_extents_cnt,
1921 &mbox->u.mqe.un.alloc_rsrc_extents.u.req,
1922 exts_count);
1923 else
1924 bf_set(lpfc_mbx_alloc_rsrc_extents_cnt,
1925 n_rsrc_extnt, exts_count);
1926 break;
1927 case LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT:
1928 case LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO:
1929 case LPFC_MBOX_OPCODE_DEALLOC_RSRC_EXTENT:
1930
1931 break;
1932 default:
1933 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
1934 "2929 Resource Extent Opcode x%x is "
1935 "unsupported\n", opcode);
1936 return 1;
1937 }
1938
1939 return 0;
1940}
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952uint8_t
1953lpfc_sli_config_mbox_subsys_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
1954{
1955 struct lpfc_mbx_sli4_config *sli4_cfg;
1956 union lpfc_sli4_cfg_shdr *cfg_shdr;
1957
1958 if (mbox->u.mb.mbxCommand != MBX_SLI4_CONFIG)
1959 return LPFC_MBOX_SUBSYSTEM_NA;
1960 sli4_cfg = &mbox->u.mqe.un.sli4_config;
1961
1962
1963 if (bf_get(lpfc_mbox_hdr_emb, &sli4_cfg->header.cfg_mhdr)) {
1964 cfg_shdr = &mbox->u.mqe.un.sli4_config.header.cfg_shdr;
1965 return bf_get(lpfc_mbox_hdr_subsystem, &cfg_shdr->request);
1966 }
1967
1968
1969 if (unlikely(!mbox->sge_array))
1970 return LPFC_MBOX_SUBSYSTEM_NA;
1971 cfg_shdr = (union lpfc_sli4_cfg_shdr *)mbox->sge_array->addr[0];
1972 return bf_get(lpfc_mbox_hdr_subsystem, &cfg_shdr->request);
1973}
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985uint8_t
1986lpfc_sli_config_mbox_opcode_get(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
1987{
1988 struct lpfc_mbx_sli4_config *sli4_cfg;
1989 union lpfc_sli4_cfg_shdr *cfg_shdr;
1990
1991 if (mbox->u.mb.mbxCommand != MBX_SLI4_CONFIG)
1992 return LPFC_MBOX_OPCODE_NA;
1993 sli4_cfg = &mbox->u.mqe.un.sli4_config;
1994
1995
1996 if (bf_get(lpfc_mbox_hdr_emb, &sli4_cfg->header.cfg_mhdr)) {
1997 cfg_shdr = &mbox->u.mqe.un.sli4_config.header.cfg_shdr;
1998 return bf_get(lpfc_mbox_hdr_opcode, &cfg_shdr->request);
1999 }
2000
2001
2002 if (unlikely(!mbox->sge_array))
2003 return LPFC_MBOX_OPCODE_NA;
2004 cfg_shdr = (union lpfc_sli4_cfg_shdr *)mbox->sge_array->addr[0];
2005 return bf_get(lpfc_mbox_hdr_opcode, &cfg_shdr->request);
2006}
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019int
2020lpfc_sli4_mbx_read_fcf_rec(struct lpfc_hba *phba,
2021 struct lpfcMboxq *mboxq,
2022 uint16_t fcf_index)
2023{
2024 void *virt_addr;
2025 uint8_t *bytep;
2026 struct lpfc_mbx_sge sge;
2027 uint32_t alloc_len, req_len;
2028 struct lpfc_mbx_read_fcf_tbl *read_fcf;
2029
2030 if (!mboxq)
2031 return -ENOMEM;
2032
2033 req_len = sizeof(struct fcf_record) +
2034 sizeof(union lpfc_sli4_cfg_shdr) + 2 * sizeof(uint32_t);
2035
2036
2037 alloc_len = lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_FCOE,
2038 LPFC_MBOX_OPCODE_FCOE_READ_FCF_TABLE, req_len,
2039 LPFC_SLI4_MBX_NEMBED);
2040
2041 if (alloc_len < req_len) {
2042 lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
2043 "0291 Allocated DMA memory size (x%x) is "
2044 "less than the requested DMA memory "
2045 "size (x%x)\n", alloc_len, req_len);
2046 return -ENOMEM;
2047 }
2048
2049
2050
2051
2052 lpfc_sli4_mbx_sge_get(mboxq, 0, &sge);
2053 virt_addr = mboxq->sge_array->addr[0];
2054 read_fcf = (struct lpfc_mbx_read_fcf_tbl *)virt_addr;
2055
2056
2057 bf_set(lpfc_mbx_read_fcf_tbl_indx, &read_fcf->u.request, fcf_index);
2058
2059 bytep = virt_addr + sizeof(union lpfc_sli4_cfg_shdr);
2060 lpfc_sli_pcimem_bcopy(bytep, bytep, sizeof(uint32_t));
2061
2062 return 0;
2063}
2064
2065
2066
2067
2068
2069
2070
2071
2072void
2073lpfc_request_features(struct lpfc_hba *phba, struct lpfcMboxq *mboxq)
2074{
2075
2076 memset(mboxq, 0, sizeof(LPFC_MBOXQ_t));
2077 bf_set(lpfc_mqe_command, &mboxq->u.mqe, MBX_SLI4_REQ_FTRS);
2078
2079
2080 bf_set(lpfc_mbx_rq_ftr_rq_fcpi, &mboxq->u.mqe.un.req_ftrs, 1);
2081 bf_set(lpfc_mbx_rq_ftr_rq_perfh, &mboxq->u.mqe.un.req_ftrs, 1);
2082
2083
2084 if (phba->cfg_enable_bg)
2085 bf_set(lpfc_mbx_rq_ftr_rq_dif, &mboxq->u.mqe.un.req_ftrs, 1);
2086
2087
2088 if (phba->max_vpi && phba->cfg_enable_npiv)
2089 bf_set(lpfc_mbx_rq_ftr_rq_npiv, &mboxq->u.mqe.un.req_ftrs, 1);
2090
2091 if (phba->nvmet_support) {
2092 bf_set(lpfc_mbx_rq_ftr_rq_mrqp, &mboxq->u.mqe.un.req_ftrs, 1);
2093
2094 bf_set(lpfc_mbx_rq_ftr_rq_iaab, &mboxq->u.mqe.un.req_ftrs, 0);
2095 bf_set(lpfc_mbx_rq_ftr_rq_iaar, &mboxq->u.mqe.un.req_ftrs, 0);
2096 }
2097 return;
2098}
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111void
2112lpfc_init_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
2113{
2114 struct lpfc_mbx_init_vfi *init_vfi;
2115
2116 memset(mbox, 0, sizeof(*mbox));
2117 mbox->vport = vport;
2118 init_vfi = &mbox->u.mqe.un.init_vfi;
2119 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VFI);
2120 bf_set(lpfc_init_vfi_vr, init_vfi, 1);
2121 bf_set(lpfc_init_vfi_vt, init_vfi, 1);
2122 bf_set(lpfc_init_vfi_vp, init_vfi, 1);
2123 bf_set(lpfc_init_vfi_vfi, init_vfi,
2124 vport->phba->sli4_hba.vfi_ids[vport->vfi]);
2125 bf_set(lpfc_init_vfi_vpi, init_vfi,
2126 vport->phba->vpi_ids[vport->vpi]);
2127 bf_set(lpfc_init_vfi_fcfi, init_vfi,
2128 vport->phba->fcf.fcfi);
2129}
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142void
2143lpfc_reg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport, dma_addr_t phys)
2144{
2145 struct lpfc_mbx_reg_vfi *reg_vfi;
2146 struct lpfc_hba *phba = vport->phba;
2147 uint8_t bbscn_fabric = 0, bbscn_max = 0, bbscn_def = 0;
2148
2149 memset(mbox, 0, sizeof(*mbox));
2150 reg_vfi = &mbox->u.mqe.un.reg_vfi;
2151 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_VFI);
2152 bf_set(lpfc_reg_vfi_vp, reg_vfi, 1);
2153 bf_set(lpfc_reg_vfi_vfi, reg_vfi,
2154 phba->sli4_hba.vfi_ids[vport->vfi]);
2155 bf_set(lpfc_reg_vfi_fcfi, reg_vfi, phba->fcf.fcfi);
2156 bf_set(lpfc_reg_vfi_vpi, reg_vfi, phba->vpi_ids[vport->vpi]);
2157 memcpy(reg_vfi->wwn, &vport->fc_portname, sizeof(struct lpfc_name));
2158 reg_vfi->wwn[0] = cpu_to_le32(reg_vfi->wwn[0]);
2159 reg_vfi->wwn[1] = cpu_to_le32(reg_vfi->wwn[1]);
2160 reg_vfi->e_d_tov = phba->fc_edtov;
2161 reg_vfi->r_a_tov = phba->fc_ratov;
2162 if (phys) {
2163 reg_vfi->bde.addrHigh = putPaddrHigh(phys);
2164 reg_vfi->bde.addrLow = putPaddrLow(phys);
2165 reg_vfi->bde.tus.f.bdeSize = sizeof(vport->fc_sparam);
2166 reg_vfi->bde.tus.f.bdeFlags = BUFF_TYPE_BDE_64;
2167 }
2168 bf_set(lpfc_reg_vfi_nport_id, reg_vfi, vport->fc_myDID);
2169
2170
2171 if ((phba->sli4_hba.lnk_info.lnk_tp == LPFC_LNK_TYPE_FC) &&
2172 (vport->fc_flag & FC_VFI_REGISTERED) &&
2173 (!phba->fc_topology_changed)) {
2174 bf_set(lpfc_reg_vfi_vp, reg_vfi, 0);
2175 bf_set(lpfc_reg_vfi_upd, reg_vfi, 1);
2176 }
2177
2178 bf_set(lpfc_reg_vfi_bbcr, reg_vfi, 0);
2179 bf_set(lpfc_reg_vfi_bbscn, reg_vfi, 0);
2180 bbscn_fabric = (phba->fc_fabparam.cmn.bbRcvSizeMsb >> 4) & 0xF;
2181
2182 if (phba->bbcredit_support && phba->cfg_enable_bbcr &&
2183 bbscn_fabric != 0) {
2184 bbscn_max = bf_get(lpfc_bbscn_max,
2185 &phba->sli4_hba.bbscn_params);
2186 if (bbscn_fabric <= bbscn_max) {
2187 bbscn_def = bf_get(lpfc_bbscn_def,
2188 &phba->sli4_hba.bbscn_params);
2189
2190 if (bbscn_fabric > bbscn_def)
2191 bf_set(lpfc_reg_vfi_bbscn, reg_vfi,
2192 bbscn_fabric);
2193 else
2194 bf_set(lpfc_reg_vfi_bbscn, reg_vfi, bbscn_def);
2195
2196 bf_set(lpfc_reg_vfi_bbcr, reg_vfi, 1);
2197 }
2198 }
2199 lpfc_printf_vlog(vport, KERN_INFO, LOG_MBOX,
2200 "3134 Register VFI, mydid:x%x, fcfi:%d, "
2201 " vfi:%d, vpi:%d, fc_pname:%x%x fc_flag:x%x"
2202 " port_state:x%x topology chg:%d bbscn_fabric :%d\n",
2203 vport->fc_myDID,
2204 phba->fcf.fcfi,
2205 phba->sli4_hba.vfi_ids[vport->vfi],
2206 phba->vpi_ids[vport->vpi],
2207 reg_vfi->wwn[0], reg_vfi->wwn[1], vport->fc_flag,
2208 vport->port_state, phba->fc_topology_changed,
2209 bbscn_fabric);
2210}
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224void
2225lpfc_init_vpi(struct lpfc_hba *phba, struct lpfcMboxq *mbox, uint16_t vpi)
2226{
2227 memset(mbox, 0, sizeof(*mbox));
2228 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_INIT_VPI);
2229 bf_set(lpfc_init_vpi_vpi, &mbox->u.mqe.un.init_vpi,
2230 phba->vpi_ids[vpi]);
2231 bf_set(lpfc_init_vpi_vfi, &mbox->u.mqe.un.init_vpi,
2232 phba->sli4_hba.vfi_ids[phba->pport->vfi]);
2233}
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246void
2247lpfc_unreg_vfi(struct lpfcMboxq *mbox, struct lpfc_vport *vport)
2248{
2249 memset(mbox, 0, sizeof(*mbox));
2250 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_VFI);
2251 bf_set(lpfc_unreg_vfi_vfi, &mbox->u.mqe.un.unreg_vfi,
2252 vport->phba->sli4_hba.vfi_ids[vport->vfi]);
2253}
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263int
2264lpfc_sli4_dump_cfg_rg23(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
2265{
2266 struct lpfc_dmabuf *mp = NULL;
2267 MAILBOX_t *mb;
2268
2269 memset(mbox, 0, sizeof(*mbox));
2270 mb = &mbox->u.mb;
2271
2272 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2273 if (mp)
2274 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
2275
2276 if (!mp || !mp->virt) {
2277 kfree(mp);
2278
2279 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
2280 "2569 lpfc dump config region 23: memory"
2281 " allocation failed\n");
2282 return 1;
2283 }
2284
2285 memset(mp->virt, 0, LPFC_BPL_SIZE);
2286 INIT_LIST_HEAD(&mp->list);
2287
2288
2289 mbox->context1 = (uint8_t *) mp;
2290
2291 mb->mbxCommand = MBX_DUMP_MEMORY;
2292 mb->un.varDmp.type = DMP_NV_PARAMS;
2293 mb->un.varDmp.region_id = DMP_REGION_23;
2294 mb->un.varDmp.sli4_length = DMP_RGN23_SIZE;
2295 mb->un.varWords[3] = putPaddrLow(mp->phys);
2296 mb->un.varWords[4] = putPaddrHigh(mp->phys);
2297 return 0;
2298}
2299
2300static void
2301lpfc_mbx_cmpl_rdp_link_stat(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq)
2302{
2303 MAILBOX_t *mb;
2304 int rc = FAILURE;
2305 struct lpfc_rdp_context *rdp_context =
2306 (struct lpfc_rdp_context *)(mboxq->context2);
2307
2308 mb = &mboxq->u.mb;
2309 if (mb->mbxStatus)
2310 goto mbx_failed;
2311
2312 memcpy(&rdp_context->link_stat, &mb->un.varRdLnk, sizeof(READ_LNK_VAR));
2313
2314 rc = SUCCESS;
2315
2316mbx_failed:
2317 lpfc_sli4_mbox_cmd_free(phba, mboxq);
2318 rdp_context->cmpl(phba, rdp_context, rc);
2319}
2320
2321static void
2322lpfc_mbx_cmpl_rdp_page_a2(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
2323{
2324 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) mbox->context1;
2325 struct lpfc_rdp_context *rdp_context =
2326 (struct lpfc_rdp_context *)(mbox->context2);
2327
2328 if (bf_get(lpfc_mqe_status, &mbox->u.mqe))
2329 goto error_mbuf_free;
2330
2331 lpfc_sli_bemem_bcopy(mp->virt, &rdp_context->page_a2,
2332 DMP_SFF_PAGE_A2_SIZE);
2333
2334
2335 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2336 kfree(mp);
2337
2338 memset(mbox, 0, sizeof(*mbox));
2339 lpfc_read_lnk_stat(phba, mbox);
2340 mbox->vport = rdp_context->ndlp->vport;
2341 mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_link_stat;
2342 mbox->context2 = (struct lpfc_rdp_context *) rdp_context;
2343 if (lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT) == MBX_NOT_FINISHED)
2344 goto error_cmd_free;
2345
2346 return;
2347
2348error_mbuf_free:
2349 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2350 kfree(mp);
2351error_cmd_free:
2352 lpfc_sli4_mbox_cmd_free(phba, mbox);
2353 rdp_context->cmpl(phba, rdp_context, FAILURE);
2354}
2355
2356void
2357lpfc_mbx_cmpl_rdp_page_a0(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox)
2358{
2359 int rc;
2360 struct lpfc_dmabuf *mp = (struct lpfc_dmabuf *) (mbox->context1);
2361 struct lpfc_rdp_context *rdp_context =
2362 (struct lpfc_rdp_context *)(mbox->context2);
2363
2364 if (bf_get(lpfc_mqe_status, &mbox->u.mqe))
2365 goto error;
2366
2367 lpfc_sli_bemem_bcopy(mp->virt, &rdp_context->page_a0,
2368 DMP_SFF_PAGE_A0_SIZE);
2369
2370 memset(mbox, 0, sizeof(*mbox));
2371
2372 memset(mp->virt, 0, DMP_SFF_PAGE_A2_SIZE);
2373 INIT_LIST_HEAD(&mp->list);
2374
2375
2376 mbox->context1 = mp;
2377 mbox->vport = rdp_context->ndlp->vport;
2378
2379 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_DUMP_MEMORY);
2380 bf_set(lpfc_mbx_memory_dump_type3_type,
2381 &mbox->u.mqe.un.mem_dump_type3, DMP_LMSD);
2382 bf_set(lpfc_mbx_memory_dump_type3_link,
2383 &mbox->u.mqe.un.mem_dump_type3, phba->sli4_hba.physical_port);
2384 bf_set(lpfc_mbx_memory_dump_type3_page_no,
2385 &mbox->u.mqe.un.mem_dump_type3, DMP_PAGE_A2);
2386 bf_set(lpfc_mbx_memory_dump_type3_length,
2387 &mbox->u.mqe.un.mem_dump_type3, DMP_SFF_PAGE_A2_SIZE);
2388 mbox->u.mqe.un.mem_dump_type3.addr_lo = putPaddrLow(mp->phys);
2389 mbox->u.mqe.un.mem_dump_type3.addr_hi = putPaddrHigh(mp->phys);
2390
2391 mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a2;
2392 mbox->context2 = (struct lpfc_rdp_context *) rdp_context;
2393 rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT);
2394 if (rc == MBX_NOT_FINISHED)
2395 goto error;
2396
2397 return;
2398
2399error:
2400 lpfc_mbuf_free(phba, mp->virt, mp->phys);
2401 kfree(mp);
2402 lpfc_sli4_mbox_cmd_free(phba, mbox);
2403 rdp_context->cmpl(phba, rdp_context, FAILURE);
2404}
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415int
2416lpfc_sli4_dump_page_a0(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
2417{
2418 struct lpfc_dmabuf *mp = NULL;
2419
2420 memset(mbox, 0, sizeof(*mbox));
2421
2422 mp = kmalloc(sizeof(struct lpfc_dmabuf), GFP_KERNEL);
2423 if (mp)
2424 mp->virt = lpfc_mbuf_alloc(phba, 0, &mp->phys);
2425 if (!mp || !mp->virt) {
2426 kfree(mp);
2427 lpfc_printf_log(phba, KERN_WARNING, LOG_MBOX,
2428 "3569 dump type 3 page 0xA0 allocation failed\n");
2429 return 1;
2430 }
2431
2432 memset(mp->virt, 0, LPFC_BPL_SIZE);
2433 INIT_LIST_HEAD(&mp->list);
2434
2435 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_DUMP_MEMORY);
2436
2437 mbox->context1 = mp;
2438
2439 bf_set(lpfc_mbx_memory_dump_type3_type,
2440 &mbox->u.mqe.un.mem_dump_type3, DMP_LMSD);
2441 bf_set(lpfc_mbx_memory_dump_type3_link,
2442 &mbox->u.mqe.un.mem_dump_type3, phba->sli4_hba.physical_port);
2443 bf_set(lpfc_mbx_memory_dump_type3_page_no,
2444 &mbox->u.mqe.un.mem_dump_type3, DMP_PAGE_A0);
2445 bf_set(lpfc_mbx_memory_dump_type3_length,
2446 &mbox->u.mqe.un.mem_dump_type3, DMP_SFF_PAGE_A0_SIZE);
2447 mbox->u.mqe.un.mem_dump_type3.addr_lo = putPaddrLow(mp->phys);
2448 mbox->u.mqe.un.mem_dump_type3.addr_hi = putPaddrHigh(mp->phys);
2449
2450 return 0;
2451}
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466void
2467lpfc_reg_fcfi(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
2468{
2469 struct lpfc_mbx_reg_fcfi *reg_fcfi;
2470
2471 memset(mbox, 0, sizeof(*mbox));
2472 reg_fcfi = &mbox->u.mqe.un.reg_fcfi;
2473 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_FCFI);
2474 if (phba->nvmet_support == 0) {
2475 bf_set(lpfc_reg_fcfi_rq_id0, reg_fcfi,
2476 phba->sli4_hba.hdr_rq->queue_id);
2477
2478 bf_set(lpfc_reg_fcfi_type_match0, reg_fcfi, 0);
2479 bf_set(lpfc_reg_fcfi_type_mask0, reg_fcfi, 0);
2480 bf_set(lpfc_reg_fcfi_rctl_match0, reg_fcfi, 0);
2481 bf_set(lpfc_reg_fcfi_rctl_mask0, reg_fcfi, 0);
2482
2483 bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi, REG_FCF_INVALID_QID);
2484
2485
2486 bf_set(lpfc_reg_fcfi_mam, reg_fcfi,
2487 (~phba->fcf.addr_mode) & 0x3);
2488 } else {
2489
2490 if (phba->cfg_nvmet_mrq != 1)
2491 return;
2492
2493 bf_set(lpfc_reg_fcfi_rq_id0, reg_fcfi,
2494 phba->sli4_hba.nvmet_mrq_hdr[0]->queue_id);
2495
2496 bf_set(lpfc_reg_fcfi_type_match0, reg_fcfi, FC_TYPE_FCP);
2497 bf_set(lpfc_reg_fcfi_type_mask0, reg_fcfi, 0xff);
2498 bf_set(lpfc_reg_fcfi_rctl_match0, reg_fcfi,
2499 FC_RCTL_DD_UNSOL_CMD);
2500
2501 bf_set(lpfc_reg_fcfi_rq_id1, reg_fcfi,
2502 phba->sli4_hba.hdr_rq->queue_id);
2503
2504 bf_set(lpfc_reg_fcfi_type_match1, reg_fcfi, 0);
2505 bf_set(lpfc_reg_fcfi_type_mask1, reg_fcfi, 0);
2506 bf_set(lpfc_reg_fcfi_rctl_match1, reg_fcfi, 0);
2507 bf_set(lpfc_reg_fcfi_rctl_mask1, reg_fcfi, 0);
2508 }
2509 bf_set(lpfc_reg_fcfi_rq_id2, reg_fcfi, REG_FCF_INVALID_QID);
2510 bf_set(lpfc_reg_fcfi_rq_id3, reg_fcfi, REG_FCF_INVALID_QID);
2511 bf_set(lpfc_reg_fcfi_info_index, reg_fcfi,
2512 phba->fcf.current_rec.fcf_indx);
2513 if (phba->fcf.current_rec.vlan_id != LPFC_FCOE_NULL_VID) {
2514 bf_set(lpfc_reg_fcfi_vv, reg_fcfi, 1);
2515 bf_set(lpfc_reg_fcfi_vlan_tag, reg_fcfi,
2516 phba->fcf.current_rec.vlan_id);
2517 }
2518}
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534void
2535lpfc_reg_fcfi_mrq(struct lpfc_hba *phba, struct lpfcMboxq *mbox, int mode)
2536{
2537 struct lpfc_mbx_reg_fcfi_mrq *reg_fcfi;
2538
2539
2540 if (phba->cfg_nvmet_mrq <= 1)
2541 return;
2542
2543 memset(mbox, 0, sizeof(*mbox));
2544 reg_fcfi = &mbox->u.mqe.un.reg_fcfi_mrq;
2545 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_REG_FCFI_MRQ);
2546 if (mode == 0) {
2547 bf_set(lpfc_reg_fcfi_mrq_info_index, reg_fcfi,
2548 phba->fcf.current_rec.fcf_indx);
2549 if (phba->fcf.current_rec.vlan_id != LPFC_FCOE_NULL_VID) {
2550 bf_set(lpfc_reg_fcfi_mrq_vv, reg_fcfi, 1);
2551 bf_set(lpfc_reg_fcfi_mrq_vlan_tag, reg_fcfi,
2552 phba->fcf.current_rec.vlan_id);
2553 }
2554 return;
2555 }
2556
2557 bf_set(lpfc_reg_fcfi_mrq_rq_id0, reg_fcfi,
2558 phba->sli4_hba.nvmet_mrq_hdr[0]->queue_id);
2559
2560 bf_set(lpfc_reg_fcfi_mrq_type_match0, reg_fcfi, FC_TYPE_FCP);
2561 bf_set(lpfc_reg_fcfi_mrq_type_mask0, reg_fcfi, 0xff);
2562 bf_set(lpfc_reg_fcfi_mrq_rctl_match0, reg_fcfi, FC_RCTL_DD_UNSOL_CMD);
2563 bf_set(lpfc_reg_fcfi_mrq_rctl_mask0, reg_fcfi, 0xff);
2564 bf_set(lpfc_reg_fcfi_mrq_ptc0, reg_fcfi, 1);
2565 bf_set(lpfc_reg_fcfi_mrq_pt0, reg_fcfi, 1);
2566
2567 bf_set(lpfc_reg_fcfi_mrq_policy, reg_fcfi, 3);
2568 bf_set(lpfc_reg_fcfi_mrq_mode, reg_fcfi, 1);
2569 bf_set(lpfc_reg_fcfi_mrq_filter, reg_fcfi, 1);
2570 bf_set(lpfc_reg_fcfi_mrq_npairs, reg_fcfi, phba->cfg_nvmet_mrq);
2571
2572 bf_set(lpfc_reg_fcfi_mrq_rq_id1, reg_fcfi,
2573 phba->sli4_hba.hdr_rq->queue_id);
2574
2575 bf_set(lpfc_reg_fcfi_mrq_type_match1, reg_fcfi, 0);
2576 bf_set(lpfc_reg_fcfi_mrq_type_mask1, reg_fcfi, 0);
2577 bf_set(lpfc_reg_fcfi_mrq_rctl_match1, reg_fcfi, 0);
2578 bf_set(lpfc_reg_fcfi_mrq_rctl_mask1, reg_fcfi, 0);
2579
2580 bf_set(lpfc_reg_fcfi_mrq_rq_id2, reg_fcfi, REG_FCF_INVALID_QID);
2581 bf_set(lpfc_reg_fcfi_mrq_rq_id3, reg_fcfi, REG_FCF_INVALID_QID);
2582}
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592void
2593lpfc_unreg_fcfi(struct lpfcMboxq *mbox, uint16_t fcfi)
2594{
2595 memset(mbox, 0, sizeof(*mbox));
2596 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_UNREG_FCFI);
2597 bf_set(lpfc_unreg_fcfi, &mbox->u.mqe.un.unreg_fcfi, fcfi);
2598}
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608void
2609lpfc_resume_rpi(struct lpfcMboxq *mbox, struct lpfc_nodelist *ndlp)
2610{
2611 struct lpfc_hba *phba = ndlp->phba;
2612 struct lpfc_mbx_resume_rpi *resume_rpi;
2613
2614 memset(mbox, 0, sizeof(*mbox));
2615 resume_rpi = &mbox->u.mqe.un.resume_rpi;
2616 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_RESUME_RPI);
2617 bf_set(lpfc_resume_rpi_index, resume_rpi,
2618 phba->sli4_hba.rpi_ids[ndlp->nlp_rpi]);
2619 bf_set(lpfc_resume_rpi_ii, resume_rpi, RESUME_INDEX_RPI);
2620 resume_rpi->event_tag = ndlp->phba->fc_eventTag;
2621}
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631void
2632lpfc_supported_pages(struct lpfcMboxq *mbox)
2633{
2634 struct lpfc_mbx_supp_pages *supp_pages;
2635
2636 memset(mbox, 0, sizeof(*mbox));
2637 supp_pages = &mbox->u.mqe.un.supp_pages;
2638 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES);
2639 bf_set(cpn, supp_pages, LPFC_SUPP_PAGES);
2640}
2641
2642
2643
2644
2645
2646
2647
2648
2649void
2650lpfc_pc_sli4_params(struct lpfcMboxq *mbox)
2651{
2652 struct lpfc_mbx_pc_sli4_params *sli4_params;
2653
2654 memset(mbox, 0, sizeof(*mbox));
2655 sli4_params = &mbox->u.mqe.un.sli4_params;
2656 bf_set(lpfc_mqe_command, &mbox->u.mqe, MBX_PORT_CAPABILITIES);
2657 bf_set(cpn, sli4_params, LPFC_SLI4_PARAMETERS);
2658}
2659