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