summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/ibm/ibmvnic.h
blob: f8416e1d4cf0942fd013faa6cefa85e552fb0849 (plain)
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
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
/* SPDX-License-Identifier: GPL-2.0-or-later */
/**************************************************************************/
/*                                                                        */
/*  IBM System i and System p Virtual NIC Device Driver                   */
/*  Copyright (C) 2014 IBM Corp.                                          */
/*  Santiago Leon (santi_leon@yahoo.com)                                  */
/*  Thomas Falcon (tlfalcon@linux.vnet.ibm.com)                           */
/*  John Allen (jallen@linux.vnet.ibm.com)                                */
/*                                                                        */
/*                                                                        */
/* This module contains the implementation of a virtual ethernet device   */
/* for use with IBM i/pSeries LPAR Linux.  It utilizes the logical LAN    */
/* option of the RS/6000 Platform Architecture to interface with virtual */
/* ethernet NICs that are presented to the partition by the hypervisor.   */
/*                                                                        */
/**************************************************************************/

#define IBMVNIC_NAME		"ibmvnic"
#define IBMVNIC_DRIVER_VERSION	"1.0.1"
#define IBMVNIC_INVALID_MAP	-1
#define IBMVNIC_STATS_TIMEOUT	1
#define IBMVNIC_INIT_FAILED	2
#define IBMVNIC_OPEN_FAILED	3

/* basic structures plus 100 2k buffers */
#define IBMVNIC_IO_ENTITLEMENT_DEFAULT	610305

/* Initial module_parameters */
#define IBMVNIC_RX_WEIGHT		16
/* when changing this, update IBMVNIC_IO_ENTITLEMENT_DEFAULT */
#define IBMVNIC_BUFFS_PER_POOL	100
#define IBMVNIC_MAX_QUEUES	16
#define IBMVNIC_MAX_QUEUE_SZ   4096

#define IBMVNIC_TSO_BUF_SZ	65536
#define IBMVNIC_TSO_BUFS	64
#define IBMVNIC_TSO_POOL_MASK	0x80000000

#define IBMVNIC_MAX_LTB_SIZE ((1 << (MAX_ORDER - 1)) * PAGE_SIZE)
#define IBMVNIC_BUFFER_HLEN 500

#define IBMVNIC_RESET_DELAY 100

static const char ibmvnic_priv_flags[][ETH_GSTRING_LEN] = {
#define IBMVNIC_USE_SERVER_MAXES 0x1
	"use-server-maxes"
};

struct ibmvnic_login_buffer {
	__be32 len;
	__be32 version;
#define INITIAL_VERSION_LB 1
	__be32 num_txcomp_subcrqs;
	__be32 off_txcomp_subcrqs;
	__be32 num_rxcomp_subcrqs;
	__be32 off_rxcomp_subcrqs;
	__be32 login_rsp_ioba;
	__be32 login_rsp_len;
	__be32 client_data_offset;
	__be32 client_data_len;
} __packed __aligned(8);

struct ibmvnic_login_rsp_buffer {
	__be32 len;
	__be32 version;
#define INITIAL_VERSION_LRB 1
	__be32 num_txsubm_subcrqs;
	__be32 off_txsubm_subcrqs;
	__be32 num_rxadd_subcrqs;
	__be32 off_rxadd_subcrqs;
	__be32 off_rxadd_buff_size;
	__be32 num_supp_tx_desc;
	__be32 off_supp_tx_desc;
} __packed __aligned(8);

struct ibmvnic_query_ip_offload_buffer {
	__be32 len;
	__be32 version;
#define INITIAL_VERSION_IOB 1
	u8 ipv4_chksum;
	u8 ipv6_chksum;
	u8 tcp_ipv4_chksum;
	u8 tcp_ipv6_chksum;
	u8 udp_ipv4_chksum;
	u8 udp_ipv6_chksum;
	u8 large_tx_ipv4;
	u8 large_tx_ipv6;
	u8 large_rx_ipv4;
	u8 large_rx_ipv6;
	u8 reserved1[14];
	__be16 max_ipv4_header_size;
	__be16 max_ipv6_header_size;
	__be16 max_tcp_header_size;
	__be16 max_udp_header_size;
	__be32 max_large_tx_size;
	__be32 max_large_rx_size;
	u8 reserved2[16];
	u8 ipv6_extension_header;
#define IPV6_EH_NOT_SUPPORTED	0x00
#define IPV6_EH_SUPPORTED_LIM	0x01
#define IPV6_EH_SUPPORTED	0xFF
	u8 tcp_pseudosum_req;
#define TCP_PS_NOT_REQUIRED	0x00
#define TCP_PS_REQUIRED		0x01
	u8 reserved3[30];
	__be16 num_ipv6_ext_headers;
	__be32 off_ipv6_ext_headers;
	u8 reserved4[154];
} __packed __aligned(8);

