/*
 * QEMU VMWARE VMXNET3 paravirtual NIC
 *
 * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com)
 *
 * Developed by Daynix Computing LTD (http://www.daynix.com)
 *
 * Authors:
 * Dmitry Fleytman <dmitry@daynix.com>
 * Tamir Shomer <tamirs@daynix.com>
 * Yan Vugenfirer <yan@daynix.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2.
 * See the COPYING file in the top-level directory.
 *
 */

#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
#include "hw/qdev-properties.h"
#include "net/tap.h"
#include "net/checksum.h"
#include "sysemu/sysemu.h"
#include "qemu/bswap.h"
#include "qemu/module.h"
#include "hw/pci/msix.h"
#include "hw/pci/msi.h"
#include "migration/register.h"
#include "migration/vmstate.h"

#include "vmxnet3.h"
#include "vmxnet3_defs.h"
#include "vmxnet_debug.h"
#include "vmware_utils.h"
#include "net_tx_pkt.h"
#include "net_rx_pkt.h"

#define PCI_DEVICE_ID_VMWARE_VMXNET3_REVISION 0x1
#define VMXNET3_MSIX_BAR_SIZE 0x2000
#define MIN_BUF_SIZE 60

/* Compatibility flags for migration */
#define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT 0
#define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS \
    (1 << VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT)
#define VMXNET3_COMPAT_FLAG_DISABLE_PCIE_BIT 1
#define VMXNET3_COMPAT_FLAG_DISABLE_PCIE \
    (1 << VMXNET3_COMPAT_FLAG_DISABLE_PCIE_BIT)

#define VMXNET3_EXP_EP_OFFSET (0x48)
#define VMXNET3_MSI_OFFSET(s) \
    ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0x50 : 0x84)
#define VMXNET3_MSIX_OFFSET(s) \
    ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0 : 0x9c)
#define VMXNET3_DSN_OFFSET     (0x100)

#define VMXNET3_BAR0_IDX      (0)
#define VMXNET3_BAR1_IDX      (1)
#define VMXNET3_MSIX_BAR_IDX  (2)

#define VMXNET3_OFF_MSIX_TABLE (0x000)
#define VMXNET3_OFF_MSIX_PBA(s) \
    ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0x800 : 0x1000)

/* Link speed in Mbps should be shifted by 16 */
#define VMXNET3_LINK_SPEED      (1000 << 16)

/* Link status: 1 - up, 0 - down. */
#define VMXNET3_LINK_STATUS_UP  0x1

/* Least significant bit should be set for revision and version */
#define VMXNET3_UPT_REVISION      0x1
#define VMXNET3_DEVICE_REVISION   0x1

/* Number of interrupt vectors for non-MSIx modes */
#define VMXNET3_MAX_NMSIX_INTRS   (1)

/* Macros for rings descriptors access */
#define VMXNET3_READ_TX_QUEUE_DESCR8(_d, dpa, field) \
    (vmw_shmem_ld8(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))

#define VMXNET3_WRITE_TX_QUEUE_DESCR8(_d, dpa, field, value) \
    (vmw_shmem_st8(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field, value)))

#define VMXNET3_READ_TX_QUEUE_DESCR32(_d, dpa, field) \
    (vmw_shmem_ld32(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))

#define VMXNET3_WRITE_TX_QUEUE_DESCR32(_d, dpa, field, value) \
    (vmw_shmem_st32(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field), value))

#define VMXNET3_READ_TX_QUEUE_DESCR64(_d, dpa, field) \
    (vmw_shmem_ld64(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field)))

#define VMXNET3_WRITE_TX_QUEUE_DESCR64(_d, dpa, field, value) \
    (vmw_shmem_st64(_d, dpa + offsetof(struct Vmxnet3_TxQueueDesc, field), value))

#define VMXNET3_READ_RX_QUEUE_DESCR64(_d, dpa, field) \
    (vmw_shmem_ld64(_d, dpa + offsetof(struct Vmxnet3_RxQueueDesc, field)))

#define VMXNET3_READ_RX_QUEUE_DESCR32(_d, dpa, field) \
    (vmw_shmem_ld32(_d, dpa + offsetof(struct Vmxnet3_RxQueueDesc, field)))

#define VMXNET3_WRITE_RX_QUEUE_DESCR64(_d, dpa, field, value) \
    (vmw_shmem_st64(_d, dpa + offsetof(struct Vmxnet3_RxQueueDesc, field), value))

#define VMXNET3_WRITE_RX_QUEUE_DESCR8(_d, dpa, field, value) \
    (vmw_shmem_st8(_d, dpa + offsetof(struct Vmxnet3_RxQueueDesc, field), value))

/* Macros for guest driver shared area access */
#define VMXNET3_READ_DRV_SHARED64(_d, shpa, field) \
    (vmw_shmem_ld64(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field)))

#define VMXNET3_READ_DRV_SHARED32(_d, shpa, field) \
    (vmw_shmem_ld32(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field)))

#define VMXNET3_WRITE_DRV_SHARED32(_d, shpa, field, val) \
    (vmw_shmem_st32(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field), val))

#define VMXNET3_READ_DRV_SHARED16(_d, shpa, field) \
    (vmw_shmem_ld16(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field)))

#define VMXNET3_READ_DRV_SHARED8(_d, shpa, field) \
    (vmw_shmem_ld8(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field)))

#define VMXNET3_READ_DRV_SHARED(_d, shpa, field, b, l) \
    (vmw_shmem_read(_d, shpa + offsetof(struct Vmxnet3_DriverShared, field), b, l))

#define VMXNET_FLAG_IS_SET(field, flag) (((field) & (flag)) == (flag))

typedef struct VMXNET3Class {
    PCIDeviceClass parent_class;
    DeviceRealize parent_dc_realize;
} VMXNET3Class;

#define VMXNET3_DEVICE_CLASS(klass) \
    OBJECT_CLASS_CHECK(VMXNET3Class, (klass), TYPE_VMXNET3)
#define VMXNET3_DEVICE_GET_CLASS(obj) \
    OBJECT_GET_CLASS(VMXNET3Class, (obj), TYPE_VMXNET3)

static inline void vmxnet3_ring_init(PCIDevice *d,
                                     Vmxnet3Ring *ring,
                                     hwaddr pa,
                                     uint32_t size,
                                     uint32_t cell_size,
                                     bool zero_region)
{
    ring->pa = pa;
    ring->size = size;
    ring->cell_size = cell_size;
    ring->gen = VMXNET3_INIT_GEN;
    ring->next = 0;

    if (zero_region) {
        vmw_shmem_set(d, pa, 0, size * cell_size);
    }
}

#define VMXNET3_RING_DUMP(macro, ring_name, ridx, r)                         \
    macro("%s#%d: base %" PRIx64 " size %u cell_size %u gen %d next %u",  \
          (ring_name), (ridx),                                               \
          (r)->pa, (r)->size, (r)->cell_size, (r)->gen, (r)->next)

static inline void vmxnet3_ring_inc(Vmxnet3Ring *ring)
{
    if (++ring->next >= ring->size) {
        ring->next = 0;
        ring->gen ^= 1;
    }
}

static inline void vmxnet3_ring_dec(Vmxnet3Ring *ring)
{
    if (ring->next-- == 0) {
        ring->next = ring->size - 1;
        ring->gen ^= 1;
    }
}

static inline hwaddr vmxnet3_ring_curr_cell_pa(Vmxnet3Ring *ring)
{
    return ring->pa + ring->next * ring->cell_size;
}

static inline void vmxnet3_ring_read_curr_cell(PCIDevice *d, Vmxnet3Ring *ring,
                                               void *buff)
{
    vmw_shmem_read(d, vmxnet3_ring_curr_cell_pa(ring), buff, ring->cell_size);
}

static inline void vmxnet3_ring_write_curr_cell(PCIDevice *d, Vmxnet3Ring *ring,
                                                void *buff)
{
    vmw_shmem_write(d, vmxnet3_ring_curr_cell_pa(ring), buff, ring->cell_size);
}

static inline size_t vmxnet3_ring_curr_cell_idx(Vmxnet3Ring *ring)
{
    return ring->next;
}

static inline uint8_t vmxnet3_ring_curr_gen(Vmxnet3Ring *ring)
{
    return ring->gen;
}

/* Debug trace-related functions */
static inline void
vmxnet3_dump_tx_descr(struct Vmxnet3_TxDesc *descr)
{
    VMW_PKPRN("TX DESCR: "
              "addr %" PRIx64 ", len: %d, gen: %d, rsvd: %d, "
              "dtype: %d, ext1: %d, msscof: %d, hlen: %d, om: %d, "
              "eop: %d, cq: %d, ext2: %d, ti: %d, tci: %d",
              descr->addr, descr->len, descr->gen, descr->rsvd,
              descr->dtype, descr->ext1, descr->msscof, descr->hlen, descr->om,
              descr->eop, descr->cq, descr->ext2, descr->ti, descr->tci);
}

static inline void
vmxnet3_dump_virt_hdr(struct virtio_net_hdr *vhdr)
{
    VMW_PKPRN("VHDR: flags 0x%x, gso_type: 0x%x, hdr_len: %d, gso_size: %d, "
              "csum_start: %d, csum_offset: %d",
              vhdr->flags, vhdr->gso_type, vhdr->hdr_len, vhdr->gso_size,
              vhdr->csum_start, vhdr->csum_offset);
}

static inline void
vmxnet3_dump_rx_descr(struct Vmxnet3_RxDesc *descr)
{
    VMW_PKPRN("RX DESCR: addr %" PRIx64 ", len: %d, gen: %d, rsvd: %d, "
              "dtype: %d, ext1: %d, btype: %d",
              descr->addr, descr->len, descr->gen,
              descr->rsvd, descr->dtype, descr->ext1, descr->btype);
}

/* Interrupt management */

/*
 * This function returns sign whether interrupt line is in asserted state
 * This depends on the type of interrupt used. For INTX interrupt line will
 * be asserted until explicit deassertion, for MSI(X) interrupt line will
 * be deasserted automatically due to notification semantics of the MSI(X)
 * interrupts
 */
static bool _vmxnet3_assert_interrupt_line(VMXNET3State *s, uint32_t int_idx)
{
    PCIDevice *d = PCI_DEVICE(s);

    if (s->msix_used && msix_enabled(d)) {
        VMW_IRPRN("Sending MSI-X notification for vector %u", int_idx);
        msix_notify(d, int_idx);
        return false;
    }
    if (msi_enabled(d)) {
        VMW_IRPRN("Sending MSI notification for vector %u", int_idx);
        msi_notify(d, int_idx);
        return false;
    }

    VMW_IRPRN("Asserting line for interrupt %u", int_idx);
    pci_irq_assert(d);
    return true;
}

static void _vmxnet3_deassert_interrupt_line(VMXNET3State *s, int lidx)
{
    PCIDevice *d = PCI_DEVICE(s);

    /*
     * This function should never be called for MSI(X) interrupts
     * because deassertion never required for message interrupts
     */
    assert(!s->msix_used || !msix_enabled(d));
    /*
     * This function should never be called for MSI(X) interrupts
     * because deassertion never required for message interrupts
     */
    assert(!msi_enabled(d));

    VMW_IRPRN("Deasserting line for interrupt %u", lidx);
    pci_irq_deassert(d);
}

static void vmxnet3_update_interrupt_line_state(VMXNET3State *s, int lidx)
{
    if (!s->interrupt_states[lidx].is_pending &&
       s->interrupt_states[lidx].is_asserted) {
        VMW_IRPRN("New interrupt line state for index %d is DOWN", lidx);
        _vmxnet3_deassert_interrupt_line(s, lidx);
        s->interrupt_states[lidx].is_asserted = false;
        return;
    }

    if (s->interrupt_states[lidx].is_pending &&
       !s->interrupt_states[lidx].is_masked &&
       !s->interrupt_states[lidx].is_asserted) {
        VMW_IRPRN("New interrupt line state for index %d is UP", lidx);
        s->interrupt_states[lidx].is_asserted =
            _vmxnet3_assert_interrupt_line(s, lidx);
        s->interrupt_states[lidx].is_pending = false;
        return;
    }
}

