/*
 * 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"
#include "qom/object.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))

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

DECLARE_CLASS_CHECKERS(VMXNET3Class, VMXNET3_DEVICE,
                       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));
}

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)