struct ibmvnic_control_ip_offload_buffer {
	__be32 len;
	__be32 version;
#define INITIAL_VERSION_IOB 1
	u8 ipv4_chksum;
	u8 ipv6_chksum;
	u8 tcp_ipv4_chksum;
	u8 tcp_ipv6_chksum;
	u8 udp_ipv4_chksum;
	u8 udp_ipv6_chksum;
	u8 large_tx_ipv4;
	u8 large_tx_ipv6;
	u8 bad_packet_rx;
	u8 large_rx_ipv4;
	u8 large_rx_ipv6;
	u8 reserved4[111];
} __packed __aligned(8);

struct ibmvnic_fw_component {
	u8 name[48];
	__be32 trace_buff_size;
	u8 correlator;
	u8 trace_level;
	u8 parent_correlator;
	u8 error_check_level;
	u8 trace_on;
	u8 reserved[7];
	u8 description[192];
} __packed __aligned(8);

struct ibmvnic_fw_trace_entry {
	__be32 trace_id;
	u8 num_valid_data;
	u8 reserved[3];
	__be64 pmc_registers;
	__be64 timebase;
	__be64 trace_data[5];
} __packed __aligned(8);

struct ibmvnic_statistics {
	__be32 version;
	__be32 promiscuous;
	__be64 rx_packets;
	__be64 rx_bytes;
	__be64 tx_packets;
	__be64 tx_bytes;
	__be64 ucast_tx_packets;
	__be64 ucast_rx_packets;
	__be64 mcast_tx_packets;
	__be64 mcast_rx_packets;
	__be64 bcast_tx_packets;
	__be64 bcast_rx_packets;
	__be64 align_errors;
	__be64 fcs_errors;
	__be64 single_collision_frames;
	__be64 multi_collision_frames;
	__be64 sqe_test_errors;
	__be64 deferred_tx;
	__be64 late_collisions;
	__be64 excess_collisions;
	__be64 internal_mac_tx_errors;
	__be64 carrier_sense;
	__be64 too_long_frames;
	__be64 internal_mac_rx_errors;
	u8 reserved[72];
} __packed __aligned(8);

#define NUM_TX_STATS 3
struct ibmvnic_tx_queue_stats {
	u64 packets;
	u64 bytes;
	u64 dropped_packets;
};

#define NUM_RX_STATS 3
struct ibmvnic_rx_queue_stats {
	u64 packets;
	u64 bytes;
	u64 interrupts;
};

struct ibmvnic_acl_buffer {
	__be32 len;
	__be32 version;
#define INITIAL_VERSION_IOB 1
	u8 mac_acls_restrict;
	u8 vlan_acls_restrict;
	u8 reserved1[22];
	__be32 num_mac_addrs;
	__be32 offset_mac_addrs;
	__be32 num_vlan_ids;
	__be32 offset_vlan_ids;
	u8 reserved2[80];
} __packed __aligned(8);

/* descriptors have been changed, how should this be defined?  1? 4? */

#define IBMVNIC_TX_DESC_VERSIONS 3

/* is this still needed? */
struct ibmvnic_tx_comp_desc {
	u8 first;
	u8 num_comps;
	__be16 rcs[5];
	__be32 correlators[5];
} __packed __aligned(8);

/* some flags that included in v0 descriptor, which is gone
 * only used for IBMVNIC_TCP_CHKSUM and IBMVNIC_UDP_CHKSUM
 * and only in some offload_flags variable that doesn't seem
 * to be used anywhere, can probably be removed?
 */

#define IBMVNIC_TCP_CHKSUM		0x20
#define IBMVNIC_UDP_CHKSUM		0x08

#define IBMVNIC_MAX_FRAGS_PER_CRQ 3

struct ibmvnic_tx_desc {
	u8 first;
	u8 type;

#define IBMVNIC_TX_DESC 0x10
	u8 n_crq_elem;
	u8 n_sge;
	u8 flags1;
#define IBMVNIC_TX_COMP_NEEDED		0x80
#define IBMVNIC_TX_CHKSUM_OFFLOAD	0x40
#define IBMVNIC_TX_LSO			0x20
#define IBMVNIC_TX_PROT_TCP		0x10
#define IBMVNIC_TX_PROT_UDP		0x08
#define IBMVNIC_TX_PROT_IPV4		0x04
#define IBMVNIC_TX_PROT_IPV6		0x02
#define IBMVNIC_TX_VLAN_PRESENT		0x01
	u8 flags2;
#define IBMVNIC_TX_VLAN_INSERT		0x80
	__be16 mss;
	u8 reserved[4];
	__be32 correlator;
	__be16 vlan_id;
	__be16 dma_reg;
	__be32 sge_len;
	__be64 ioba;
} __packed __aligned(8);