static void vmxnet3_trigger_interrupt(VMXNET3State *s, int lidx)
{
    PCIDevice *d = PCI_DEVICE(s);
    s->interrupt_states[lidx].is_pending = true;
    vmxnet3_update_interrupt_line_state(s, lidx);

    if (s->msix_used && msix_enabled(d) && s->auto_int_masking) {
        goto do_automask;
    }

    if (msi_enabled(d) && s->auto_int_masking) {
        goto do_automask;
    }

    return;

do_automask:
    s->interrupt_states[lidx].is_masked = true;
    vmxnet3_update_interrupt_line_state(s, lidx);
}

static bool vmxnet3_interrupt_asserted(VMXNET3State *s, int lidx)
{
    return s->interrupt_states[lidx].is_asserted;
}

static void vmxnet3_clear_interrupt(VMXNET3State *s, int int_idx)
{
    s->interrupt_states[int_idx].is_pending = false;
    if (s->auto_int_masking) {
        s->interrupt_states[int_idx].is_masked = true;
    }
    vmxnet3_update_interrupt_line_state(s, int_idx);
}

static void
vmxnet3_on_interrupt_mask_changed(VMXNET3State *s, int lidx, bool is_masked)
{
    s->interrupt_states[lidx].is_masked = is_masked;
    vmxnet3_update_interrupt_line_state(s, lidx);
}

static bool vmxnet3_verify_driver_magic(PCIDevice *d, hwaddr dshmem)
{
    return (VMXNET3_READ_DRV_SHARED32(d, dshmem, magic) == VMXNET3_REV1_MAGIC);
}

#define VMXNET3_GET_BYTE(x, byte_num) (((x) >> (byte_num)*8) & 0xFF)
#define VMXNET3_MAKE_BYTE(byte_num, val) \
    (((uint32_t)((val) & 0xFF)) << (byte_num)*8)

static void vmxnet3_set_variable_mac(VMXNET3State *s, uint32_t h, uint32_t l)
{
    s->conf.macaddr.a[0] = VMXNET3_GET_BYTE(l,  0);
    s->conf.macaddr.a[1] = VMXNET3_GET_BYTE(l,  1);
    s->conf.macaddr.a[2] = VMXNET3_GET_BYTE(l,  2);
    s->conf.macaddr.a[3] = VMXNET3_GET_BYTE(l,  3);
    s->conf.macaddr.a[4] = VMXNET3_GET_BYTE(h, 0);
    s->conf.macaddr.a[5] = VMXNET3_GET_BYTE(h, 1);

    VMW_CFPRN("Variable MAC: " MAC_FMT, MAC_ARG(s->conf.macaddr.a));

    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
}

static uint64_t vmxnet3_get_mac_low(MACAddr *addr)
{
    return VMXNET3_MAKE_BYTE(0, addr->a[0]) |
           VMXNET3_MAKE_BYTE(1, addr->a[1]) |
           VMXNET3_MAKE_BYTE(2, addr->a[2]) |
           VMXNET3_MAKE_BYTE(3, addr->a[3]);
}

static uint64_t vmxnet3_get_mac_high(MACAddr *addr)
{
    return VMXNET3_MAKE_BYTE(0, addr->a[4]) |
           VMXNET3_MAKE_BYTE(1, addr->a[5]);
}

static void
vmxnet3_inc_tx_consumption_counter(VMXNET3State *s, int qidx)
{
    vmxnet3_ring_inc(&s->txq_descr[qidx].tx_ring);
}

static inline void
vmxnet3_inc_rx_consumption_counter(VMXNET3State *s, int qidx, int ridx)
{
    vmxnet3_ring_inc(&s->rxq_descr[qidx].rx_ring[ridx]);
}

static inline void
vmxnet3_inc_tx_completion_counter(VMXNET3State *s, int qidx)
{
    vmxnet3_ring_inc(&s->txq_descr[qidx].comp_ring);
}

static void
vmxnet3_inc_rx_completion_counter(VMXNET3State *s, int qidx)
{
    vmxnet3_ring_inc(&s->rxq_descr[qidx].comp_ring);
}

static void
vmxnet3_dec_rx_completion_counter(VMXNET3State *s, int qidx)
{
    vmxnet3_ring_dec(&s->rxq_descr[qidx].comp_ring);
}

static void vmxnet3_complete_packet(VMXNET3State *s, int qidx, uint32_t tx_ridx)
{
    struct Vmxnet3_TxCompDesc txcq_descr;
    PCIDevice *d = PCI_DEVICE(s);

    VMXNET3_RING_DUMP(VMW_RIPRN, "TXC", qidx, &s->txq_descr[qidx].comp_ring);

    memset(&txcq_descr, 0, sizeof(txcq_descr));
    txcq_descr.txdIdx = tx_ridx;
    txcq_descr.gen = vmxnet3_ring_curr_gen(&s->txq_descr[qidx].comp_ring);
    txcq_descr.val1 = cpu_to_le32(txcq_descr.val1);
    txcq_descr.val2 = cpu_to_le32(txcq_descr.val2);
    vmxnet3_ring_write_curr_cell(d, &s->txq_descr[qidx].comp_ring, &txcq_descr);

    /* Flush changes in TX descriptor before changing the counter value */
    smp_wmb();

    vmxnet3_inc_tx_completion_counter(s, qidx);
    vmxnet3_trigger_interrupt(s, s->txq_descr[qidx].intr_idx);
}

static bool
vmxnet3_setup_tx_offloads(VMXNET3State *s)
{
    switch (s->offload_mode) {
    case VMXNET3_OM_NONE:
        net_tx_pkt_build_vheader(s->tx_pkt, false, false, 0);
        break;

    case VMXNET3_OM_CSUM:
        net_tx_pkt_build_vheader(s->tx_pkt, false, true, 0);
        VMW_PKPRN("L4 CSO requested\n");
        break;

    case VMXNET3_OM_TSO:
        net_tx_pkt_build_vheader(s->tx_pkt, true, true,
            s->cso_or_gso_size);
        net_tx_pkt_update_ip_checksums(s->tx_pkt);
        VMW_PKPRN("GSO offload requested.");
        break;

    default:
        g_assert_not_reached();
        return false;
    }

    return true;
}

static void
vmxnet3_tx_retrieve_metadata(VMXNET3State *s,
                             const struct Vmxnet3_TxDesc *txd)
{
    s->offload_mode = txd->om;
    s->cso_or_gso_size = txd->msscof;
    s->tci = txd->tci;
    s->needs_vlan = txd->ti;
}

typedef enum {
    VMXNET3_PKT_STATUS_OK,
    VMXNET3_PKT_STATUS_ERROR,
    VMXNET3_PKT_STATUS_DISCARD,/* only for tx */
    VMXNET3_PKT_STATUS_OUT_OF_BUF /* only for rx */
} Vmxnet3PktStatus;

static void
vmxnet3_on_tx_done_update_stats(VMXNET3State *s, int qidx,
    Vmxnet3PktStatus status)
{
    size_t tot_len = net_tx_pkt_get_total_len(s->tx_pkt);
    struct UPT1_TxStats *stats = &s->txq_descr[qidx].txq_stats;

    switch (status) {
    case VMXNET3_PKT_STATUS_OK:
        switch (net_tx_pkt_get_packet_type(s->tx_pkt)) {
        case ETH_PKT_BCAST:
            stats->bcastPktsTxOK++;
            stats->bcastBytesTxOK += tot_len;
            break;
        case ETH_PKT_MCAST:
            stats->mcastPktsTxOK++;
            stats->mcastBytesTxOK += tot_len;
            break;
        case ETH_PKT_UCAST:
            stats->ucastPktsTxOK++;
            stats->ucastBytesTxOK += tot_len;
            break;
        default:
            g_assert_not_reached();
        }

        if (s->offload_mode == VMXNET3_OM_TSO) {
            /*
             * According to VMWARE headers this statistic is a number
             * of packets after segmentation but since we don't have
             * this information in QEMU model, the best we can do is to
             * provide number of non-segmented packets
             */
            stats->TSOPktsTxOK++;
            stats->TSOBytesTxOK += tot_len;
        }
        break;

    case VMXNET3_PKT_STATUS_DISCARD:
        stats->pktsTxDiscard++;
        break;

    case VMXNET3_PKT_STATUS_ERROR:
        stats->pktsTxError++;
        break;

    default:
        g_assert_not_reached();
    }
}

static void
vmxnet3_on_rx_done_update_stats(VMXNET3State *s,
                                int qidx,
                                Vmxnet3PktStatus status)
{
    struct UPT1_RxStats *stats = &s->rxq_descr[qidx].rxq_stats;
    size_t tot_len = net_rx_pkt_get_total_len(s->rx_pkt);

    switch (status) {
    case VMXNET3_PKT_STATUS_OUT_OF_BUF:
        stats->pktsRxOutOfBuf++;
        break;

    case VMXNET3_PKT_STATUS_ERROR:
        stats->pktsRxError++;
        break;
    case VMXNET3_PKT_STATUS_OK:
        switch (net_rx_pkt_get_packet_type(s->rx_pkt)) {
        case ETH_PKT_BCAST:
            stats->bcastPktsRxOK++;
            stats->bcastBytesRxOK += tot_len;
            break;
        case ETH_PKT_MCAST:
            stats->mcastPktsRxOK++;
            stats->mcastBytesRxOK += tot_len;
            break;
        case ETH_PKT_UCAST:
            stats->ucastPktsRxOK++;
            stats->ucastBytesRxOK += tot_len;
            break;
        default:
            g_assert_not_reached();
        }

        if (tot_len > s->mtu) {
            stats->LROPktsRxOK++;
            stats->LROBytesRxOK += tot_len;
        }
        break;
    default:
        g_assert_not_reached();
    }
}

static inline void
vmxnet3_ring_read_curr_txdesc(PCIDevice *pcidev, Vmxnet3Ring *ring,
                              struct Vmxnet3_TxDesc *txd)
{
    vmxnet3_ring_read_curr_cell(pcidev, ring, txd);
    txd->addr = le64_to_cpu(txd->addr);
    txd->val1 = le32_to_cpu(txd->val1);
    txd->val2 = le32_to_cpu(txd->val2);
}

static inline bool
vmxnet3_pop_next_tx_descr(VMXNET3State *s,
                          int qidx,
                          struct Vmxnet3_TxDesc *txd,
                          uint32_t *descr_idx)
{
    Vmxnet3Ring *ring = &s->txq_descr[qidx].tx_ring;
    PCIDevice *d = PCI_DEVICE(s);

    vmxnet3_ring_read_curr_txdesc(d, ring, txd);
    if (txd->gen == vmxnet3_ring_curr_gen(ring)) {
        /* Only read after generation field verification */
        smp_rmb();
        /* Re-read to be sure we got the latest version */
        vmxnet3_ring_read_curr_txdesc(d, ring, txd);
        VMXNET3_RING_DUMP(VMW_RIPRN, "TX", qidx, ring);
        *descr_idx = vmxnet3_ring_curr_cell_idx(ring);
        vmxnet3_inc_tx_consumption_counter(s, qidx);
        return true;
    }

    return false;
}

static bool
vmxnet3_send_packet(VMXNET3State *s, uint32_t qidx)
{
    Vmxnet3PktStatus status = VMXNET3_PKT_STATUS_OK;

    if (!vmxnet3_setup_tx_offloads(s)) {
        status = VMXNET3_PKT_STATUS_ERROR;
        goto func_exit;
    }

    /* debug prints */
    vmxnet3_dump_virt_hdr(net_tx_pkt_get_vhdr(s->tx_pkt));
    net_tx_pkt_dump(s->tx_pkt);

    if (!net_tx_pkt_send(s->tx_pkt, qemu_get_queue(s->nic))) {
        status = VMXNET3_PKT_STATUS_DISCARD;
        goto func_exit;
    }

func_exit:
    vmxnet3_on_tx_done_update_stats(s, qidx, status);
    return (status == VMXNET3_PKT_STATUS_OK);
}

