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