xref: /openbmc/qemu/hw/net/vmxnet3.h (revision 49ab747f668f421138d5b40d83fa279c4c5e278d)
1*49ab747fSPaolo Bonzini /*
2*49ab747fSPaolo Bonzini  * QEMU VMWARE VMXNET3 paravirtual NIC interface definitions
3*49ab747fSPaolo Bonzini  *
4*49ab747fSPaolo Bonzini  * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
5*49ab747fSPaolo Bonzini  *
6*49ab747fSPaolo Bonzini  * Developed by Daynix Computing LTD (http://www.daynix.com)
7*49ab747fSPaolo Bonzini  *
8*49ab747fSPaolo Bonzini  * Authors:
9*49ab747fSPaolo Bonzini  * Dmitry Fleytman <dmitry@daynix.com>
10*49ab747fSPaolo Bonzini  * Tamir Shomer <tamirs@daynix.com>
11*49ab747fSPaolo Bonzini  * Yan Vugenfirer <yan@daynix.com>
12*49ab747fSPaolo Bonzini  *
13*49ab747fSPaolo Bonzini  * This work is licensed under the terms of the GNU GPL, version 2.
14*49ab747fSPaolo Bonzini  * See the COPYING file in the top-level directory.
15*49ab747fSPaolo Bonzini  *
16*49ab747fSPaolo Bonzini  */
17*49ab747fSPaolo Bonzini 
18*49ab747fSPaolo Bonzini #ifndef _QEMU_VMXNET3_H
19*49ab747fSPaolo Bonzini #define _QEMU_VMXNET3_H
20*49ab747fSPaolo Bonzini 
21*49ab747fSPaolo Bonzini #define VMXNET3_DEVICE_MAX_TX_QUEUES 8
22*49ab747fSPaolo Bonzini #define VMXNET3_DEVICE_MAX_RX_QUEUES 8   /* Keep this value as a power of 2 */
23*49ab747fSPaolo Bonzini 
24*49ab747fSPaolo Bonzini /*
25*49ab747fSPaolo Bonzini  * VMWARE headers we got from Linux kernel do not fully comply QEMU coding
26*49ab747fSPaolo Bonzini  * standards in sense of types and defines used.
27*49ab747fSPaolo Bonzini  * Since we didn't want to change VMWARE code, following set of typedefs
28*49ab747fSPaolo Bonzini  * and defines needed to compile these headers with QEMU introduced.
29*49ab747fSPaolo Bonzini  */
30*49ab747fSPaolo Bonzini #define u64     uint64_t
31*49ab747fSPaolo Bonzini #define u32     uint32_t
32*49ab747fSPaolo Bonzini #define u16     uint16_t
33*49ab747fSPaolo Bonzini #define u8      uint8_t
34*49ab747fSPaolo Bonzini #define __le16  uint16_t
35*49ab747fSPaolo Bonzini #define __le32  uint32_t
36*49ab747fSPaolo Bonzini #define __le64  uint64_t
37*49ab747fSPaolo Bonzini #define __packed QEMU_PACKED
38*49ab747fSPaolo Bonzini 
39*49ab747fSPaolo Bonzini #if defined(HOST_WORDS_BIGENDIAN)
40*49ab747fSPaolo Bonzini #define const_cpu_to_le64(x) bswap_64(x)
41*49ab747fSPaolo Bonzini #define __BIG_ENDIAN_BITFIELD
42*49ab747fSPaolo Bonzini #else
43*49ab747fSPaolo Bonzini #define const_cpu_to_le64(x) (x)
44*49ab747fSPaolo Bonzini #endif
45*49ab747fSPaolo Bonzini 
46*49ab747fSPaolo Bonzini /*
47*49ab747fSPaolo Bonzini  * Following is an interface definition for
48*49ab747fSPaolo Bonzini  * VMXNET3 device as provided by VMWARE
49*49ab747fSPaolo Bonzini  * See original copyright from Linux kernel v3.2.8
50*49ab747fSPaolo Bonzini  * header file drivers/net/vmxnet3/vmxnet3_defs.h below.
51*49ab747fSPaolo Bonzini  */
52*49ab747fSPaolo Bonzini 
53*49ab747fSPaolo Bonzini /*
54*49ab747fSPaolo Bonzini  * Linux driver for VMware's vmxnet3 ethernet NIC.
55*49ab747fSPaolo Bonzini  *
56*49ab747fSPaolo Bonzini  * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
57*49ab747fSPaolo Bonzini  *
58*49ab747fSPaolo Bonzini  * This program is free software; you can redistribute it and/or modify it
59*49ab747fSPaolo Bonzini  * under the terms of the GNU General Public License as published by the
60*49ab747fSPaolo Bonzini  * Free Software Foundation; version 2 of the License and no later version.
61*49ab747fSPaolo Bonzini  *
62*49ab747fSPaolo Bonzini  * This program is distributed in the hope that it will be useful, but
63*49ab747fSPaolo Bonzini  * WITHOUT ANY WARRANTY; without even the implied warranty of
64*49ab747fSPaolo Bonzini  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
65*49ab747fSPaolo Bonzini  * NON INFRINGEMENT.  See the GNU General Public License for more
66*49ab747fSPaolo Bonzini  * details.
67*49ab747fSPaolo Bonzini  *
68*49ab747fSPaolo Bonzini  * You should have received a copy of the GNU General Public License
69*49ab747fSPaolo Bonzini  * along with this program; if not, write to the Free Software
70*49ab747fSPaolo Bonzini  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
71*49ab747fSPaolo Bonzini  *
72*49ab747fSPaolo Bonzini  * The full GNU General Public License is included in this distribution in
73*49ab747fSPaolo Bonzini  * the file called "COPYING".
74*49ab747fSPaolo Bonzini  *
75*49ab747fSPaolo Bonzini  * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
76*49ab747fSPaolo Bonzini  *
77*49ab747fSPaolo Bonzini  */
78*49ab747fSPaolo Bonzini 
79*49ab747fSPaolo Bonzini struct UPT1_TxStats {
80*49ab747fSPaolo Bonzini     u64            TSOPktsTxOK;  /* TSO pkts post-segmentation */
81*49ab747fSPaolo Bonzini     u64            TSOBytesTxOK;
82*49ab747fSPaolo Bonzini     u64            ucastPktsTxOK;
83*49ab747fSPaolo Bonzini     u64            ucastBytesTxOK;
84*49ab747fSPaolo Bonzini     u64            mcastPktsTxOK;
85*49ab747fSPaolo Bonzini     u64            mcastBytesTxOK;
86*49ab747fSPaolo Bonzini     u64            bcastPktsTxOK;
87*49ab747fSPaolo Bonzini     u64            bcastBytesTxOK;
88*49ab747fSPaolo Bonzini     u64            pktsTxError;
89*49ab747fSPaolo Bonzini     u64            pktsTxDiscard;
90*49ab747fSPaolo Bonzini };
91*49ab747fSPaolo Bonzini 
92*49ab747fSPaolo Bonzini struct UPT1_RxStats {
93*49ab747fSPaolo Bonzini     u64            LROPktsRxOK;    /* LRO pkts */
94*49ab747fSPaolo Bonzini     u64            LROBytesRxOK;   /* bytes from LRO pkts */
95*49ab747fSPaolo Bonzini     /* the following counters are for pkts from the wire, i.e., pre-LRO */
96*49ab747fSPaolo Bonzini     u64            ucastPktsRxOK;
97*49ab747fSPaolo Bonzini     u64            ucastBytesRxOK;
98*49ab747fSPaolo Bonzini     u64            mcastPktsRxOK;
99*49ab747fSPaolo Bonzini     u64            mcastBytesRxOK;
100*49ab747fSPaolo Bonzini     u64            bcastPktsRxOK;
101*49ab747fSPaolo Bonzini     u64            bcastBytesRxOK;
102*49ab747fSPaolo Bonzini     u64            pktsRxOutOfBuf;
103*49ab747fSPaolo Bonzini     u64            pktsRxError;
104*49ab747fSPaolo Bonzini };
105*49ab747fSPaolo Bonzini 
106*49ab747fSPaolo Bonzini /* interrupt moderation level */
107*49ab747fSPaolo Bonzini enum {
108*49ab747fSPaolo Bonzini     UPT1_IML_NONE        = 0, /* no interrupt moderation */
109*49ab747fSPaolo Bonzini     UPT1_IML_HIGHEST    = 7, /* least intr generated */
110*49ab747fSPaolo Bonzini     UPT1_IML_ADAPTIVE    = 8, /* adpative intr moderation */
111*49ab747fSPaolo Bonzini };
112*49ab747fSPaolo Bonzini /* values for UPT1_RSSConf.hashFunc */
113*49ab747fSPaolo Bonzini enum {
114*49ab747fSPaolo Bonzini     UPT1_RSS_HASH_TYPE_NONE      = 0x0,
115*49ab747fSPaolo Bonzini     UPT1_RSS_HASH_TYPE_IPV4      = 0x01,
116*49ab747fSPaolo Bonzini     UPT1_RSS_HASH_TYPE_TCP_IPV4  = 0x02,
117*49ab747fSPaolo Bonzini     UPT1_RSS_HASH_TYPE_IPV6      = 0x04,
118*49ab747fSPaolo Bonzini     UPT1_RSS_HASH_TYPE_TCP_IPV6  = 0x08,
119*49ab747fSPaolo Bonzini };
120*49ab747fSPaolo Bonzini 
121*49ab747fSPaolo Bonzini enum {
122*49ab747fSPaolo Bonzini     UPT1_RSS_HASH_FUNC_NONE      = 0x0,
123*49ab747fSPaolo Bonzini     UPT1_RSS_HASH_FUNC_TOEPLITZ  = 0x01,
124*49ab747fSPaolo Bonzini };
125*49ab747fSPaolo Bonzini 
126*49ab747fSPaolo Bonzini #define UPT1_RSS_MAX_KEY_SIZE        40
127*49ab747fSPaolo Bonzini #define UPT1_RSS_MAX_IND_TABLE_SIZE  128
128*49ab747fSPaolo Bonzini 
129*49ab747fSPaolo Bonzini struct UPT1_RSSConf {
130*49ab747fSPaolo Bonzini     u16            hashType;
131*49ab747fSPaolo Bonzini     u16            hashFunc;
132*49ab747fSPaolo Bonzini     u16            hashKeySize;
133*49ab747fSPaolo Bonzini     u16            indTableSize;
134*49ab747fSPaolo Bonzini     u8            hashKey[UPT1_RSS_MAX_KEY_SIZE];
135*49ab747fSPaolo Bonzini     u8            indTable[UPT1_RSS_MAX_IND_TABLE_SIZE];
136*49ab747fSPaolo Bonzini };
137*49ab747fSPaolo Bonzini 
138*49ab747fSPaolo Bonzini /* features */
139*49ab747fSPaolo Bonzini enum {
140*49ab747fSPaolo Bonzini     UPT1_F_RXCSUM        = const_cpu_to_le64(0x0001), /* rx csum verification */
141*49ab747fSPaolo Bonzini     UPT1_F_RSS        = const_cpu_to_le64(0x0002),
142*49ab747fSPaolo Bonzini     UPT1_F_RXVLAN        = const_cpu_to_le64(0x0004), /* VLAN tag stripping */
143*49ab747fSPaolo Bonzini     UPT1_F_LRO        = const_cpu_to_le64(0x0008),
144*49ab747fSPaolo Bonzini };
145*49ab747fSPaolo Bonzini 
146*49ab747fSPaolo Bonzini /* all registers are 32 bit wide */
147*49ab747fSPaolo Bonzini /* BAR 1 */
148*49ab747fSPaolo Bonzini enum {
149*49ab747fSPaolo Bonzini     VMXNET3_REG_VRRS    = 0x0,    /* Vmxnet3 Revision Report Selection */
150*49ab747fSPaolo Bonzini     VMXNET3_REG_UVRS    = 0x8,    /* UPT Version Report Selection */
151*49ab747fSPaolo Bonzini     VMXNET3_REG_DSAL    = 0x10,    /* Driver Shared Address Low */
152*49ab747fSPaolo Bonzini     VMXNET3_REG_DSAH    = 0x18,    /* Driver Shared Address High */
153*49ab747fSPaolo Bonzini     VMXNET3_REG_CMD        = 0x20,    /* Command */
154*49ab747fSPaolo Bonzini     VMXNET3_REG_MACL    = 0x28,    /* MAC Address Low */
155*49ab747fSPaolo Bonzini     VMXNET3_REG_MACH    = 0x30,    /* MAC Address High */
156*49ab747fSPaolo Bonzini     VMXNET3_REG_ICR        = 0x38,    /* Interrupt Cause Register */
157*49ab747fSPaolo Bonzini     VMXNET3_REG_ECR        = 0x40    /* Event Cause Register */
158*49ab747fSPaolo Bonzini };
159*49ab747fSPaolo Bonzini 
160*49ab747fSPaolo Bonzini /* BAR 0 */
161*49ab747fSPaolo Bonzini enum {
162*49ab747fSPaolo Bonzini     VMXNET3_REG_IMR        = 0x0,     /* Interrupt Mask Register */
163*49ab747fSPaolo Bonzini     VMXNET3_REG_TXPROD    = 0x600, /* Tx Producer Index */
164*49ab747fSPaolo Bonzini     VMXNET3_REG_RXPROD    = 0x800, /* Rx Producer Index for ring 1 */
165*49ab747fSPaolo Bonzini     VMXNET3_REG_RXPROD2    = 0xA00     /* Rx Producer Index for ring 2 */
166*49ab747fSPaolo Bonzini };
167*49ab747fSPaolo Bonzini 
168*49ab747fSPaolo Bonzini #define VMXNET3_PT_REG_SIZE     4096    /* BAR 0 */
169*49ab747fSPaolo Bonzini #define VMXNET3_VD_REG_SIZE     4096    /* BAR 1 */
170*49ab747fSPaolo Bonzini 
171*49ab747fSPaolo Bonzini #define VMXNET3_REG_ALIGN       8    /* All registers are 8-byte aligned. */
172*49ab747fSPaolo Bonzini #define VMXNET3_REG_ALIGN_MASK  0x7
173*49ab747fSPaolo Bonzini 
174*49ab747fSPaolo Bonzini /* I/O Mapped access to registers */
175*49ab747fSPaolo Bonzini #define VMXNET3_IO_TYPE_PT              0
176*49ab747fSPaolo Bonzini #define VMXNET3_IO_TYPE_VD              1
177*49ab747fSPaolo Bonzini #define VMXNET3_IO_ADDR(type, reg)      (((type) << 24) | ((reg) & 0xFFFFFF))
178*49ab747fSPaolo Bonzini #define VMXNET3_IO_TYPE(addr)           ((addr) >> 24)
179*49ab747fSPaolo Bonzini #define VMXNET3_IO_REG(addr)            ((addr) & 0xFFFFFF)
180*49ab747fSPaolo Bonzini 
181*49ab747fSPaolo Bonzini enum {
182*49ab747fSPaolo Bonzini     VMXNET3_CMD_FIRST_SET = 0xCAFE0000,
183*49ab747fSPaolo Bonzini     VMXNET3_CMD_ACTIVATE_DEV = VMXNET3_CMD_FIRST_SET, /* 0xCAFE0000 */
184*49ab747fSPaolo Bonzini     VMXNET3_CMD_QUIESCE_DEV,                          /* 0xCAFE0001 */
185*49ab747fSPaolo Bonzini     VMXNET3_CMD_RESET_DEV,                            /* 0xCAFE0002 */
186*49ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_RX_MODE,                       /* 0xCAFE0003 */
187*49ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_MAC_FILTERS,                   /* 0xCAFE0004 */
188*49ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_VLAN_FILTERS,                  /* 0xCAFE0005 */
189*49ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_RSSIDT,                        /* 0xCAFE0006 */
190*49ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_IML,                           /* 0xCAFE0007 */
191*49ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_PMCFG,                         /* 0xCAFE0008 */
192*49ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_FEATURE,                       /* 0xCAFE0009 */
193*49ab747fSPaolo Bonzini     VMXNET3_CMD_LOAD_PLUGIN,                          /* 0xCAFE000A */
194*49ab747fSPaolo Bonzini 
195*49ab747fSPaolo Bonzini     VMXNET3_CMD_FIRST_GET = 0xF00D0000,
196*49ab747fSPaolo Bonzini     VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET, /* 0xF00D0000 */
197*49ab747fSPaolo Bonzini     VMXNET3_CMD_GET_STATS,                                /* 0xF00D0001 */
198*49ab747fSPaolo Bonzini     VMXNET3_CMD_GET_LINK,                                 /* 0xF00D0002 */
199*49ab747fSPaolo Bonzini     VMXNET3_CMD_GET_PERM_MAC_LO,                          /* 0xF00D0003 */
200*49ab747fSPaolo Bonzini     VMXNET3_CMD_GET_PERM_MAC_HI,                          /* 0xF00D0004 */
201*49ab747fSPaolo Bonzini     VMXNET3_CMD_GET_DID_LO,                               /* 0xF00D0005 */
202*49ab747fSPaolo Bonzini     VMXNET3_CMD_GET_DID_HI,                               /* 0xF00D0006 */
203*49ab747fSPaolo Bonzini     VMXNET3_CMD_GET_DEV_EXTRA_INFO,                       /* 0xF00D0007 */
204*49ab747fSPaolo Bonzini     VMXNET3_CMD_GET_CONF_INTR                             /* 0xF00D0008 */
205*49ab747fSPaolo Bonzini };
206*49ab747fSPaolo Bonzini 
207*49ab747fSPaolo Bonzini /*
208*49ab747fSPaolo Bonzini  *    Little Endian layout of bitfields -
209*49ab747fSPaolo Bonzini  *    Byte 0 :    7.....len.....0
210*49ab747fSPaolo Bonzini  *    Byte 1 :    rsvd gen 13.len.8
211*49ab747fSPaolo Bonzini  *    Byte 2 :     5.msscof.0 ext1  dtype
212*49ab747fSPaolo Bonzini  *    Byte 3 :     13...msscof...6
213*49ab747fSPaolo Bonzini  *
214*49ab747fSPaolo Bonzini  *    Big Endian layout of bitfields -
215*49ab747fSPaolo Bonzini  *    Byte 0:        13...msscof...6
216*49ab747fSPaolo Bonzini  *    Byte 1 :     5.msscof.0 ext1  dtype
217*49ab747fSPaolo Bonzini  *    Byte 2 :    rsvd gen 13.len.8
218*49ab747fSPaolo Bonzini  *    Byte 3 :    7.....len.....0
219*49ab747fSPaolo Bonzini  *
220*49ab747fSPaolo Bonzini  *    Thus, le32_to_cpu on the dword will allow the big endian driver to read
221*49ab747fSPaolo Bonzini  *    the bit fields correctly. And cpu_to_le32 will convert bitfields
222*49ab747fSPaolo Bonzini  *    bit fields written by big endian driver to format required by device.
223*49ab747fSPaolo Bonzini  */
224*49ab747fSPaolo Bonzini 
225*49ab747fSPaolo Bonzini struct Vmxnet3_TxDesc {
226*49ab747fSPaolo Bonzini     __le64 addr;
227*49ab747fSPaolo Bonzini 
228*49ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
229*49ab747fSPaolo Bonzini     u32 msscof:14;  /* MSS, checksum offset, flags */
230*49ab747fSPaolo Bonzini     u32 ext1:1;
231*49ab747fSPaolo Bonzini     u32 dtype:1;    /* descriptor type */
232*49ab747fSPaolo Bonzini     u32 rsvd:1;
233*49ab747fSPaolo Bonzini     u32 gen:1;      /* generation bit */
234*49ab747fSPaolo Bonzini     u32 len:14;
235*49ab747fSPaolo Bonzini #else
236*49ab747fSPaolo Bonzini     u32 len:14;
237*49ab747fSPaolo Bonzini     u32 gen:1;      /* generation bit */
238*49ab747fSPaolo Bonzini     u32 rsvd:1;
239*49ab747fSPaolo Bonzini     u32 dtype:1;    /* descriptor type */
240*49ab747fSPaolo Bonzini     u32 ext1:1;
241*49ab747fSPaolo Bonzini     u32 msscof:14;  /* MSS, checksum offset, flags */
242*49ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
243*49ab747fSPaolo Bonzini 
244*49ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
245*49ab747fSPaolo Bonzini     u32 tci:16;     /* Tag to Insert */
246*49ab747fSPaolo Bonzini     u32 ti:1;       /* VLAN Tag Insertion */
247*49ab747fSPaolo Bonzini     u32 ext2:1;
248*49ab747fSPaolo Bonzini     u32 cq:1;       /* completion request */
249*49ab747fSPaolo Bonzini     u32 eop:1;      /* End Of Packet */
250*49ab747fSPaolo Bonzini     u32 om:2;       /* offload mode */
251*49ab747fSPaolo Bonzini     u32 hlen:10;    /* header len */
252*49ab747fSPaolo Bonzini #else
253*49ab747fSPaolo Bonzini     u32 hlen:10;    /* header len */
254*49ab747fSPaolo Bonzini     u32 om:2;       /* offload mode */
255*49ab747fSPaolo Bonzini     u32 eop:1;      /* End Of Packet */
256*49ab747fSPaolo Bonzini     u32 cq:1;       /* completion request */
257*49ab747fSPaolo Bonzini     u32 ext2:1;
258*49ab747fSPaolo Bonzini     u32 ti:1;       /* VLAN Tag Insertion */
259*49ab747fSPaolo Bonzini     u32 tci:16;     /* Tag to Insert */
260*49ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
261*49ab747fSPaolo Bonzini };
262*49ab747fSPaolo Bonzini 
263*49ab747fSPaolo Bonzini /* TxDesc.OM values */
264*49ab747fSPaolo Bonzini #define VMXNET3_OM_NONE        0
265*49ab747fSPaolo Bonzini #define VMXNET3_OM_CSUM        2
266*49ab747fSPaolo Bonzini #define VMXNET3_OM_TSO        3
267*49ab747fSPaolo Bonzini 
268*49ab747fSPaolo Bonzini /* fields in TxDesc we access w/o using bit fields */
269*49ab747fSPaolo Bonzini #define VMXNET3_TXD_EOP_SHIFT    12
270*49ab747fSPaolo Bonzini #define VMXNET3_TXD_CQ_SHIFT    13
271*49ab747fSPaolo Bonzini #define VMXNET3_TXD_GEN_SHIFT    14
272*49ab747fSPaolo Bonzini #define VMXNET3_TXD_EOP_DWORD_SHIFT 3
273*49ab747fSPaolo Bonzini #define VMXNET3_TXD_GEN_DWORD_SHIFT 2
274*49ab747fSPaolo Bonzini 
275*49ab747fSPaolo Bonzini #define VMXNET3_TXD_CQ        (1 << VMXNET3_TXD_CQ_SHIFT)
276*49ab747fSPaolo Bonzini #define VMXNET3_TXD_EOP        (1 << VMXNET3_TXD_EOP_SHIFT)
277*49ab747fSPaolo Bonzini #define VMXNET3_TXD_GEN        (1 << VMXNET3_TXD_GEN_SHIFT)
278*49ab747fSPaolo Bonzini 
279*49ab747fSPaolo Bonzini #define VMXNET3_HDR_COPY_SIZE   128
280*49ab747fSPaolo Bonzini 
281*49ab747fSPaolo Bonzini 
282*49ab747fSPaolo Bonzini struct Vmxnet3_TxDataDesc {
283*49ab747fSPaolo Bonzini     u8        data[VMXNET3_HDR_COPY_SIZE];
284*49ab747fSPaolo Bonzini };
285*49ab747fSPaolo Bonzini 
286*49ab747fSPaolo Bonzini #define VMXNET3_TCD_GEN_SHIFT    31
287*49ab747fSPaolo Bonzini #define VMXNET3_TCD_GEN_SIZE    1
288*49ab747fSPaolo Bonzini #define VMXNET3_TCD_TXIDX_SHIFT    0
289*49ab747fSPaolo Bonzini #define VMXNET3_TCD_TXIDX_SIZE    12
290*49ab747fSPaolo Bonzini #define VMXNET3_TCD_GEN_DWORD_SHIFT    3
291*49ab747fSPaolo Bonzini 
292*49ab747fSPaolo Bonzini struct Vmxnet3_TxCompDesc {
293*49ab747fSPaolo Bonzini     u32        txdIdx:12;    /* Index of the EOP TxDesc */
294*49ab747fSPaolo Bonzini     u32        ext1:20;
295*49ab747fSPaolo Bonzini 
296*49ab747fSPaolo Bonzini     __le32        ext2;
297*49ab747fSPaolo Bonzini     __le32        ext3;
298*49ab747fSPaolo Bonzini 
299*49ab747fSPaolo Bonzini     u32        rsvd:24;
300*49ab747fSPaolo Bonzini     u32        type:7;       /* completion type */
301*49ab747fSPaolo Bonzini     u32        gen:1;        /* generation bit */
302*49ab747fSPaolo Bonzini };
303*49ab747fSPaolo Bonzini 
304*49ab747fSPaolo Bonzini struct Vmxnet3_RxDesc {
305*49ab747fSPaolo Bonzini     __le64        addr;
306*49ab747fSPaolo Bonzini 
307*49ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
308*49ab747fSPaolo Bonzini     u32        gen:1;        /* Generation bit */
309*49ab747fSPaolo Bonzini     u32        rsvd:15;
310*49ab747fSPaolo Bonzini     u32        dtype:1;      /* Descriptor type */
311*49ab747fSPaolo Bonzini     u32        btype:1;      /* Buffer Type */
312*49ab747fSPaolo Bonzini     u32        len:14;
313*49ab747fSPaolo Bonzini #else
314*49ab747fSPaolo Bonzini     u32        len:14;
315*49ab747fSPaolo Bonzini     u32        btype:1;      /* Buffer Type */
316*49ab747fSPaolo Bonzini     u32        dtype:1;      /* Descriptor type */
317*49ab747fSPaolo Bonzini     u32        rsvd:15;
318*49ab747fSPaolo Bonzini     u32        gen:1;        /* Generation bit */
319*49ab747fSPaolo Bonzini #endif
320*49ab747fSPaolo Bonzini     u32        ext1;
321*49ab747fSPaolo Bonzini };
322*49ab747fSPaolo Bonzini 
323*49ab747fSPaolo Bonzini /* values of RXD.BTYPE */
324*49ab747fSPaolo Bonzini #define VMXNET3_RXD_BTYPE_HEAD   0    /* head only */
325*49ab747fSPaolo Bonzini #define VMXNET3_RXD_BTYPE_BODY   1    /* body only */
326*49ab747fSPaolo Bonzini 
327*49ab747fSPaolo Bonzini /* fields in RxDesc we access w/o using bit fields */
328*49ab747fSPaolo Bonzini #define VMXNET3_RXD_BTYPE_SHIFT  14
329*49ab747fSPaolo Bonzini #define VMXNET3_RXD_GEN_SHIFT    31
330*49ab747fSPaolo Bonzini 
331*49ab747fSPaolo Bonzini struct Vmxnet3_RxCompDesc {
332*49ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
333*49ab747fSPaolo Bonzini     u32        ext2:1;
334*49ab747fSPaolo Bonzini     u32        cnc:1;        /* Checksum Not Calculated */
335*49ab747fSPaolo Bonzini     u32        rssType:4;    /* RSS hash type used */
336*49ab747fSPaolo Bonzini     u32        rqID:10;      /* rx queue/ring ID */
337*49ab747fSPaolo Bonzini     u32        sop:1;        /* Start of Packet */
338*49ab747fSPaolo Bonzini     u32        eop:1;        /* End of Packet */
339*49ab747fSPaolo Bonzini     u32        ext1:2;
340*49ab747fSPaolo Bonzini     u32        rxdIdx:12;    /* Index of the RxDesc */
341*49ab747fSPaolo Bonzini #else
342*49ab747fSPaolo Bonzini     u32        rxdIdx:12;    /* Index of the RxDesc */
343*49ab747fSPaolo Bonzini     u32        ext1:2;
344*49ab747fSPaolo Bonzini     u32        eop:1;        /* End of Packet */
345*49ab747fSPaolo Bonzini     u32        sop:1;        /* Start of Packet */
346*49ab747fSPaolo Bonzini     u32        rqID:10;      /* rx queue/ring ID */
347*49ab747fSPaolo Bonzini     u32        rssType:4;    /* RSS hash type used */
348*49ab747fSPaolo Bonzini     u32        cnc:1;        /* Checksum Not Calculated */
349*49ab747fSPaolo Bonzini     u32        ext2:1;
350*49ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
351*49ab747fSPaolo Bonzini 
352*49ab747fSPaolo Bonzini     __le32        rssHash;      /* RSS hash value */
353*49ab747fSPaolo Bonzini 
354*49ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
355*49ab747fSPaolo Bonzini     u32        tci:16;       /* Tag stripped */
356*49ab747fSPaolo Bonzini     u32        ts:1;         /* Tag is stripped */
357*49ab747fSPaolo Bonzini     u32        err:1;        /* Error */
358*49ab747fSPaolo Bonzini     u32        len:14;       /* data length */
359*49ab747fSPaolo Bonzini #else
360*49ab747fSPaolo Bonzini     u32        len:14;       /* data length */
361*49ab747fSPaolo Bonzini     u32        err:1;        /* Error */
362*49ab747fSPaolo Bonzini     u32        ts:1;         /* Tag is stripped */
363*49ab747fSPaolo Bonzini     u32        tci:16;       /* Tag stripped */
364*49ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
365*49ab747fSPaolo Bonzini 
366*49ab747fSPaolo Bonzini 
367*49ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
368*49ab747fSPaolo Bonzini     u32        gen:1;        /* generation bit */
369*49ab747fSPaolo Bonzini     u32        type:7;       /* completion type */
370*49ab747fSPaolo Bonzini     u32        fcs:1;        /* Frame CRC correct */
371*49ab747fSPaolo Bonzini     u32        frg:1;        /* IP Fragment */
372*49ab747fSPaolo Bonzini     u32        v4:1;         /* IPv4 */
373*49ab747fSPaolo Bonzini     u32        v6:1;         /* IPv6 */
374*49ab747fSPaolo Bonzini     u32        ipc:1;        /* IP Checksum Correct */
375*49ab747fSPaolo Bonzini     u32        tcp:1;        /* TCP packet */
376*49ab747fSPaolo Bonzini     u32        udp:1;        /* UDP packet */
377*49ab747fSPaolo Bonzini     u32        tuc:1;        /* TCP/UDP Checksum Correct */
378*49ab747fSPaolo Bonzini     u32        csum:16;
379*49ab747fSPaolo Bonzini #else
380*49ab747fSPaolo Bonzini     u32        csum:16;
381*49ab747fSPaolo Bonzini     u32        tuc:1;        /* TCP/UDP Checksum Correct */
382*49ab747fSPaolo Bonzini     u32        udp:1;        /* UDP packet */
383*49ab747fSPaolo Bonzini     u32        tcp:1;        /* TCP packet */
384*49ab747fSPaolo Bonzini     u32        ipc:1;        /* IP Checksum Correct */
385*49ab747fSPaolo Bonzini     u32        v6:1;         /* IPv6 */
386*49ab747fSPaolo Bonzini     u32        v4:1;         /* IPv4 */
387*49ab747fSPaolo Bonzini     u32        frg:1;        /* IP Fragment */
388*49ab747fSPaolo Bonzini     u32        fcs:1;        /* Frame CRC correct */
389*49ab747fSPaolo Bonzini     u32        type:7;       /* completion type */
390*49ab747fSPaolo Bonzini     u32        gen:1;        /* generation bit */
391*49ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
392*49ab747fSPaolo Bonzini };
393*49ab747fSPaolo Bonzini 
394*49ab747fSPaolo Bonzini /* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */
395*49ab747fSPaolo Bonzini #define VMXNET3_RCD_TUC_SHIFT    16
396*49ab747fSPaolo Bonzini #define VMXNET3_RCD_IPC_SHIFT    19
397*49ab747fSPaolo Bonzini 
398*49ab747fSPaolo Bonzini /* fields in RxCompDesc we access via Vmxnet3_GenericDesc.qword[1] */
399*49ab747fSPaolo Bonzini #define VMXNET3_RCD_TYPE_SHIFT    56
400*49ab747fSPaolo Bonzini #define VMXNET3_RCD_GEN_SHIFT    63
401*49ab747fSPaolo Bonzini 
402*49ab747fSPaolo Bonzini /* csum OK for TCP/UDP pkts over IP */
403*49ab747fSPaolo Bonzini #define VMXNET3_RCD_CSUM_OK (1 << VMXNET3_RCD_TUC_SHIFT | \
404*49ab747fSPaolo Bonzini                      1 << VMXNET3_RCD_IPC_SHIFT)
405*49ab747fSPaolo Bonzini #define VMXNET3_TXD_GEN_SIZE 1
406*49ab747fSPaolo Bonzini #define VMXNET3_TXD_EOP_SIZE 1
407*49ab747fSPaolo Bonzini 
408*49ab747fSPaolo Bonzini /* value of RxCompDesc.rssType */
409*49ab747fSPaolo Bonzini enum {
410*49ab747fSPaolo Bonzini     VMXNET3_RCD_RSS_TYPE_NONE     = 0,
411*49ab747fSPaolo Bonzini     VMXNET3_RCD_RSS_TYPE_IPV4     = 1,
412*49ab747fSPaolo Bonzini     VMXNET3_RCD_RSS_TYPE_TCPIPV4  = 2,
413*49ab747fSPaolo Bonzini     VMXNET3_RCD_RSS_TYPE_IPV6     = 3,
414*49ab747fSPaolo Bonzini     VMXNET3_RCD_RSS_TYPE_TCPIPV6  = 4,
415*49ab747fSPaolo Bonzini };
416*49ab747fSPaolo Bonzini 
417*49ab747fSPaolo Bonzini 
418*49ab747fSPaolo Bonzini /* a union for accessing all cmd/completion descriptors */
419*49ab747fSPaolo Bonzini union Vmxnet3_GenericDesc {
420*49ab747fSPaolo Bonzini     __le64                qword[2];
421*49ab747fSPaolo Bonzini     __le32                dword[4];
422*49ab747fSPaolo Bonzini     __le16                word[8];
423*49ab747fSPaolo Bonzini     struct Vmxnet3_TxDesc        txd;
424*49ab747fSPaolo Bonzini     struct Vmxnet3_RxDesc        rxd;
425*49ab747fSPaolo Bonzini     struct Vmxnet3_TxCompDesc    tcd;
426*49ab747fSPaolo Bonzini     struct Vmxnet3_RxCompDesc    rcd;
427*49ab747fSPaolo Bonzini };
428*49ab747fSPaolo Bonzini 
429*49ab747fSPaolo Bonzini #define VMXNET3_INIT_GEN       1
430*49ab747fSPaolo Bonzini 
431*49ab747fSPaolo Bonzini /* Max size of a single tx buffer */
432*49ab747fSPaolo Bonzini #define VMXNET3_MAX_TX_BUF_SIZE  (1 << 14)
433*49ab747fSPaolo Bonzini 
434*49ab747fSPaolo Bonzini /* # of tx desc needed for a tx buffer size */
435*49ab747fSPaolo Bonzini #define VMXNET3_TXD_NEEDED(size) (((size) + VMXNET3_MAX_TX_BUF_SIZE - 1) / \
436*49ab747fSPaolo Bonzini                     VMXNET3_MAX_TX_BUF_SIZE)
437*49ab747fSPaolo Bonzini 
438*49ab747fSPaolo Bonzini /* max # of tx descs for a non-tso pkt */
439*49ab747fSPaolo Bonzini #define VMXNET3_MAX_TXD_PER_PKT 16
440*49ab747fSPaolo Bonzini 
441*49ab747fSPaolo Bonzini /* Max size of a single rx buffer */
442*49ab747fSPaolo Bonzini #define VMXNET3_MAX_RX_BUF_SIZE  ((1 << 14) - 1)
443*49ab747fSPaolo Bonzini /* Minimum size of a type 0 buffer */
444*49ab747fSPaolo Bonzini #define VMXNET3_MIN_T0_BUF_SIZE  128
445*49ab747fSPaolo Bonzini #define VMXNET3_MAX_CSUM_OFFSET  1024
446*49ab747fSPaolo Bonzini 
447*49ab747fSPaolo Bonzini /* Ring base address alignment */
448*49ab747fSPaolo Bonzini #define VMXNET3_RING_BA_ALIGN   512
449*49ab747fSPaolo Bonzini #define VMXNET3_RING_BA_MASK    (VMXNET3_RING_BA_ALIGN - 1)
450*49ab747fSPaolo Bonzini 
451*49ab747fSPaolo Bonzini /* Ring size must be a multiple of 32 */
452*49ab747fSPaolo Bonzini #define VMXNET3_RING_SIZE_ALIGN 32
453*49ab747fSPaolo Bonzini #define VMXNET3_RING_SIZE_MASK  (VMXNET3_RING_SIZE_ALIGN - 1)
454*49ab747fSPaolo Bonzini 
455*49ab747fSPaolo Bonzini /* Max ring size */
456*49ab747fSPaolo Bonzini #define VMXNET3_TX_RING_MAX_SIZE   4096
457*49ab747fSPaolo Bonzini #define VMXNET3_TC_RING_MAX_SIZE   4096
458*49ab747fSPaolo Bonzini #define VMXNET3_RX_RING_MAX_SIZE   4096
459*49ab747fSPaolo Bonzini #define VMXNET3_RC_RING_MAX_SIZE   8192
460*49ab747fSPaolo Bonzini 
461*49ab747fSPaolo Bonzini /* a list of reasons for queue stop */
462*49ab747fSPaolo Bonzini 
463*49ab747fSPaolo Bonzini enum {
464*49ab747fSPaolo Bonzini  VMXNET3_ERR_NOEOP        = 0x80000000, /* cannot find the EOP desc of a pkt */
465*49ab747fSPaolo Bonzini  VMXNET3_ERR_TXD_REUSE    = 0x80000001, /* reuse TxDesc before tx completion */
466*49ab747fSPaolo Bonzini  VMXNET3_ERR_BIG_PKT      = 0x80000002, /* too many TxDesc for a pkt */
467*49ab747fSPaolo Bonzini  VMXNET3_ERR_DESC_NOT_SPT = 0x80000003, /* descriptor type not supported */
468*49ab747fSPaolo Bonzini  VMXNET3_ERR_SMALL_BUF    = 0x80000004, /* type 0 buffer too small */
469*49ab747fSPaolo Bonzini  VMXNET3_ERR_STRESS       = 0x80000005, /* stress option firing in vmkernel */
470*49ab747fSPaolo Bonzini  VMXNET3_ERR_SWITCH       = 0x80000006, /* mode switch failure */
471*49ab747fSPaolo Bonzini  VMXNET3_ERR_TXD_INVALID  = 0x80000007, /* invalid TxDesc */
472*49ab747fSPaolo Bonzini };
473*49ab747fSPaolo Bonzini 
474*49ab747fSPaolo Bonzini /* completion descriptor types */
475*49ab747fSPaolo Bonzini #define VMXNET3_CDTYPE_TXCOMP      0    /* Tx Completion Descriptor */
476*49ab747fSPaolo Bonzini #define VMXNET3_CDTYPE_RXCOMP      3    /* Rx Completion Descriptor */
477*49ab747fSPaolo Bonzini 
478*49ab747fSPaolo Bonzini enum {
479*49ab747fSPaolo Bonzini     VMXNET3_GOS_BITS_UNK    = 0,   /* unknown */
480*49ab747fSPaolo Bonzini     VMXNET3_GOS_BITS_32     = 1,
481*49ab747fSPaolo Bonzini     VMXNET3_GOS_BITS_64     = 2,
482*49ab747fSPaolo Bonzini };
483*49ab747fSPaolo Bonzini 
484*49ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_UNK        0 /* unknown */
485*49ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_LINUX      1
486*49ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_WIN        2
487*49ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_SOLARIS    3
488*49ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_FREEBSD    4
489*49ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_PXE        5
490*49ab747fSPaolo Bonzini 
491*49ab747fSPaolo Bonzini struct Vmxnet3_GOSInfo {
492*49ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
493*49ab747fSPaolo Bonzini     u32        gosMisc:10;    /* other info about gos */
494*49ab747fSPaolo Bonzini     u32        gosVer:16;     /* gos version */
495*49ab747fSPaolo Bonzini     u32        gosType:4;     /* which guest */
496*49ab747fSPaolo Bonzini     u32        gosBits:2;    /* 32-bit or 64-bit? */
497*49ab747fSPaolo Bonzini #else
498*49ab747fSPaolo Bonzini     u32        gosBits:2;     /* 32-bit or 64-bit? */
499*49ab747fSPaolo Bonzini     u32        gosType:4;     /* which guest */
500*49ab747fSPaolo Bonzini     u32        gosVer:16;     /* gos version */
501*49ab747fSPaolo Bonzini     u32        gosMisc:10;    /* other info about gos */
502*49ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
503*49ab747fSPaolo Bonzini };
504*49ab747fSPaolo Bonzini 
505*49ab747fSPaolo Bonzini struct Vmxnet3_DriverInfo {
506*49ab747fSPaolo Bonzini     __le32                version;
507*49ab747fSPaolo Bonzini     struct Vmxnet3_GOSInfo        gos;
508*49ab747fSPaolo Bonzini     __le32                vmxnet3RevSpt;
509*49ab747fSPaolo Bonzini     __le32                uptVerSpt;
510*49ab747fSPaolo Bonzini };
511*49ab747fSPaolo Bonzini 
512*49ab747fSPaolo Bonzini 
513*49ab747fSPaolo Bonzini #define VMXNET3_REV1_MAGIC  0xbabefee1
514*49ab747fSPaolo Bonzini 
515*49ab747fSPaolo Bonzini /*
516*49ab747fSPaolo Bonzini  * QueueDescPA must be 128 bytes aligned. It points to an array of
517*49ab747fSPaolo Bonzini  * Vmxnet3_TxQueueDesc followed by an array of Vmxnet3_RxQueueDesc.
518*49ab747fSPaolo Bonzini  * The number of Vmxnet3_TxQueueDesc/Vmxnet3_RxQueueDesc are specified by
519*49ab747fSPaolo Bonzini  * Vmxnet3_MiscConf.numTxQueues/numRxQueues, respectively.
520*49ab747fSPaolo Bonzini  */
521*49ab747fSPaolo Bonzini #define VMXNET3_QUEUE_DESC_ALIGN  128
522*49ab747fSPaolo Bonzini 
523*49ab747fSPaolo Bonzini 
524*49ab747fSPaolo Bonzini struct Vmxnet3_MiscConf {
525*49ab747fSPaolo Bonzini     struct Vmxnet3_DriverInfo driverInfo;
526*49ab747fSPaolo Bonzini     __le64        uptFeatures;
527*49ab747fSPaolo Bonzini     __le64        ddPA;         /* driver data PA */
528*49ab747fSPaolo Bonzini     __le64        queueDescPA;  /* queue descriptor table PA */
529*49ab747fSPaolo Bonzini     __le32        ddLen;        /* driver data len */
530*49ab747fSPaolo Bonzini     __le32        queueDescLen; /* queue desc. table len in bytes */
531*49ab747fSPaolo Bonzini     __le32        mtu;
532*49ab747fSPaolo Bonzini     __le16        maxNumRxSG;
533*49ab747fSPaolo Bonzini     u8        numTxQueues;
534*49ab747fSPaolo Bonzini     u8        numRxQueues;
535*49ab747fSPaolo Bonzini     __le32        reserved[4];
536*49ab747fSPaolo Bonzini };
537*49ab747fSPaolo Bonzini 
538*49ab747fSPaolo Bonzini 
539*49ab747fSPaolo Bonzini struct Vmxnet3_TxQueueConf {
540*49ab747fSPaolo Bonzini     __le64        txRingBasePA;
541*49ab747fSPaolo Bonzini     __le64        dataRingBasePA;
542*49ab747fSPaolo Bonzini     __le64        compRingBasePA;
543*49ab747fSPaolo Bonzini     __le64        ddPA;         /* driver data */
544*49ab747fSPaolo Bonzini     __le64        reserved;
545*49ab747fSPaolo Bonzini     __le32        txRingSize;   /* # of tx desc */
546*49ab747fSPaolo Bonzini     __le32        dataRingSize; /* # of data desc */
547*49ab747fSPaolo Bonzini     __le32        compRingSize; /* # of comp desc */
548*49ab747fSPaolo Bonzini     __le32        ddLen;        /* size of driver data */
549*49ab747fSPaolo Bonzini     u8        intrIdx;
550*49ab747fSPaolo Bonzini     u8        _pad[7];
551*49ab747fSPaolo Bonzini };
552*49ab747fSPaolo Bonzini 
553*49ab747fSPaolo Bonzini 
554*49ab747fSPaolo Bonzini struct Vmxnet3_RxQueueConf {
555*49ab747fSPaolo Bonzini     __le64        rxRingBasePA[2];
556*49ab747fSPaolo Bonzini     __le64        compRingBasePA;
557*49ab747fSPaolo Bonzini     __le64        ddPA;            /* driver data */
558*49ab747fSPaolo Bonzini     __le64        reserved;
559*49ab747fSPaolo Bonzini     __le32        rxRingSize[2];   /* # of rx desc */
560*49ab747fSPaolo Bonzini     __le32        compRingSize;    /* # of rx comp desc */
561*49ab747fSPaolo Bonzini     __le32        ddLen;           /* size of driver data */
562*49ab747fSPaolo Bonzini     u8        intrIdx;
563*49ab747fSPaolo Bonzini     u8        _pad[7];
564*49ab747fSPaolo Bonzini };
565*49ab747fSPaolo Bonzini 
566*49ab747fSPaolo Bonzini 
567*49ab747fSPaolo Bonzini enum vmxnet3_intr_mask_mode {
568*49ab747fSPaolo Bonzini     VMXNET3_IMM_AUTO   = 0,
569*49ab747fSPaolo Bonzini     VMXNET3_IMM_ACTIVE = 1,
570*49ab747fSPaolo Bonzini     VMXNET3_IMM_LAZY   = 2
571*49ab747fSPaolo Bonzini };
572*49ab747fSPaolo Bonzini 
573*49ab747fSPaolo Bonzini enum vmxnet3_intr_type {
574*49ab747fSPaolo Bonzini     VMXNET3_IT_AUTO = 0,
575*49ab747fSPaolo Bonzini     VMXNET3_IT_INTX = 1,
576*49ab747fSPaolo Bonzini     VMXNET3_IT_MSI  = 2,
577*49ab747fSPaolo Bonzini     VMXNET3_IT_MSIX = 3
578*49ab747fSPaolo Bonzini };
579*49ab747fSPaolo Bonzini 
580*49ab747fSPaolo Bonzini #define VMXNET3_MAX_TX_QUEUES  8
581*49ab747fSPaolo Bonzini #define VMXNET3_MAX_RX_QUEUES  16
582*49ab747fSPaolo Bonzini /* addition 1 for events */
583*49ab747fSPaolo Bonzini #define VMXNET3_MAX_INTRS      25
584*49ab747fSPaolo Bonzini 
585*49ab747fSPaolo Bonzini /* value of intrCtrl */
586*49ab747fSPaolo Bonzini #define VMXNET3_IC_DISABLE_ALL  0x1   /* bit 0 */
587*49ab747fSPaolo Bonzini 
588*49ab747fSPaolo Bonzini 
589*49ab747fSPaolo Bonzini struct Vmxnet3_IntrConf {
590*49ab747fSPaolo Bonzini     bool        autoMask;
591*49ab747fSPaolo Bonzini     u8        numIntrs;      /* # of interrupts */
592*49ab747fSPaolo Bonzini     u8        eventIntrIdx;
593*49ab747fSPaolo Bonzini     u8        modLevels[VMXNET3_MAX_INTRS];    /* moderation level for
594*49ab747fSPaolo Bonzini                              * each intr */
595*49ab747fSPaolo Bonzini     __le32        intrCtrl;
596*49ab747fSPaolo Bonzini     __le32        reserved[2];
597*49ab747fSPaolo Bonzini };
598*49ab747fSPaolo Bonzini 
599*49ab747fSPaolo Bonzini /* one bit per VLAN ID, the size is in the units of u32 */
600*49ab747fSPaolo Bonzini #define VMXNET3_VFT_SIZE  (4096/(sizeof(uint32_t)*8))
601*49ab747fSPaolo Bonzini 
602*49ab747fSPaolo Bonzini 
603*49ab747fSPaolo Bonzini struct Vmxnet3_QueueStatus {
604*49ab747fSPaolo Bonzini     bool        stopped;
605*49ab747fSPaolo Bonzini     u8        _pad[3];
606*49ab747fSPaolo Bonzini     __le32        error;
607*49ab747fSPaolo Bonzini };
608*49ab747fSPaolo Bonzini 
609*49ab747fSPaolo Bonzini 
610*49ab747fSPaolo Bonzini struct Vmxnet3_TxQueueCtrl {
611*49ab747fSPaolo Bonzini     __le32        txNumDeferred;
612*49ab747fSPaolo Bonzini     __le32        txThreshold;
613*49ab747fSPaolo Bonzini     __le64        reserved;
614*49ab747fSPaolo Bonzini };
615*49ab747fSPaolo Bonzini 
616*49ab747fSPaolo Bonzini 
617*49ab747fSPaolo Bonzini struct Vmxnet3_RxQueueCtrl {
618*49ab747fSPaolo Bonzini     bool        updateRxProd;
619*49ab747fSPaolo Bonzini     u8        _pad[7];
620*49ab747fSPaolo Bonzini     __le64        reserved;
621*49ab747fSPaolo Bonzini };
622*49ab747fSPaolo Bonzini 
623*49ab747fSPaolo Bonzini enum {
624*49ab747fSPaolo Bonzini     VMXNET3_RXM_UCAST     = 0x01,  /* unicast only */
625*49ab747fSPaolo Bonzini     VMXNET3_RXM_MCAST     = 0x02,  /* multicast passing the filters */
626*49ab747fSPaolo Bonzini     VMXNET3_RXM_BCAST     = 0x04,  /* broadcast only */
627*49ab747fSPaolo Bonzini     VMXNET3_RXM_ALL_MULTI = 0x08,  /* all multicast */
628*49ab747fSPaolo Bonzini     VMXNET3_RXM_PROMISC   = 0x10  /* promiscuous */
629*49ab747fSPaolo Bonzini };
630*49ab747fSPaolo Bonzini 
631*49ab747fSPaolo Bonzini struct Vmxnet3_RxFilterConf {
632*49ab747fSPaolo Bonzini     __le32        rxMode;       /* VMXNET3_RXM_xxx */
633*49ab747fSPaolo Bonzini     __le16        mfTableLen;   /* size of the multicast filter table */
634*49ab747fSPaolo Bonzini     __le16        _pad1;
635*49ab747fSPaolo Bonzini     __le64        mfTablePA;    /* PA of the multicast filters table */
636*49ab747fSPaolo Bonzini     __le32        vfTable[VMXNET3_VFT_SIZE]; /* vlan filter */
637*49ab747fSPaolo Bonzini };
638*49ab747fSPaolo Bonzini 
639*49ab747fSPaolo Bonzini 
640*49ab747fSPaolo Bonzini #define VMXNET3_PM_MAX_FILTERS        6
641*49ab747fSPaolo Bonzini #define VMXNET3_PM_MAX_PATTERN_SIZE   128
642*49ab747fSPaolo Bonzini #define VMXNET3_PM_MAX_MASK_SIZE      (VMXNET3_PM_MAX_PATTERN_SIZE / 8)
643*49ab747fSPaolo Bonzini 
644*49ab747fSPaolo Bonzini #define VMXNET3_PM_WAKEUP_MAGIC  cpu_to_le16(0x01)  /* wake up on magic pkts */
645*49ab747fSPaolo Bonzini #define VMXNET3_PM_WAKEUP_FILTER cpu_to_le16(0x02)  /* wake up on pkts matching
646*49ab747fSPaolo Bonzini                                                      * filters */
647*49ab747fSPaolo Bonzini 
648*49ab747fSPaolo Bonzini 
649*49ab747fSPaolo Bonzini struct Vmxnet3_PM_PktFilter {
650*49ab747fSPaolo Bonzini     u8        maskSize;
651*49ab747fSPaolo Bonzini     u8        patternSize;
652*49ab747fSPaolo Bonzini     u8        mask[VMXNET3_PM_MAX_MASK_SIZE];
653*49ab747fSPaolo Bonzini     u8        pattern[VMXNET3_PM_MAX_PATTERN_SIZE];
654*49ab747fSPaolo Bonzini     u8        pad[6];
655*49ab747fSPaolo Bonzini };
656*49ab747fSPaolo Bonzini 
657*49ab747fSPaolo Bonzini 
658*49ab747fSPaolo Bonzini struct Vmxnet3_PMConf {
659*49ab747fSPaolo Bonzini     __le16        wakeUpEvents;  /* VMXNET3_PM_WAKEUP_xxx */
660*49ab747fSPaolo Bonzini     u8        numFilters;
661*49ab747fSPaolo Bonzini     u8        pad[5];
662*49ab747fSPaolo Bonzini     struct Vmxnet3_PM_PktFilter filters[VMXNET3_PM_MAX_FILTERS];
663*49ab747fSPaolo Bonzini };
664*49ab747fSPaolo Bonzini 
665*49ab747fSPaolo Bonzini 
666*49ab747fSPaolo Bonzini struct Vmxnet3_VariableLenConfDesc {
667*49ab747fSPaolo Bonzini     __le32        confVer;
668*49ab747fSPaolo Bonzini     __le32        confLen;
669*49ab747fSPaolo Bonzini     __le64        confPA;
670*49ab747fSPaolo Bonzini };
671*49ab747fSPaolo Bonzini 
672*49ab747fSPaolo Bonzini 
673*49ab747fSPaolo Bonzini struct Vmxnet3_TxQueueDesc {
674*49ab747fSPaolo Bonzini     struct Vmxnet3_TxQueueCtrl        ctrl;
675*49ab747fSPaolo Bonzini     struct Vmxnet3_TxQueueConf        conf;
676*49ab747fSPaolo Bonzini 
677*49ab747fSPaolo Bonzini     /* Driver read after a GET command */
678*49ab747fSPaolo Bonzini     struct Vmxnet3_QueueStatus        status;
679*49ab747fSPaolo Bonzini     struct UPT1_TxStats            stats;
680*49ab747fSPaolo Bonzini     u8                    _pad[88]; /* 128 aligned */
681*49ab747fSPaolo Bonzini };
682*49ab747fSPaolo Bonzini 
683*49ab747fSPaolo Bonzini 
684*49ab747fSPaolo Bonzini struct Vmxnet3_RxQueueDesc {
685*49ab747fSPaolo Bonzini     struct Vmxnet3_RxQueueCtrl        ctrl;
686*49ab747fSPaolo Bonzini     struct Vmxnet3_RxQueueConf        conf;
687*49ab747fSPaolo Bonzini     /* Driver read after a GET commad */
688*49ab747fSPaolo Bonzini     struct Vmxnet3_QueueStatus        status;
689*49ab747fSPaolo Bonzini     struct UPT1_RxStats            stats;
690*49ab747fSPaolo Bonzini     u8                      __pad[88]; /* 128 aligned */
691*49ab747fSPaolo Bonzini };
692*49ab747fSPaolo Bonzini 
693*49ab747fSPaolo Bonzini 
694*49ab747fSPaolo Bonzini struct Vmxnet3_DSDevRead {
695*49ab747fSPaolo Bonzini     /* read-only region for device, read by dev in response to a SET cmd */
696*49ab747fSPaolo Bonzini     struct Vmxnet3_MiscConf            misc;
697*49ab747fSPaolo Bonzini     struct Vmxnet3_IntrConf            intrConf;
698*49ab747fSPaolo Bonzini     struct Vmxnet3_RxFilterConf        rxFilterConf;
699*49ab747fSPaolo Bonzini     struct Vmxnet3_VariableLenConfDesc    rssConfDesc;
700*49ab747fSPaolo Bonzini     struct Vmxnet3_VariableLenConfDesc    pmConfDesc;
701*49ab747fSPaolo Bonzini     struct Vmxnet3_VariableLenConfDesc    pluginConfDesc;
702*49ab747fSPaolo Bonzini };
703*49ab747fSPaolo Bonzini 
704*49ab747fSPaolo Bonzini /* All structures in DriverShared are padded to multiples of 8 bytes */
705*49ab747fSPaolo Bonzini struct Vmxnet3_DriverShared {
706*49ab747fSPaolo Bonzini     __le32              magic;
707*49ab747fSPaolo Bonzini     /* make devRead start at 64bit boundaries */
708*49ab747fSPaolo Bonzini     __le32              pad;
709*49ab747fSPaolo Bonzini     struct Vmxnet3_DSDevRead    devRead;
710*49ab747fSPaolo Bonzini     __le32              ecr;
711*49ab747fSPaolo Bonzini     __le32              reserved[5];
712*49ab747fSPaolo Bonzini };
713*49ab747fSPaolo Bonzini 
714*49ab747fSPaolo Bonzini 
715*49ab747fSPaolo Bonzini #define VMXNET3_ECR_RQERR       (1 << 0)
716*49ab747fSPaolo Bonzini #define VMXNET3_ECR_TQERR       (1 << 1)
717*49ab747fSPaolo Bonzini #define VMXNET3_ECR_LINK        (1 << 2)
718*49ab747fSPaolo Bonzini #define VMXNET3_ECR_DIC         (1 << 3)
719*49ab747fSPaolo Bonzini #define VMXNET3_ECR_DEBUG       (1 << 4)
720*49ab747fSPaolo Bonzini 
721*49ab747fSPaolo Bonzini /* flip the gen bit of a ring */
722*49ab747fSPaolo Bonzini #define VMXNET3_FLIP_RING_GEN(gen) ((gen) = (gen) ^ 0x1)
723*49ab747fSPaolo Bonzini 
724*49ab747fSPaolo Bonzini /* only use this if moving the idx won't affect the gen bit */
725*49ab747fSPaolo Bonzini #define VMXNET3_INC_RING_IDX_ONLY(idx, ring_size) \
726*49ab747fSPaolo Bonzini     do {\
727*49ab747fSPaolo Bonzini         (idx)++;\
728*49ab747fSPaolo Bonzini         if (unlikely((idx) == (ring_size))) {\
729*49ab747fSPaolo Bonzini             (idx) = 0;\
730*49ab747fSPaolo Bonzini         } \
731*49ab747fSPaolo Bonzini     } while (0)
732*49ab747fSPaolo Bonzini 
733*49ab747fSPaolo Bonzini #define VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid) \
734*49ab747fSPaolo Bonzini     (vfTable[vid >> 5] |= (1 << (vid & 31)))
735*49ab747fSPaolo Bonzini #define VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid) \
736*49ab747fSPaolo Bonzini     (vfTable[vid >> 5] &= ~(1 << (vid & 31)))
737*49ab747fSPaolo Bonzini 
738*49ab747fSPaolo Bonzini #define VMXNET3_VFTABLE_ENTRY_IS_SET(vfTable, vid) \
739*49ab747fSPaolo Bonzini     ((vfTable[vid >> 5] & (1 << (vid & 31))) != 0)
740*49ab747fSPaolo Bonzini 
741*49ab747fSPaolo Bonzini #define VMXNET3_MAX_MTU     9000
742*49ab747fSPaolo Bonzini #define VMXNET3_MIN_MTU     60
743*49ab747fSPaolo Bonzini 
744*49ab747fSPaolo Bonzini #define VMXNET3_LINK_UP         (10000 << 16 | 1)    /* 10 Gbps, up */
745*49ab747fSPaolo Bonzini #define VMXNET3_LINK_DOWN       0
746*49ab747fSPaolo Bonzini 
747*49ab747fSPaolo Bonzini #undef u64
748*49ab747fSPaolo Bonzini #undef u32
749*49ab747fSPaolo Bonzini #undef u16
750*49ab747fSPaolo Bonzini #undef u8
751*49ab747fSPaolo Bonzini #undef __le16
752*49ab747fSPaolo Bonzini #undef __le32
753*49ab747fSPaolo Bonzini #undef __le64
754*49ab747fSPaolo Bonzini #undef __packed
755*49ab747fSPaolo Bonzini #undef const_cpu_to_le64
756*49ab747fSPaolo Bonzini #if defined(HOST_WORDS_BIGENDIAN)
757*49ab747fSPaolo Bonzini #undef __BIG_ENDIAN_BITFIELD
758*49ab747fSPaolo Bonzini #endif
759*49ab747fSPaolo Bonzini 
760*49ab747fSPaolo Bonzini #endif
761