static void vmxnet3_process_tx_queue(VMXNET3State *s, int qidx)
{
    struct Vmxnet3_TxDesc txd;
    uint32_t txd_idx;
    uint32_t data_len;
    hwaddr data_pa;

    for (;;) {
        if (!vmxnet3_pop_next_tx_descr(s, qidx, &txd, &txd_idx)) {
            break;
        }

        vmxnet3_dump_tx_descr(&txd);

        if (!s->skip_current_tx_pkt) {
            data_len = (txd.len > 0) ? txd.len : VMXNET3_MAX_TX_BUF_SIZE;
            data_pa = txd.addr;

            if (!net_tx_pkt_add_raw_fragment(s->tx_pkt,
                                                data_pa,
                                                data_len)) {
                s->skip_current_tx_pkt = true;
            }
        }

        if (s->tx_sop) {
            vmxnet3_tx_retrieve_metadata(s, &txd);
            s->tx_sop = false;
        }

        if (txd.eop) {
            if (!s->skip_current_tx_pkt && net_tx_pkt_parse(s->tx_pkt)) {
                if (s->needs_vlan) {
                    net_tx_pkt_setup_vlan_header(s->tx_pkt, s->tci);
                }

                vmxnet3_send_packet(s, qidx);
            } else {
                vmxnet3_on_tx_done_update_stats(s, qidx,
                                                VMXNET3_PKT_STATUS_ERROR);
            }

            vmxnet3_complete_packet(s, qidx, txd_idx);
            s->tx_sop = true;
            s->skip_current_tx_pkt = false;
            net_tx_pkt_reset(s->tx_pkt);
        }
    }
}

static inline void
vmxnet3_read_next_rx_descr(VMXNET3State *s, int qidx, int ridx,
                           struct Vmxnet3_RxDesc *dbuf, uint32_t *didx)
{
    PCIDevice *d = PCI_DEVICE(s);

    Vmxnet3Ring *ring = &s->rxq_descr[qidx].rx_ring[ridx];
    *didx = vmxnet3_ring_curr_cell_idx(ring);
    vmxnet3_ring_read_curr_cell(d, ring, dbuf);
    dbuf->addr = le64_to_cpu(dbuf->addr);
    dbuf->val1 = le32_to_cpu(dbuf->val1);
    dbuf->ext1 = le32_to_cpu(dbuf->ext1);
}

static inline uint8_t
vmxnet3_get_rx_ring_gen(VMXNET3State *s, int qidx, int ridx)
{
    return s->rxq_descr[qidx].rx_ring[ridx].gen;
}

static inline hwaddr
vmxnet3_pop_rxc_descr(VMXNET3State *s, int qidx, uint32_t *descr_gen)
{
    uint8_t ring_gen;
    struct Vmxnet3_RxCompDesc rxcd;

    hwaddr daddr =
        vmxnet3_ring_curr_cell_pa(&s->rxq_descr[qidx].comp_ring);

    pci_dma_read(PCI_DEVICE(s),
                 daddr, &rxcd, sizeof(struct Vmxnet3_RxCompDesc));
    rxcd.val1 = le32_to_cpu(rxcd.val1);
    rxcd.val2 = le32_to_cpu(rxcd.val2);
    rxcd.val3 = le32_to_cpu(rxcd.val3);
    ring_gen = vmxnet3_ring_curr_gen(&s->rxq_descr[qidx].comp_ring);

    if (rxcd.gen != ring_gen) {
        *descr_gen = ring_gen;
        vmxnet3_inc_rx_completion_counter(s, qidx);
        return daddr;
    }

    return 0;
}

static inline void
vmxnet3_revert_rxc_descr(VMXNET3State *s, int qidx)
{
    vmxnet3_dec_rx_completion_counter(s, qidx);
}

#define RXQ_IDX      (0)
#define RX_HEAD_BODY_RING (0)
#define RX_BODY_ONLY_RING (1)

static bool
vmxnet3_get_next_head_rx_descr(VMXNET3State *s,
                               struct Vmxnet3_RxDesc *descr_buf,
                               uint32_t *descr_idx,
                               uint32_t *ridx)
{
    for (;;) {
        uint32_t ring_gen;
        vmxnet3_read_next_rx_descr(s, RXQ_IDX, RX_HEAD_BODY_RING,
                                   descr_buf, descr_idx);

        /* If no more free descriptors - return */
        ring_gen = vmxnet3_get_rx_ring_gen(s, RXQ_IDX, RX_HEAD_BODY_RING);
        if (descr_buf->gen != ring_gen) {
            return false;
        }

        /* Only read after generation field verification */
        smp_rmb();
        /* Re-read to be sure we got the latest version */
        vmxnet3_read_next_rx_descr(s, RXQ_IDX, RX_HEAD_BODY_RING,
                                   descr_buf, descr_idx);

        /* Mark current descriptor as used/skipped */
        vmxnet3_inc_rx_consumption_counter(s, RXQ_IDX, RX_HEAD_BODY_RING);

        /* If this is what we are looking for - return */
        if (descr_buf->btype == VMXNET3_RXD_BTYPE_HEAD) {
            *ridx = RX_HEAD_BODY_RING;
            return true;
        }
    }
}

static bool
vmxnet3_get_next_body_rx_descr(VMXNET3State *s,
                               struct Vmxnet3_RxDesc *d,
                               uint32_t *didx,
                               uint32_t *ridx)
{
    vmxnet3_read_next_rx_descr(s, RXQ_IDX, RX_HEAD_BODY_RING, d, didx);

    /* Try to find corresponding descriptor in head/body ring */
    if (d->gen == vmxnet3_get_rx_ring_gen(s, RXQ_IDX, RX_HEAD_BODY_RING)) {
        /* Only read after generation field verification */
        smp_rmb();
        /* Re-read to be sure we got the latest version */
        vmxnet3_read_next_rx_descr(s, RXQ_IDX, RX_HEAD_BODY_RING, d, didx);
        if (d->btype == VMXNET3_RXD_BTYPE_BODY) {
            vmxnet3_inc_rx_consumption_counter(s, RXQ_IDX, RX_HEAD_BODY_RING);
            *ridx = RX_HEAD_BODY_RING;
            return true;
        }
    }

    /*
     * If there is no free descriptors on head/body ring or next free
     * descriptor is a head descriptor switch to body only ring
     */
    vmxnet3_read_next_rx_descr(s, RXQ_IDX, RX_BODY_ONLY_RING, d, didx);

    /* If no more free descriptors - return */
    if (d->gen == vmxnet3_get_rx_ring_gen(s, RXQ_IDX, RX_BODY_ONLY_RING)) {
        /* Only read after generation field verification */
        smp_rmb();
        /* Re-read to be sure we got the latest version */
        vmxnet3_read_next_rx_descr(s, RXQ_IDX, RX_BODY_ONLY_RING, d, didx);
        assert(d->btype == VMXNET3_RXD_BTYPE_BODY);
        *ridx = RX_BODY_ONLY_RING;
        vmxnet3_inc_rx_consumption_counter(s, RXQ_IDX, RX_BODY_ONLY_RING);
        return true;
    }

    return false;
}

static inline bool
vmxnet3_get_next_rx_descr(VMXNET3State *s, bool is_head,
                          struct Vmxnet3_RxDesc *descr_buf,
                          uint32_t *descr_idx,
                          uint32_t *ridx)
{
    if (is_head || !s->rx_packets_compound) {
        return vmxnet3_get_next_head_rx_descr(s, descr_buf, descr_idx, ridx);
    } else {
        return vmxnet3_get_next_body_rx_descr(s, descr_buf, descr_idx, ridx);
    }
}

/* In case packet was csum offloaded (either NEEDS_CSUM or DATA_VALID),
 * the implementation always passes an RxCompDesc with a "Checksum
 * calculated and found correct" to the OS (cnc=0 and tuc=1, see
 * vmxnet3_rx_update_descr). This emulates the observed ESXi behavior.
 *
 * Therefore, if packet has the NEEDS_CSUM set, we must calculate
 * and place a fully computed checksum into the tcp/udp header.
 * Otherwise, the OS driver will receive a checksum-correct indication
 * (CHECKSUM_UNNECESSARY), but with the actual tcp/udp checksum field
 * having just the pseudo header csum value.
 *
 * While this is not a problem if packet is destined for local delivery,
 * in the case the host OS performs forwarding, it will forward an
 * incorrectly checksummed packet.
 */
static void vmxnet3_rx_need_csum_calculate(struct NetRxPkt *pkt,
                                           const void *pkt_data,
                                           size_t pkt_len)
{
    struct virtio_net_hdr *vhdr;
    bool isip4, isip6, istcp, isudp;
    uint8_t *data;
    int len;

    if (!net_rx_pkt_has_virt_hdr(pkt)) {
        return;
    }

    vhdr = net_rx_pkt_get_vhdr(pkt);
    if (!VMXNET_FLAG_IS_SET(vhdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM)) {
        return;
    }

    net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
    if (!(isip4 || isip6) || !(istcp || isudp)) {
        return;
    }

    vmxnet3_dump_virt_hdr(vhdr);

    /* Validate packet len: csum_start + scum_offset + length of csum field */
    if (pkt_len < (vhdr->csum_start + vhdr->csum_offset + 2)) {
        VMW_PKPRN("packet len:%zu < csum_start(%d) + csum_offset(%d) + 2, "
                  "cannot calculate checksum",
                  pkt_len, vhdr->csum_start, vhdr->csum_offset);
        return;
    }

    data = (uint8_t *)pkt_data + vhdr->csum_start;
    len = pkt_len - vhdr->csum_start;
    /* Put the checksum obtained into the packet */
    stw_be_p(data + vhdr->csum_offset,
             net_checksum_finish_nozero(net_checksum_add(len, data)));

    vhdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM;
    vhdr->flags |= VIRTIO_NET_HDR_F_DATA_VALID;
}

static void vmxnet3_rx_update_descr(struct NetRxPkt *pkt,
    struct Vmxnet3_RxCompDesc *rxcd)
{
    int csum_ok, is_gso;
    bool isip4, isip6, istcp, isudp;
    struct virtio_net_hdr *vhdr;
    uint8_t offload_type;

    if (net_rx_pkt_is_vlan_stripped(pkt)) {
        rxcd->ts = 1;
        rxcd->tci = net_rx_pkt_get_vlan_tag(pkt);
    }

    if (!net_rx_pkt_has_virt_hdr(pkt)) {
        goto nocsum;
    }

    vhdr = net_rx_pkt_get_vhdr(pkt);
    /*
     * Checksum is valid when lower level tell so or when lower level
     * requires checksum offload telling that packet produced/bridged
     * locally and did travel over network after last checksum calculation
     * or production
     */
    csum_ok = VMXNET_FLAG_IS_SET(vhdr->flags, VIRTIO_NET_HDR_F_DATA_VALID) ||
              VMXNET_FLAG_IS_SET(vhdr->flags, VIRTIO_NET_HDR_F_NEEDS_CSUM);

    offload_type = vhdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN;
    is_gso = (offload_type != VIRTIO_NET_HDR_GSO_NONE) ? 1 : 0;

    if (!csum_ok && !is_gso) {
        goto nocsum;
    }

    net_rx_pkt_get_protocols(pkt, &isip4, &isip6, &isudp, &istcp);
    if ((!istcp && !isudp) || (!isip4 && !isip6)) {
        goto nocsum;
    }

    rxcd->cnc = 0;
    rxcd->v4 = isip4 ? 1 : 0;
    rxcd->v6 = isip6 ? 1 : 0;
    rxcd->tcp = istcp ? 1 : 0;
    rxcd->udp = isudp ? 1 : 0;
    rxcd->fcs = rxcd->tuc = rxcd->ipc = 1;
    return;

nocsum:
    rxcd->cnc = 1;
    return;
}

