-
Notifications
You must be signed in to change notification settings - Fork 848
/
if_mcx.c
8904 lines (7558 loc) · 228 KB
/
if_mcx.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
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
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/* $OpenBSD: if_mcx.c,v 1.111 2023/11/10 15:51:20 bluhm Exp $ */
/*
* Copyright (c) 2017 David Gwynne <dlg@openbsd.org>
* Copyright (c) 2019 Jonathan Matthew <jmatthew@openbsd.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "bpfilter.h"
#include "vlan.h"
#include "kstat.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/device.h>
#include <sys/pool.h>
#include <sys/queue.h>
#include <sys/timeout.h>
#include <sys/task.h>
#include <sys/atomic.h>
#include <sys/timetc.h>
#include <sys/intrmap.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/toeplitz.h>
#if NBPFILTER > 0
#include <net/bpf.h>
#endif
#if NKSTAT > 0
#include <sys/kstat.h>
#endif
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcidevs.h>
#define BUS_DMASYNC_PRERW (BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
#define BUS_DMASYNC_POSTRW (BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
#define MCX_HCA_BAR PCI_MAPREG_START /* BAR 0 */
#define MCX_FW_VER 0x0000
#define MCX_FW_VER_MAJOR(_v) ((_v) & 0xffff)
#define MCX_FW_VER_MINOR(_v) ((_v) >> 16)
#define MCX_CMDIF_FW_SUBVER 0x0004
#define MCX_FW_VER_SUBMINOR(_v) ((_v) & 0xffff)
#define MCX_CMDIF(_v) ((_v) >> 16)
#define MCX_ISSI 1 /* as per the PRM */
#define MCX_CMD_IF_SUPPORTED 5
#define MCX_HARDMTU 9500
enum mcx_cmdq_slot {
MCX_CMDQ_SLOT_POLL = 0,
MCX_CMDQ_SLOT_IOCTL,
MCX_CMDQ_SLOT_KSTAT,
MCX_CMDQ_SLOT_LINK,
MCX_CMDQ_NUM_SLOTS
};
#define MCX_PAGE_SHIFT 12
#define MCX_PAGE_SIZE (1 << MCX_PAGE_SHIFT)
/* queue sizes */
#define MCX_LOG_EQ_SIZE 7
#define MCX_LOG_CQ_SIZE 12
#define MCX_LOG_RQ_SIZE 10
#define MCX_LOG_SQ_SIZE 11
#define MCX_MAX_QUEUES 16
/* completion event moderation - about 10khz, or 90% of the cq */
#define MCX_CQ_MOD_PERIOD 50
#define MCX_CQ_MOD_COUNTER \
(((1 << (MCX_LOG_CQ_SIZE - 1)) * 9) / 10)
#define MCX_LOG_SQ_ENTRY_SIZE 6
#define MCX_SQ_ENTRY_MAX_SLOTS 4
#define MCX_SQ_SEGS_PER_SLOT \
(sizeof(struct mcx_sq_entry) / sizeof(struct mcx_sq_entry_seg))
#define MCX_SQ_MAX_SEGMENTS \
1 + ((MCX_SQ_ENTRY_MAX_SLOTS-1) * MCX_SQ_SEGS_PER_SLOT)
#define MCX_LOG_FLOW_TABLE_SIZE 5
#define MCX_NUM_STATIC_FLOWS 4 /* promisc, allmulti, ucast, bcast */
#define MCX_NUM_MCAST_FLOWS \
((1 << MCX_LOG_FLOW_TABLE_SIZE) - MCX_NUM_STATIC_FLOWS)
#define MCX_SQ_INLINE_SIZE 18
CTASSERT(ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN == MCX_SQ_INLINE_SIZE);
/* doorbell offsets */
#define MCX_DOORBELL_AREA_SIZE MCX_PAGE_SIZE
#define MCX_CQ_DOORBELL_BASE 0
#define MCX_CQ_DOORBELL_STRIDE 64
#define MCX_WQ_DOORBELL_BASE MCX_PAGE_SIZE/2
#define MCX_WQ_DOORBELL_STRIDE 64
/* make sure the doorbells fit */
CTASSERT(MCX_MAX_QUEUES * MCX_CQ_DOORBELL_STRIDE < MCX_WQ_DOORBELL_BASE);
CTASSERT(MCX_MAX_QUEUES * MCX_WQ_DOORBELL_STRIDE <
MCX_DOORBELL_AREA_SIZE - MCX_WQ_DOORBELL_BASE);
#define MCX_WQ_DOORBELL_MASK 0xffff
/* uar registers */
#define MCX_UAR_CQ_DOORBELL 0x20
#define MCX_UAR_EQ_DOORBELL_ARM 0x40
#define MCX_UAR_EQ_DOORBELL 0x48
#define MCX_UAR_BF 0x800
#define MCX_CMDQ_ADDR_HI 0x0010
#define MCX_CMDQ_ADDR_LO 0x0014
#define MCX_CMDQ_ADDR_NMASK 0xfff
#define MCX_CMDQ_LOG_SIZE(_v) ((_v) >> 4 & 0xf)
#define MCX_CMDQ_LOG_STRIDE(_v) ((_v) >> 0 & 0xf)
#define MCX_CMDQ_INTERFACE_MASK (0x3 << 8)
#define MCX_CMDQ_INTERFACE_FULL_DRIVER (0x0 << 8)
#define MCX_CMDQ_INTERFACE_DISABLED (0x1 << 8)
#define MCX_CMDQ_DOORBELL 0x0018
#define MCX_STATE 0x01fc
#define MCX_STATE_MASK (1U << 31)
#define MCX_STATE_INITIALIZING (1U << 31)
#define MCX_STATE_READY (0 << 31)
#define MCX_STATE_INTERFACE_MASK (0x3 << 24)
#define MCX_STATE_INTERFACE_FULL_DRIVER (0x0 << 24)
#define MCX_STATE_INTERFACE_DISABLED (0x1 << 24)
#define MCX_INTERNAL_TIMER 0x1000
#define MCX_INTERNAL_TIMER_H 0x1000
#define MCX_INTERNAL_TIMER_L 0x1004
#define MCX_CLEAR_INT 0x100c
#define MCX_REG_OP_WRITE 0
#define MCX_REG_OP_READ 1
#define MCX_REG_PMLP 0x5002
#define MCX_REG_PMTU 0x5003
#define MCX_REG_PTYS 0x5004
#define MCX_REG_PAOS 0x5006
#define MCX_REG_PFCC 0x5007
#define MCX_REG_PPCNT 0x5008
#define MCX_REG_MTCAP 0x9009 /* mgmt temp capabilities */
#define MCX_REG_MTMP 0x900a /* mgmt temp */
#define MCX_REG_MCIA 0x9014
#define MCX_REG_MCAM 0x907f
#define MCX_ETHER_CAP_SGMII 0
#define MCX_ETHER_CAP_1000_KX 1
#define MCX_ETHER_CAP_10G_CX4 2
#define MCX_ETHER_CAP_10G_KX4 3
#define MCX_ETHER_CAP_10G_KR 4
#define MCX_ETHER_CAP_40G_CR4 6
#define MCX_ETHER_CAP_40G_KR4 7
#define MCX_ETHER_CAP_10G_CR 12
#define MCX_ETHER_CAP_10G_SR 13
#define MCX_ETHER_CAP_10G_LR 14
#define MCX_ETHER_CAP_40G_SR4 15
#define MCX_ETHER_CAP_40G_LR4 16
#define MCX_ETHER_CAP_50G_SR2 18
#define MCX_ETHER_CAP_100G_CR4 20
#define MCX_ETHER_CAP_100G_SR4 21
#define MCX_ETHER_CAP_100G_KR4 22
#define MCX_ETHER_CAP_100G_LR4 23
#define MCX_ETHER_CAP_25G_CR 27
#define MCX_ETHER_CAP_25G_KR 28
#define MCX_ETHER_CAP_25G_SR 29
#define MCX_ETHER_CAP_50G_CR2 30
#define MCX_ETHER_CAP_50G_KR2 31
#define MCX_MAX_CQE 32
#define MCX_CMD_QUERY_HCA_CAP 0x100
#define MCX_CMD_QUERY_ADAPTER 0x101
#define MCX_CMD_INIT_HCA 0x102
#define MCX_CMD_TEARDOWN_HCA 0x103
#define MCX_CMD_ENABLE_HCA 0x104
#define MCX_CMD_DISABLE_HCA 0x105
#define MCX_CMD_QUERY_PAGES 0x107
#define MCX_CMD_MANAGE_PAGES 0x108
#define MCX_CMD_SET_HCA_CAP 0x109
#define MCX_CMD_QUERY_ISSI 0x10a
#define MCX_CMD_SET_ISSI 0x10b
#define MCX_CMD_SET_DRIVER_VERSION 0x10d
#define MCX_CMD_QUERY_SPECIAL_CONTEXTS 0x203
#define MCX_CMD_CREATE_EQ 0x301
#define MCX_CMD_DESTROY_EQ 0x302
#define MCX_CMD_QUERY_EQ 0x303
#define MCX_CMD_CREATE_CQ 0x400
#define MCX_CMD_DESTROY_CQ 0x401
#define MCX_CMD_QUERY_CQ 0x402
#define MCX_CMD_QUERY_NIC_VPORT_CONTEXT 0x754
#define MCX_CMD_MODIFY_NIC_VPORT_CONTEXT \
0x755
#define MCX_CMD_QUERY_VPORT_COUNTERS 0x770
#define MCX_CMD_ALLOC_PD 0x800
#define MCX_CMD_ALLOC_UAR 0x802
#define MCX_CMD_ACCESS_REG 0x805
#define MCX_CMD_ALLOC_TRANSPORT_DOMAIN 0x816
#define MCX_CMD_CREATE_TIR 0x900
#define MCX_CMD_DESTROY_TIR 0x902
#define MCX_CMD_CREATE_SQ 0x904
#define MCX_CMD_MODIFY_SQ 0x905
#define MCX_CMD_DESTROY_SQ 0x906
#define MCX_CMD_QUERY_SQ 0x907
#define MCX_CMD_CREATE_RQ 0x908
#define MCX_CMD_MODIFY_RQ 0x909
#define MCX_CMD_DESTROY_RQ 0x90a
#define MCX_CMD_QUERY_RQ 0x90b
#define MCX_CMD_CREATE_TIS 0x912
#define MCX_CMD_DESTROY_TIS 0x914
#define MCX_CMD_CREATE_RQT 0x916
#define MCX_CMD_DESTROY_RQT 0x918
#define MCX_CMD_SET_FLOW_TABLE_ROOT 0x92f
#define MCX_CMD_CREATE_FLOW_TABLE 0x930
#define MCX_CMD_DESTROY_FLOW_TABLE 0x931
#define MCX_CMD_QUERY_FLOW_TABLE 0x932
#define MCX_CMD_CREATE_FLOW_GROUP 0x933
#define MCX_CMD_DESTROY_FLOW_GROUP 0x934
#define MCX_CMD_QUERY_FLOW_GROUP 0x935
#define MCX_CMD_SET_FLOW_TABLE_ENTRY 0x936
#define MCX_CMD_QUERY_FLOW_TABLE_ENTRY 0x937
#define MCX_CMD_DELETE_FLOW_TABLE_ENTRY 0x938
#define MCX_CMD_ALLOC_FLOW_COUNTER 0x939
#define MCX_CMD_QUERY_FLOW_COUNTER 0x93b
#define MCX_QUEUE_STATE_RST 0
#define MCX_QUEUE_STATE_RDY 1
#define MCX_QUEUE_STATE_ERR 3
#define MCX_FLOW_TABLE_TYPE_RX 0
#define MCX_FLOW_TABLE_TYPE_TX 1
#define MCX_CMDQ_INLINE_DATASIZE 16
struct mcx_cmdq_entry {
uint8_t cq_type;
#define MCX_CMDQ_TYPE_PCIE 0x7
uint8_t cq_reserved0[3];
uint32_t cq_input_length;
uint64_t cq_input_ptr;
uint8_t cq_input_data[MCX_CMDQ_INLINE_DATASIZE];
uint8_t cq_output_data[MCX_CMDQ_INLINE_DATASIZE];
uint64_t cq_output_ptr;
uint32_t cq_output_length;
uint8_t cq_token;
uint8_t cq_signature;
uint8_t cq_reserved1[1];
uint8_t cq_status;
#define MCX_CQ_STATUS_SHIFT 1
#define MCX_CQ_STATUS_MASK (0x7f << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_OK (0x00 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_INT_ERR (0x01 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_BAD_OPCODE (0x02 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_BAD_PARAM (0x03 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_BAD_SYS_STATE (0x04 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_BAD_RESOURCE (0x05 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_RESOURCE_BUSY (0x06 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_EXCEED_LIM (0x08 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_BAD_RES_STATE (0x09 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_BAD_INDEX (0x0a << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_NO_RESOURCES (0x0f << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_BAD_INPUT_LEN (0x50 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_BAD_OUTPUT_LEN (0x51 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_BAD_RESOURCE_STATE \
(0x10 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_BAD_SIZE (0x40 << MCX_CQ_STATUS_SHIFT)
#define MCX_CQ_STATUS_OWN_MASK 0x1
#define MCX_CQ_STATUS_OWN_SW 0x0
#define MCX_CQ_STATUS_OWN_HW 0x1
} __packed __aligned(8);
#define MCX_CMDQ_MAILBOX_DATASIZE 512
struct mcx_cmdq_mailbox {
uint8_t mb_data[MCX_CMDQ_MAILBOX_DATASIZE];
uint8_t mb_reserved0[48];
uint64_t mb_next_ptr;
uint32_t mb_block_number;
uint8_t mb_reserved1[1];
uint8_t mb_token;
uint8_t mb_ctrl_signature;
uint8_t mb_signature;
} __packed __aligned(8);
#define MCX_CMDQ_MAILBOX_ALIGN (1 << 10)
#define MCX_CMDQ_MAILBOX_SIZE roundup(sizeof(struct mcx_cmdq_mailbox), \
MCX_CMDQ_MAILBOX_ALIGN)
/*
* command mailbox structures
*/
struct mcx_cmd_enable_hca_in {
uint16_t cmd_opcode;
uint8_t cmd_reserved0[4];
uint16_t cmd_op_mod;
uint8_t cmd_reserved1[2];
uint16_t cmd_function_id;
uint8_t cmd_reserved2[4];
} __packed __aligned(4);
struct mcx_cmd_enable_hca_out {
uint8_t cmd_status;
uint8_t cmd_reserved0[3];
uint32_t cmd_syndrome;
uint8_t cmd_reserved1[4];
} __packed __aligned(4);
struct mcx_cmd_init_hca_in {
uint16_t cmd_opcode;
uint8_t cmd_reserved0[4];
uint16_t cmd_op_mod;
uint8_t cmd_reserved1[8];
} __packed __aligned(4);
struct mcx_cmd_init_hca_out {
uint8_t cmd_status;
uint8_t cmd_reserved0[3];
uint32_t cmd_syndrome;
uint8_t cmd_reserved1[8];
} __packed __aligned(4);
struct mcx_cmd_teardown_hca_in {
uint16_t cmd_opcode;
uint8_t cmd_reserved0[4];
uint16_t cmd_op_mod;
uint8_t cmd_reserved1[2];
#define MCX_CMD_TEARDOWN_HCA_GRACEFUL 0x0
#define MCX_CMD_TEARDOWN_HCA_PANIC 0x1
uint16_t cmd_profile;
uint8_t cmd_reserved2[4];
} __packed __aligned(4);
struct mcx_cmd_teardown_hca_out {
uint8_t cmd_status;
uint8_t cmd_reserved0[3];
uint32_t cmd_syndrome;
uint8_t cmd_reserved1[8];
} __packed __aligned(4);
struct mcx_cmd_access_reg_in {
uint16_t cmd_opcode;
uint8_t cmd_reserved0[4];
uint16_t cmd_op_mod;
uint8_t cmd_reserved1[2];
uint16_t cmd_register_id;
uint32_t cmd_argument;
} __packed __aligned(4);
struct mcx_cmd_access_reg_out {
uint8_t cmd_status;
uint8_t cmd_reserved0[3];
uint32_t cmd_syndrome;
uint8_t cmd_reserved1[8];
} __packed __aligned(4);
struct mcx_reg_pmtu {
uint8_t rp_reserved1;
uint8_t rp_local_port;
uint8_t rp_reserved2[2];
uint16_t rp_max_mtu;
uint8_t rp_reserved3[2];
uint16_t rp_admin_mtu;
uint8_t rp_reserved4[2];
uint16_t rp_oper_mtu;
uint8_t rp_reserved5[2];
} __packed __aligned(4);
struct mcx_reg_ptys {
uint8_t rp_reserved1;
uint8_t rp_local_port;
uint8_t rp_reserved2;
uint8_t rp_proto_mask;
#define MCX_REG_PTYS_PROTO_MASK_ETH (1 << 2)
uint8_t rp_reserved3[8];
uint32_t rp_eth_proto_cap;
uint8_t rp_reserved4[8];
uint32_t rp_eth_proto_admin;
uint8_t rp_reserved5[8];
uint32_t rp_eth_proto_oper;
uint8_t rp_reserved6[24];
} __packed __aligned(4);
struct mcx_reg_paos {
uint8_t rp_reserved1;
uint8_t rp_local_port;
uint8_t rp_admin_status;
#define MCX_REG_PAOS_ADMIN_STATUS_UP 1
#define MCX_REG_PAOS_ADMIN_STATUS_DOWN 2
#define MCX_REG_PAOS_ADMIN_STATUS_UP_ONCE 3
#define MCX_REG_PAOS_ADMIN_STATUS_DISABLED 4
uint8_t rp_oper_status;
#define MCX_REG_PAOS_OPER_STATUS_UP 1
#define MCX_REG_PAOS_OPER_STATUS_DOWN 2
#define MCX_REG_PAOS_OPER_STATUS_FAILED 4
uint8_t rp_admin_state_update;
#define MCX_REG_PAOS_ADMIN_STATE_UPDATE_EN (1 << 7)
uint8_t rp_reserved2[11];
} __packed __aligned(4);
struct mcx_reg_pfcc {
uint8_t rp_reserved1;
uint8_t rp_local_port;
uint8_t rp_reserved2[3];
uint8_t rp_prio_mask_tx;
uint8_t rp_reserved3;
uint8_t rp_prio_mask_rx;
uint8_t rp_pptx_aptx;
uint8_t rp_pfctx;
uint8_t rp_fctx_dis;
uint8_t rp_reserved4;
uint8_t rp_pprx_aprx;
uint8_t rp_pfcrx;
uint8_t rp_reserved5[2];
uint16_t rp_dev_stall_min;
uint16_t rp_dev_stall_crit;
uint8_t rp_reserved6[12];
} __packed __aligned(4);
#define MCX_PMLP_MODULE_NUM_MASK 0xff
struct mcx_reg_pmlp {
uint8_t rp_rxtx;
uint8_t rp_local_port;
uint8_t rp_reserved0;
uint8_t rp_width;
uint32_t rp_lane0_mapping;
uint32_t rp_lane1_mapping;
uint32_t rp_lane2_mapping;
uint32_t rp_lane3_mapping;
uint8_t rp_reserved1[44];
} __packed __aligned(4);
struct mcx_reg_ppcnt {
uint8_t ppcnt_swid;
uint8_t ppcnt_local_port;
uint8_t ppcnt_pnat;
uint8_t ppcnt_grp;
#define MCX_REG_PPCNT_GRP_IEEE8023 0x00
#define MCX_REG_PPCNT_GRP_RFC2863 0x01
#define MCX_REG_PPCNT_GRP_RFC2819 0x02
#define MCX_REG_PPCNT_GRP_RFC3635 0x03
#define MCX_REG_PPCNT_GRP_PER_PRIO 0x10
#define MCX_REG_PPCNT_GRP_PER_TC 0x11
#define MCX_REG_PPCNT_GRP_PER_RX_BUFFER 0x11
uint8_t ppcnt_clr;
uint8_t ppcnt_reserved1[2];
uint8_t ppcnt_prio_tc;
#define MCX_REG_PPCNT_CLR (1 << 7)
uint8_t ppcnt_counter_set[248];
} __packed __aligned(8);
CTASSERT(sizeof(struct mcx_reg_ppcnt) == 256);
CTASSERT((offsetof(struct mcx_reg_ppcnt, ppcnt_counter_set) %
sizeof(uint64_t)) == 0);
enum mcx_ppcnt_ieee8023 {
frames_transmitted_ok,
frames_received_ok,
frame_check_sequence_errors,
alignment_errors,
octets_transmitted_ok,
octets_received_ok,
multicast_frames_xmitted_ok,
broadcast_frames_xmitted_ok,
multicast_frames_received_ok,
broadcast_frames_received_ok,
in_range_length_errors,
out_of_range_length_field,
frame_too_long_errors,
symbol_error_during_carrier,
mac_control_frames_transmitted,
mac_control_frames_received,
unsupported_opcodes_received,
pause_mac_ctrl_frames_received,
pause_mac_ctrl_frames_transmitted,
mcx_ppcnt_ieee8023_count
};
CTASSERT(mcx_ppcnt_ieee8023_count * sizeof(uint64_t) == 0x98);
enum mcx_ppcnt_rfc2863 {
in_octets,
in_ucast_pkts,
in_discards,
in_errors,
in_unknown_protos,
out_octets,
out_ucast_pkts,
out_discards,
out_errors,
in_multicast_pkts,
in_broadcast_pkts,
out_multicast_pkts,
out_broadcast_pkts,
mcx_ppcnt_rfc2863_count
};
CTASSERT(mcx_ppcnt_rfc2863_count * sizeof(uint64_t) == 0x68);
enum mcx_ppcnt_rfc2819 {
drop_events,
octets,
pkts,
broadcast_pkts,
multicast_pkts,
crc_align_errors,
undersize_pkts,
oversize_pkts,
fragments,
jabbers,
collisions,
pkts64octets,
pkts65to127octets,
pkts128to255octets,
pkts256to511octets,
pkts512to1023octets,
pkts1024to1518octets,
pkts1519to2047octets,
pkts2048to4095octets,
pkts4096to8191octets,
pkts8192to10239octets,
mcx_ppcnt_rfc2819_count
};
CTASSERT((mcx_ppcnt_rfc2819_count * sizeof(uint64_t)) == 0xa8);
enum mcx_ppcnt_rfc3635 {
dot3stats_alignment_errors,
dot3stats_fcs_errors,
dot3stats_single_collision_frames,
dot3stats_multiple_collision_frames,
dot3stats_sqe_test_errors,
dot3stats_deferred_transmissions,
dot3stats_late_collisions,
dot3stats_excessive_collisions,
dot3stats_internal_mac_transmit_errors,
dot3stats_carrier_sense_errors,
dot3stats_frame_too_longs,
dot3stats_internal_mac_receive_errors,
dot3stats_symbol_errors,
dot3control_in_unknown_opcodes,
dot3in_pause_frames,
dot3out_pause_frames,
mcx_ppcnt_rfc3635_count
};
CTASSERT((mcx_ppcnt_rfc3635_count * sizeof(uint64_t)) == 0x80);
struct mcx_reg_mcam {
uint8_t _reserved1[1];
uint8_t mcam_feature_group;
uint8_t _reserved2[1];
uint8_t mcam_access_reg_group;
uint8_t _reserved3[4];
uint8_t mcam_access_reg_cap_mask[16];
uint8_t _reserved4[16];
uint8_t mcam_feature_cap_mask[16];
uint8_t _reserved5[16];
} __packed __aligned(4);
#define MCX_BITFIELD_BIT(bf, b) (bf[(sizeof bf - 1) - (b / 8)] & (b % 8))
#define MCX_MCAM_FEATURE_CAP_SENSOR_MAP 6
struct mcx_reg_mtcap {
uint8_t _reserved1[3];
uint8_t mtcap_sensor_count;
uint8_t _reserved2[4];
uint64_t mtcap_sensor_map;
};
struct mcx_reg_mtmp {
uint8_t _reserved1[2];
uint16_t mtmp_sensor_index;
uint8_t _reserved2[2];
uint16_t mtmp_temperature;
uint16_t mtmp_mte_mtr;
#define MCX_REG_MTMP_MTE (1 << 15)
#define MCX_REG_MTMP_MTR (1 << 14)
uint16_t mtmp_max_temperature;
uint16_t mtmp_tee;
#define MCX_REG_MTMP_TEE_NOPE (0 << 14)
#define MCX_REG_MTMP_TEE_GENERATE (1 << 14)
#define MCX_REG_MTMP_TEE_GENERATE_ONE (2 << 14)
uint16_t mtmp_temperature_threshold_hi;
uint8_t _reserved3[2];
uint16_t mtmp_temperature_threshold_lo;
uint8_t _reserved4[4];
uint8_t mtmp_sensor_name[8];
};
CTASSERT(sizeof(struct mcx_reg_mtmp) == 0x20);
CTASSERT(offsetof(struct mcx_reg_mtmp, mtmp_sensor_name) == 0x18);
#define MCX_MCIA_EEPROM_BYTES 32
struct mcx_reg_mcia {
uint8_t rm_l;
uint8_t rm_module;
uint8_t rm_reserved0;
uint8_t rm_status;
uint8_t rm_i2c_addr;
uint8_t rm_page_num;
uint16_t rm_dev_addr;
uint16_t rm_reserved1;
uint16_t rm_size;
uint32_t rm_reserved2;
uint8_t rm_data[48];
} __packed __aligned(4);
struct mcx_cmd_query_issi_in {
uint16_t cmd_opcode;
uint8_t cmd_reserved0[4];
uint16_t cmd_op_mod;
uint8_t cmd_reserved1[8];
} __packed __aligned(4);
struct mcx_cmd_query_issi_il_out {
uint8_t cmd_status;
uint8_t cmd_reserved0[3];
uint32_t cmd_syndrome;
uint8_t cmd_reserved1[2];
uint16_t cmd_current_issi;
uint8_t cmd_reserved2[4];
} __packed __aligned(4);
CTASSERT(sizeof(struct mcx_cmd_query_issi_il_out) == MCX_CMDQ_INLINE_DATASIZE);
struct mcx_cmd_query_issi_mb_out {
uint8_t cmd_reserved2[16];
uint8_t cmd_supported_issi[80]; /* very big endian */
} __packed __aligned(4);
CTASSERT(sizeof(struct mcx_cmd_query_issi_mb_out) <= MCX_CMDQ_MAILBOX_DATASIZE);
struct mcx_cmd_set_issi_in {
uint16_t cmd_opcode;
uint8_t cmd_reserved0[4];
uint16_t cmd_op_mod;
uint8_t cmd_reserved1[2];
uint16_t cmd_current_issi;
uint8_t cmd_reserved2[4];
} __packed __aligned(4);
CTASSERT(sizeof(struct mcx_cmd_set_issi_in) <= MCX_CMDQ_INLINE_DATASIZE);
struct mcx_cmd_set_issi_out {
uint8_t cmd_status;
uint8_t cmd_reserved0[3];
uint32_t cmd_syndrome;
uint8_t cmd_reserved1[8];
} __packed __aligned(4);
CTASSERT(sizeof(struct mcx_cmd_set_issi_out) <= MCX_CMDQ_INLINE_DATASIZE);
struct mcx_cmd_query_pages_in {
uint16_t cmd_opcode;
uint8_t cmd_reserved0[4];
uint16_t cmd_op_mod;
#define MCX_CMD_QUERY_PAGES_BOOT 0x01
#define MCX_CMD_QUERY_PAGES_INIT 0x02
#define MCX_CMD_QUERY_PAGES_REGULAR 0x03
uint8_t cmd_reserved1[8];
} __packed __aligned(4);
struct mcx_cmd_query_pages_out {
uint8_t cmd_status;
uint8_t cmd_reserved0[3];
uint32_t cmd_syndrome;
uint8_t cmd_reserved1[2];
uint16_t cmd_func_id;
int32_t cmd_num_pages;
} __packed __aligned(4);
struct mcx_cmd_manage_pages_in {
uint16_t cmd_opcode;
uint8_t cmd_reserved0[4];
uint16_t cmd_op_mod;
#define MCX_CMD_MANAGE_PAGES_ALLOC_FAIL \
0x00
#define MCX_CMD_MANAGE_PAGES_ALLOC_SUCCESS \
0x01
#define MCX_CMD_MANAGE_PAGES_HCA_RETURN_PAGES \
0x02
uint8_t cmd_reserved1[2];
uint16_t cmd_func_id;
uint32_t cmd_input_num_entries;
} __packed __aligned(4);
CTASSERT(sizeof(struct mcx_cmd_manage_pages_in) == MCX_CMDQ_INLINE_DATASIZE);
struct mcx_cmd_manage_pages_out {
uint8_t cmd_status;
uint8_t cmd_reserved0[3];
uint32_t cmd_syndrome;
uint32_t cmd_output_num_entries;
uint8_t cmd_reserved1[4];
} __packed __aligned(4);
CTASSERT(sizeof(struct mcx_cmd_manage_pages_out) == MCX_CMDQ_INLINE_DATASIZE);
struct mcx_cmd_query_hca_cap_in {
uint16_t cmd_opcode;
uint8_t cmd_reserved0[4];
uint16_t cmd_op_mod;
#define MCX_CMD_QUERY_HCA_CAP_MAX (0x0 << 0)
#define MCX_CMD_QUERY_HCA_CAP_CURRENT (0x1 << 0)
#define MCX_CMD_QUERY_HCA_CAP_DEVICE (0x0 << 1)
#define MCX_CMD_QUERY_HCA_CAP_OFFLOAD (0x1 << 1)
#define MCX_CMD_QUERY_HCA_CAP_FLOW (0x7 << 1)
uint8_t cmd_reserved1[8];
} __packed __aligned(4);
struct mcx_cmd_query_hca_cap_out {
uint8_t cmd_status;
uint8_t cmd_reserved0[3];
uint32_t cmd_syndrome;
uint8_t cmd_reserved1[8];
} __packed __aligned(4);
#define MCX_HCA_CAP_LEN 0x1000
#define MCX_HCA_CAP_NMAILBOXES \
(MCX_HCA_CAP_LEN / MCX_CMDQ_MAILBOX_DATASIZE)
#if __GNUC_PREREQ__(4, 3)
#define __counter__ __COUNTER__
#else
#define __counter__ __LINE__
#endif
#define __token(_tok, _num) _tok##_num
#define _token(_tok, _num) __token(_tok, _num)
#define __reserved__ _token(__reserved, __counter__)
struct mcx_cap_device {
uint8_t reserved0[16];
uint8_t log_max_srq_sz;
uint8_t log_max_qp_sz;
uint8_t __reserved__[1];
uint8_t log_max_qp; /* 5 bits */
#define MCX_CAP_DEVICE_LOG_MAX_QP 0x1f
uint8_t __reserved__[1];
uint8_t log_max_srq; /* 5 bits */
#define MCX_CAP_DEVICE_LOG_MAX_SRQ 0x1f
uint8_t __reserved__[2];
uint8_t __reserved__[1];
uint8_t log_max_cq_sz;
uint8_t __reserved__[1];
uint8_t log_max_cq; /* 5 bits */
#define MCX_CAP_DEVICE_LOG_MAX_CQ 0x1f
uint8_t log_max_eq_sz;
uint8_t log_max_mkey; /* 6 bits */
#define MCX_CAP_DEVICE_LOG_MAX_MKEY 0x3f
uint8_t __reserved__[1];
uint8_t log_max_eq; /* 4 bits */
#define MCX_CAP_DEVICE_LOG_MAX_EQ 0x0f
uint8_t max_indirection;
uint8_t log_max_mrw_sz; /* 7 bits */
#define MCX_CAP_DEVICE_LOG_MAX_MRW_SZ 0x7f
uint8_t teardown_log_max_msf_list_size;
#define MCX_CAP_DEVICE_FORCE_TEARDOWN 0x80
#define MCX_CAP_DEVICE_LOG_MAX_MSF_LIST_SIZE \
0x3f
uint8_t log_max_klm_list_size; /* 6 bits */
#define MCX_CAP_DEVICE_LOG_MAX_KLM_LIST_SIZE \
0x3f
uint8_t __reserved__[1];
uint8_t log_max_ra_req_dc; /* 6 bits */
#define MCX_CAP_DEVICE_LOG_MAX_REQ_DC 0x3f
uint8_t __reserved__[1];
uint8_t log_max_ra_res_dc; /* 6 bits */
#define MCX_CAP_DEVICE_LOG_MAX_RA_RES_DC \
0x3f
uint8_t __reserved__[1];
uint8_t log_max_ra_req_qp; /* 6 bits */
#define MCX_CAP_DEVICE_LOG_MAX_RA_REQ_QP \
0x3f
uint8_t __reserved__[1];
uint8_t log_max_ra_res_qp; /* 6 bits */
#define MCX_CAP_DEVICE_LOG_MAX_RA_RES_QP \
0x3f
uint8_t flags1;
#define MCX_CAP_DEVICE_END_PAD 0x80
#define MCX_CAP_DEVICE_CC_QUERY_ALLOWED 0x40
#define MCX_CAP_DEVICE_CC_MODIFY_ALLOWED \
0x20
#define MCX_CAP_DEVICE_START_PAD 0x10
#define MCX_CAP_DEVICE_128BYTE_CACHELINE \
0x08
uint8_t __reserved__[1];
uint16_t gid_table_size;
uint16_t flags2;
#define MCX_CAP_DEVICE_OUT_OF_SEQ_CNT 0x8000
#define MCX_CAP_DEVICE_VPORT_COUNTERS 0x4000
#define MCX_CAP_DEVICE_RETRANSMISSION_Q_COUNTERS \
0x2000
#define MCX_CAP_DEVICE_DEBUG 0x1000
#define MCX_CAP_DEVICE_MODIFY_RQ_COUNTERS_SET_ID \
0x8000
#define MCX_CAP_DEVICE_RQ_DELAY_DROP 0x4000
#define MCX_CAP_DEVICe_MAX_QP_CNT_MASK 0x03ff
uint16_t pkey_table_size;
uint8_t flags3;
#define MCX_CAP_DEVICE_VPORT_GROUP_MANAGER \
0x80
#define MCX_CAP_DEVICE_VHCA_GROUP_MANAGER \
0x40
#define MCX_CAP_DEVICE_IB_VIRTUAL 0x20
#define MCX_CAP_DEVICE_ETH_VIRTUAL 0x10
#define MCX_CAP_DEVICE_ETS 0x04
#define MCX_CAP_DEVICE_NIC_FLOW_TABLE 0x02
#define MCX_CAP_DEVICE_ESWITCH_FLOW_TABLE \
0x01
uint8_t local_ca_ack_delay; /* 5 bits */
#define MCX_CAP_DEVICE_LOCAL_CA_ACK_DELAY \
0x1f
#define MCX_CAP_DEVICE_MCAM_REG 0x40
uint8_t port_type;
#define MCX_CAP_DEVICE_PORT_MODULE_EVENT \
0x80
#define MCX_CAP_DEVICE_PORT_TYPE 0x03
#define MCX_CAP_DEVICE_PORT_TYPE_ETH 0x01
uint8_t num_ports;
uint8_t snapshot_log_max_msg;
#define MCX_CAP_DEVICE_SNAPSHOT 0x80
#define MCX_CAP_DEVICE_LOG_MAX_MSG 0x1f
uint8_t max_tc; /* 4 bits */
#define MCX_CAP_DEVICE_MAX_TC 0x0f
uint8_t flags4;
#define MCX_CAP_DEVICE_TEMP_WARN_EVENT 0x80
#define MCX_CAP_DEVICE_DCBX 0x40
#define MCX_CAP_DEVICE_ROL_S 0x02
#define MCX_CAP_DEVICE_ROL_G 0x01
uint8_t wol;
#define MCX_CAP_DEVICE_WOL_S 0x40
#define MCX_CAP_DEVICE_WOL_G 0x20
#define MCX_CAP_DEVICE_WOL_A 0x10
#define MCX_CAP_DEVICE_WOL_B 0x08
#define MCX_CAP_DEVICE_WOL_M 0x04
#define MCX_CAP_DEVICE_WOL_U 0x02
#define MCX_CAP_DEVICE_WOL_P 0x01
uint16_t stat_rate_support;
uint8_t __reserved__[1];
uint8_t cqe_version; /* 4 bits */
#define MCX_CAP_DEVICE_CQE_VERSION 0x0f
uint32_t flags5;
#define MCX_CAP_DEVICE_COMPACT_ADDRESS_VECTOR \
0x80000000
#define MCX_CAP_DEVICE_STRIDING_RQ 0x40000000
#define MCX_CAP_DEVICE_IPOIP_ENHANCED_OFFLOADS \
0x10000000
#define MCX_CAP_DEVICE_IPOIP_IPOIP_OFFLOADS \
0x08000000
#define MCX_CAP_DEVICE_DC_CONNECT_CP 0x00040000
#define MCX_CAP_DEVICE_DC_CNAK_DRACE 0x00020000
#define MCX_CAP_DEVICE_DRAIN_SIGERR 0x00010000
#define MCX_CAP_DEVICE_DRAIN_SIGERR 0x00010000
#define MCX_CAP_DEVICE_CMDIF_CHECKSUM 0x0000c000
#define MCX_CAP_DEVICE_SIGERR_QCE 0x00002000
#define MCX_CAP_DEVICE_WQ_SIGNATURE 0x00000800
#define MCX_CAP_DEVICE_SCTR_DATA_CQE 0x00000400
#define MCX_CAP_DEVICE_SHO 0x00000100
#define MCX_CAP_DEVICE_TPH 0x00000080
#define MCX_CAP_DEVICE_RF 0x00000040
#define MCX_CAP_DEVICE_DCT 0x00000020
#define MCX_CAP_DEVICE_QOS 0x00000010
#define MCX_CAP_DEVICe_ETH_NET_OFFLOADS 0x00000008
#define MCX_CAP_DEVICE_ROCE 0x00000004
#define MCX_CAP_DEVICE_ATOMIC 0x00000002
uint32_t flags6;
#define MCX_CAP_DEVICE_CQ_OI 0x80000000
#define MCX_CAP_DEVICE_CQ_RESIZE 0x40000000
#define MCX_CAP_DEVICE_CQ_MODERATION 0x20000000
#define MCX_CAP_DEVICE_CQ_PERIOD_MODE_MODIFY \
0x10000000
#define MCX_CAP_DEVICE_CQ_INVALIDATE 0x08000000
#define MCX_CAP_DEVICE_RESERVED_AT_255 0x04000000
#define MCX_CAP_DEVICE_CQ_EQ_REMAP 0x02000000
#define MCX_CAP_DEVICE_PG 0x01000000
#define MCX_CAP_DEVICE_BLOCK_LB_MC 0x00800000
#define MCX_CAP_DEVICE_EXPONENTIAL_BACKOFF \
0x00400000
#define MCX_CAP_DEVICE_SCQE_BREAK_MODERATION \
0x00200000
#define MCX_CAP_DEVICE_CQ_PERIOD_START_FROM_CQE \
0x00100000
#define MCX_CAP_DEVICE_CD 0x00080000
#define MCX_CAP_DEVICE_ATM 0x00040000
#define MCX_CAP_DEVICE_APM 0x00020000
#define MCX_CAP_DEVICE_IMAICL 0x00010000
#define MCX_CAP_DEVICE_QKV 0x00000200
#define MCX_CAP_DEVICE_PKV 0x00000100
#define MCX_CAP_DEVICE_SET_DETH_SQPN 0x00000080
#define MCX_CAP_DEVICE_XRC 0x00000008
#define MCX_CAP_DEVICE_UD 0x00000004
#define MCX_CAP_DEVICE_UC 0x00000002
#define MCX_CAP_DEVICE_RC 0x00000001
uint8_t uar_flags;
#define MCX_CAP_DEVICE_UAR_4K 0x80
uint8_t uar_sz; /* 6 bits */
#define MCX_CAP_DEVICE_UAR_SZ 0x3f
uint8_t __reserved__[1];
uint8_t log_pg_sz;
uint8_t flags7;
#define MCX_CAP_DEVICE_BF 0x80
#define MCX_CAP_DEVICE_DRIVER_VERSION 0x40
#define MCX_CAP_DEVICE_PAD_TX_ETH_PACKET \
0x20
uint8_t log_bf_reg_size; /* 5 bits */
#define MCX_CAP_DEVICE_LOG_BF_REG_SIZE 0x1f
uint8_t __reserved__[2];
uint16_t num_of_diagnostic_counters;
uint16_t max_wqe_sz_sq;
uint8_t __reserved__[2];
uint16_t max_wqe_sz_rq;
uint8_t __reserved__[2];
uint16_t max_wqe_sz_sq_dc;
uint32_t max_qp_mcg; /* 25 bits */
#define MCX_CAP_DEVICE_MAX_QP_MCG 0x1ffffff
uint8_t __reserved__[3];
uint8_t log_max_mcq;
uint8_t log_max_transport_domain; /* 5 bits */
#define MCX_CAP_DEVICE_LOG_MAX_TRANSORT_DOMAIN \
0x1f
uint8_t log_max_pd; /* 5 bits */
#define MCX_CAP_DEVICE_LOG_MAX_PD 0x1f
uint8_t __reserved__[1];
uint8_t log_max_xrcd; /* 5 bits */
#define MCX_CAP_DEVICE_LOG_MAX_XRCD 0x1f
uint8_t __reserved__[2];
uint16_t max_flow_counter;
uint8_t log_max_rq; /* 5 bits */
#define MCX_CAP_DEVICE_LOG_MAX_RQ 0x1f
uint8_t log_max_sq; /* 5 bits */
#define MCX_CAP_DEVICE_LOG_MAX_SQ 0x1f
uint8_t log_max_tir; /* 5 bits */