struct ibmvnic_hdr_desc {
	u8 first;
	u8 type;
#define IBMVNIC_HDR_DESC		0x11
	u8 len;
	u8 l2_len;
	__be16 l3_len;
	u8 l4_len;
	u8 flag;
	u8 data[24];
} __packed __aligned(8);

struct ibmvnic_hdr_ext_desc {
	u8 first;
	u8 type;
#define IBMVNIC_HDR_EXT_DESC		0x12
	u8 len;
	u8 data[29];
} __packed __aligned(8);

struct ibmvnic_sge_desc {
	u8 first;
	u8 type;
#define IBMVNIC_SGE_DESC		0x30
	__be16 sge1_dma_reg;
	__be32 sge1_len;
	__be64 sge1_ioba;
	__be16 reserved;
	__be16 sge2_dma_reg;
	__be32 sge2_len;
	__be64 sge2_ioba;
} __packed __aligned(8);

struct ibmvnic_rx_comp_desc {
	u8 first;
	u8 flags;
#define IBMVNIC_IP_CHKSUM_GOOD		0x80
#define IBMVNIC_TCP_UDP_CHKSUM_GOOD	0x40
#define IBMVNIC_END_FRAME			0x20
#define IBMVNIC_EXACT_MC			0x10
#define IBMVNIC_VLAN_STRIPPED			0x08
	__be16 off_frame_data;
	__be32 len;
	__be64 correlator;
	__be16 vlan_tci;
	__be16 rc;
	u8 reserved[12];
} __packed __aligned(8);

struct ibmvnic_generic_scrq {
	u8 first;
	u8 reserved[31];
} __packed __aligned(8);

struct ibmvnic_rx_buff_add_desc {
	u8 first;
	u8 reserved[7];
	__be64 correlator;
	__be32 ioba;
	u8 map_id;
	__be32 len:24;
	u8 reserved2[8];
} __packed __aligned(8);

struct ibmvnic_rc {
	u8 code; /* one of enum ibmvnic_rc_codes */
	u8 detailed_data[3];
} __packed __aligned(4);