static void
vmxnet3_pci_dma_writev(PCIDevice *pci_dev,
                       const struct iovec *iov,
                       size_t start_iov_off,
                       hwaddr target_addr,
                       size_t bytes_to_copy)
{
    size_t curr_off = 0;
    size_t copied = 0;

    while (bytes_to_copy) {
        if (start_iov_off < (curr_off + iov->iov_len)) {
            size_t chunk_len =
                MIN((curr_off + iov->iov_len) - start_iov_off, bytes_to_copy);

            pci_dma_write(pci_dev, target_addr + copied,
                          iov->iov_base + start_iov_off - curr_off,
                          chunk_len);

            copied += chunk_len;
            start_iov_off += chunk_len;
            curr_off = start_iov_off;
            bytes_to_copy -= chunk_len;
        } else {
            curr_off += iov->iov_len;
        }
        iov++;
    }
}

static void
vmxnet3_pci_dma_write_rxcd(PCIDevice *pcidev, dma_addr_t pa,
                           struct Vmxnet3_RxCompDesc *rxcd)
{
    rxcd->val1 = cpu_to_le32(rxcd->val1);
    rxcd->val2 = cpu_to_le32(rxcd->val2);
    rxcd->val3 = cpu_to_le32(rxcd->val3);
    pci_dma_write(pcidev, pa, rxcd, sizeof(*rxcd));
}

static bool
vmxnet3_indicate_packet(VMXNET3State *s)
{
    struct Vmxnet3_RxDesc rxd;
    PCIDevice *d = PCI_DEVICE(s);
    bool is_head = true;
    uint32_t rxd_idx;
    uint32_t rx_ridx = 0;

    struct Vmxnet3_RxCompDesc rxcd;
    uint32_t new_rxcd_gen = VMXNET3_INIT_GEN;
    hwaddr new_rxcd_pa = 0;
    hwaddr ready_rxcd_pa = 0;
    struct iovec *data = net_rx_pkt_get_iovec(s->rx_pkt);
    size_t bytes_copied = 0;
    size_t bytes_left = net_rx_pkt_get_total_len(s->rx_pkt);
    uint16_t num_frags = 0;
    size_t chunk_size;

    net_rx_pkt_dump(s->rx_pkt);

    while (bytes_left > 0) {

        /* cannot add more frags to packet */
        if (num_frags == s->max_rx_frags) {
            break;
        }

        new_rxcd_pa = vmxnet3_pop_rxc_descr(s, RXQ_IDX, &new_rxcd_gen);
        if (!new_rxcd_pa) {
            break;
        }

        if (!vmxnet3_get_next_rx_descr(s, is_head, &rxd, &rxd_idx, &rx_ridx)) {
            break;
        }

        chunk_size = MIN(bytes_left, rxd.len);
        vmxnet3_pci_dma_writev(d, data, bytes_copied, rxd.addr, chunk_size);
        bytes_copied += chunk_size;
        bytes_left -= chunk_size;

        vmxnet3_dump_rx_descr(&rxd);

        if (ready_rxcd_pa != 0) {
            vmxnet3_pci_dma_write_rxcd(d, ready_rxcd_pa, &rxcd);
        }

        memset(&rxcd, 0, sizeof(struct Vmxnet3_RxCompDesc));
        rxcd.rxdIdx = rxd_idx;
        rxcd.len = chunk_size;
        rxcd.sop = is_head;
        rxcd.gen = new_rxcd_gen;
        rxcd.rqID = RXQ_IDX + rx_ridx * s->rxq_num;

        if (bytes_left == 0) {
            vmxnet3_rx_update_descr(s->rx_pkt, &rxcd);
        }

        VMW_RIPRN("RX Completion descriptor: rxRing: %lu rxIdx %lu len %lu "
                  "sop %d csum_correct %lu",
                  (unsigned long) rx_ridx,
                  (unsigned long) rxcd.rxdIdx,
                  (unsigned long) rxcd.len,
                  (int) rxcd.sop,
                  (unsigned long) rxcd.tuc);

        is_head = false;
        ready_rxcd_pa = new_rxcd_pa;
        new_rxcd_pa = 0;
        num_frags++;
    }

    if (ready_rxcd_pa != 0) {
        rxcd.eop = 1;
        rxcd.err = (bytes_left != 0);

        vmxnet3_pci_dma_write_rxcd(d, ready_rxcd_pa, &rxcd);

        /* Flush RX descriptor changes */
        smp_wmb();
    }

    if (new_rxcd_pa != 0) {
        vmxnet3_revert_rxc_descr(s, RXQ_IDX);
    }

    vmxnet3_trigger_interrupt(s, s->rxq_descr[RXQ_IDX].intr_idx);

    if (bytes_left == 0) {
        vmxnet3_on_rx_done_update_stats(s, RXQ_IDX, VMXNET3_PKT_STATUS_OK);
        return true;
    } else if (num_frags == s->max_rx_frags) {
        vmxnet3_on_rx_done_update_stats(s, RXQ_IDX, VMXNET3_PKT_STATUS_ERROR);
        return false;
    } else {
        vmxnet3_on_rx_done_update_stats(s, RXQ_IDX,
                                        VMXNET3_PKT_STATUS_OUT_OF_BUF);
        return false;
    }
}

static void
vmxnet3_io_bar0_write(void *opaque, hwaddr addr,
                      uint64_t val, unsigned size)
{
    VMXNET3State *s = opaque;

    if (!s->device_active) {
        return;
    }

    if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_TXPROD,
                        VMXNET3_DEVICE_MAX_TX_QUEUES, VMXNET3_REG_ALIGN)) {
        int tx_queue_idx =
            VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_TXPROD,
                                     VMXNET3_REG_ALIGN);
        assert(tx_queue_idx <= s->txq_num);
        vmxnet3_process_tx_queue(s, tx_queue_idx);
        return;
    }

    if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_IMR,
                        VMXNET3_MAX_INTRS, VMXNET3_REG_ALIGN)) {
        int l = VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_IMR,
                                         VMXNET3_REG_ALIGN);

        VMW_CBPRN("Interrupt mask for line %d written: 0x%" PRIx64, l, val);

        vmxnet3_on_interrupt_mask_changed(s, l, val);
        return;
    }

    if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_RXPROD,
                        VMXNET3_DEVICE_MAX_RX_QUEUES, VMXNET3_REG_ALIGN) ||
       VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_RXPROD2,
                        VMXNET3_DEVICE_MAX_RX_QUEUES, VMXNET3_REG_ALIGN)) {
        return;
    }

    VMW_WRPRN("BAR0 unknown write [%" PRIx64 "] = %" PRIx64 ", size %d",
              (uint64_t) addr, val, size);
}

static uint64_t
vmxnet3_io_bar0_read(void *opaque, hwaddr addr, unsigned size)
{
    VMXNET3State *s = opaque;

    if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_IMR,
                        VMXNET3_MAX_INTRS, VMXNET3_REG_ALIGN)) {
        int l = VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_IMR,
                                         VMXNET3_REG_ALIGN);
        return s->interrupt_states[l].is_masked;
    }

    VMW_CBPRN("BAR0 unknown read [%" PRIx64 "], size %d", addr, size);
    return 0;
}

static void vmxnet3_reset_interrupt_states(VMXNET3State *s)
{
    int i;
    for (i = 0; i < ARRAY_SIZE(s->interrupt_states); i++) {
        s->interrupt_states[i].is_asserted = false;
        s->interrupt_states[i].is_pending = false;
        s->interrupt_states[i].is_masked = true;
    }
}

static void vmxnet3_reset_mac(VMXNET3State *s)
{
    memcpy(&s->conf.macaddr.a, &s->perm_mac.a, sizeof(s->perm_mac.a));
    VMW_CFPRN("MAC address set to: " MAC_FMT, MAC_ARG(s->conf.macaddr.a));
}

static void vmxnet3_deactivate_device(VMXNET3State *s)
{
    if (s->device_active) {
        VMW_CBPRN("Deactivating vmxnet3...");
        net_tx_pkt_reset(s->tx_pkt);
        net_tx_pkt_uninit(s->tx_pkt);
        net_rx_pkt_uninit(s->rx_pkt);
        s->device_active = false;
    }
}

static void vmxnet3_reset(VMXNET3State *s)
{
    VMW_CBPRN("Resetting vmxnet3...");

    vmxnet3_deactivate_device(s);
    vmxnet3_reset_interrupt_states(s);
    s->drv_shmem = 0;
    s->tx_sop = true;
    s->skip_current_tx_pkt = false;
}

static void vmxnet3_update_rx_mode(VMXNET3State *s)
{
    PCIDevice *d = PCI_DEVICE(s);

    s->rx_mode = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem,
                                           devRead.rxFilterConf.rxMode);
    VMW_CFPRN("RX mode: 0x%08X", s->rx_mode);
}

static void vmxnet3_update_vlan_filters(VMXNET3State *s)
{
    int i;
    PCIDevice *d = PCI_DEVICE(s);

    /* Copy configuration from shared memory */
    VMXNET3_READ_DRV_SHARED(d, s->drv_shmem,
                            devRead.rxFilterConf.vfTable,
                            s->vlan_table,
                            sizeof(s->vlan_table));

    /* Invert byte order when needed */
    for (i = 0; i < ARRAY_SIZE(s->vlan_table); i++) {
        s->vlan_table[i] = le32_to_cpu(s->vlan_table[i]);
    }

    /* Dump configuration for debugging purposes */
    VMW_CFPRN("Configured VLANs:");
    for (i = 0; i < sizeof(s->vlan_table) * 8; i++) {
        if (VMXNET3_VFTABLE_ENTRY_IS_SET(s->vlan_table, i)) {
            VMW_CFPRN("\tVLAN %d is present", i);
        }
    }
}

static void vmxnet3_update_mcast_filters(VMXNET3State *s)
{
    PCIDevice *d = PCI_DEVICE(s);

    uint16_t list_bytes =
        VMXNET3_READ_DRV_SHARED16(d, s->drv_shmem,
                                  devRead.rxFilterConf.mfTableLen);

    s->mcast_list_len = list_bytes / sizeof(s->mcast_list[0]);

    s->mcast_list = g_realloc(s->mcast_list, list_bytes);
    if (!s->mcast_list) {
        if (s->mcast_list_len == 0) {
            VMW_CFPRN("Current multicast list is empty");
        } else {
            VMW_ERPRN("Failed to allocate multicast list of %d elements",
                      s->mcast_list_len);
        }
        s->mcast_list_len = 0;
    } else {
        int i;
        hwaddr mcast_list_pa =
            VMXNET3_READ_DRV_SHARED64(d, s->drv_shmem,
                                      devRead.rxFilterConf.mfTablePA);

        pci_dma_read(d, mcast_list_pa, s->mcast_list, list_bytes);

        VMW_CFPRN("Current multicast list len is %d:", s->mcast_list_len);
        for (i = 0; i < s->mcast_list_len; i++) {
            VMW_CFPRN("\t" MAC_FMT, MAC_ARG(s->mcast_list[i].a));
        }
    }
}

static void vmxnet3_setup_rx_filtering(VMXNET3State *s)
{
    vmxnet3_update_rx_mode(s);
    vmxnet3_update_vlan_filters(s);
    vmxnet3_update_mcast_filters(s);
}

static uint32_t vmxnet3_get_interrupt_config(VMXNET3State *s)
{
    uint32_t interrupt_mode = VMXNET3_IT_AUTO | (VMXNET3_IMM_AUTO << 2);
    VMW_CFPRN("Interrupt config is 0x%X", interrupt_mode);
    return interrupt_mode;
}

static void vmxnet3_fill_stats(VMXNET3State *s)
{
    int i;
    PCIDevice *d = PCI_DEVICE(s);

    if (!s->device_active)
        return;

    for (i = 0; i < s->txq_num; i++) {
        pci_dma_write(d,
                      s->txq_descr[i].tx_stats_pa,
                      &s->txq_descr[i].txq_stats,
                      sizeof(s->txq_descr[i].txq_stats));
    }

    for (i = 0; i < s->rxq_num; i++) {
        pci_dma_write(d,
                      s->rxq_descr[i].rx_stats_pa,
                      &s->rxq_descr[i].rxq_stats,
                      sizeof(s->rxq_descr[i].rxq_stats));
    }
}

