xref: /qemu/hw/net/vmxnet3.h (revision 2431f4f1)
149ab747fSPaolo Bonzini /*
249ab747fSPaolo Bonzini  * QEMU VMWARE VMXNET3 paravirtual NIC interface definitions
349ab747fSPaolo Bonzini  *
449ab747fSPaolo Bonzini  * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
549ab747fSPaolo Bonzini  *
649ab747fSPaolo Bonzini  * Developed by Daynix Computing LTD (http://www.daynix.com)
749ab747fSPaolo Bonzini  *
849ab747fSPaolo Bonzini  * Authors:
949ab747fSPaolo Bonzini  * Dmitry Fleytman <dmitry@daynix.com>
1049ab747fSPaolo Bonzini  * Tamir Shomer <tamirs@daynix.com>
1149ab747fSPaolo Bonzini  * Yan Vugenfirer <yan@daynix.com>
1249ab747fSPaolo Bonzini  *
1349ab747fSPaolo Bonzini  * This work is licensed under the terms of the GNU GPL, version 2.
1449ab747fSPaolo Bonzini  * See the COPYING file in the top-level directory.
1549ab747fSPaolo Bonzini  *
1649ab747fSPaolo Bonzini  */
1749ab747fSPaolo Bonzini 
182a6a4076SMarkus Armbruster #ifndef QEMU_VMXNET3_H
192a6a4076SMarkus Armbruster #define QEMU_VMXNET3_H
2049ab747fSPaolo Bonzini 
2149ab747fSPaolo Bonzini #define VMXNET3_DEVICE_MAX_TX_QUEUES 8
2249ab747fSPaolo Bonzini #define VMXNET3_DEVICE_MAX_RX_QUEUES 8   /* Keep this value as a power of 2 */
2349ab747fSPaolo Bonzini 
2449ab747fSPaolo Bonzini /*
2549ab747fSPaolo Bonzini  * VMWARE headers we got from Linux kernel do not fully comply QEMU coding
2649ab747fSPaolo Bonzini  * standards in sense of types and defines used.
2749ab747fSPaolo Bonzini  * Since we didn't want to change VMWARE code, following set of typedefs
2849ab747fSPaolo Bonzini  * and defines needed to compile these headers with QEMU introduced.
2949ab747fSPaolo Bonzini  */
3049ab747fSPaolo Bonzini #define u64     uint64_t
3149ab747fSPaolo Bonzini #define u32     uint32_t
3249ab747fSPaolo Bonzini #define u16     uint16_t
3349ab747fSPaolo Bonzini #define u8      uint8_t
3449ab747fSPaolo Bonzini #define __le16  uint16_t
3549ab747fSPaolo Bonzini #define __le32  uint32_t
3649ab747fSPaolo Bonzini #define __le64  uint64_t
3749ab747fSPaolo Bonzini 
38e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
3949ab747fSPaolo Bonzini #define __BIG_ENDIAN_BITFIELD
4049ab747fSPaolo Bonzini #else
4149ab747fSPaolo Bonzini #endif
4249ab747fSPaolo Bonzini 
4349ab747fSPaolo Bonzini /*
4449ab747fSPaolo Bonzini  * Following is an interface definition for
4549ab747fSPaolo Bonzini  * VMXNET3 device as provided by VMWARE
4649ab747fSPaolo Bonzini  * See original copyright from Linux kernel v3.2.8
4749ab747fSPaolo Bonzini  * header file drivers/net/vmxnet3/vmxnet3_defs.h below.
4849ab747fSPaolo Bonzini  */
4949ab747fSPaolo Bonzini 
5049ab747fSPaolo Bonzini /*
5149ab747fSPaolo Bonzini  * Linux driver for VMware's vmxnet3 ethernet NIC.
5249ab747fSPaolo Bonzini  *
5349ab747fSPaolo Bonzini  * Copyright (C) 2008-2009, VMware, Inc. All Rights Reserved.
5449ab747fSPaolo Bonzini  *
5549ab747fSPaolo Bonzini  * This program is free software; you can redistribute it and/or modify it
5649ab747fSPaolo Bonzini  * under the terms of the GNU General Public License as published by the
5749ab747fSPaolo Bonzini  * Free Software Foundation; version 2 of the License and no later version.
5849ab747fSPaolo Bonzini  *
5949ab747fSPaolo Bonzini  * This program is distributed in the hope that it will be useful, but
6049ab747fSPaolo Bonzini  * WITHOUT ANY WARRANTY; without even the implied warranty of
6149ab747fSPaolo Bonzini  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
6249ab747fSPaolo Bonzini  * NON INFRINGEMENT.  See the GNU General Public License for more
6349ab747fSPaolo Bonzini  * details.
6449ab747fSPaolo Bonzini  *
6549ab747fSPaolo Bonzini  * You should have received a copy of the GNU General Public License
6649ab747fSPaolo Bonzini  * along with this program; if not, write to the Free Software
6749ab747fSPaolo Bonzini  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
6849ab747fSPaolo Bonzini  *
6949ab747fSPaolo Bonzini  * The full GNU General Public License is included in this distribution in
7049ab747fSPaolo Bonzini  * the file called "COPYING".
7149ab747fSPaolo Bonzini  *
7249ab747fSPaolo Bonzini  * Maintained by: Shreyas Bhatewara <pv-drivers@vmware.com>
7349ab747fSPaolo Bonzini  *
7449ab747fSPaolo Bonzini  */
7549ab747fSPaolo Bonzini 
7649ab747fSPaolo Bonzini struct UPT1_TxStats {
7749ab747fSPaolo Bonzini     u64            TSOPktsTxOK;  /* TSO pkts post-segmentation */
7849ab747fSPaolo Bonzini     u64            TSOBytesTxOK;
7949ab747fSPaolo Bonzini     u64            ucastPktsTxOK;
8049ab747fSPaolo Bonzini     u64            ucastBytesTxOK;
8149ab747fSPaolo Bonzini     u64            mcastPktsTxOK;
8249ab747fSPaolo Bonzini     u64            mcastBytesTxOK;
8349ab747fSPaolo Bonzini     u64            bcastPktsTxOK;
8449ab747fSPaolo Bonzini     u64            bcastBytesTxOK;
8549ab747fSPaolo Bonzini     u64            pktsTxError;
8649ab747fSPaolo Bonzini     u64            pktsTxDiscard;
8749ab747fSPaolo Bonzini };
8849ab747fSPaolo Bonzini 
8949ab747fSPaolo Bonzini struct UPT1_RxStats {
9049ab747fSPaolo Bonzini     u64            LROPktsRxOK;    /* LRO pkts */
9149ab747fSPaolo Bonzini     u64            LROBytesRxOK;   /* bytes from LRO pkts */
9249ab747fSPaolo Bonzini     /* the following counters are for pkts from the wire, i.e., pre-LRO */
9349ab747fSPaolo Bonzini     u64            ucastPktsRxOK;
9449ab747fSPaolo Bonzini     u64            ucastBytesRxOK;
9549ab747fSPaolo Bonzini     u64            mcastPktsRxOK;
9649ab747fSPaolo Bonzini     u64            mcastBytesRxOK;
9749ab747fSPaolo Bonzini     u64            bcastPktsRxOK;
9849ab747fSPaolo Bonzini     u64            bcastBytesRxOK;
9949ab747fSPaolo Bonzini     u64            pktsRxOutOfBuf;
10049ab747fSPaolo Bonzini     u64            pktsRxError;
10149ab747fSPaolo Bonzini };
10249ab747fSPaolo Bonzini 
10349ab747fSPaolo Bonzini /* interrupt moderation level */
10449ab747fSPaolo Bonzini enum {
10549ab747fSPaolo Bonzini     UPT1_IML_NONE        = 0, /* no interrupt moderation */
10649ab747fSPaolo Bonzini     UPT1_IML_HIGHEST    = 7, /* least intr generated */
10749ab747fSPaolo Bonzini     UPT1_IML_ADAPTIVE    = 8, /* adpative intr moderation */
10849ab747fSPaolo Bonzini };
10949ab747fSPaolo Bonzini /* values for UPT1_RSSConf.hashFunc */
11049ab747fSPaolo Bonzini enum {
11149ab747fSPaolo Bonzini     UPT1_RSS_HASH_TYPE_NONE      = 0x0,
11249ab747fSPaolo Bonzini     UPT1_RSS_HASH_TYPE_IPV4      = 0x01,
11349ab747fSPaolo Bonzini     UPT1_RSS_HASH_TYPE_TCP_IPV4  = 0x02,
11449ab747fSPaolo Bonzini     UPT1_RSS_HASH_TYPE_IPV6      = 0x04,
11549ab747fSPaolo Bonzini     UPT1_RSS_HASH_TYPE_TCP_IPV6  = 0x08,
11649ab747fSPaolo Bonzini };
11749ab747fSPaolo Bonzini 
11849ab747fSPaolo Bonzini enum {
11949ab747fSPaolo Bonzini     UPT1_RSS_HASH_FUNC_NONE      = 0x0,
12049ab747fSPaolo Bonzini     UPT1_RSS_HASH_FUNC_TOEPLITZ  = 0x01,
12149ab747fSPaolo Bonzini };
12249ab747fSPaolo Bonzini 
12349ab747fSPaolo Bonzini #define UPT1_RSS_MAX_KEY_SIZE        40
12449ab747fSPaolo Bonzini #define UPT1_RSS_MAX_IND_TABLE_SIZE  128
12549ab747fSPaolo Bonzini 
12649ab747fSPaolo Bonzini struct UPT1_RSSConf {
12749ab747fSPaolo Bonzini     u16            hashType;
12849ab747fSPaolo Bonzini     u16            hashFunc;
12949ab747fSPaolo Bonzini     u16            hashKeySize;
13049ab747fSPaolo Bonzini     u16            indTableSize;
13149ab747fSPaolo Bonzini     u8            hashKey[UPT1_RSS_MAX_KEY_SIZE];
13249ab747fSPaolo Bonzini     u8            indTable[UPT1_RSS_MAX_IND_TABLE_SIZE];
13349ab747fSPaolo Bonzini };
13449ab747fSPaolo Bonzini 
13549ab747fSPaolo Bonzini /* features */
13649ab747fSPaolo Bonzini enum {
13747b5264eSAnthony Liguori     UPT1_F_RXCSUM        = 0x0001, /* rx csum verification */
13847b5264eSAnthony Liguori     UPT1_F_RSS           = 0x0002,
13947b5264eSAnthony Liguori     UPT1_F_RXVLAN        = 0x0004, /* VLAN tag stripping */
14047b5264eSAnthony Liguori     UPT1_F_LRO           = 0x0008,
14149ab747fSPaolo Bonzini };
14249ab747fSPaolo Bonzini 
14349ab747fSPaolo Bonzini /* all registers are 32 bit wide */
14449ab747fSPaolo Bonzini /* BAR 1 */
14549ab747fSPaolo Bonzini enum {
14649ab747fSPaolo Bonzini     VMXNET3_REG_VRRS    = 0x0,    /* Vmxnet3 Revision Report Selection */
14749ab747fSPaolo Bonzini     VMXNET3_REG_UVRS    = 0x8,    /* UPT Version Report Selection */
14849ab747fSPaolo Bonzini     VMXNET3_REG_DSAL    = 0x10,    /* Driver Shared Address Low */
14949ab747fSPaolo Bonzini     VMXNET3_REG_DSAH    = 0x18,    /* Driver Shared Address High */
15049ab747fSPaolo Bonzini     VMXNET3_REG_CMD        = 0x20,    /* Command */
15149ab747fSPaolo Bonzini     VMXNET3_REG_MACL    = 0x28,    /* MAC Address Low */
15249ab747fSPaolo Bonzini     VMXNET3_REG_MACH    = 0x30,    /* MAC Address High */
15349ab747fSPaolo Bonzini     VMXNET3_REG_ICR        = 0x38,    /* Interrupt Cause Register */
15449ab747fSPaolo Bonzini     VMXNET3_REG_ECR        = 0x40    /* Event Cause Register */
15549ab747fSPaolo Bonzini };
15649ab747fSPaolo Bonzini 
15749ab747fSPaolo Bonzini /* BAR 0 */
15849ab747fSPaolo Bonzini enum {
15949ab747fSPaolo Bonzini     VMXNET3_REG_IMR        = 0x0,     /* Interrupt Mask Register */
16049ab747fSPaolo Bonzini     VMXNET3_REG_TXPROD    = 0x600, /* Tx Producer Index */
16149ab747fSPaolo Bonzini     VMXNET3_REG_RXPROD    = 0x800, /* Rx Producer Index for ring 1 */
16249ab747fSPaolo Bonzini     VMXNET3_REG_RXPROD2    = 0xA00     /* Rx Producer Index for ring 2 */
16349ab747fSPaolo Bonzini };
16449ab747fSPaolo Bonzini 
16549ab747fSPaolo Bonzini #define VMXNET3_PT_REG_SIZE     4096    /* BAR 0 */
16649ab747fSPaolo Bonzini #define VMXNET3_VD_REG_SIZE     4096    /* BAR 1 */
16749ab747fSPaolo Bonzini 
16849ab747fSPaolo Bonzini #define VMXNET3_REG_ALIGN       8    /* All registers are 8-byte aligned. */
16949ab747fSPaolo Bonzini #define VMXNET3_REG_ALIGN_MASK  0x7
17049ab747fSPaolo Bonzini 
17149ab747fSPaolo Bonzini /* I/O Mapped access to registers */
17249ab747fSPaolo Bonzini #define VMXNET3_IO_TYPE_PT              0
17349ab747fSPaolo Bonzini #define VMXNET3_IO_TYPE_VD              1
17449ab747fSPaolo Bonzini #define VMXNET3_IO_ADDR(type, reg)      (((type) << 24) | ((reg) & 0xFFFFFF))
17549ab747fSPaolo Bonzini #define VMXNET3_IO_TYPE(addr)           ((addr) >> 24)
17649ab747fSPaolo Bonzini #define VMXNET3_IO_REG(addr)            ((addr) & 0xFFFFFF)
17749ab747fSPaolo Bonzini 
17849ab747fSPaolo Bonzini enum {
17949ab747fSPaolo Bonzini     VMXNET3_CMD_FIRST_SET = 0xCAFE0000,
18049ab747fSPaolo Bonzini     VMXNET3_CMD_ACTIVATE_DEV = VMXNET3_CMD_FIRST_SET, /* 0xCAFE0000 */
18149ab747fSPaolo Bonzini     VMXNET3_CMD_QUIESCE_DEV,                          /* 0xCAFE0001 */
18249ab747fSPaolo Bonzini     VMXNET3_CMD_RESET_DEV,                            /* 0xCAFE0002 */
18349ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_RX_MODE,                       /* 0xCAFE0003 */
18449ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_MAC_FILTERS,                   /* 0xCAFE0004 */
18549ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_VLAN_FILTERS,                  /* 0xCAFE0005 */
18649ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_RSSIDT,                        /* 0xCAFE0006 */
18749ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_IML,                           /* 0xCAFE0007 */
18849ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_PMCFG,                         /* 0xCAFE0008 */
18949ab747fSPaolo Bonzini     VMXNET3_CMD_UPDATE_FEATURE,                       /* 0xCAFE0009 */
19049ab747fSPaolo Bonzini     VMXNET3_CMD_LOAD_PLUGIN,                          /* 0xCAFE000A */
19149ab747fSPaolo Bonzini 
19249ab747fSPaolo Bonzini     VMXNET3_CMD_FIRST_GET = 0xF00D0000,
19349ab747fSPaolo Bonzini     VMXNET3_CMD_GET_QUEUE_STATUS = VMXNET3_CMD_FIRST_GET, /* 0xF00D0000 */
19449ab747fSPaolo Bonzini     VMXNET3_CMD_GET_STATS,                                /* 0xF00D0001 */
19549ab747fSPaolo Bonzini     VMXNET3_CMD_GET_LINK,                                 /* 0xF00D0002 */
19649ab747fSPaolo Bonzini     VMXNET3_CMD_GET_PERM_MAC_LO,                          /* 0xF00D0003 */
19749ab747fSPaolo Bonzini     VMXNET3_CMD_GET_PERM_MAC_HI,                          /* 0xF00D0004 */
19849ab747fSPaolo Bonzini     VMXNET3_CMD_GET_DID_LO,                               /* 0xF00D0005 */
19949ab747fSPaolo Bonzini     VMXNET3_CMD_GET_DID_HI,                               /* 0xF00D0006 */
20049ab747fSPaolo Bonzini     VMXNET3_CMD_GET_DEV_EXTRA_INFO,                       /* 0xF00D0007 */
201d62241ebSShmulik Ladkani     VMXNET3_CMD_GET_CONF_INTR,                            /* 0xF00D0008 */
202d62241ebSShmulik Ladkani     VMXNET3_CMD_GET_ADAPTIVE_RING_INFO                    /* 0xF00D0009 */
20349ab747fSPaolo Bonzini };
20449ab747fSPaolo Bonzini 
205d62241ebSShmulik Ladkani /* Adaptive Ring Info Flags */
206d62241ebSShmulik Ladkani #define VMXNET3_DISABLE_ADAPTIVE_RING 1
207d62241ebSShmulik Ladkani 
20849ab747fSPaolo Bonzini /*
20949ab747fSPaolo Bonzini  *    Little Endian layout of bitfields -
21049ab747fSPaolo Bonzini  *    Byte 0 :    7.....len.....0
21149ab747fSPaolo Bonzini  *    Byte 1 :    rsvd gen 13.len.8
21249ab747fSPaolo Bonzini  *    Byte 2 :     5.msscof.0 ext1  dtype
21349ab747fSPaolo Bonzini  *    Byte 3 :     13...msscof...6
21449ab747fSPaolo Bonzini  *
21549ab747fSPaolo Bonzini  *    Big Endian layout of bitfields -
21649ab747fSPaolo Bonzini  *    Byte 0:        13...msscof...6
21749ab747fSPaolo Bonzini  *    Byte 1 :     5.msscof.0 ext1  dtype
21849ab747fSPaolo Bonzini  *    Byte 2 :    rsvd gen 13.len.8
21949ab747fSPaolo Bonzini  *    Byte 3 :    7.....len.....0
22049ab747fSPaolo Bonzini  *
22149ab747fSPaolo Bonzini  *    Thus, le32_to_cpu on the dword will allow the big endian driver to read
22249ab747fSPaolo Bonzini  *    the bit fields correctly. And cpu_to_le32 will convert bitfields
22349ab747fSPaolo Bonzini  *    bit fields written by big endian driver to format required by device.
22449ab747fSPaolo Bonzini  */
22549ab747fSPaolo Bonzini 
22649ab747fSPaolo Bonzini struct Vmxnet3_TxDesc {
22749ab747fSPaolo Bonzini     __le64 addr;
22849ab747fSPaolo Bonzini 
229c527e0afSThomas Huth     union {
230c527e0afSThomas Huth         struct {
23149ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
23249ab747fSPaolo Bonzini             u32 msscof:14;  /* MSS, checksum offset, flags */
23349ab747fSPaolo Bonzini             u32 ext1:1;
23449ab747fSPaolo Bonzini             u32 dtype:1;    /* descriptor type */
23549ab747fSPaolo Bonzini             u32 rsvd:1;
23649ab747fSPaolo Bonzini             u32 gen:1;      /* generation bit */
23749ab747fSPaolo Bonzini             u32 len:14;
23849ab747fSPaolo Bonzini #else
23949ab747fSPaolo Bonzini             u32 len:14;
24049ab747fSPaolo Bonzini             u32 gen:1;      /* generation bit */
24149ab747fSPaolo Bonzini             u32 rsvd:1;
24249ab747fSPaolo Bonzini             u32 dtype:1;    /* descriptor type */
24349ab747fSPaolo Bonzini             u32 ext1:1;
24449ab747fSPaolo Bonzini             u32 msscof:14;  /* MSS, checksum offset, flags */
24549ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
246c527e0afSThomas Huth         };
247c527e0afSThomas Huth         u32 val1;
248c527e0afSThomas Huth     };
24949ab747fSPaolo Bonzini 
250c527e0afSThomas Huth     union {
251c527e0afSThomas Huth         struct {
25249ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
25349ab747fSPaolo Bonzini             u32 tci:16;     /* Tag to Insert */
25449ab747fSPaolo Bonzini             u32 ti:1;       /* VLAN Tag Insertion */
25549ab747fSPaolo Bonzini             u32 ext2:1;
25649ab747fSPaolo Bonzini             u32 cq:1;       /* completion request */
25749ab747fSPaolo Bonzini             u32 eop:1;      /* End Of Packet */
25849ab747fSPaolo Bonzini             u32 om:2;       /* offload mode */
25949ab747fSPaolo Bonzini             u32 hlen:10;    /* header len */
26049ab747fSPaolo Bonzini #else
26149ab747fSPaolo Bonzini             u32 hlen:10;    /* header len */
26249ab747fSPaolo Bonzini             u32 om:2;       /* offload mode */
26349ab747fSPaolo Bonzini             u32 eop:1;      /* End Of Packet */
26449ab747fSPaolo Bonzini             u32 cq:1;       /* completion request */
26549ab747fSPaolo Bonzini             u32 ext2:1;
26649ab747fSPaolo Bonzini             u32 ti:1;       /* VLAN Tag Insertion */
26749ab747fSPaolo Bonzini             u32 tci:16;     /* Tag to Insert */
26849ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
26949ab747fSPaolo Bonzini         };
270c527e0afSThomas Huth         u32 val2;
271c527e0afSThomas Huth     };
272c527e0afSThomas Huth };
27349ab747fSPaolo Bonzini 
27449ab747fSPaolo Bonzini /* TxDesc.OM values */
27549ab747fSPaolo Bonzini #define VMXNET3_OM_NONE        0
27649ab747fSPaolo Bonzini #define VMXNET3_OM_CSUM        2
27749ab747fSPaolo Bonzini #define VMXNET3_OM_TSO        3
27849ab747fSPaolo Bonzini 
27949ab747fSPaolo Bonzini /* fields in TxDesc we access w/o using bit fields */
28049ab747fSPaolo Bonzini #define VMXNET3_TXD_EOP_SHIFT    12
28149ab747fSPaolo Bonzini #define VMXNET3_TXD_CQ_SHIFT    13
28249ab747fSPaolo Bonzini #define VMXNET3_TXD_GEN_SHIFT    14
28349ab747fSPaolo Bonzini #define VMXNET3_TXD_EOP_DWORD_SHIFT 3
28449ab747fSPaolo Bonzini #define VMXNET3_TXD_GEN_DWORD_SHIFT 2
28549ab747fSPaolo Bonzini 
28649ab747fSPaolo Bonzini #define VMXNET3_TXD_CQ        (1 << VMXNET3_TXD_CQ_SHIFT)
28749ab747fSPaolo Bonzini #define VMXNET3_TXD_EOP        (1 << VMXNET3_TXD_EOP_SHIFT)
28849ab747fSPaolo Bonzini #define VMXNET3_TXD_GEN        (1 << VMXNET3_TXD_GEN_SHIFT)
28949ab747fSPaolo Bonzini 
29049ab747fSPaolo Bonzini #define VMXNET3_HDR_COPY_SIZE   128
29149ab747fSPaolo Bonzini 
29249ab747fSPaolo Bonzini 
29349ab747fSPaolo Bonzini struct Vmxnet3_TxDataDesc {
29449ab747fSPaolo Bonzini     u8        data[VMXNET3_HDR_COPY_SIZE];
29549ab747fSPaolo Bonzini };
29649ab747fSPaolo Bonzini 
29749ab747fSPaolo Bonzini #define VMXNET3_TCD_GEN_SHIFT    31
29849ab747fSPaolo Bonzini #define VMXNET3_TCD_GEN_SIZE    1
29949ab747fSPaolo Bonzini #define VMXNET3_TCD_TXIDX_SHIFT    0
30049ab747fSPaolo Bonzini #define VMXNET3_TCD_TXIDX_SIZE    12
30149ab747fSPaolo Bonzini #define VMXNET3_TCD_GEN_DWORD_SHIFT    3
30249ab747fSPaolo Bonzini 
30349ab747fSPaolo Bonzini struct Vmxnet3_TxCompDesc {
304c527e0afSThomas Huth     union {
305c527e0afSThomas Huth         struct {
306c527e0afSThomas Huth #ifdef __BIG_ENDIAN_BITFIELD
307c527e0afSThomas Huth             u32 ext1:20;
308c527e0afSThomas Huth             u32 txdIdx:12;    /* Index of the EOP TxDesc */
309c527e0afSThomas Huth #else
31049ab747fSPaolo Bonzini             u32 txdIdx:12;    /* Index of the EOP TxDesc */
31149ab747fSPaolo Bonzini             u32 ext1:20;
312c527e0afSThomas Huth #endif
313c527e0afSThomas Huth         };
314c527e0afSThomas Huth         u32 val1;
315c527e0afSThomas Huth     };
31649ab747fSPaolo Bonzini     __le32        ext2;
31749ab747fSPaolo Bonzini     __le32        ext3;
31849ab747fSPaolo Bonzini 
319c527e0afSThomas Huth     union {
320c527e0afSThomas Huth         struct {
321c527e0afSThomas Huth #ifdef __BIG_ENDIAN_BITFIELD
322c527e0afSThomas Huth             u32 gen:1;        /* generation bit */
323c527e0afSThomas Huth             u32 type:7;       /* completion type */
324c527e0afSThomas Huth             u32 rsvd:24;
325c527e0afSThomas Huth #else
32649ab747fSPaolo Bonzini             u32 rsvd:24;
32749ab747fSPaolo Bonzini             u32 type:7;       /* completion type */
32849ab747fSPaolo Bonzini             u32 gen:1;        /* generation bit */
329c527e0afSThomas Huth #endif
330c527e0afSThomas Huth         };
331c527e0afSThomas Huth         u32 val2;
332c527e0afSThomas Huth     };
33349ab747fSPaolo Bonzini };
33449ab747fSPaolo Bonzini 
33549ab747fSPaolo Bonzini struct Vmxnet3_RxDesc {
33649ab747fSPaolo Bonzini     __le64        addr;
337c527e0afSThomas Huth     union {
338c527e0afSThomas Huth         struct {
33949ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
34049ab747fSPaolo Bonzini             u32 gen:1;        /* Generation bit */
34149ab747fSPaolo Bonzini             u32 rsvd:15;
34249ab747fSPaolo Bonzini             u32 dtype:1;      /* Descriptor type */
34349ab747fSPaolo Bonzini             u32 btype:1;      /* Buffer Type */
34449ab747fSPaolo Bonzini             u32 len:14;
34549ab747fSPaolo Bonzini #else
34649ab747fSPaolo Bonzini             u32 len:14;
34749ab747fSPaolo Bonzini             u32 btype:1;      /* Buffer Type */
34849ab747fSPaolo Bonzini             u32 dtype:1;      /* Descriptor type */
34949ab747fSPaolo Bonzini             u32 rsvd:15;
35049ab747fSPaolo Bonzini             u32 gen:1;        /* Generation bit */
35149ab747fSPaolo Bonzini #endif
352c527e0afSThomas Huth         };
353c527e0afSThomas Huth         u32 val1;
354c527e0afSThomas Huth     };
35549ab747fSPaolo Bonzini     u32        ext1;
35649ab747fSPaolo Bonzini };
35749ab747fSPaolo Bonzini 
35849ab747fSPaolo Bonzini /* values of RXD.BTYPE */
35949ab747fSPaolo Bonzini #define VMXNET3_RXD_BTYPE_HEAD   0    /* head only */
36049ab747fSPaolo Bonzini #define VMXNET3_RXD_BTYPE_BODY   1    /* body only */
36149ab747fSPaolo Bonzini 
36249ab747fSPaolo Bonzini /* fields in RxDesc we access w/o using bit fields */
36349ab747fSPaolo Bonzini #define VMXNET3_RXD_BTYPE_SHIFT  14
36449ab747fSPaolo Bonzini #define VMXNET3_RXD_GEN_SHIFT    31
36549ab747fSPaolo Bonzini 
36649ab747fSPaolo Bonzini struct Vmxnet3_RxCompDesc {
367c527e0afSThomas Huth     union {
368c527e0afSThomas Huth         struct {
36949ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
37049ab747fSPaolo Bonzini             u32 ext2:1;
37149ab747fSPaolo Bonzini             u32 cnc:1;        /* Checksum Not Calculated */
37249ab747fSPaolo Bonzini             u32 rssType:4;    /* RSS hash type used */
37349ab747fSPaolo Bonzini             u32 rqID:10;      /* rx queue/ring ID */
37449ab747fSPaolo Bonzini             u32 sop:1;        /* Start of Packet */
37549ab747fSPaolo Bonzini             u32 eop:1;        /* End of Packet */
37649ab747fSPaolo Bonzini             u32 ext1:2;
37749ab747fSPaolo Bonzini             u32 rxdIdx:12;    /* Index of the RxDesc */
37849ab747fSPaolo Bonzini #else
37949ab747fSPaolo Bonzini             u32 rxdIdx:12;    /* Index of the RxDesc */
38049ab747fSPaolo Bonzini             u32 ext1:2;
38149ab747fSPaolo Bonzini             u32 eop:1;        /* End of Packet */
38249ab747fSPaolo Bonzini             u32 sop:1;        /* Start of Packet */
38349ab747fSPaolo Bonzini             u32 rqID:10;      /* rx queue/ring ID */
38449ab747fSPaolo Bonzini             u32 rssType:4;    /* RSS hash type used */
38549ab747fSPaolo Bonzini             u32 cnc:1;        /* Checksum Not Calculated */
38649ab747fSPaolo Bonzini             u32 ext2:1;
38749ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
388c527e0afSThomas Huth         };
389c527e0afSThomas Huth         u32 val1;
390c527e0afSThomas Huth     };
39149ab747fSPaolo Bonzini 
39249ab747fSPaolo Bonzini     __le32        rssHash;      /* RSS hash value */
39349ab747fSPaolo Bonzini 
394c527e0afSThomas Huth     union {
395c527e0afSThomas Huth         struct {
39649ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
39749ab747fSPaolo Bonzini             u32 tci:16;       /* Tag stripped */
39849ab747fSPaolo Bonzini             u32 ts:1;         /* Tag is stripped */
39949ab747fSPaolo Bonzini             u32 err:1;        /* Error */
40049ab747fSPaolo Bonzini             u32 len:14;       /* data length */
40149ab747fSPaolo Bonzini #else
40249ab747fSPaolo Bonzini             u32 len:14;       /* data length */
40349ab747fSPaolo Bonzini             u32 err:1;        /* Error */
40449ab747fSPaolo Bonzini             u32 ts:1;         /* Tag is stripped */
40549ab747fSPaolo Bonzini             u32 tci:16;       /* Tag stripped */
40649ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
407c527e0afSThomas Huth         };
408c527e0afSThomas Huth         u32 val2;
409c527e0afSThomas Huth     };
41049ab747fSPaolo Bonzini 
411c527e0afSThomas Huth     union {
412c527e0afSThomas Huth         struct {
41349ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
41449ab747fSPaolo Bonzini             u32 gen:1;        /* generation bit */
41549ab747fSPaolo Bonzini             u32 type:7;       /* completion type */
41649ab747fSPaolo Bonzini             u32 fcs:1;        /* Frame CRC correct */
41749ab747fSPaolo Bonzini             u32 frg:1;        /* IP Fragment */
41849ab747fSPaolo Bonzini             u32 v4:1;         /* IPv4 */
41949ab747fSPaolo Bonzini             u32 v6:1;         /* IPv6 */
42049ab747fSPaolo Bonzini             u32 ipc:1;        /* IP Checksum Correct */
42149ab747fSPaolo Bonzini             u32 tcp:1;        /* TCP packet */
42249ab747fSPaolo Bonzini             u32 udp:1;        /* UDP packet */
42349ab747fSPaolo Bonzini             u32 tuc:1;        /* TCP/UDP Checksum Correct */
42449ab747fSPaolo Bonzini             u32 csum:16;
42549ab747fSPaolo Bonzini #else
42649ab747fSPaolo Bonzini             u32 csum:16;
42749ab747fSPaolo Bonzini             u32 tuc:1;        /* TCP/UDP Checksum Correct */
42849ab747fSPaolo Bonzini             u32 udp:1;        /* UDP packet */
42949ab747fSPaolo Bonzini             u32 tcp:1;        /* TCP packet */
43049ab747fSPaolo Bonzini             u32 ipc:1;        /* IP Checksum Correct */
43149ab747fSPaolo Bonzini             u32 v6:1;         /* IPv6 */
43249ab747fSPaolo Bonzini             u32 v4:1;         /* IPv4 */
43349ab747fSPaolo Bonzini             u32 frg:1;        /* IP Fragment */
43449ab747fSPaolo Bonzini             u32 fcs:1;        /* Frame CRC correct */
43549ab747fSPaolo Bonzini             u32 type:7;       /* completion type */
43649ab747fSPaolo Bonzini             u32 gen:1;        /* generation bit */
43749ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
43849ab747fSPaolo Bonzini         };
439c527e0afSThomas Huth         u32 val3;
440c527e0afSThomas Huth     };
441c527e0afSThomas Huth };
44249ab747fSPaolo Bonzini 
44349ab747fSPaolo Bonzini /* fields in RxCompDesc we access via Vmxnet3_GenericDesc.dword[3] */
44449ab747fSPaolo Bonzini #define VMXNET3_RCD_TUC_SHIFT    16
44549ab747fSPaolo Bonzini #define VMXNET3_RCD_IPC_SHIFT    19
44649ab747fSPaolo Bonzini 
44749ab747fSPaolo Bonzini /* fields in RxCompDesc we access via Vmxnet3_GenericDesc.qword[1] */
44849ab747fSPaolo Bonzini #define VMXNET3_RCD_TYPE_SHIFT    56
44949ab747fSPaolo Bonzini #define VMXNET3_RCD_GEN_SHIFT    63
45049ab747fSPaolo Bonzini 
45149ab747fSPaolo Bonzini /* csum OK for TCP/UDP pkts over IP */
45249ab747fSPaolo Bonzini #define VMXNET3_RCD_CSUM_OK (1 << VMXNET3_RCD_TUC_SHIFT | \
45349ab747fSPaolo Bonzini                      1 << VMXNET3_RCD_IPC_SHIFT)
45449ab747fSPaolo Bonzini #define VMXNET3_TXD_GEN_SIZE 1
45549ab747fSPaolo Bonzini #define VMXNET3_TXD_EOP_SIZE 1
45649ab747fSPaolo Bonzini 
45749ab747fSPaolo Bonzini /* value of RxCompDesc.rssType */
45849ab747fSPaolo Bonzini enum {
45949ab747fSPaolo Bonzini     VMXNET3_RCD_RSS_TYPE_NONE     = 0,
46049ab747fSPaolo Bonzini     VMXNET3_RCD_RSS_TYPE_IPV4     = 1,
46149ab747fSPaolo Bonzini     VMXNET3_RCD_RSS_TYPE_TCPIPV4  = 2,
46249ab747fSPaolo Bonzini     VMXNET3_RCD_RSS_TYPE_IPV6     = 3,
46349ab747fSPaolo Bonzini     VMXNET3_RCD_RSS_TYPE_TCPIPV6  = 4,
46449ab747fSPaolo Bonzini };
46549ab747fSPaolo Bonzini 
46649ab747fSPaolo Bonzini 
46749ab747fSPaolo Bonzini /* a union for accessing all cmd/completion descriptors */
46849ab747fSPaolo Bonzini union Vmxnet3_GenericDesc {
46949ab747fSPaolo Bonzini     __le64                qword[2];
47049ab747fSPaolo Bonzini     __le32                dword[4];
47149ab747fSPaolo Bonzini     __le16                word[8];
47249ab747fSPaolo Bonzini     struct Vmxnet3_TxDesc        txd;
47349ab747fSPaolo Bonzini     struct Vmxnet3_RxDesc        rxd;
47449ab747fSPaolo Bonzini     struct Vmxnet3_TxCompDesc    tcd;
47549ab747fSPaolo Bonzini     struct Vmxnet3_RxCompDesc    rcd;
47649ab747fSPaolo Bonzini };
47749ab747fSPaolo Bonzini 
47849ab747fSPaolo Bonzini #define VMXNET3_INIT_GEN       1
47949ab747fSPaolo Bonzini 
48049ab747fSPaolo Bonzini /* Max size of a single tx buffer */
48149ab747fSPaolo Bonzini #define VMXNET3_MAX_TX_BUF_SIZE  (1 << 14)
48249ab747fSPaolo Bonzini 
48349ab747fSPaolo Bonzini /* # of tx desc needed for a tx buffer size */
48449ab747fSPaolo Bonzini #define VMXNET3_TXD_NEEDED(size) (((size) + VMXNET3_MAX_TX_BUF_SIZE - 1) / \
48549ab747fSPaolo Bonzini                     VMXNET3_MAX_TX_BUF_SIZE)
48649ab747fSPaolo Bonzini 
48749ab747fSPaolo Bonzini /* max # of tx descs for a non-tso pkt */
48849ab747fSPaolo Bonzini #define VMXNET3_MAX_TXD_PER_PKT 16
48949ab747fSPaolo Bonzini 
49049ab747fSPaolo Bonzini /* Max size of a single rx buffer */
49149ab747fSPaolo Bonzini #define VMXNET3_MAX_RX_BUF_SIZE  ((1 << 14) - 1)
49249ab747fSPaolo Bonzini /* Minimum size of a type 0 buffer */
49349ab747fSPaolo Bonzini #define VMXNET3_MIN_T0_BUF_SIZE  128
49449ab747fSPaolo Bonzini #define VMXNET3_MAX_CSUM_OFFSET  1024
49549ab747fSPaolo Bonzini 
49649ab747fSPaolo Bonzini /* Ring base address alignment */
49749ab747fSPaolo Bonzini #define VMXNET3_RING_BA_ALIGN   512
49849ab747fSPaolo Bonzini #define VMXNET3_RING_BA_MASK    (VMXNET3_RING_BA_ALIGN - 1)
49949ab747fSPaolo Bonzini 
50049ab747fSPaolo Bonzini /* Ring size must be a multiple of 32 */
50149ab747fSPaolo Bonzini #define VMXNET3_RING_SIZE_ALIGN 32
50249ab747fSPaolo Bonzini #define VMXNET3_RING_SIZE_MASK  (VMXNET3_RING_SIZE_ALIGN - 1)
50349ab747fSPaolo Bonzini 
50449ab747fSPaolo Bonzini /* Max ring size */
50549ab747fSPaolo Bonzini #define VMXNET3_TX_RING_MAX_SIZE   4096
50649ab747fSPaolo Bonzini #define VMXNET3_TC_RING_MAX_SIZE   4096
50749ab747fSPaolo Bonzini #define VMXNET3_RX_RING_MAX_SIZE   4096
50849ab747fSPaolo Bonzini #define VMXNET3_RC_RING_MAX_SIZE   8192
50949ab747fSPaolo Bonzini 
51049ab747fSPaolo Bonzini /* a list of reasons for queue stop */
51149ab747fSPaolo Bonzini 
51249ab747fSPaolo Bonzini enum {
51349ab747fSPaolo Bonzini  VMXNET3_ERR_NOEOP        = 0x80000000, /* cannot find the EOP desc of a pkt */
51449ab747fSPaolo Bonzini  VMXNET3_ERR_TXD_REUSE    = 0x80000001, /* reuse TxDesc before tx completion */
51549ab747fSPaolo Bonzini  VMXNET3_ERR_BIG_PKT      = 0x80000002, /* too many TxDesc for a pkt */
51649ab747fSPaolo Bonzini  VMXNET3_ERR_DESC_NOT_SPT = 0x80000003, /* descriptor type not supported */
51749ab747fSPaolo Bonzini  VMXNET3_ERR_SMALL_BUF    = 0x80000004, /* type 0 buffer too small */
51849ab747fSPaolo Bonzini  VMXNET3_ERR_STRESS       = 0x80000005, /* stress option firing in vmkernel */
51949ab747fSPaolo Bonzini  VMXNET3_ERR_SWITCH       = 0x80000006, /* mode switch failure */
52049ab747fSPaolo Bonzini  VMXNET3_ERR_TXD_INVALID  = 0x80000007, /* invalid TxDesc */
52149ab747fSPaolo Bonzini };
52249ab747fSPaolo Bonzini 
52349ab747fSPaolo Bonzini /* completion descriptor types */
52449ab747fSPaolo Bonzini #define VMXNET3_CDTYPE_TXCOMP      0    /* Tx Completion Descriptor */
52549ab747fSPaolo Bonzini #define VMXNET3_CDTYPE_RXCOMP      3    /* Rx Completion Descriptor */
52649ab747fSPaolo Bonzini 
52749ab747fSPaolo Bonzini enum {
52849ab747fSPaolo Bonzini     VMXNET3_GOS_BITS_UNK    = 0,   /* unknown */
52949ab747fSPaolo Bonzini     VMXNET3_GOS_BITS_32     = 1,
53049ab747fSPaolo Bonzini     VMXNET3_GOS_BITS_64     = 2,
53149ab747fSPaolo Bonzini };
53249ab747fSPaolo Bonzini 
53349ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_UNK        0 /* unknown */
53449ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_LINUX      1
53549ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_WIN        2
53649ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_SOLARIS    3
53749ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_FREEBSD    4
53849ab747fSPaolo Bonzini #define VMXNET3_GOS_TYPE_PXE        5
53949ab747fSPaolo Bonzini 
54049ab747fSPaolo Bonzini struct Vmxnet3_GOSInfo {
54149ab747fSPaolo Bonzini #ifdef __BIG_ENDIAN_BITFIELD
54249ab747fSPaolo Bonzini     u32        gosMisc:10;    /* other info about gos */
54349ab747fSPaolo Bonzini     u32        gosVer:16;     /* gos version */
54449ab747fSPaolo Bonzini     u32        gosType:4;     /* which guest */
54549ab747fSPaolo Bonzini     u32        gosBits:2;    /* 32-bit or 64-bit? */
54649ab747fSPaolo Bonzini #else
54749ab747fSPaolo Bonzini     u32        gosBits:2;     /* 32-bit or 64-bit? */
54849ab747fSPaolo Bonzini     u32        gosType:4;     /* which guest */
54949ab747fSPaolo Bonzini     u32        gosVer:16;     /* gos version */
55049ab747fSPaolo Bonzini     u32        gosMisc:10;    /* other info about gos */
55149ab747fSPaolo Bonzini #endif  /* __BIG_ENDIAN_BITFIELD */
55249ab747fSPaolo Bonzini };
55349ab747fSPaolo Bonzini 
55449ab747fSPaolo Bonzini struct Vmxnet3_DriverInfo {
55549ab747fSPaolo Bonzini     __le32                version;
55649ab747fSPaolo Bonzini     struct Vmxnet3_GOSInfo        gos;
55749ab747fSPaolo Bonzini     __le32                vmxnet3RevSpt;
55849ab747fSPaolo Bonzini     __le32                uptVerSpt;
55949ab747fSPaolo Bonzini };
56049ab747fSPaolo Bonzini 
56149ab747fSPaolo Bonzini 
56249ab747fSPaolo Bonzini #define VMXNET3_REV1_MAGIC  0xbabefee1
56349ab747fSPaolo Bonzini 
56449ab747fSPaolo Bonzini /*
56549ab747fSPaolo Bonzini  * QueueDescPA must be 128 bytes aligned. It points to an array of
56649ab747fSPaolo Bonzini  * Vmxnet3_TxQueueDesc followed by an array of Vmxnet3_RxQueueDesc.
56749ab747fSPaolo Bonzini  * The number of Vmxnet3_TxQueueDesc/Vmxnet3_RxQueueDesc are specified by
56849ab747fSPaolo Bonzini  * Vmxnet3_MiscConf.numTxQueues/numRxQueues, respectively.
56949ab747fSPaolo Bonzini  */
57049ab747fSPaolo Bonzini #define VMXNET3_QUEUE_DESC_ALIGN  128
57149ab747fSPaolo Bonzini 
57249ab747fSPaolo Bonzini 
57349ab747fSPaolo Bonzini struct Vmxnet3_MiscConf {
57449ab747fSPaolo Bonzini     struct Vmxnet3_DriverInfo driverInfo;
57549ab747fSPaolo Bonzini     __le64        uptFeatures;
57649ab747fSPaolo Bonzini     __le64        ddPA;         /* driver data PA */
57749ab747fSPaolo Bonzini     __le64        queueDescPA;  /* queue descriptor table PA */
57849ab747fSPaolo Bonzini     __le32        ddLen;        /* driver data len */
57949ab747fSPaolo Bonzini     __le32        queueDescLen; /* queue desc. table len in bytes */
58049ab747fSPaolo Bonzini     __le32        mtu;
58149ab747fSPaolo Bonzini     __le16        maxNumRxSG;
58249ab747fSPaolo Bonzini     u8        numTxQueues;
58349ab747fSPaolo Bonzini     u8        numRxQueues;
58449ab747fSPaolo Bonzini     __le32        reserved[4];
58549ab747fSPaolo Bonzini };
58649ab747fSPaolo Bonzini 
58749ab747fSPaolo Bonzini 
58849ab747fSPaolo Bonzini struct Vmxnet3_TxQueueConf {
58949ab747fSPaolo Bonzini     __le64        txRingBasePA;
59049ab747fSPaolo Bonzini     __le64        dataRingBasePA;
59149ab747fSPaolo Bonzini     __le64        compRingBasePA;
59249ab747fSPaolo Bonzini     __le64        ddPA;         /* driver data */
59349ab747fSPaolo Bonzini     __le64        reserved;
59449ab747fSPaolo Bonzini     __le32        txRingSize;   /* # of tx desc */
59549ab747fSPaolo Bonzini     __le32        dataRingSize; /* # of data desc */
59649ab747fSPaolo Bonzini     __le32        compRingSize; /* # of comp desc */
59749ab747fSPaolo Bonzini     __le32        ddLen;        /* size of driver data */
59849ab747fSPaolo Bonzini     u8        intrIdx;
59949ab747fSPaolo Bonzini     u8        _pad[7];
60049ab747fSPaolo Bonzini };
60149ab747fSPaolo Bonzini 
60249ab747fSPaolo Bonzini 
60349ab747fSPaolo Bonzini struct Vmxnet3_RxQueueConf {
60449ab747fSPaolo Bonzini     __le64        rxRingBasePA[2];
60549ab747fSPaolo Bonzini     __le64        compRingBasePA;
60649ab747fSPaolo Bonzini     __le64        ddPA;            /* driver data */
60749ab747fSPaolo Bonzini     __le64        reserved;
60849ab747fSPaolo Bonzini     __le32        rxRingSize[2];   /* # of rx desc */
60949ab747fSPaolo Bonzini     __le32        compRingSize;    /* # of rx comp desc */
61049ab747fSPaolo Bonzini     __le32        ddLen;           /* size of driver data */
61149ab747fSPaolo Bonzini     u8        intrIdx;
61249ab747fSPaolo Bonzini     u8        _pad[7];
61349ab747fSPaolo Bonzini };
61449ab747fSPaolo Bonzini 
61549ab747fSPaolo Bonzini 
61649ab747fSPaolo Bonzini enum vmxnet3_intr_mask_mode {
61749ab747fSPaolo Bonzini     VMXNET3_IMM_AUTO   = 0,
61849ab747fSPaolo Bonzini     VMXNET3_IMM_ACTIVE = 1,
61949ab747fSPaolo Bonzini     VMXNET3_IMM_LAZY   = 2
62049ab747fSPaolo Bonzini };
62149ab747fSPaolo Bonzini 
62249ab747fSPaolo Bonzini enum vmxnet3_intr_type {
62349ab747fSPaolo Bonzini     VMXNET3_IT_AUTO = 0,
62449ab747fSPaolo Bonzini     VMXNET3_IT_INTX = 1,
62549ab747fSPaolo Bonzini     VMXNET3_IT_MSI  = 2,
62649ab747fSPaolo Bonzini     VMXNET3_IT_MSIX = 3
62749ab747fSPaolo Bonzini };
62849ab747fSPaolo Bonzini 
62949ab747fSPaolo Bonzini #define VMXNET3_MAX_TX_QUEUES  8
63049ab747fSPaolo Bonzini #define VMXNET3_MAX_RX_QUEUES  16
63149ab747fSPaolo Bonzini /* addition 1 for events */
63249ab747fSPaolo Bonzini #define VMXNET3_MAX_INTRS      25
63349ab747fSPaolo Bonzini 
63449ab747fSPaolo Bonzini /* value of intrCtrl */
63549ab747fSPaolo Bonzini #define VMXNET3_IC_DISABLE_ALL  0x1   /* bit 0 */
63649ab747fSPaolo Bonzini 
63749ab747fSPaolo Bonzini 
63849ab747fSPaolo Bonzini struct Vmxnet3_IntrConf {
63949ab747fSPaolo Bonzini     bool        autoMask;
64049ab747fSPaolo Bonzini     u8        numIntrs;      /* # of interrupts */
64149ab747fSPaolo Bonzini     u8        eventIntrIdx;
64249ab747fSPaolo Bonzini     u8        modLevels[VMXNET3_MAX_INTRS];    /* moderation level for
64349ab747fSPaolo Bonzini                              * each intr */
64449ab747fSPaolo Bonzini     __le32        intrCtrl;
64549ab747fSPaolo Bonzini     __le32        reserved[2];
64649ab747fSPaolo Bonzini };
64749ab747fSPaolo Bonzini 
64849ab747fSPaolo Bonzini /* one bit per VLAN ID, the size is in the units of u32 */
64949ab747fSPaolo Bonzini #define VMXNET3_VFT_SIZE  (4096/(sizeof(uint32_t)*8))
65049ab747fSPaolo Bonzini 
65149ab747fSPaolo Bonzini 
65249ab747fSPaolo Bonzini struct Vmxnet3_QueueStatus {
65349ab747fSPaolo Bonzini     bool        stopped;
65449ab747fSPaolo Bonzini     u8        _pad[3];
65549ab747fSPaolo Bonzini     __le32        error;
65649ab747fSPaolo Bonzini };
65749ab747fSPaolo Bonzini 
65849ab747fSPaolo Bonzini 
65949ab747fSPaolo Bonzini struct Vmxnet3_TxQueueCtrl {
66049ab747fSPaolo Bonzini     __le32        txNumDeferred;
66149ab747fSPaolo Bonzini     __le32        txThreshold;
66249ab747fSPaolo Bonzini     __le64        reserved;
66349ab747fSPaolo Bonzini };
66449ab747fSPaolo Bonzini 
66549ab747fSPaolo Bonzini 
66649ab747fSPaolo Bonzini struct Vmxnet3_RxQueueCtrl {
66749ab747fSPaolo Bonzini     bool        updateRxProd;
66849ab747fSPaolo Bonzini     u8        _pad[7];
66949ab747fSPaolo Bonzini     __le64        reserved;
67049ab747fSPaolo Bonzini };
67149ab747fSPaolo Bonzini 
67249ab747fSPaolo Bonzini enum {
67349ab747fSPaolo Bonzini     VMXNET3_RXM_UCAST     = 0x01,  /* unicast only */
67449ab747fSPaolo Bonzini     VMXNET3_RXM_MCAST     = 0x02,  /* multicast passing the filters */
67549ab747fSPaolo Bonzini     VMXNET3_RXM_BCAST     = 0x04,  /* broadcast only */
67649ab747fSPaolo Bonzini     VMXNET3_RXM_ALL_MULTI = 0x08,  /* all multicast */
67749ab747fSPaolo Bonzini     VMXNET3_RXM_PROMISC   = 0x10  /* promiscuous */
67849ab747fSPaolo Bonzini };
67949ab747fSPaolo Bonzini 
68049ab747fSPaolo Bonzini struct Vmxnet3_RxFilterConf {
68149ab747fSPaolo Bonzini     __le32        rxMode;       /* VMXNET3_RXM_xxx */
68249ab747fSPaolo Bonzini     __le16        mfTableLen;   /* size of the multicast filter table */
68349ab747fSPaolo Bonzini     __le16        _pad1;
68449ab747fSPaolo Bonzini     __le64        mfTablePA;    /* PA of the multicast filters table */
68549ab747fSPaolo Bonzini     __le32        vfTable[VMXNET3_VFT_SIZE]; /* vlan filter */
68649ab747fSPaolo Bonzini };
68749ab747fSPaolo Bonzini 
68849ab747fSPaolo Bonzini 
68949ab747fSPaolo Bonzini #define VMXNET3_PM_MAX_FILTERS        6
69049ab747fSPaolo Bonzini #define VMXNET3_PM_MAX_PATTERN_SIZE   128
69149ab747fSPaolo Bonzini #define VMXNET3_PM_MAX_MASK_SIZE      (VMXNET3_PM_MAX_PATTERN_SIZE / 8)
69249ab747fSPaolo Bonzini 
69349ab747fSPaolo Bonzini #define VMXNET3_PM_WAKEUP_MAGIC  cpu_to_le16(0x01)  /* wake up on magic pkts */
69449ab747fSPaolo Bonzini #define VMXNET3_PM_WAKEUP_FILTER cpu_to_le16(0x02)  /* wake up on pkts matching
69549ab747fSPaolo Bonzini                                                      * filters */
69649ab747fSPaolo Bonzini 
69749ab747fSPaolo Bonzini 
69849ab747fSPaolo Bonzini struct Vmxnet3_PM_PktFilter {
69949ab747fSPaolo Bonzini     u8        maskSize;
70049ab747fSPaolo Bonzini     u8        patternSize;
70149ab747fSPaolo Bonzini     u8        mask[VMXNET3_PM_MAX_MASK_SIZE];
70249ab747fSPaolo Bonzini     u8        pattern[VMXNET3_PM_MAX_PATTERN_SIZE];
70349ab747fSPaolo Bonzini     u8        pad[6];
70449ab747fSPaolo Bonzini };
70549ab747fSPaolo Bonzini 
70649ab747fSPaolo Bonzini 
70749ab747fSPaolo Bonzini struct Vmxnet3_PMConf {
70849ab747fSPaolo Bonzini     __le16        wakeUpEvents;  /* VMXNET3_PM_WAKEUP_xxx */
70949ab747fSPaolo Bonzini     u8        numFilters;
71049ab747fSPaolo Bonzini     u8        pad[5];
71149ab747fSPaolo Bonzini     struct Vmxnet3_PM_PktFilter filters[VMXNET3_PM_MAX_FILTERS];
71249ab747fSPaolo Bonzini };
71349ab747fSPaolo Bonzini 
71449ab747fSPaolo Bonzini 
71549ab747fSPaolo Bonzini struct Vmxnet3_VariableLenConfDesc {
71649ab747fSPaolo Bonzini     __le32        confVer;
71749ab747fSPaolo Bonzini     __le32        confLen;
71849ab747fSPaolo Bonzini     __le64        confPA;
71949ab747fSPaolo Bonzini };
72049ab747fSPaolo Bonzini 
72149ab747fSPaolo Bonzini 
72249ab747fSPaolo Bonzini struct Vmxnet3_TxQueueDesc {
72349ab747fSPaolo Bonzini     struct Vmxnet3_TxQueueCtrl        ctrl;
72449ab747fSPaolo Bonzini     struct Vmxnet3_TxQueueConf        conf;
72549ab747fSPaolo Bonzini 
72649ab747fSPaolo Bonzini     /* Driver read after a GET command */
72749ab747fSPaolo Bonzini     struct Vmxnet3_QueueStatus        status;
72849ab747fSPaolo Bonzini     struct UPT1_TxStats            stats;
72949ab747fSPaolo Bonzini     u8                    _pad[88]; /* 128 aligned */
73049ab747fSPaolo Bonzini };
73149ab747fSPaolo Bonzini 
73249ab747fSPaolo Bonzini 
73349ab747fSPaolo Bonzini struct Vmxnet3_RxQueueDesc {
73449ab747fSPaolo Bonzini     struct Vmxnet3_RxQueueCtrl        ctrl;
73549ab747fSPaolo Bonzini     struct Vmxnet3_RxQueueConf        conf;
7362431f4f1SMichael Tokarev     /* Driver read after a GET command */
73749ab747fSPaolo Bonzini     struct Vmxnet3_QueueStatus        status;
73849ab747fSPaolo Bonzini     struct UPT1_RxStats            stats;
73949ab747fSPaolo Bonzini     u8                      __pad[88]; /* 128 aligned */
74049ab747fSPaolo Bonzini };
74149ab747fSPaolo Bonzini 
74249ab747fSPaolo Bonzini 
74349ab747fSPaolo Bonzini struct Vmxnet3_DSDevRead {
74449ab747fSPaolo Bonzini     /* read-only region for device, read by dev in response to a SET cmd */
74549ab747fSPaolo Bonzini     struct Vmxnet3_MiscConf            misc;
74649ab747fSPaolo Bonzini     struct Vmxnet3_IntrConf            intrConf;
74749ab747fSPaolo Bonzini     struct Vmxnet3_RxFilterConf        rxFilterConf;
74849ab747fSPaolo Bonzini     struct Vmxnet3_VariableLenConfDesc    rssConfDesc;
74949ab747fSPaolo Bonzini     struct Vmxnet3_VariableLenConfDesc    pmConfDesc;
75049ab747fSPaolo Bonzini     struct Vmxnet3_VariableLenConfDesc    pluginConfDesc;
75149ab747fSPaolo Bonzini };
75249ab747fSPaolo Bonzini 
75349ab747fSPaolo Bonzini /* All structures in DriverShared are padded to multiples of 8 bytes */
75449ab747fSPaolo Bonzini struct Vmxnet3_DriverShared {
75549ab747fSPaolo Bonzini     __le32              magic;
75649ab747fSPaolo Bonzini     /* make devRead start at 64bit boundaries */
75749ab747fSPaolo Bonzini     __le32              pad;
75849ab747fSPaolo Bonzini     struct Vmxnet3_DSDevRead    devRead;
75949ab747fSPaolo Bonzini     __le32              ecr;
76049ab747fSPaolo Bonzini     __le32              reserved[5];
76149ab747fSPaolo Bonzini };
76249ab747fSPaolo Bonzini 
76349ab747fSPaolo Bonzini 
76449ab747fSPaolo Bonzini #define VMXNET3_ECR_RQERR       (1 << 0)
76549ab747fSPaolo Bonzini #define VMXNET3_ECR_TQERR       (1 << 1)
76649ab747fSPaolo Bonzini #define VMXNET3_ECR_LINK        (1 << 2)
76749ab747fSPaolo Bonzini #define VMXNET3_ECR_DIC         (1 << 3)
76849ab747fSPaolo Bonzini #define VMXNET3_ECR_DEBUG       (1 << 4)
76949ab747fSPaolo Bonzini 
77049ab747fSPaolo Bonzini /* flip the gen bit of a ring */
77149ab747fSPaolo Bonzini #define VMXNET3_FLIP_RING_GEN(gen) ((gen) = (gen) ^ 0x1)
77249ab747fSPaolo Bonzini 
77349ab747fSPaolo Bonzini /* only use this if moving the idx won't affect the gen bit */
77449ab747fSPaolo Bonzini #define VMXNET3_INC_RING_IDX_ONLY(idx, ring_size) \
77549ab747fSPaolo Bonzini     do {\
77649ab747fSPaolo Bonzini         (idx)++;\
77749ab747fSPaolo Bonzini         if (unlikely((idx) == (ring_size))) {\
77849ab747fSPaolo Bonzini             (idx) = 0;\
77949ab747fSPaolo Bonzini         } \
78049ab747fSPaolo Bonzini     } while (0)
78149ab747fSPaolo Bonzini 
78249ab747fSPaolo Bonzini #define VMXNET3_SET_VFTABLE_ENTRY(vfTable, vid) \
78349ab747fSPaolo Bonzini     (vfTable[vid >> 5] |= (1 << (vid & 31)))
78449ab747fSPaolo Bonzini #define VMXNET3_CLEAR_VFTABLE_ENTRY(vfTable, vid) \
78549ab747fSPaolo Bonzini     (vfTable[vid >> 5] &= ~(1 << (vid & 31)))
78649ab747fSPaolo Bonzini 
78749ab747fSPaolo Bonzini #define VMXNET3_VFTABLE_ENTRY_IS_SET(vfTable, vid) \
78849ab747fSPaolo Bonzini     ((vfTable[vid >> 5] & (1 << (vid & 31))) != 0)
78949ab747fSPaolo Bonzini 
79049ab747fSPaolo Bonzini #define VMXNET3_MAX_MTU     9000
79149ab747fSPaolo Bonzini #define VMXNET3_MIN_MTU     60
79249ab747fSPaolo Bonzini 
79349ab747fSPaolo Bonzini #define VMXNET3_LINK_UP         (10000 << 16 | 1)    /* 10 Gbps, up */
79449ab747fSPaolo Bonzini #define VMXNET3_LINK_DOWN       0
79549ab747fSPaolo Bonzini 
79649ab747fSPaolo Bonzini #undef u64
79749ab747fSPaolo Bonzini #undef u32
79849ab747fSPaolo Bonzini #undef u16
79949ab747fSPaolo Bonzini #undef u8
80049ab747fSPaolo Bonzini #undef __le16
80149ab747fSPaolo Bonzini #undef __le32
80249ab747fSPaolo Bonzini #undef __le64
803e03b5686SMarc-André Lureau #if HOST_BIG_ENDIAN
80449ab747fSPaolo Bonzini #undef __BIG_ENDIAN_BITFIELD
80549ab747fSPaolo Bonzini #endif
80649ab747fSPaolo Bonzini 
80749ab747fSPaolo Bonzini #endif
808