summaryrefslogtreecommitdiff
path: root/usr/src/uts/intel/io/vmxnet3s/vmxnet3_defs.h
blob: 4dfac84e770d6a60756a1a30fe4eb1ae74573d4d (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
/*
 * Copyright (C) 2007 VMware, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of the Common
 * Development and Distribution License (the "License") version 1.0
 * and no later version.  You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the License at
 *         http://www.opensource.org/licenses/cddl1.php
 *
 * See the License for the specific language governing permissions
 * and limitations under the License.
 */

/*
 * vmxnet3_defs.h --
 *
 *      Definitions shared by device emulation and guest drivers for
 *      VMXNET3 NIC
 */

#ifndef _VMXNET3_DEFS_H_
#define	_VMXNET3_DEFS_H_

#include <upt1_defs.h>

/* all registers are 32 bit wide */
/* BAR 1 */
#define	VMXNET3_REG_VRRS	0x0	/* Vmxnet3 Revision Report Selection */
#define	VMXNET3_REG_UVRS	0x8	/* UPT Version Report Selection */
#define	VMXNET3_REG_DSAL	0x10	/* Driver Shared Address Low */
#define	VMXNET3_REG_DSAH	0x18	/* Driver Shared Address High */
#define	VMXNET3_REG_CMD		0x20	/* Command */
#define	VMXNET3_REG_MACL	0x28	/* MAC Address Low */
#define	VMXNET3_REG_MACH	0x30	/* MAC Address High */
#define	VMXNET3_REG_ICR		0x38	/* Interrupt Cause Register */
#define	VMXNET3_REG_ECR		0x40	/* Event Cause Register */

#define	VMXNET3_REG_WSAL	0xF00	/* Wireless Shared Address Lo */
#define	VMXNET3_REG_WSAH	0xF08	/* Wireless Shared Address Hi */
#define	VMXNET3_REG_WCMD	0xF18	/* Wireless Command */

/* BAR 0 */
#define	VMXNET3_REG_IMR		0x0	/* Interrupt Mask Register */
#define	VMXNET3_REG_TXPROD	0x600	/* Tx Producer Index */
#define	VMXNET3_REG_RXPROD	0x800	/* Rx Producer Index for ring 1 */
#define	VMXNET3_REG_RXPROD2	0xA00	/* Rx Producer Index for ring 2 */

#define	VMXNET3_PT_REG_SIZE	4096	/* BAR 0 */
#define	VMXNET3_VD_REG_SIZE	4096	/* BAR 1 */

/*
 * The two Vmxnet3 MMIO Register PCI BARs (BAR 0 at offset 10h and BAR 1 at
 * offset 14h) as well as the MSI-X BAR are combined into one PhysMem region:
 * <-VMXNET3_PT_REG_SIZE-><-VMXNET3_VD_REG_SIZE-><-VMXNET3_MSIX_BAR_SIZE-->
 * -------------------------------------------------------------------------
 * |Pass Thru Registers  | Virtual Dev Registers | MSI-X Vector/PBA Table  |
 * -------------------------------------------------------------------------
 * VMXNET3_MSIX_BAR_SIZE is defined in "vmxnet3Int.h"
 */
#define	VMXNET3_PHYSMEM_PAGES	4

#define	VMXNET3_REG_ALIGN	8	/* All registers are 8-byte aligned. */
#define	VMXNET3_REG_ALIGN_MASK	0x7

/* I/O Mapped access to registers */
#define	VMXNET3_IO_TYPE_PT		0
#define	VMXNET3_IO_TYPE_VD		1
#define	VMXNET3_IO_ADDR(type, reg)	(((type) << 24) | ((reg) & 0xFFFFFF))
#define	VMXNET3_IO_TYPE(addr)		((addr) >> 24)
#define	VMXNET3_IO_REG(addr)		((addr) & 0xFFFFFF)

/*
 * The Sun Studio compiler complains if enums overflow INT_MAX, so we can only
 * use an enum with gcc.  We keep this here for the convenience of merging
 * from upstream.
 */
#ifdef __GNUC__

typedef enum {
	VMXNET3_CMD_FIRST_SET = 0xCAFE0000,
	VMXNET3_CMD_ACTIVATE_DEV = VMXNET3_CMD_FIRST_SET,
	VMXNET3_CMD_QUIESCE_DEV,
	VMXNET3_CMD_RESET_DEV,
	VMXNET3_CMD_UPDATE_RX_MODE,
	VMXNET3_CMD_UPDATE_MAC_FILTERS,
	VMXNET3_CMD_UPDATE_VLAN_FILTERS,
	VMXNET3_CMD_UPDATE_RSSIDT,
	VMXNET3_CMD_UPDATE_IML,
	VMXNET3_CMD_UPDATE_PMCFG,
	VMXNET3_CMD_UPDATE_FEATURE,
	VMXNET3_CMD_STOP_EMULATION,
	VMXNET3_CMD_LOAD_PLUGIN,
	VMXNET3_CMD_ACTIVATE_VF,

	VMXNET3_CMD_FIRST_GET = 0xF00D0000,
	VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET,
	VMXNET3_CMD_GET_STATS,
	VMXNET3_CMD_GET_LINK,
	VMXNET3_CMD_GET_PERM_MAC_LO,
	VMXNET3_CMD_GET_PERM_MAC_HI,
	VMXNET3_CMD_GET_DID_LO,
	VMXNET3_CMD_GET_DID_HI,
	VMXNET3_CMD_GET_DEV_EXTRA_INFO,
	VMXNET3_CMD_GET_CONF_INTR,
	VMXNET3_CMD_GET_ADAPTIVE_RING_INFO
} Vmxnet3_Cmd;

#else

#define	VMXNET3_CMD_FIRST_SET 0xCAFE0000U
#define	VMXNET3_CMD_ACTIVATE_DEV VMXNET3_CMD_FIRST_SET
#define	VMXNET3_CMD_QUIESCE_DEV (VMXNET3_CMD_FIRST_SET + 1)
#define	VMXNET3_CMD_RESET_DEV (VMXNET3_CMD_FIRST_SET + 2)
#define	VMXNET3_CMD_UPDATE_RX_MODE (VMXNET3_CMD_FIRST_SET + 3)
#define	VMXNET3_CMD_UPDATE_MAC_FILTERS (VMXNET3_CMD_FIRST_SET + 4)
#define	VMXNET3_CMD_UPDATE_VLAN_FILTERS (VMXNET3_CMD_FIRST_SET + 5)
#define	VMXNET3_CMD_UPDATE_RSSIDT (VMXNET3_CMD_FIRST_SET + 6)
#define	VMXNET3_CMD_UPDATE_IML (VMXNET3_CMD_FIRST_SET + 7)
#define	VMXNET3_CMD_UPDATE_PMCFG (VMXNET3_CMD_FIRST_SET + 8)
#define	VMXNET3_CMD_UPDATE_FEATURE (VMXNET3_CMD_FIRST_SET + 9)
#define	VMXNET3_CMD_STOP_EMULATION (VMXNET3_CMD_FIRST_SET + 10)
#define	VMXNET3_CMD_LOAD_PLUGIN (VMXNET3_CMD_FIRST_SET + 11)
#define	VMXNET3_CMD_ACTIVATE_VF (VMXNET3_CMD_FIRST_SET + 12)

#define	VMXNET3_CMD_FIRST_GET 0xF00D0000U
#define	VMXNET3_CMD_GET_QUEUE_STATUS VMXNET3_CMD_FIRST_GET
#define	VMXNET3_CMD_GET_STATS (VMXNET3_CMD_FIRST_GET + 1)
#define	VMXNET3_CMD_GET_LINK (VMXNET3_CMD_FIRST_GET + 2)
#define	VMXNET3_CMD_GET_PERM_MAC_LO (VMXNET3_CMD_FIRST_GET + 3)
#define	VMXNET3_CMD_GET_PERM_MAC_HI (VMXNET3_CMD_FIRST_GET + 4)
#define	VMXNET3_CMD_GET_DID_LO (VMXNET3_CMD_FIRST_GET + 5)
#define	VMXNET3_CMD_GET_DID_HI (VMXNET3_CMD_FIRST_GET + 6)
#define	VMXNET3_CMD_GET_DEV_EXTRA_INFO (VMXNET3_CMD_FIRST_GET + 7)
#define	VMXNET3_CMD_GET_CONF_INTR (VMXNET3_CMD_FIRST_GET + 8)
#define	VMXNET3_CMD_GET_ADAPTIVE_RING_INFO (VMXNET3_CMD_FIRST_GET + 9)

#endif

/* Adaptive Ring Info Flags */
#define	VMXNET3_DISABLE_ADAPTIVE_RING 1

#pragma pack(1)
typedef struct Vmxnet3_TxDesc {
	uint64_t	addr;
	uint32_t	len:14;
	uint32_t	gen:1;		/* generation bit */
	uint32_t	rsvd:1;
	uint32_t	dtype:1;	/* descriptor type */
	uint32_t	ext1:1;
	uint32_t	msscof:14;	/* MSS, checksum offset, flags */
	uint32_t	hlen:10;	/* header len */
	uint32_t	om:2;		/* offload mode */
	uint32_t	eop:1;		/* End Of Packet */
	uint32_t	cq:1;		/* completion request */
	uint32_t	ext2:1;
	uint32_t	ti:1;		/* VLAN Tag Insertion */
	uint32_t	tci:16;		/* Tag to Insert */
} Vmxnet3_TxDesc;
#pragma pack()

/* TxDesc.OM values */
#define	VMXNET3_OM_NONE		0
#define	VMXNET3_OM_CSUM		2
#define	VMXNET3_OM_TSO		3

/* fields in TxDesc we access w/o using bit fields */
#define	VMXNET3_TXD_EOP_SHIFT		12
#define	VMXNET3_TXD_CQ_SHIFT		13
#define	VMXNET3_TXD_GEN_SHIFT		14
#define	VMXNET3_TXD_EOP_DWORD_SHIFT	3
#define	VMXNET3_TXD_GEN_DWORD_SHIFT	2

#define	VMXNET3_TXD_CQ	(1 << VMXNET3_TXD_CQ_SHIFT)
#define	VMXNET3_TXD_EOP	(1 << VMXNET3_TXD_EOP_SHIFT)
#define	VMXNET3_TXD_GEN	(1 << VMXNET3_TXD_GEN_SHIFT)

#define	VMXNET3_TXD_GEN_SIZE	1
#define	VMXNET3_TXD_EOP_SIZE	1

#define	VMXNET3_HDR_COPY_SIZE	128

#pragma pack(1)
typedef struct Vmxnet3_TxDataDesc {
	uint8_t		data[VMXNET3_HDR_COPY_SIZE];
} Vmxnet3_TxDataDesc;
#pragma pack()

#define	VMXNET3_TCD_GEN_SHIFT		31
#define	VMXNET3_TCD_GEN_SIZE		1
#define	VMXNET3_TCD_TXIDX_SHIFT		0
#define	VMXNET3_TCD_TXIDX_SIZE		12
#define	VMXNET3_TCD_GEN_DWORD_SHIFT	3

#pragma pack(1)
typedef struct Vmxnet3_TxCompDesc {
	uint32_t	txdIdx:12;	/* Index of the EOP TxDesc */
	uint32_t	ext1:20;

	uint32_t	ext2;
	uint32_t	ext3;

	uint32_t	rsvd:24;
	uint32_t	type:7;		/* completion type */
	uint32_t	gen:1;		/* generation bit */
} Vmxnet3_TxCompDesc;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_RxDesc {
	uint64_t	addr;
	uint32_t	len:14;
	uint32_t	btype:1;	/* Buffer Type */
	uint32_t	dtype:1;	/* Descriptor type */
	uint32_t	rsvd:15;
	uint32_t	gen:1;		/* Generation bit */
	uint32_t	ext1;
} Vmxnet3_RxDesc;
#pragma pack()

/* values of RXD.BTYPE */
#define	VMXNET3_RXD_BTYPE_HEAD	0	/* head only */
#define	VMXNET3_RXD_BTYPE_BODY	1	/* body only */

/* fields in RxDesc we access w/o using bit fields */
#define	VMXNET3_RXD_BTYPE_SHIFT	14
#define	VMXNET3_RXD_GEN_SHIFT	31

#pragma pack(1)
typedef struct Vmxnet3_RxCompDesc {
	uint32_t	rxdIdx:12;	/* Index of the RxDesc */
	uint32_t	ext1:2;
	uint32_t	eop:1;		/* End of Packet */
	uint32_t	sop:1;		/* Start of Packet */
	uint32_t	rqID:10;	/* rx queue/ring ID */
	uint32_t	rssType:4;	/* RSS hash type used */
	uint32_t	cnc:1;		/* Checksum Not Calculated */
	uint32_t	ext2:1;
	uint32_t	rssHash;	/* RSS hash value */
	uint32_t	len:14;		/* data length */
	uint32_t	err:1;		/* Error */
	uint32_t	ts:1;		/* Tag is stripped */
	uint32_t	tci:16;		/* Tag stripped */
	uint32_t	csum:16;
	uint32_t	tuc:1;		/* TCP/UDP Checksum Correct */
	uint32_t	udp:1;		/* UDP packet */
	uint32_t	tcp:1;		/* TCP packet */
	uint32_t	ipc:1;		/* IP Checksum Correct */
	uint32_t	v6:1;		/* IPv6 */
	uint32_t	v4:1;		/* IPv4 */
	uint32_t	frg:1;		/* IP Fragment */
	uint32_t	fcs:1;		/* Frame CRC correct */
	uint32_t	type:7;		/* completion type */
	uint32_t	gen:1;		/* generation bit */
} Vmxnet3_RxCompDesc;
#pragma pack()

/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */
#define	VMXNET3_RCD_TUC_SHIFT	16
#define	VMXNET3_RCD_IPC_SHIFT	19

/* fields in RxCompDesc we access via Vmxnet3_GenericDesc.qword[1] */
#define	VMXNET3_RCD_TYPE_SHIFT	56
#define	VMXNET3_RCD_GEN_SHIFT	63

/* csum OK for TCP/UDP pkts over IP */
#define	VMXNET3_RCD_CSUM_OK \
	(1 << VMXNET3_RCD_TUC_SHIFT | 1 << VMXNET3_RCD_IPC_SHIFT)

/* value of RxCompDesc.rssType */
#define	VMXNET3_RCD_RSS_TYPE_NONE	0
#define	VMXNET3_RCD_RSS_TYPE_IPV4	1
#define	VMXNET3_RCD_RSS_TYPE_TCPIPV4	2
#define	VMXNET3_RCD_RSS_TYPE_IPV6	3
#define	VMXNET3_RCD_RSS_TYPE_TCPIPV6	4

/* a union for accessing all cmd/completion descriptors */
typedef union Vmxnet3_GenericDesc {
	uint64_t	qword[2];
	uint32_t	dword[4];
	uint16_t	word[8];
	Vmxnet3_TxDesc	txd;
	Vmxnet3_RxDesc	rxd;
	Vmxnet3_TxCompDesc tcd;
	Vmxnet3_RxCompDesc rcd;
} Vmxnet3_GenericDesc;

#define	VMXNET3_INIT_GEN	1

/* Max size of a single tx buffer */
#define	VMXNET3_MAX_TX_BUF_SIZE	(1 << 14)

/* # of tx desc needed for a tx buffer size */
#define	VMXNET3_TXD_NEEDED(size) \
	(((size) + VMXNET3_MAX_TX_BUF_SIZE - 1) / VMXNET3_MAX_TX_BUF_SIZE)

/* max # of tx descs for a non-tso pkt */
#define	VMXNET3_MAX_TXD_PER_PKT	16

/* Max size of a single rx buffer */
#define	VMXNET3_MAX_RX_BUF_SIZE	((1 << 14) - 1)
/* Minimum size of a type 0 buffer */
#define	VMXNET3_MIN_T0_BUF_SIZE	128
#define	VMXNET3_MAX_CSUM_OFFSET	1024

/* Ring base address alignment */
#define	VMXNET3_RING_BA_ALIGN	512
#define	VMXNET3_RING_BA_MASK	(VMXNET3_RING_BA_ALIGN - 1)

/* Ring size must be a multiple of 32 */
#define	VMXNET3_RING_SIZE_ALIGN	32
#define	VMXNET3_RING_SIZE_MASK	(VMXNET3_RING_SIZE_ALIGN - 1)

/* Max ring size */
#define	VMXNET3_TX_RING_MAX_SIZE	4096
#define	VMXNET3_TC_RING_MAX_SIZE	4096
#define	VMXNET3_RX_RING_MAX_SIZE	4096
#define	VMXNET3_RC_RING_MAX_SIZE	8192

/* a list of reasons for queue stop */

#define	VMXNET3_ERR_NOEOP	0x80000000	/* cannot find the */
						/* EOP desc of a pkt */
#define	VMXNET3_ERR_TXD_REUSE	0x80000001	/* reuse a TxDesc before tx */
						/* completion */
#define	VMXNET3_ERR_BIG_PKT	0x80000002	/* too many TxDesc for a pkt */
#define	VMXNET3_ERR_DESC_NOT_SPT 0x80000003	/* descriptor type not */
						/* supported */
#define	VMXNET3_ERR_SMALL_BUF	0x80000004	/* type 0 buffer too small */
#define	VMXNET3_ERR_STRESS	0x80000005	/* stress option firing */
						/* in vmkernel */
#define	VMXNET3_ERR_SWITCH	0x80000006	/* mode switch failure */
#define	VMXNET3_ERR_TXD_INVALID	0x80000007	/* invalid TxDesc */

/* completion descriptor types */
#define	VMXNET3_CDTYPE_TXCOMP	0	/* Tx Completion Descriptor */
#define	VMXNET3_CDTYPE_RXCOMP	3	/* Rx Completion Descriptor */

#define	VMXNET3_GOS_BITS_UNK	0	/* unknown */
#define	VMXNET3_GOS_BITS_32	1
#define	VMXNET3_GOS_BITS_64	2

#define	VMXNET3_GOS_TYPE_UNK	0 /* unknown */
#define	VMXNET3_GOS_TYPE_LINUX	1
#define	VMXNET3_GOS_TYPE_WIN	2
#define	VMXNET3_GOS_TYPE_SOLARIS 3
#define	VMXNET3_GOS_TYPE_FREEBSD 4
#define	VMXNET3_GOS_TYPE_PXE	5

/* All structures in DriverShared are padded to multiples of 8 bytes */

#pragma pack(1)
typedef struct Vmxnet3_GOSInfo {
	uint32_t	gosBits: 2;	/* 32-bit or 64-bit? */
	uint32_t	gosType: 4;	/* which guest */
	uint32_t	gosVer: 16;	/* gos version */
	uint32_t	gosMisc: 10;	/* other info about gos */
} Vmxnet3_GOSInfo;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_DriverInfo {
	uint32_t	version;	/* driver version */
	Vmxnet3_GOSInfo	gos;
	uint32_t	vmxnet3RevSpt;	/* vmxnet3 revision supported */
	uint32_t	uptVerSpt;	/* upt version supported */
} Vmxnet3_DriverInfo;
#pragma pack()

#define	VMXNET3_REV1_MAGIC	0xbabefee1

/*
 * QueueDescPA must be 128 bytes aligned. It points to an array of
 * Vmxnet3_TxQueueDesc followed by an array of Vmxnet3_RxQueueDesc.
 * The number of Vmxnet3_TxQueueDesc/Vmxnet3_RxQueueDesc are specified by
 * Vmxnet3_MiscConf.numTxQueues/numRxQueues, respectively.
 */
#define	VMXNET3_QUEUE_DESC_ALIGN	128

#pragma pack(1)
typedef struct Vmxnet3_MiscConf {
	Vmxnet3_DriverInfo driverInfo;
	uint64_t	uptFeatures;
	uint64_t	ddPA;		/* driver data PA */
	uint64_t	queueDescPA;	/* queue descriptor table PA */
	uint32_t	ddLen;		/* driver data len */
	uint32_t	queueDescLen;	/* queue descriptor table len, bytes */
	uint32_t	mtu;
	uint16_t	maxNumRxSG;
	uint8_t		numTxQueues;
	uint8_t		numRxQueues;
	uint32_t	reserved[4];
} Vmxnet3_MiscConf;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_TxQueueConf {
	uint64_t	txRingBasePA;
	uint64_t	dataRingBasePA;
	uint64_t	compRingBasePA;
	uint64_t	ddPA;		/* driver data */
	uint64_t	reserved;
	uint32_t	txRingSize;	/* # of tx desc */
	uint32_t	dataRingSize;	/* # of data desc */
	uint32_t	compRingSize;	/* # of comp desc */
	uint32_t	ddLen;		/* size of driver data */
	uint8_t		intrIdx;
	uint8_t		_pad[7];
} Vmxnet3_TxQueueConf;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_RxQueueConf {
	uint64_t	rxRingBasePA[2];
	uint64_t	compRingBasePA;
	uint64_t	ddPA;		/* driver data */
	uint64_t	reserved;
	uint32_t	rxRingSize[2];	/* # of rx desc */
	uint32_t	compRingSize;	/* # of rx comp desc */
	uint32_t	ddLen;		/* size of driver data */
	uint8_t		intrIdx;
	uint8_t		_pad[7];
} Vmxnet3_RxQueueConf;
#pragma pack()

enum vmxnet3_intr_mask_mode {
	VMXNET3_IMM_AUTO =	0,
	VMXNET3_IMM_ACTIVE =	1,
	VMXNET3_IMM_LAZY =	2
};

enum vmxnet3_intr_type {
	VMXNET3_IT_AUTO =	0,
	VMXNET3_IT_INTX =	1,
	VMXNET3_IT_MSI =	2,
	VMXNET3_IT_MSIX =	3
};

#define	VMXNET3_MAX_TX_QUEUES	8
#define	VMXNET3_MAX_RX_QUEUES	16
/* addition 1 for events */
#define	VMXNET3_MAX_INTRS	25

/* value of intrCtrl */
#define	VMXNET3_IC_DISABLE_ALL	0x1	/* bit 0 */

#pragma pack(1)
typedef struct Vmxnet3_IntrConf {
	char		autoMask;
	uint8_t		numIntrs;	/* # of interrupts */
	uint8_t		eventIntrIdx;
	uint8_t		modLevels[VMXNET3_MAX_INTRS];	/* moderation level */
							/* for each intr */
	uint32_t	intrCtrl;
	uint32_t	reserved[2];
} Vmxnet3_IntrConf;
#pragma pack()

/* one bit per VLAN ID, the size is in the units of uint32_t */
#define	VMXNET3_VFT_SIZE (4096 / (sizeof (uint32_t) * 8))

#pragma pack(1)
typedef struct Vmxnet3_QueueStatus {
	char		stopped;
	uint8_t		_pad[3];
	uint32_t	error;
} Vmxnet3_QueueStatus;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_TxQueueCtrl {
	uint32_t	txNumDeferred;
	uint32_t	txThreshold;
	uint64_t	reserved;
} Vmxnet3_TxQueueCtrl;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_RxQueueCtrl {
	char		updateRxProd;
	uint8_t		_pad[7];
	uint64_t	reserved;
} Vmxnet3_RxQueueCtrl;
#pragma pack()

#define	VMXNET3_RXM_UCAST	0x01	/* unicast only */
#define	VMXNET3_RXM_MCAST	0x02	/* multicast passing the filters */
#define	VMXNET3_RXM_BCAST	0x04	/* broadcast only */
#define	VMXNET3_RXM_ALL_MULTI	0x08	/* all multicast */
#define	VMXNET3_RXM_PROMISC	0x10	/* promiscuous */

#pragma pack(1)
typedef struct Vmxnet3_RxFilterConf {
	uint32_t	rxMode;		/* VMXNET3_RXM_xxx */
	uint16_t	mfTableLen;	/* size of the multicast filter table */
	uint16_t	_pad1;
	uint64_t	mfTablePA;	/* PA of the multicast filters table */
	uint32_t	vfTable[VMXNET3_VFT_SIZE]; /* vlan filter */
} Vmxnet3_RxFilterConf;
#pragma pack()

#define	VMXNET3_PM_MAX_FILTERS		6
#define	VMXNET3_PM_MAX_PATTERN_SIZE	128
#define	VMXNET3_PM_MAX_MASK_SIZE	(VMXNET3_PM_MAX_PATTERN_SIZE / 8)

#define	VMXNET3_PM_WAKEUP_MAGIC		0x01	/* wake up on magic pkts */
#define	VMXNET3_PM_WAKEUP_FILTER	0x02	/* wake up on pkts matching */
						/* filters */

#pragma pack(1)
typedef struct Vmxnet3_PM_PktFilter {
	uint8_t		maskSize;
	uint8_t		patternSize;
	uint8_t		mask[VMXNET3_PM_MAX_MASK_SIZE];
	uint8_t		pattern[VMXNET3_PM_MAX_PATTERN_SIZE];
	uint8_t		pad[6];
} Vmxnet3_PM_PktFilter;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_PMConf {
	uint16_t	wakeUpEvents;	/* VMXNET3_PM_WAKEUP_xxx */
	uint8_t		numFilters;
	uint8_t		pad[5];
	Vmxnet3_PM_PktFilter filters[VMXNET3_PM_MAX_FILTERS];
} Vmxnet3_PMConf;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_VariableLenConfDesc {
	uint32_t	confVer;
	uint32_t	confLen;
	uint64_t	confPA;
} Vmxnet3_VariableLenConfDesc;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_DSDevRead {
	/* read-only region for device, read by dev in response to a SET cmd */
	Vmxnet3_MiscConf misc;
	Vmxnet3_IntrConf intrConf;
	Vmxnet3_RxFilterConf rxFilterConf;
	Vmxnet3_VariableLenConfDesc rssConfDesc;
	Vmxnet3_VariableLenConfDesc pmConfDesc;
	Vmxnet3_VariableLenConfDesc pluginConfDesc;
} Vmxnet3_DSDevRead;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_TxQueueDesc {
	Vmxnet3_TxQueueCtrl ctrl;
	Vmxnet3_TxQueueConf conf;
	/* Driver read after a GET command */
	Vmxnet3_QueueStatus status;
	UPT1_TxStats	stats;
	uint8_t		_pad[88];	/* 128 aligned */
} Vmxnet3_TxQueueDesc;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_RxQueueDesc {
	Vmxnet3_RxQueueCtrl ctrl;
	Vmxnet3_RxQueueConf conf;
	/* Driver read after a GET command */
	Vmxnet3_QueueStatus status;
	UPT1_RxStats	stats;
	uint8_t		_pad[88];	/* 128 aligned */
} Vmxnet3_RxQueueDesc;
#pragma pack()

#pragma pack(1)
typedef struct Vmxnet3_DriverShared {
	uint32_t	magic;
	uint32_t	pad;		/* make devRead start at */
					/* 64-bit boundaries */
	Vmxnet3_DSDevRead devRead;
	uint32_t	ecr;
	uint32_t	reserved[5];
} Vmxnet3_DriverShared;
#pragma pack()

#define	VMXNET3_ECR_RQERR	(1 << 0)
#define	VMXNET3_ECR_TQERR	(1 << 1)
#define	VMXNET3_ECR_LINK	(1 << 2)
#define	VMXNET3_ECR_DIC		(1 << 3)
#define	VMXNET3_ECR_DEBUG	(1 << 4)

/* flip the gen bit of a ring */
#define	VMXNET3_FLIP_RING_GEN(gen) ((gen) = (gen) ^ 0x1)

/* only use this if moving the idx won't affect the gen bit */
#define	VMXNET3_INC_RING_IDX_ONLY(idx, ring_size) {	\
	(idx)++;					\
	if (UNLIKELY((idx) == (ring_size))) {		\
		(idx) = 0;				\
	}						\
}

#define	VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid) \
	vfTable[vid >> 5] |= (1 << (vid & 31))
#define	VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid) \
	vfTable[vid >> 5] &= ~(1 << (vid & 31))

#define	VMXNET3_VFTABLE_ENTRY_IS_SET(vfTable, vid) \
	((vfTable[vid >> 5] & (1 << (vid & 31))) != 0)

#define	VMXNET3_MAX_MTU		9000
#define	VMXNET3_MIN_MTU		60

#define	VMXNET3_LINK_UP		(10000 << 16 | 1)	/* 10 Gbps, up */
#define	VMXNET3_LINK_DOWN	0

#define	VMXWIFI_DRIVER_SHARED_LEN	8192

#define	VMXNET3_DID_PASSTHRU		0xFFFF

#endif /* _VMXNET3_DEFS_H_ */