static void vmxnet3_adjust_by_guest_type(VMXNET3State *s)
{
    struct Vmxnet3_GOSInfo gos;
    PCIDevice *d = PCI_DEVICE(s);

    VMXNET3_READ_DRV_SHARED(d, s->drv_shmem, devRead.misc.driverInfo.gos,
                            &gos, sizeof(gos));
    s->rx_packets_compound =
        (gos.gosType == VMXNET3_GOS_TYPE_WIN) ? false : true;

    VMW_CFPRN("Guest type specifics: RXCOMPOUND: %d", s->rx_packets_compound);
}

static void
vmxnet3_dump_conf_descr(const char *name,
                        struct Vmxnet3_VariableLenConfDesc *pm_descr)
{
    VMW_CFPRN("%s descriptor dump: Version %u, Length %u",
              name, pm_descr->confVer, pm_descr->confLen);

};

static void vmxnet3_update_pm_state(VMXNET3State *s)
{
    struct Vmxnet3_VariableLenConfDesc pm_descr;
    PCIDevice *d = PCI_DEVICE(s);

    pm_descr.confLen =
        VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.pmConfDesc.confLen);
    pm_descr.confVer =
        VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.pmConfDesc.confVer);
    pm_descr.confPA =
        VMXNET3_READ_DRV_SHARED64(d, s->drv_shmem, devRead.pmConfDesc.confPA);

    vmxnet3_dump_conf_descr("PM State", &pm_descr);
}

static void vmxnet3_update_features(VMXNET3State *s)
{
    uint32_t guest_features;
    int rxcso_supported;
    PCIDevice *d = PCI_DEVICE(s);

    guest_features = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem,
                                               devRead.misc.uptFeatures);

    rxcso_supported = VMXNET_FLAG_IS_SET(guest_features, UPT1_F_RXCSUM);
    s->rx_vlan_stripping = VMXNET_FLAG_IS_SET(guest_features, UPT1_F_RXVLAN);
    s->lro_supported = VMXNET_FLAG_IS_SET(guest_features, UPT1_F_LRO);

    VMW_CFPRN("Features configuration: LRO: %d, RXCSUM: %d, VLANSTRIP: %d",
              s->lro_supported, rxcso_supported,
              s->rx_vlan_stripping);
    if (s->peer_has_vhdr) {
        qemu_set_offload(qemu_get_queue(s->nic)->peer,
                         rxcso_supported,
                         s->lro_supported,
                         s->lro_supported,
                         0,
                         0);
    }
}

static bool vmxnet3_verify_intx(VMXNET3State *s, int intx)
{
    return s->msix_used || msi_enabled(PCI_DEVICE(s))
        || intx == pci_get_byte(s->parent_obj.config + PCI_INTERRUPT_PIN) - 1;
}

static void vmxnet3_validate_interrupt_idx(bool is_msix, int idx)
{
    int max_ints = is_msix ? VMXNET3_MAX_INTRS : VMXNET3_MAX_NMSIX_INTRS;
    if (idx >= max_ints) {
        hw_error("Bad interrupt index: %d\n", idx);
    }
}

static void vmxnet3_validate_interrupts(VMXNET3State *s)
{
    int i;

    VMW_CFPRN("Verifying event interrupt index (%d)", s->event_int_idx);
    vmxnet3_validate_interrupt_idx(s->msix_used, s->event_int_idx);

    for (i = 0; i < s->txq_num; i++) {
        int idx = s->txq_descr[i].intr_idx;
        VMW_CFPRN("Verifying TX queue %d interrupt index (%d)", i, idx);
        vmxnet3_validate_interrupt_idx(s->msix_used, idx);
    }

    for (i = 0; i < s->rxq_num; i++) {
        int idx = s->rxq_descr[i].intr_idx;
        VMW_CFPRN("Verifying RX queue %d interrupt index (%d)", i, idx);
        vmxnet3_validate_interrupt_idx(s->msix_used, idx);
    }
}

static void vmxnet3_validate_queues(VMXNET3State *s)
{
    /*
    * txq_num and rxq_num are total number of queues
    * configured by guest. These numbers must not
    * exceed corresponding maximal values.
    */

    if (s->txq_num > VMXNET3_DEVICE_MAX_TX_QUEUES) {
        hw_error("Bad TX queues number: %d\n", s->txq_num);
    }

    if (s->rxq_num > VMXNET3_DEVICE_MAX_RX_QUEUES) {
        hw_error("Bad RX queues number: %d\n", s->rxq_num);
    }
}

static void vmxnet3_activate_device(VMXNET3State *s)
{
    int i;
    static const uint32_t VMXNET3_DEF_TX_THRESHOLD = 1;
    PCIDevice *d = PCI_DEVICE(s);
    hwaddr qdescr_table_pa;
    uint64_t pa;
    uint32_t size;

    /* Verify configuration consistency */
    if (!vmxnet3_verify_driver_magic(d, s->drv_shmem)) {
        VMW_ERPRN("Device configuration received from driver is invalid");
        return;
    }

    /* Verify if device is active */
    if (s->device_active) {
        VMW_CFPRN("Vmxnet3 device is active");
        return;
    }

    vmxnet3_adjust_by_guest_type(s);
    vmxnet3_update_features(s);
    vmxnet3_update_pm_state(s);
    vmxnet3_setup_rx_filtering(s);
    /* Cache fields from shared memory */
    s->mtu = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, devRead.misc.mtu);
    VMW_CFPRN("MTU is %u", s->mtu);

    s->max_rx_frags =
        VMXNET3_READ_DRV_SHARED16(d, s->drv_shmem, devRead.misc.maxNumRxSG);

    if (s->max_rx_frags == 0) {
        s->max_rx_frags = 1;
    }

    VMW_CFPRN("Max RX fragments is %u", s->max_rx_frags);

    s->event_int_idx =
        VMXNET3_READ_DRV_SHARED8(d, s->drv_shmem, devRead.intrConf.eventIntrIdx);
    assert(vmxnet3_verify_intx(s, s->event_int_idx));
    VMW_CFPRN("Events interrupt line is %u", s->event_int_idx);

    s->auto_int_masking =
        VMXNET3_READ_DRV_SHARED8(d, s->drv_shmem, devRead.intrConf.autoMask);
    VMW_CFPRN("Automatic interrupt masking is %d", (int)s->auto_int_masking);

    s->txq_num =
        VMXNET3_READ_DRV_SHARED8(d, s->drv_shmem, devRead.misc.numTxQueues);
    s->rxq_num =
        VMXNET3_READ_DRV_SHARED8(d, s->drv_shmem, devRead.misc.numRxQueues);

    VMW_CFPRN("Number of TX/RX queues %u/%u", s->txq_num, s->rxq_num);
    vmxnet3_validate_queues(s);

    qdescr_table_pa =
        VMXNET3_READ_DRV_SHARED64(d, s->drv_shmem, devRead.misc.queueDescPA);
    VMW_CFPRN("TX queues descriptors table is at 0x%" PRIx64, qdescr_table_pa);

    /*
     * Worst-case scenario is a packet that holds all TX rings space so
     * we calculate total size of all TX rings for max TX fragments number
     */
    s->max_tx_frags = 0;

    /* TX queues */
    for (i = 0; i < s->txq_num; i++) {
        hwaddr qdescr_pa =
            qdescr_table_pa + i * sizeof(struct Vmxnet3_TxQueueDesc);

        /* Read interrupt number for this TX queue */
        s->txq_descr[i].intr_idx =
            VMXNET3_READ_TX_QUEUE_DESCR8(d, qdescr_pa, conf.intrIdx);
        assert(vmxnet3_verify_intx(s, s->txq_descr[i].intr_idx));

        VMW_CFPRN("TX Queue %d interrupt: %d", i, s->txq_descr[i].intr_idx);

        /* Read rings memory locations for TX queues */
        pa = VMXNET3_READ_TX_QUEUE_DESCR64(d, qdescr_pa, conf.txRingBasePA);
        size = VMXNET3_READ_TX_QUEUE_DESCR32(d, qdescr_pa, conf.txRingSize);

        vmxnet3_ring_init(d, &s->txq_descr[i].tx_ring, pa, size,
                          sizeof(struct Vmxnet3_TxDesc), false);
        VMXNET3_RING_DUMP(VMW_CFPRN, "TX", i, &s->txq_descr[i].tx_ring);

        s->max_tx_frags += size;

        /* TXC ring */
        pa = VMXNET3_READ_TX_QUEUE_DESCR64(d, qdescr_pa, conf.compRingBasePA);
        size = VMXNET3_READ_TX_QUEUE_DESCR32(d, qdescr_pa, conf.compRingSize);
        vmxnet3_ring_init(d, &s->txq_descr[i].comp_ring, pa, size,
                          sizeof(struct Vmxnet3_TxCompDesc), true);
        VMXNET3_RING_DUMP(VMW_CFPRN, "TXC", i, &s->txq_descr[i].comp_ring);

        s->txq_descr[i].tx_stats_pa =
            qdescr_pa + offsetof(struct Vmxnet3_TxQueueDesc, stats);

        memset(&s->txq_descr[i].txq_stats, 0,
               sizeof(s->txq_descr[i].txq_stats));

        /* Fill device-managed parameters for queues */
        VMXNET3_WRITE_TX_QUEUE_DESCR32(d, qdescr_pa,
                                       ctrl.txThreshold,
                                       VMXNET3_DEF_TX_THRESHOLD);
    }

    /* Preallocate TX packet wrapper */
    VMW_CFPRN("Max TX fragments is %u", s->max_tx_frags);
    net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s),
                    s->max_tx_frags, s->peer_has_vhdr);
    net_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);

    /* Read rings memory locations for RX queues */
    for (i = 0; i < s->rxq_num; i++) {
        int j;
        hwaddr qd_pa =
            qdescr_table_pa + s->txq_num * sizeof(struct Vmxnet3_TxQueueDesc) +
            i * sizeof(struct Vmxnet3_RxQueueDesc);

        /* Read interrupt number for this RX queue */
        s->rxq_descr[i].intr_idx =
            VMXNET3_READ_TX_QUEUE_DESCR8(d, qd_pa, conf.intrIdx);
        assert(vmxnet3_verify_intx(s, s->rxq_descr[i].intr_idx));

        VMW_CFPRN("RX Queue %d interrupt: %d", i, s->rxq_descr[i].intr_idx);

        /* Read rings memory locations */
        for (j = 0; j < VMXNET3_RX_RINGS_PER_QUEUE; j++) {
            /* RX rings */
            pa = VMXNET3_READ_RX_QUEUE_DESCR64(d, qd_pa, conf.rxRingBasePA[j]);
            size = VMXNET3_READ_RX_QUEUE_DESCR32(d, qd_pa, conf.rxRingSize[j]);
            vmxnet3_ring_init(d, &s->rxq_descr[i].rx_ring[j], pa, size,
                              sizeof(struct Vmxnet3_RxDesc), false);
            VMW_CFPRN("RX queue %d:%d: Base: %" PRIx64 ", Size: %d",
                      i, j, pa, size);
        }

        /* RXC ring */
        pa = VMXNET3_READ_RX_QUEUE_DESCR64(d, qd_pa, conf.compRingBasePA);
        size = VMXNET3_READ_RX_QUEUE_DESCR32(d, qd_pa, conf.compRingSize);
        vmxnet3_ring_init(d, &s->rxq_descr[i].comp_ring, pa, size,
                          sizeof(struct Vmxnet3_RxCompDesc), true);
        VMW_CFPRN("RXC queue %d: Base: %" PRIx64 ", Size: %d", i, pa, size);

        s->rxq_descr[i].rx_stats_pa =
            qd_pa + offsetof(struct Vmxnet3_RxQueueDesc, stats);
        memset(&s->rxq_descr[i].rxq_stats, 0,
               sizeof(s->rxq_descr[i].rxq_stats));
    }

    vmxnet3_validate_interrupts(s);

    /* Make sure everything is in place before device activation */
    smp_wmb();

    vmxnet3_reset_mac(s);

    s->device_active = true;
}

