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