struct ibmvnic_generic_crq {
	u8 first;
	u8 cmd;
	u8 params[10];
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_version_exchange {
	u8 first;
	u8 cmd;
	__be16 version;
#define IBMVNIC_INITIAL_VERSION 1
	u8 reserved[8];
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_capability {
	u8 first;
	u8 cmd;
	__be16 capability; /* one of ibmvnic_capabilities */
	__be64 number;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_login {
	u8 first;
	u8 cmd;
	u8 reserved[6];
	__be32 ioba;
	__be32 len;
} __packed __aligned(8);

struct ibmvnic_phys_parms {
	u8 first;
	u8 cmd;
	u8 flags1;
#define IBMVNIC_EXTERNAL_LOOPBACK	0x80
#define IBMVNIC_INTERNAL_LOOPBACK	0x40
#define IBMVNIC_PROMISC		0x20
#define IBMVNIC_PHYS_LINK_ACTIVE	0x10
#define IBMVNIC_AUTONEG_DUPLEX	0x08
#define IBMVNIC_FULL_DUPLEX	0x04
#define IBMVNIC_HALF_DUPLEX	0x02
#define IBMVNIC_CAN_CHG_PHYS_PARMS	0x01
	u8 flags2;
#define IBMVNIC_LOGICAL_LNK_ACTIVE 0x80
	__be32 speed;
#define IBMVNIC_AUTONEG		0x80000000
#define IBMVNIC_10MBPS		0x40000000
#define IBMVNIC_100MBPS		0x20000000
#define IBMVNIC_1GBPS		0x10000000
#define IBMVNIC_10GBP		0x08000000
#define IBMVNIC_40GBPS		0x04000000
#define IBMVNIC_100GBPS		0x02000000
#define IBMVNIC_25GBPS		0x01000000
#define IBMVNIC_50GBPS		0x00800000
#define IBMVNIC_200GBPS		0x00400000
	__be32 mtu;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_logical_link_state {
	u8 first;
	u8 cmd;
	u8 link_state;
#define IBMVNIC_LOGICAL_LNK_DN 0x00
#define IBMVNIC_LOGICAL_LNK_UP 0x01
#define IBMVNIC_LOGICAL_LNK_QUERY 0xff
	u8 reserved[9];
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_query_ip_offload {
	u8 first;
	u8 cmd;
	u8 reserved[2];
	__be32 len;
	__be32 ioba;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_control_ip_offload {
	u8 first;
	u8 cmd;
	u8 reserved[2];
	__be32 ioba;
	__be32 len;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_request_dump_size {
	u8 first;
	u8 cmd;
	u8 reserved[6];
	__be32 len;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_request_dump {
	u8 first;
	u8 cmd;
	u8 reserved1[2];
	__be32 ioba;
	__be32 len;
	u8 reserved2[4];
} __packed __aligned(8);

struct ibmvnic_request_dump_rsp {
	u8 first;
	u8 cmd;
	u8 reserved[6];
	__be32 dumped_len;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_request_ras_comp_num {
	u8 first;
	u8 cmd;
	u8 reserved1[2];
	__be32 num_components;
	u8 reserved2[4];
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_request_ras_comps {
	u8 first;
	u8 cmd;
	u8 reserved[2];
	__be32 ioba;
	__be32 len;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_control_ras {
	u8 first;
	u8 cmd;
	u8 correlator;
	u8 level;
	u8 op;
#define IBMVNIC_TRACE_LEVEL	1
#define IBMVNIC_ERROR_LEVEL	2
#define IBMVNIC_TRACE_PAUSE	3
#define IBMVNIC_TRACE_RESUME	4
#define IBMVNIC_TRACE_ON		5
#define IBMVNIC_TRACE_OFF		6
#define IBMVNIC_CHG_TRACE_BUFF_SZ	7
	u8 trace_buff_sz[3];
	u8 reserved[4];
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_collect_fw_trace {
	u8 first;
	u8 cmd;
	u8 correlator;
	u8 reserved;
	__be32 ioba;
	__be32 len;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_request_statistics {
	u8 first;
	u8 cmd;
	u8 flags;
#define IBMVNIC_PHYSICAL_PORT	0x80
	u8 reserved1;
	__be32 ioba;
	__be32 len;
	u8 reserved[4];
} __packed __aligned(8);

struct ibmvnic_request_debug_stats {
	u8 first;
	u8 cmd;
	u8 reserved[2];
	__be32 ioba;
	__be32 len;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_error_indication {
	u8 first;
	u8 cmd;
	u8 flags;
#define IBMVNIC_FATAL_ERROR	0x80
	u8 reserved1;
	__be32 error_id;
	__be32 detail_error_sz;
	__be16 error_cause;
	u8 reserved2[2];
} __packed __aligned(8);

struct ibmvnic_link_state_indication {
	u8 first;
	u8 cmd;
	u8 reserved1[2];
	u8 phys_link_state;
	u8 logical_link_state;
	u8 reserved2[10];
} __packed __aligned(8);

struct ibmvnic_change_mac_addr {
	u8 first;
	u8 cmd;
	u8 mac_addr[6];
	u8 reserved[4];
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_multicast_ctrl {
	u8 first;
	u8 cmd;
	u8 mac_addr[6];
	u8 flags;
#define IBMVNIC_ENABLE_MC		0x80
#define IBMVNIC_DISABLE_MC		0x40
#define IBMVNIC_ENABLE_ALL		0x20
#define IBMVNIC_DISABLE_ALL	0x10
	u8 reserved1;
	__be16 reserved2; /* was num_enabled_mc_addr; */
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_get_vpd_size {
	u8 first;
	u8 cmd;
	u8 reserved[14];
} __packed __aligned(8);

struct ibmvnic_get_vpd_size_rsp {
	u8 first;
	u8 cmd;
	u8 reserved[2];
	__be64 len;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_get_vpd {
	u8 first;
	u8 cmd;
	u8 reserved1[2];
	__be32 ioba;
	__be32 len;
	u8 reserved[4];
} __packed __aligned(8);

struct ibmvnic_get_vpd_rsp {
	u8 first;
	u8 cmd;
	u8 reserved[10];
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_acl_change_indication {
	u8 first;
	u8 cmd;
	__be16 change_type;
#define IBMVNIC_MAC_ACL 0
#define IBMVNIC_VLAN_ACL 1
	u8 reserved[12];
} __packed __aligned(8);

struct ibmvnic_acl_query {
	u8 first;
	u8 cmd;
	u8 reserved1[2];
	__be32 ioba;
	__be32 len;
	u8 reserved2[4];
} __packed __aligned(8);

struct ibmvnic_tune {
	u8 first;
	u8 cmd;
	u8 reserved1[2];
	__be32 ioba;
	__be32 len;
	u8 reserved2[4];
} __packed __aligned(8);

struct ibmvnic_request_map {
	u8 first;
	u8 cmd;
	u8 reserved1;
	u8 map_id;
	__be32 ioba;
	__be32 len;
	u8 reserved2[4];
} __packed __aligned(8);

struct ibmvnic_request_map_rsp {
	u8 first;
	u8 cmd;
	u8 reserved1;
	u8 map_id;
	u8 reserved2[8];
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_request_unmap {
	u8 first;
	u8 cmd;
	u8 reserved1;
	u8 map_id;
	u8 reserved2[12];
} __packed __aligned(8);

struct ibmvnic_request_unmap_rsp {
	u8 first;
	u8 cmd;
	u8 reserved1;
	u8 map_id;
	u8 reserved2[8];
	struct ibmvnic_rc rc;
} __packed __aligned(8);

struct ibmvnic_query_map {
	u8 first;
	u8 cmd;
	u8 reserved[14];
} __packed __aligned(8);

struct ibmvnic_query_map_rsp {
	u8 first;
	u8 cmd;
	u8 reserved;
	u8 page_size;
	__be32 tot_pages;
	__be32 free_pages;
	struct ibmvnic_rc rc;
} __packed __aligned(8);

union ibmvnic_crq {
	struct ibmvnic_generic_crq generic;
	struct ibmvnic_version_exchange version_exchange;
	struct ibmvnic_version_exchange version_exchange_rsp;
	struct ibmvnic_capability query_capability;
	struct ibmvnic_capability query_capability_rsp;
	struct ibmvnic_capability request_capability;
	struct ibmvnic_capability request_capability_rsp;
	struct ibmvnic_login login;
	struct ibmvnic_generic_crq login_rsp;
	struct ibmvnic_phys_parms query_phys_parms;
	struct ibmvnic_phys_parms query_phys_parms_rsp;
	struct ibmvnic_phys_parms query_phys_capabilities;
	struct ibmvnic_phys_parms query_phys_capabilities_rsp;
	struct ibmvnic_phys_parms set_phys_parms;
	struct ibmvnic_phys_parms set_phys_parms_rsp;
	struct ibmvnic_logical_link_state logical_link_state;
	struct ibmvnic_logical_link_state logical_link_state_rsp;
	struct ibmvnic_query_ip_offload query_ip_offload;
	struct ibmvnic_query_ip_offload query_ip_offload_rsp;
	struct ibmvnic_control_ip_offload control_ip_offload;
	struct ibmvnic_control_ip_offload control_ip_offload_rsp;
	struct ibmvnic_request_dump_size request_dump_size;
	struct ibmvnic_request_dump_size request_dump_size_rsp;
	struct ibmvnic_request_dump request_dump;
	struct ibmvnic_request_dump_rsp request_dump_rsp;
	struct ibmvnic_request_ras_comp_num request_ras_comp_num;
	struct ibmvnic_request_ras_comp_num request_ras_comp_num_rsp;
	struct ibmvnic_request_ras_comps request_ras_comps;
	struct ibmvnic_request_ras_comps request_ras_comps_rsp;
	struct ibmvnic_control_ras control_ras;
	struct ibmvnic_control_ras control_ras_rsp;
	struct ibmvnic_collect_fw_trace collect_fw_trace;
	struct ibmvnic_collect_fw_trace collect_fw_trace_rsp;
	struct ibmvnic_request_statistics request_statistics;
	struct ibmvnic_generic_crq request_statistics_rsp;
	struct ibmvnic_request_debug_stats request_debug_stats;
	struct ibmvnic_request_debug_stats request_debug_stats_rsp;
	struct ibmvnic_error_indication error_indication;
	struct ibmvnic_link_state_indication link_state_indication;
	struct ibmvnic_change_mac_addr change_mac_addr;
	struct ibmvnic_change_mac_addr change_mac_addr_rsp;
	struct ibmvnic_multicast_ctrl multicast_ctrl;
	struct ibmvnic_multicast_ctrl multicast_ctrl_rsp;
	struct ibmvnic_get_vpd_size get_vpd_size;
	struct ibmvnic_get_vpd_size_rsp get_vpd_size_rsp;
	struct ibmvnic_get_vpd get_vpd;
	struct ibmvnic_get_vpd_rsp get_vpd_rsp;
	struct ibmvnic_acl_change_indication acl_change_indication;
	struct ibmvnic_acl_query acl_query;
	struct ibmvnic_generic_crq acl_query_rsp;
	struct ibmvnic_tune tune;
	struct ibmvnic_generic_crq tune_rsp;
	struct ibmvnic_request_map request_map;
	struct ibmvnic_request_map_rsp request_map_rsp;
	struct ibmvnic_request_unmap request_unmap;
	struct ibmvnic_request_unmap_rsp request_unmap_rsp;
	struct ibmvnic_query_map query_map;
	struct ibmvnic_query_map_rsp query_map_rsp;
};

enum ibmvnic_rc_codes {
	SUCCESS = 0,
	PARTIALSUCCESS = 1,
	PERMISSION = 2,
	NOMEMORY = 3,
	PARAMETER = 4,
	UNKNOWNCOMMAND = 5,
	ABORTED = 6,
	INVALIDSTATE = 7,
	INVALIDIOBA = 8,
	INVALIDLENGTH = 9,
	UNSUPPORTEDOPTION = 10,
};

enum ibmvnic_capabilities {
	MIN_TX_QUEUES = 1,
	MIN_RX_QUEUES = 2,
	MIN_RX_ADD_QUEUES = 3,
	MAX_TX_QUEUES = 4,
	MAX_RX_QUEUES = 5,
	MAX_RX_ADD_QUEUES = 6,
	REQ_TX_QUEUES = 7,
	REQ_RX_QUEUES = 8,
	REQ_RX_ADD_QUEUES = 9,
	MIN_TX_ENTRIES_PER_SUBCRQ = 10,
	MIN_RX_ADD_ENTRIES_PER_SUBCRQ = 11,
	MAX_TX_ENTRIES_PER_SUBCRQ = 12,
	MAX_RX_ADD_ENTRIES_PER_SUBCRQ = 13,
	REQ_TX_ENTRIES_PER_SUBCRQ = 14,
	REQ_RX_ADD_ENTRIES_PER_SUBCRQ = 15,
	TCP_IP_OFFLOAD = 16,
	PROMISC_REQUESTED = 17,
	PROMISC_SUPPORTED = 18,
	MIN_MTU = 19,
	MAX_MTU = 20,
	REQ_MTU = 21,
	MAX_MULTICAST_FILTERS = 22,
	VLAN_HEADER_INSERTION = 23,
	RX_VLAN_HEADER_INSERTION = 24,
	MAX_TX_SG_ENTRIES = 25,
	RX_SG_SUPPORTED = 26,
	RX_SG_REQUESTED = 27,
	OPT_TX_COMP_SUB_QUEUES = 28,
	OPT_RX_COMP_QUEUES = 29,
	OPT_RX_BUFADD_Q_PER_RX_COMP_Q = 30,
	OPT_TX_ENTRIES_PER_SUBCRQ = 31,
	OPT_RXBA_ENTRIES_PER_SUBCRQ = 32,
	TX_RX_DESC_REQ = 33,
};

enum ibmvnic_error_cause {
	ADAPTER_PROBLEM = 0,
	BUS_PROBLEM = 1,
	FW_PROBLEM = 2,
	DD_PROBLEM = 3,
	EEH_RECOVERY = 4,
	FW_UPDATED = 5,
	LOW_MEMORY = 6,
};

enum ibmvnic_commands {
	VERSION_EXCHANGE = 0x01,
	VERSION_EXCHANGE_RSP = 0x81,
	QUERY_CAPABILITY = 0x02,
	QUERY_CAPABILITY_RSP = 0x82,
	REQUEST_CAPABILITY = 0x03,
	REQUEST_CAPABILITY_RSP = 0x83,
	LOGIN = 0x04,
	LOGIN_RSP = 0x84,
	QUERY_PHYS_PARMS = 0x05,
	QUERY_PHYS_PARMS_RSP = 0x85,
	QUERY_PHYS_CAPABILITIES = 0x06,
	QUERY_PHYS_CAPABILITIES_RSP = 0x86,
	SET_PHYS_PARMS = 0x07,
	SET_PHYS_PARMS_RSP = 0x87,
	ERROR_INDICATION = 0x08,
	LOGICAL_LINK_STATE = 0x0C,
	LOGICAL_LINK_STATE_RSP = 0x8C,
	REQUEST_STATISTICS = 0x0D,
	REQUEST_STATISTICS_RSP = 0x8D,
	COLLECT_FW_TRACE = 0x11,
	COLLECT_FW_TRACE_RSP = 0x91,
	LINK_STATE_INDICATION = 0x12,
	CHANGE_MAC_ADDR = 0x13,
	CHANGE_MAC_ADDR_RSP = 0x93,
	MULTICAST_CTRL = 0x14,
	MULTICAST_CTRL_RSP = 0x94,
	GET_VPD_SIZE = 0x15,
	GET_VPD_SIZE_RSP = 0x95,
	GET_VPD = 0x16,
	GET_VPD_RSP = 0x96,
	TUNE = 0x17,
	TUNE_RSP = 0x97,
	QUERY_IP_OFFLOAD = 0x18,
	QUERY_IP_OFFLOAD_RSP = 0x98,
	CONTROL_IP_OFFLOAD = 0x19,
	CONTROL_IP_OFFLOAD_RSP = 0x99,
	ACL_CHANGE_INDICATION = 0x1A,
	ACL_QUERY = 0x1B,
	ACL_QUERY_RSP = 0x9B,
	QUERY_MAP = 0x1D,
	QUERY_MAP_RSP = 0x9D,
	REQUEST_MAP = 0x1E,
	REQUEST_MAP_RSP = 0x9E,
	REQUEST_UNMAP = 0x1F,
	REQUEST_UNMAP_RSP = 0x9F,
	VLAN_CTRL = 0x20,
	VLAN_CTRL_RSP = 0xA0,
};

enum ibmvnic_crq_type {
	IBMVNIC_CRQ_CMD			= 0x80,
	IBMVNIC_CRQ_CMD_RSP		= 0x80,
	IBMVNIC_CRQ_INIT_CMD		= 0xC0,
	IBMVNIC_CRQ_INIT_RSP		= 0xC0,
	IBMVNIC_CRQ_XPORT_EVENT		= 0xFF,
};

enum ibmvfc_crq_format {
	IBMVNIC_CRQ_INIT                 = 0x01,
	IBMVNIC_CRQ_INIT_COMPLETE        = 0x02,
	IBMVNIC_PARTITION_MIGRATED       = 0x06,
	IBMVNIC_DEVICE_FAILOVER          = 0x08,
};

struct ibmvnic_crq_queue {
	union ibmvnic_crq *msgs;
	int size, cur;
	dma_addr_t msg_token;
	spinlock_t lock;
	bool active;
	char name[32];
};

union sub_crq {
	struct ibmvnic_generic_scrq generic;
	struct ibmvnic_tx_comp_desc tx_comp;
	struct ibmvnic_tx_desc v1;
	struct ibmvnic_hdr_desc hdr;
	struct ibmvnic_hdr_ext_desc hdr_ext;
	struct ibmvnic_sge_desc sge;
	struct ibmvnic_rx_comp_desc rx_comp;
	struct ibmvnic_rx_buff_add_desc rx_add;
};

struct ibmvnic_sub_crq_queue {
	union sub_crq *msgs;
	int size, cur;
	dma_addr_t msg_token;
	unsigned long crq_num;
	unsigned long hw_irq;
	unsigned int irq;
	unsigned int pool_index;
	int scrq_num;
	spinlock_t lock;
	struct sk_buff *rx_skb_top;
	struct ibmvnic_adapter *adapter;
	atomic_t used;
	char name[32];
};

struct ibmvnic_long_term_buff {
	unsigned char *buff;
	dma_addr_t addr;
	u64 size;
	u8 map_id;
};

struct ibmvnic_tx_buff {
	struct sk_buff *skb;
	dma_addr_t data_dma[IBMVNIC_MAX_FRAGS_PER_CRQ];
	unsigned int data_len[IBMVNIC_MAX_FRAGS_PER_CRQ];
	int index;
	int pool_index;
	bool last_frag;
	union sub_crq indir_arr[6];
	u8 hdr_data[140];
	dma_addr_t indir_dma;
	int num_entries;
};

struct ibmvnic_tx_pool {
	struct ibmvnic_tx_buff *tx_buff;
	int *free_map;
	int consumer_index;
	int producer_index;
	struct ibmvnic_long_term_buff long_term_buff;
	int num_buffers;
	int buf_size;
};

struct ibmvnic_rx_buff {
	struct sk_buff *skb;
	dma_addr_t dma;
	unsigned char *data;
	int size;
	int pool_index;
};

struct ibmvnic_rx_pool {
	struct ibmvnic_rx_buff *rx_buff;
	int size;
	int index;
	int buff_size;
	atomic_t available;
	int *free_map;
	int next_free;
	int next_alloc;
	int active;
	struct ibmvnic_long_term_buff long_term_buff;
};

struct ibmvnic_vpd {
	unsigned char *buff;
	dma_addr_t dma_addr;
	u64 len;
};

enum vnic_state {VNIC_PROBING = 1,
		 VNIC_PROBED,
		 VNIC_OPENING,
		 VNIC_OPEN,
		 VNIC_CLOSING,
		 VNIC_CLOSED,
		 VNIC_REMOVING,
		 VNIC_REMOVED,
		 VNIC_RESETTING};

enum ibmvnic_reset_reason {VNIC_RESET_FAILOVER = 1,
			   VNIC_RESET_MOBILITY,
			   VNIC_RESET_FATAL,
			   VNIC_RESET_NON_FATAL,
			   VNIC_RESET_TIMEOUT,
			   VNIC_RESET_CHANGE_PARAM};

struct ibmvnic_rwi {
	enum ibmvnic_reset_reason reset_reason;
	struct list_head list;
};

struct ibmvnic_tunables {
	u64 rx_queues;
	u64 tx_queues;
	u64 rx_entries;
	u64 tx_entries;
	u64 mtu;
};

struct ibmvnic_adapter {
	struct vio_dev *vdev;
	struct net_device *netdev;
	struct ibmvnic_crq_queue crq;
	u8 mac_addr[ETH_ALEN];
	struct ibmvnic_query_ip_offload_buffer ip_offload_buf;
	dma_addr_t ip_offload_tok;
	struct ibmvnic_control_ip_offload_buffer ip_offload_ctrl;
	dma_addr_t ip_offload_ctrl_tok;
	u32 msg_enable;
	u32 priv_flags;

	/* Vital Product Data (VPD) */
	struct ibmvnic_vpd *vpd;
	char fw_version[32];

	/* Statistics */
	struct ibmvnic_statistics stats;
	dma_addr_t stats_token;
	struct completion stats_done;
	spinlock_t stats_lock;
	int replenish_no_mem;
	int replenish_add_buff_success;
	int replenish_add_buff_failure;
	int replenish_task_cycles;
	int tx_send_failed;
	int tx_map_failed;

	struct ibmvnic_tx_queue_stats *tx_stats_buffers;
	struct ibmvnic_rx_queue_stats *rx_stats_buffers;

	int phys_link_state;
	int logical_link_state;

	u32 speed;
	u8 duplex;

	/* login data */
	struct ibmvnic_login_buffer *login_buf;
	dma_addr_t login_buf_token;
	int login_buf_sz;

	struct ibmvnic_login_rsp_buffer *login_rsp_buf;
	dma_addr_t login_rsp_buf_token;
	int login_rsp_buf_sz;

	atomic_t running_cap_crqs;
	bool wait_capability;

	struct ibmvnic_sub_crq_queue **tx_scrq;
	struct ibmvnic_sub_crq_queue **rx_scrq;

	/* rx structs */
	struct napi_struct *napi;
	struct ibmvnic_rx_pool *rx_pool;
	u64 promisc;

	struct ibmvnic_tx_pool *tx_pool;
	struct ibmvnic_tx_pool *tso_pool;
	struct completion init_done;
	int init_done_rc;

	struct completion fw_done;
	/* Used for serialization of device commands */
	struct mutex fw_lock;
	int fw_done_rc;

	struct completion reset_done;
	int reset_done_rc;
	bool wait_for_reset;

	/* partner capabilities */
	u64 min_tx_queues;
	u64 min_rx_queues;
	u64 min_rx_add_queues;
	u64 max_tx_queues;
	u64 max_rx_queues;
	u64 max_rx_add_queues;
	u64 req_tx_queues;
	u64 req_rx_queues;
	u64 req_rx_add_queues;
	u64 min_tx_entries_per_subcrq;
	u64 min_rx_add_entries_per_subcrq;
	u64 max_tx_entries_per_subcrq;
	u64 max_rx_add_entries_per_subcrq;
	u64 req_tx_entries_per_subcrq;
	u64 req_rx_add_entries_per_subcrq;
	u64 tcp_ip_offload;
	u64 promisc_requested;
	u64 promisc_supported;
	u64 min_mtu;
	u64 max_mtu;
	u64 req_mtu;
	u64 max_multicast_filters;
	u64 vlan_header_insertion;
	u64 rx_vlan_header_insertion;
	u64 max_tx_sg_entries;
	u64 rx_sg_supported;
	u64 rx_sg_requested;
	u64 opt_tx_comp_sub_queues;
	u64 opt_rx_comp_queues;
	u64 opt_rx_bufadd_q_per_rx_comp_q;
	u64 opt_tx_entries_per_subcrq;
	u64 opt_rxba_entries_per_subcrq;
	__be64 tx_rx_desc_req;
	u8 map_id;
	u32 num_active_rx_scrqs;
	u32 num_active_rx_pools;
	u32 num_active_rx_napi;
	u32 num_active_tx_scrqs;
	u32 num_active_tx_pools;

	struct tasklet_struct tasklet;
	enum vnic_state state;
	enum ibmvnic_reset_reason reset_reason;
	spinlock_t rwi_lock;
	struct list_head rwi_list;
	struct work_struct ibmvnic_reset;
	struct delayed_work ibmvnic_delayed_reset;
	unsigned long resetting;
	bool napi_enabled, from_passive_init;

	bool failover_pending;
	bool force_reset_recovery;

	struct ibmvnic_tunables desired;
	struct ibmvnic_tunables fallback;

	/* Used for serializatin of state field */
	spinlock_t state_lock;
};