static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd)
{
    s->last_command = cmd;

    switch (cmd) {
    case VMXNET3_CMD_GET_PERM_MAC_HI:
        VMW_CBPRN("Set: Get upper part of permanent MAC");
        break;

    case VMXNET3_CMD_GET_PERM_MAC_LO:
        VMW_CBPRN("Set: Get lower part of permanent MAC");
        break;

    case VMXNET3_CMD_GET_STATS:
        VMW_CBPRN("Set: Get device statistics");
        vmxnet3_fill_stats(s);
        break;

    case VMXNET3_CMD_ACTIVATE_DEV:
        VMW_CBPRN("Set: Activating vmxnet3 device");
        vmxnet3_activate_device(s);
        break;

    case VMXNET3_CMD_UPDATE_RX_MODE:
        VMW_CBPRN("Set: Update rx mode");
        vmxnet3_update_rx_mode(s);
        break;

    case VMXNET3_CMD_UPDATE_VLAN_FILTERS:
        VMW_CBPRN("Set: Update VLAN filters");
        vmxnet3_update_vlan_filters(s);
        break;

    case VMXNET3_CMD_UPDATE_MAC_FILTERS:
        VMW_CBPRN("Set: Update MAC filters");
        vmxnet3_update_mcast_filters(s);
        break;

    case VMXNET3_CMD_UPDATE_FEATURE:
        VMW_CBPRN("Set: Update features");
        vmxnet3_update_features(s);
        break;

    case VMXNET3_CMD_UPDATE_PMCFG:
        VMW_CBPRN("Set: Update power management config");
        vmxnet3_update_pm_state(s);
        break;

    case VMXNET3_CMD_GET_LINK:
        VMW_CBPRN("Set: Get link");
        break;

    case VMXNET3_CMD_RESET_DEV:
        VMW_CBPRN("Set: Reset device");
        vmxnet3_reset(s);
        break;

    case VMXNET3_CMD_QUIESCE_DEV:
        VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - deactivate the device");
        vmxnet3_deactivate_device(s);
        break;

    case VMXNET3_CMD_GET_CONF_INTR:
        VMW_CBPRN("Set: VMXNET3_CMD_GET_CONF_INTR - interrupt configuration");
        break;

    case VMXNET3_CMD_GET_ADAPTIVE_RING_INFO:
        VMW_CBPRN("Set: VMXNET3_CMD_GET_ADAPTIVE_RING_INFO - "
                  "adaptive ring info flags");
        break;

    case VMXNET3_CMD_GET_DID_LO:
        VMW_CBPRN("Set: Get lower part of device ID");
        break;

    case VMXNET3_CMD_GET_DID_HI:
        VMW_CBPRN("Set: Get upper part of device ID");
        break;

    case VMXNET3_CMD_GET_DEV_EXTRA_INFO:
        VMW_CBPRN("Set: Get device extra info");
        break;

    default:
        VMW_CBPRN("Received unknown command: %" PRIx64, cmd);
        break;
    }
}

static uint64_t vmxnet3_get_command_status(VMXNET3State *s)
{
    uint64_t ret;

    switch (s->last_command) {
    case VMXNET3_CMD_ACTIVATE_DEV:
        ret = (s->device_active) ? 0 : 1;
        VMW_CFPRN("Device active: %" PRIx64, ret);
        break;

    case VMXNET3_CMD_RESET_DEV:
    case VMXNET3_CMD_QUIESCE_DEV:
    case VMXNET3_CMD_GET_QUEUE_STATUS:
    case VMXNET3_CMD_GET_DEV_EXTRA_INFO:
        ret = 0;
        break;

    case VMXNET3_CMD_GET_LINK:
        ret = s->link_status_and_speed;
        VMW_CFPRN("Link and speed: %" PRIx64, ret);
        break;

    case VMXNET3_CMD_GET_PERM_MAC_LO:
        ret = vmxnet3_get_mac_low(&s->perm_mac);
        break;

    case VMXNET3_CMD_GET_PERM_MAC_HI:
        ret = vmxnet3_get_mac_high(&s->perm_mac);
        break;

    case VMXNET3_CMD_GET_CONF_INTR:
        ret = vmxnet3_get_interrupt_config(s);
        break;

    case VMXNET3_CMD_GET_ADAPTIVE_RING_INFO:
        ret = VMXNET3_DISABLE_ADAPTIVE_RING;
        break;

    case VMXNET3_CMD_GET_DID_LO:
        ret = PCI_DEVICE_ID_VMWARE_VMXNET3;
        break;

    case VMXNET3_CMD_GET_DID_HI:
        ret = VMXNET3_DEVICE_REVISION;
        break;

    default:
        VMW_WRPRN("Received request for unknown command: %x", s->last_command);
        ret = 0;
        break;
    }

    return ret;
}

static void vmxnet3_set_events(VMXNET3State *s, uint32_t val)
{
    uint32_t events;
    PCIDevice *d = PCI_DEVICE(s);

    VMW_CBPRN("Setting events: 0x%x", val);
    events = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, ecr) | val;
    VMXNET3_WRITE_DRV_SHARED32(d, s->drv_shmem, ecr, events);
}

static void vmxnet3_ack_events(VMXNET3State *s, uint32_t val)
{
    PCIDevice *d = PCI_DEVICE(s);
    uint32_t events;

    VMW_CBPRN("Clearing events: 0x%x", val);
    events = VMXNET3_READ_DRV_SHARED32(d, s->drv_shmem, ecr) & ~val;
    VMXNET3_WRITE_DRV_SHARED32(d, s->drv_shmem, ecr, events);
}

static void
vmxnet3_io_bar1_write(void *opaque,
                      hwaddr addr,
                      uint64_t val,
                      unsigned size)
{
    VMXNET3State *s = opaque;

    switch (addr) {
    /* Vmxnet3 Revision Report Selection */
    case VMXNET3_REG_VRRS:
        VMW_CBPRN("Write BAR1 [VMXNET3_REG_VRRS] = %" PRIx64 ", size %d",
                  val, size);
        break;

    /* UPT Version Report Selection */
    case VMXNET3_REG_UVRS:
        VMW_CBPRN("Write BAR1 [VMXNET3_REG_UVRS] = %" PRIx64 ", size %d",
                  val, size);
        break;

    /* Driver Shared Address Low */
    case VMXNET3_REG_DSAL:
        VMW_CBPRN("Write BAR1 [VMXNET3_REG_DSAL] = %" PRIx64 ", size %d",
                  val, size);
        /*
         * Guest driver will first write the low part of the shared
         * memory address. We save it to temp variable and set the
         * shared address only after we get the high part
         */
        if (val == 0) {
            vmxnet3_deactivate_device(s);
        }
        s->temp_shared_guest_driver_memory = val;
        s->drv_shmem = 0;
        break;

    /* Driver Shared Address High */
    case VMXNET3_REG_DSAH:
        VMW_CBPRN("Write BAR1 [VMXNET3_REG_DSAH] = %" PRIx64 ", size %d",
                  val, size);
        /*
         * Set the shared memory between guest driver and device.
         * We already should have low address part.
         */
        s->drv_shmem = s->temp_shared_guest_driver_memory | (val << 32);
        break;

    /* Command */
    case VMXNET3_REG_CMD:
        VMW_CBPRN("Write BAR1 [VMXNET3_REG_CMD] = %" PRIx64 ", size %d",
                  val, size);
        vmxnet3_handle_command(s, val);
        break;

    /* MAC Address Low */
    case VMXNET3_REG_MACL:
        VMW_CBPRN("Write BAR1 [VMXNET3_REG_MACL] = %" PRIx64 ", size %d",
                  val, size);
        s->temp_mac = val;
        break;

    /* MAC Address High */
    case VMXNET3_REG_MACH:
        VMW_CBPRN("Write BAR1 [VMXNET3_REG_MACH] = %" PRIx64 ", size %d",
                  val, size);
        vmxnet3_set_variable_mac(s, val, s->temp_mac);
        break;

    /* Interrupt Cause Register */
    case VMXNET3_REG_ICR:
        VMW_CBPRN("Write BAR1 [VMXNET3_REG_ICR] = %" PRIx64 ", size %d",
                  val, size);
        g_assert_not_reached();
        break;

    /* Event Cause Register */
    case VMXNET3_REG_ECR:
        VMW_CBPRN("Write BAR1 [VMXNET3_REG_ECR] = %" PRIx64 ", size %d",
                  val, size);
        vmxnet3_ack_events(s, val);
        break;

    default:
        VMW_CBPRN("Unknown Write to BAR1 [%" PRIx64 "] = %" PRIx64 ", size %d",
                  addr, val, size);
        break;
    }
}

static uint64_t
vmxnet3_io_bar1_read(void *opaque, hwaddr addr, unsigned size)
{
        VMXNET3State *s = opaque;
        uint64_t ret = 0;

        switch (addr) {
        /* Vmxnet3 Revision Report Selection */
        case VMXNET3_REG_VRRS:
            VMW_CBPRN("Read BAR1 [VMXNET3_REG_VRRS], size %d", size);
            ret = VMXNET3_DEVICE_REVISION;
            break;

        /* UPT Version Report Selection */
        case VMXNET3_REG_UVRS:
            VMW_CBPRN("Read BAR1 [VMXNET3_REG_UVRS], size %d", size);
            ret = VMXNET3_UPT_REVISION;
            break;

        /* Command */
        case VMXNET3_REG_CMD:
            VMW_CBPRN("Read BAR1 [VMXNET3_REG_CMD], size %d", size);
            ret = vmxnet3_get_command_status(s);
            break;

        /* MAC Address Low */
        case VMXNET3_REG_MACL:
            VMW_CBPRN("Read BAR1 [VMXNET3_REG_MACL], size %d", size);
            ret = vmxnet3_get_mac_low(&s->conf.macaddr);
            break;

        /* MAC Address High */
        case VMXNET3_REG_MACH:
            VMW_CBPRN("Read BAR1 [VMXNET3_REG_MACH], size %d", size);
            ret = vmxnet3_get_mac_high(&s->conf.macaddr);
            break;

        /*
         * Interrupt Cause Register
         * Used for legacy interrupts only so interrupt index always 0
         */
        case VMXNET3_REG_ICR:
            VMW_CBPRN("Read BAR1 [VMXNET3_REG_ICR], size %d", size);
            if (vmxnet3_interrupt_asserted(s, 0)) {
                vmxnet3_clear_interrupt(s, 0);
                ret = true;
            } else {
                ret = false;
            }
            break;

        default:
            VMW_CBPRN("Unknow read BAR1[%" PRIx64 "], %d bytes", addr, size);
            break;
        }

        return ret;
}

static int
vmxnet3_can_receive(NetClientState *nc)
{
    VMXNET3State *s = qemu_get_nic_opaque(nc);
    return s->device_active &&
           VMXNET_FLAG_IS_SET(s->link_status_and_speed, VMXNET3_LINK_STATUS_UP);
}

static inline bool
vmxnet3_is_registered_vlan(VMXNET3State *s, const void *data)
{
    uint16_t vlan_tag = eth_get_pkt_tci(data) & VLAN_VID_MASK;
    if (IS_SPECIAL_VLAN_ID(vlan_tag)) {
        return true;
    }

    return VMXNET3_VFTABLE_ENTRY_IS_SET(s->vlan_table, vlan_tag);
}

static bool
vmxnet3_is_allowed_mcast_group(VMXNET3State *s, const uint8_t *group_mac)
{
    int i;
    for (i = 0; i < s->mcast_list_len; i++) {
        if (!memcmp(group_mac, s->mcast_list[i].a, sizeof(s->mcast_list[i]))) {
            return true;
        }
    }
    return false;
}

