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