static bool
vmxnet3_rx_filter_may_indicate(VMXNET3State *s, const void *data,
    size_t size)
{
    struct eth_header *ehdr = PKT_GET_ETH_HDR(data);

    if (VMXNET_FLAG_IS_SET(s->rx_mode, VMXNET3_RXM_PROMISC)) {
        return true;
    }

    if (!vmxnet3_is_registered_vlan(s, data)) {
        return false;
    }

    switch (net_rx_pkt_get_packet_type(s->rx_pkt)) {
    case ETH_PKT_UCAST:
        if (!VMXNET_FLAG_IS_SET(s->rx_mode, VMXNET3_RXM_UCAST)) {
            return false;
        }
        if (memcmp(s->conf.macaddr.a, ehdr->h_dest, ETH_ALEN)) {
            return false;
        }
        break;

    case ETH_PKT_BCAST:
        if (!VMXNET_FLAG_IS_SET(s->rx_mode, VMXNET3_RXM_BCAST)) {
            return false;
        }
        break;

    case ETH_PKT_MCAST:
        if (VMXNET_FLAG_IS_SET(s->rx_mode, VMXNET3_RXM_ALL_MULTI)) {
            return true;
        }
        if (!VMXNET_FLAG_IS_SET(s->rx_mode, VMXNET3_RXM_MCAST)) {
            return false;
        }
        if (!vmxnet3_is_allowed_mcast_group(s, ehdr->h_dest)) {
            return false;
        }
        break;

    default:
        g_assert_not_reached();
    }

    return true;
}

static ssize_t
vmxnet3_receive(NetClientState *nc, const uint8_t *buf, size_t size)
{
    VMXNET3State *s = qemu_get_nic_opaque(nc);
    size_t bytes_indicated;
    uint8_t min_buf[MIN_BUF_SIZE];

    if (!vmxnet3_can_receive(nc)) {
        VMW_PKPRN("Cannot receive now");
        return -1;
    }

    if (s->peer_has_vhdr) {
        net_rx_pkt_set_vhdr(s->rx_pkt, (struct virtio_net_hdr *)buf);
        buf += sizeof(struct virtio_net_hdr);
        size -= sizeof(struct virtio_net_hdr);
    }

    /* Pad to minimum Ethernet frame length */
    if (size < sizeof(min_buf)) {
        memcpy(min_buf, buf, size);
        memset(&min_buf[size], 0, sizeof(min_buf) - size);
        buf = min_buf;
        size = sizeof(min_buf);
    }

    net_rx_pkt_set_packet_type(s->rx_pkt,
        get_eth_packet_type(PKT_GET_ETH_HDR(buf)));

    if (vmxnet3_rx_filter_may_indicate(s, buf, size)) {
        net_rx_pkt_set_protocols(s->rx_pkt, buf, size);
        vmxnet3_rx_need_csum_calculate(s->rx_pkt, buf, size);
        net_rx_pkt_attach_data(s->rx_pkt, buf, size, s->rx_vlan_stripping);
        bytes_indicated = vmxnet3_indicate_packet(s) ? size : -1;
        if (bytes_indicated < size) {
            VMW_PKPRN("RX: %zu of %zu bytes indicated", bytes_indicated, size);
        }
    } else {
        VMW_PKPRN("Packet dropped by RX filter");
        bytes_indicated = size;
    }

    assert(size > 0);
    assert(bytes_indicated != 0);
    return bytes_indicated;
}

static void vmxnet3_set_link_status(NetClientState *nc)
{
    VMXNET3State *s = qemu_get_nic_opaque(nc);

    if (nc->link_down) {
        s->link_status_and_speed &= ~VMXNET3_LINK_STATUS_UP;
    } else {
        s->link_status_and_speed |= VMXNET3_LINK_STATUS_UP;
    }

    vmxnet3_set_events(s, VMXNET3_ECR_LINK);
    vmxnet3_trigger_interrupt(s, s->event_int_idx);
}

static NetClientInfo net_vmxnet3_info = {
        .type = NET_CLIENT_DRIVER_NIC,
        .size = sizeof(NICState),
        .receive = vmxnet3_receive,
        .link_status_changed = vmxnet3_set_link_status,
};

static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s)
{
    NetClientState *nc = qemu_get_queue(s->nic);

    if (qemu_has_vnet_hdr(nc->peer)) {
        return true;
    }

    return false;
}

static void vmxnet3_net_uninit(VMXNET3State *s)
{
    g_free(s->mcast_list);
    vmxnet3_deactivate_device(s);
    qemu_del_nic(s->nic);
}

static void vmxnet3_net_init(VMXNET3State *s)
{
    DeviceState *d = DEVICE(s);

    VMW_CBPRN("vmxnet3_net_init called...");

    qemu_macaddr_default_if_unset(&s->conf.macaddr);

    /* Windows guest will query the address that was set on init */
    memcpy(&s->perm_mac.a, &s->conf.macaddr.a, sizeof(s->perm_mac.a));

    s->mcast_list = NULL;
    s->mcast_list_len = 0;

    s->link_status_and_speed = VMXNET3_LINK_SPEED | VMXNET3_LINK_STATUS_UP;

    VMW_CFPRN("Permanent MAC: " MAC_FMT, MAC_ARG(s->perm_mac.a));

    s->nic = qemu_new_nic(&net_vmxnet3_info, &s->conf,
                          object_get_typename(OBJECT(s)),
                          d->id, s);

    s->peer_has_vhdr = vmxnet3_peer_has_vnet_hdr(s);
    s->tx_sop = true;
    s->skip_current_tx_pkt = false;
    s->tx_pkt = NULL;
    s->rx_pkt = NULL;
    s->rx_vlan_stripping = false;
    s->lro_supported = false;

    if (s->peer_has_vhdr) {
        qemu_set_vnet_hdr_len(qemu_get_queue(s->nic)->peer,
            sizeof(struct virtio_net_hdr));

        qemu_using_vnet_hdr(qemu_get_queue(s->nic)->peer, 1);
    }

    qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
}

static void
vmxnet3_unuse_msix_vectors(VMXNET3State *s, int num_vectors)
{
    PCIDevice *d = PCI_DEVICE(s);
    int i;
    for (i = 0; i < num_vectors; i++) {
        msix_vector_unuse(d, i);
    }
}

static bool
vmxnet3_use_msix_vectors(VMXNET3State *s, int num_vectors)
{
    PCIDevice *d = PCI_DEVICE(s);
    int i;
    for (i = 0; i < num_vectors; i++) {
        int res = msix_vector_use(d, i);
        if (0 > res) {
            VMW_WRPRN("Failed to use MSI-X vector %d, error %d", i, res);
            vmxnet3_unuse_msix_vectors(s, i);
            return false;
        }
    }
    return true;
}

static bool
vmxnet3_init_msix(VMXNET3State *s)
{
    PCIDevice *d = PCI_DEVICE(s);
    int res = msix_init(d, VMXNET3_MAX_INTRS,
                        &s->msix_bar,
                        VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_TABLE,
                        &s->msix_bar,
                        VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_PBA(s),
                        VMXNET3_MSIX_OFFSET(s), NULL);

    if (0 > res) {
        VMW_WRPRN("Failed to initialize MSI-X, error %d", res);
        s->msix_used = false;
    } else {
        if (!vmxnet3_use_msix_vectors(s, VMXNET3_MAX_INTRS)) {
            VMW_WRPRN("Failed to use MSI-X vectors, error %d", res);
            msix_uninit(d, &s->msix_bar, &s->msix_bar);
            s->msix_used = false;
        } else {
            s->msix_used = true;
        }
    }
    return s->msix_used;
}

static void
vmxnet3_cleanup_msix(VMXNET3State *s)
{
    PCIDevice *d = PCI_DEVICE(s);

    if (s->msix_used) {
        vmxnet3_unuse_msix_vectors(s, VMXNET3_MAX_INTRS);
        msix_uninit(d, &s->msix_bar, &s->msix_bar);
    }
}

static void
vmxnet3_cleanup_msi(VMXNET3State *s)
{
    PCIDevice *d = PCI_DEVICE(s);

    msi_uninit(d);
}

static const MemoryRegionOps b0_ops = {
    .read = vmxnet3_io_bar0_read,
    .write = vmxnet3_io_bar0_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
            .min_access_size = 4,
            .max_access_size = 4,
    },
};

static const MemoryRegionOps b1_ops = {
    .read = vmxnet3_io_bar1_read,
    .write = vmxnet3_io_bar1_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .impl = {
            .min_access_size = 4,
            .max_access_size = 4,
    },
};

static uint64_t vmxnet3_device_serial_num(VMXNET3State *s)
{
    uint64_t dsn_payload;
    uint8_t *dsnp = (uint8_t *)&dsn_payload;

    dsnp[0] = 0xfe;
    dsnp[1] = s->conf.macaddr.a[3];
    dsnp[2] = s->conf.macaddr.a[4];
    dsnp[3] = s->conf.macaddr.a[5];
    dsnp[4] = s->conf.macaddr.a[0];
    dsnp[5] = s->conf.macaddr.a[1];
    dsnp[6] = s->conf.macaddr.a[2];
    dsnp[7] = 0xff;
    return dsn_payload;
}


#define VMXNET3_USE_64BIT         (true)
#define VMXNET3_PER_VECTOR_MASK   (false)

static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp)
{
    VMXNET3State *s = VMXNET3(pci_dev);
    int ret;

    VMW_CBPRN("Starting init...");

    memory_region_init_io(&s->bar0, OBJECT(s), &b0_ops, s,
                          "vmxnet3-b0", VMXNET3_PT_REG_SIZE);
    pci_register_bar(pci_dev, VMXNET3_BAR0_IDX,
                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar0);

    memory_region_init_io(&s->bar1, OBJECT(s), &b1_ops, s,
                          "vmxnet3-b1", VMXNET3_VD_REG_SIZE);
    pci_register_bar(pci_dev, VMXNET3_BAR1_IDX,
                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->bar1);

    memory_region_init(&s->msix_bar, OBJECT(s), "vmxnet3-msix-bar",
                       VMXNET3_MSIX_BAR_SIZE);
    pci_register_bar(pci_dev, VMXNET3_MSIX_BAR_IDX,
                     PCI_BASE_ADDRESS_SPACE_MEMORY, &s->msix_bar);

    vmxnet3_reset_interrupt_states(s);

    /* Interrupt pin A */
    pci_dev->config[PCI_INTERRUPT_PIN] = 0x01;

    ret = msi_init(pci_dev, VMXNET3_MSI_OFFSET(s), VMXNET3_MAX_NMSIX_INTRS,
                   VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK, NULL);
    /* Any error other than -ENOTSUP(board's MSI support is broken)
     * is a programming error. Fall back to INTx silently on -ENOTSUP */
    assert(!ret || ret == -ENOTSUP);

    if (!vmxnet3_init_msix(s)) {
        VMW_WRPRN("Failed to initialize MSI-X, configuration is inconsistent.");
    }

    vmxnet3_net_init(s);

    if (pci_is_express(pci_dev)) {
        if (pci_bus_is_express(pci_get_bus(pci_dev))) {
            pcie_endpoint_cap_init(pci_dev, VMXNET3_EXP_EP_OFFSET);
        }

        pcie_dev_ser_num_init(pci_dev, VMXNET3_DSN_OFFSET,
                              vmxnet3_device_serial_num(s));
    }
}

static void vmxnet3_instance_init(Object *obj)
{
    VMXNET3State *s = VMXNET3(obj);
    device_add_bootindex_property(obj, &s->conf.bootindex,
                                  "bootindex", "/ethernet-phy@0",
                                  DEVICE(obj), NULL);
}

static void vmxnet3_pci_uninit(PCIDevice *pci_dev)
{
    VMXNET3State *s = VMXNET3(pci_dev);

    VMW_CBPRN("Starting uninit...");

    vmxnet3_net_uninit(s);

    vmxnet3_cleanup_msix(s);

    vmxnet3_cleanup_msi(s);
}

static void vmxnet3_qdev_reset(DeviceState *dev)
{
    PCIDevice *d = PCI_DEVICE(dev);
    VMXNET3State *s = VMXNET3(d);

    VMW_CBPRN("Starting QDEV reset...");
    vmxnet3_reset(s);
}

static bool vmxnet3_mc_list_needed(void *opaque)
{
    return true;
}

static int vmxnet3_mcast_list_pre_load(void *opaque)
{
    VMXNET3State *s = opaque;

    s->mcast_list = g_malloc(s->mcast_list_buff_size);

    return 0;
}


static int vmxnet3_pre_save(void *opaque)
{
    VMXNET3State *s = opaque;

    s->mcast_list_buff_size = s->mcast_list_len * sizeof(MACAddr);

    return 0;
}

static const VMStateDescription vmxstate_vmxnet3_mcast_list = {
    .name = "vmxnet3/mcast_list",
    .version_id = 1,
    .minimum_version_id = 1,
    .pre_load = vmxnet3_mcast_list_pre_load,
    .needed = vmxnet3_mc_list_needed,
    .fields = (VMStateField[]) {
        VMSTATE_VBUFFER_UINT32(mcast_list, VMXNET3State, 0, NULL,
            mcast_list_buff_size),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_vmxnet3_ring = {
    .name = "vmxnet3-ring",
    .version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(pa, Vmxnet3Ring),
        VMSTATE_UINT32(size, Vmxnet3Ring),
        VMSTATE_UINT32(cell_size, Vmxnet3Ring),
        VMSTATE_UINT32(next, Vmxnet3Ring),
        VMSTATE_UINT8(gen, Vmxnet3Ring),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_vmxnet3_tx_stats = {
    .name = "vmxnet3-tx-stats",
    .version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(TSOPktsTxOK, struct UPT1_TxStats),
        VMSTATE_UINT64(TSOBytesTxOK, struct UPT1_TxStats),
        VMSTATE_UINT64(ucastPktsTxOK, struct UPT1_TxStats),
        VMSTATE_UINT64(ucastBytesTxOK, struct UPT1_TxStats),
        VMSTATE_UINT64(mcastPktsTxOK, struct UPT1_TxStats),
        VMSTATE_UINT64(mcastBytesTxOK, struct UPT1_TxStats),
        VMSTATE_UINT64(bcastPktsTxOK, struct UPT1_TxStats),
        VMSTATE_UINT64(bcastBytesTxOK, struct UPT1_TxStats),
        VMSTATE_UINT64(pktsTxError, struct UPT1_TxStats),
        VMSTATE_UINT64(pktsTxDiscard, struct UPT1_TxStats),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_vmxnet3_txq_descr = {
    .name = "vmxnet3-txq-descr",
    .version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT(tx_ring, Vmxnet3TxqDescr, 0, vmstate_vmxnet3_ring,
                       Vmxnet3Ring),
        VMSTATE_STRUCT(comp_ring, Vmxnet3TxqDescr, 0, vmstate_vmxnet3_ring,
                       Vmxnet3Ring),
        VMSTATE_UINT8(intr_idx, Vmxnet3TxqDescr),
        VMSTATE_UINT64(tx_stats_pa, Vmxnet3TxqDescr),
        VMSTATE_STRUCT(txq_stats, Vmxnet3TxqDescr, 0, vmstate_vmxnet3_tx_stats,
                       struct UPT1_TxStats),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_vmxnet3_rx_stats = {
    .name = "vmxnet3-rx-stats",
    .version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(LROPktsRxOK, struct UPT1_RxStats),
        VMSTATE_UINT64(LROBytesRxOK, struct UPT1_RxStats),
        VMSTATE_UINT64(ucastPktsRxOK, struct UPT1_RxStats),
        VMSTATE_UINT64(ucastBytesRxOK, struct UPT1_RxStats),
        VMSTATE_UINT64(mcastPktsRxOK, struct UPT1_RxStats),
        VMSTATE_UINT64(mcastBytesRxOK, struct UPT1_RxStats),
        VMSTATE_UINT64(bcastPktsRxOK, struct UPT1_RxStats),
        VMSTATE_UINT64(bcastBytesRxOK, struct UPT1_RxStats),
        VMSTATE_UINT64(pktsRxOutOfBuf, struct UPT1_RxStats),
        VMSTATE_UINT64(pktsRxError, struct UPT1_RxStats),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_vmxnet3_rxq_descr = {
    .name = "vmxnet3-rxq-descr",
    .version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT_ARRAY(rx_ring, Vmxnet3RxqDescr,
                             VMXNET3_RX_RINGS_PER_QUEUE, 0,
                             vmstate_vmxnet3_ring, Vmxnet3Ring),
        VMSTATE_STRUCT(comp_ring, Vmxnet3RxqDescr, 0, vmstate_vmxnet3_ring,
                       Vmxnet3Ring),
        VMSTATE_UINT8(intr_idx, Vmxnet3RxqDescr),
        VMSTATE_UINT64(rx_stats_pa, Vmxnet3RxqDescr),
        VMSTATE_STRUCT(rxq_stats, Vmxnet3RxqDescr, 0, vmstate_vmxnet3_rx_stats,
                       struct UPT1_RxStats),
        VMSTATE_END_OF_LIST()
    }
};

static int vmxnet3_post_load(void *opaque, int version_id)
{
    VMXNET3State *s = opaque;
    PCIDevice *d = PCI_DEVICE(s);

    net_tx_pkt_init(&s->tx_pkt, PCI_DEVICE(s),
                    s->max_tx_frags, s->peer_has_vhdr);
    net_rx_pkt_init(&s->rx_pkt, s->peer_has_vhdr);

    if (s->msix_used) {
        if  (!vmxnet3_use_msix_vectors(s, VMXNET3_MAX_INTRS)) {
            VMW_WRPRN("Failed to re-use MSI-X vectors");
            msix_uninit(d, &s->msix_bar, &s->msix_bar);
            s->msix_used = false;
            return -1;
        }
    }

    vmxnet3_validate_queues(s);
    vmxnet3_validate_interrupts(s);

    return 0;
}

static const VMStateDescription vmstate_vmxnet3_int_state = {
    .name = "vmxnet3-int-state",
    .version_id = 0,
    .fields = (VMStateField[]) {
        VMSTATE_BOOL(is_masked, Vmxnet3IntState),
        VMSTATE_BOOL(is_pending, Vmxnet3IntState),
        VMSTATE_BOOL(is_asserted, Vmxnet3IntState),
        VMSTATE_END_OF_LIST()
    }
};

static const VMStateDescription vmstate_vmxnet3 = {
    .name = "vmxnet3",
    .version_id = 1,
    .minimum_version_id = 1,
    .pre_save = vmxnet3_pre_save,
    .post_load = vmxnet3_post_load,
    .fields = (VMStateField[]) {
            VMSTATE_PCI_DEVICE(parent_obj, VMXNET3State),
            VMSTATE_MSIX(parent_obj, VMXNET3State),
            VMSTATE_BOOL(rx_packets_compound, VMXNET3State),
            VMSTATE_BOOL(rx_vlan_stripping, VMXNET3State),
            VMSTATE_BOOL(lro_supported, VMXNET3State),
            VMSTATE_UINT32(rx_mode, VMXNET3State),
            VMSTATE_UINT32(mcast_list_len, VMXNET3State),
            VMSTATE_UINT32(mcast_list_buff_size, VMXNET3State),
            VMSTATE_UINT32_ARRAY(vlan_table, VMXNET3State, VMXNET3_VFT_SIZE),
            VMSTATE_UINT32(mtu, VMXNET3State),
            VMSTATE_UINT16(max_rx_frags, VMXNET3State),
            VMSTATE_UINT32(max_tx_frags, VMXNET3State),
            VMSTATE_UINT8(event_int_idx, VMXNET3State),
            VMSTATE_BOOL(auto_int_masking, VMXNET3State),
            VMSTATE_UINT8(txq_num, VMXNET3State),
            VMSTATE_UINT8(rxq_num, VMXNET3State),
            VMSTATE_UINT32(device_active, VMXNET3State),
            VMSTATE_UINT32(last_command, VMXNET3State),
            VMSTATE_UINT32(link_status_and_speed, VMXNET3State),
            VMSTATE_UINT32(temp_mac, VMXNET3State),
            VMSTATE_UINT64(drv_shmem, VMXNET3State),
            VMSTATE_UINT64(temp_shared_guest_driver_memory, VMXNET3State),

            VMSTATE_STRUCT_ARRAY(txq_descr, VMXNET3State,
                VMXNET3_DEVICE_MAX_TX_QUEUES, 0, vmstate_vmxnet3_txq_descr,
                Vmxnet3TxqDescr),
            VMSTATE_STRUCT_ARRAY(rxq_descr, VMXNET3State,
                VMXNET3_DEVICE_MAX_RX_QUEUES, 0, vmstate_vmxnet3_rxq_descr,
                Vmxnet3RxqDescr),
            VMSTATE_STRUCT_ARRAY(interrupt_states, VMXNET3State,
                VMXNET3_MAX_INTRS, 0, vmstate_vmxnet3_int_state,
                Vmxnet3IntState),

            VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription*[]) {
        &vmxstate_vmxnet3_mcast_list,
        NULL
    }
};

static Property vmxnet3_properties[] = {
    DEFINE_NIC_PROPERTIES(VMXNET3State, conf),
    DEFINE_PROP_BIT("x-old-msi-offsets", VMXNET3State, compat_flags,
                    VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT, false),
    DEFINE_PROP_BIT("x-disable-pcie", VMXNET3State, compat_flags,
                    VMXNET3_COMPAT_FLAG_DISABLE_PCIE_BIT, false),
    DEFINE_PROP_END_OF_LIST(),
};

static void vmxnet3_realize(DeviceState *qdev, Error **errp)
{
    VMXNET3Class *vc = VMXNET3_DEVICE_GET_CLASS(qdev);
    PCIDevice *pci_dev = PCI_DEVICE(qdev);
    VMXNET3State *s = VMXNET3(qdev);

    if (!(s->compat_flags & VMXNET3_COMPAT_FLAG_DISABLE_PCIE)) {
        pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
    }

    vc->parent_dc_realize(qdev, errp);
}

static void vmxnet3_class_init(ObjectClass *class, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(class);
    PCIDeviceClass *c = PCI_DEVICE_CLASS(class);
    VMXNET3Class *vc = VMXNET3_DEVICE_CLASS(class);

    c->realize = vmxnet3_pci_realize;
    c->exit = vmxnet3_pci_uninit;
    c->vendor_id = PCI_VENDOR_ID_VMWARE;
    c->device_id = PCI_DEVICE_ID_VMWARE_VMXNET3;
    c->revision = PCI_DEVICE_ID_VMWARE_VMXNET3_REVISION;
    c->romfile = "efi-vmxnet3.rom";
    c->class_id = PCI_CLASS_NETWORK_ETHERNET;
    c->subsystem_vendor_id = PCI_VENDOR_ID_VMWARE;
    c->subsystem_id = PCI_DEVICE_ID_VMWARE_VMXNET3;
    device_class_set_parent_realize(dc, vmxnet3_realize,
                                    &vc->parent_dc_realize);
    dc->desc = "VMWare Paravirtualized Ethernet v3";
    dc->reset = vmxnet3_qdev_reset;
    dc->vmsd = &vmstate_vmxnet3;
    device_class_set_props(dc, vmxnet3_properties);
    set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
}

static const TypeInfo vmxnet3_info = {
    .name          = TYPE_VMXNET3,
    .parent        = TYPE_PCI_DEVICE,
    .class_size    = sizeof(VMXNET3Class),
    .instance_size = sizeof(VMXNET3State),
    .class_init    = vmxnet3_class_init,
    .instance_init = vmxnet3_instance_init,
    .interfaces = (InterfaceInfo[]) {
        { INTERFACE_PCIE_DEVICE },
        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
        { }
    },
};

static void vmxnet3_register_types(void)
{
    VMW_CBPRN("vmxnet3_register_types called...");
    type_register_static(&vmxnet3_info);
}

type_init(vmxnet3_register_types)
