aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/vmxnet3/vmxnet3.h
diff options
context:
space:
mode:
authorSteven Luong <sluong@cisco.com>2018-03-18 08:01:27 -0700
committerSteven <sluong@cisco.com>2018-09-14 14:27:41 -0700
commitdf7f8e8cffcc43531f7daeda44d436b60e538141 (patch)
tree1ff98cd205995a3c499048c5f93b11c9feda39c6 /src/plugins/vmxnet3/vmxnet3.h
parentef90ed08fbcde7535b4a789349b39dc25798c77d (diff)
vmxnet3 device driver
Implemented vmxnet3 deivice driver for VMWare ESXi. Tested with Ubuntu 18.04 connected to ESXi 6.0 Ubuntu-18.04 (VPP) --- ESXi-6.0 Change-Id: I85fbc86f2d8532b017bc4271612d17e24e498e4d Signed-off-by: Steven Luong <sluong@cisco.com>
Diffstat (limited to 'src/plugins/vmxnet3/vmxnet3.h')
-rw-r--r--src/plugins/vmxnet3/vmxnet3.h639
1 files changed, 639 insertions, 0 deletions
diff --git a/src/plugins/vmxnet3/vmxnet3.h b/src/plugins/vmxnet3/vmxnet3.h
new file mode 100644
index 00000000000..13799407d1e
--- /dev/null
+++ b/src/plugins/vmxnet3/vmxnet3.h
@@ -0,0 +1,639 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __included_vmnet_vmnet_h__
+#define __included_vmnet_vmnet_h__
+
+#define foreach_vmxnet3_tx_func_error \
+ _(ERROR_PACKETS, "error packets") \
+ _(NO_FREE_SLOTS, "no free tx slots")
+
+typedef enum
+{
+#define _(f,s) VMXNET3_TX_ERROR_##f,
+ foreach_vmxnet3_tx_func_error
+#undef _
+ VMXNET3_TX_N_ERROR,
+} vmxnet3_tx_func_error_t;
+
+#define foreach_vmxnet3_rxmode_flags \
+ _(0, UCAST, "unicast") \
+ _(1, MCAST, "multicast") \
+ _(2, BCAST, "broadcast") \
+ _(3, ALL_MULTI, "all multicast") \
+ _(4, PROMISC, "promiscuous")
+
+enum
+{
+#define _(a, b, c) VMXNET3_RXMODE_##b = (1 << a),
+ foreach_vmxnet3_rxmode_flags
+#undef _
+};
+
+/* BAR 0 */
+#define VMXNET3_REG_IMR 0x0000 /* Interrupt Mask Register */
+#define VMXNET3_REG_TXPROD 0x0600 /* Tx Producer Index */
+#define VMXNET3_REG_RXPROD 0x0800 /* Rx Producer Index for ring 1 */
+#define VMXNET3_REG_RXPROD2 0x0A00 /* Rx Producer Index for ring 2 */
+
+
+/* BAR 1 */
+#define VMXNET3_REG_VRRS 0x0000 /* VMXNET3 Revision Report Selection */
+#define VMXNET3_REG_UVRS 0x0008 /* UPT Version Report Selection */
+#define VMXNET3_REG_DSAL 0x0010 /* Driver Shared Address Low */
+#define VMXNET3_REG_DSAH 0x0018 /* Driver Shared Address High */
+#define VMXNET3_REG_CMD 0x0020 /* Command */
+#define VMXNET3_REG_MACL 0x0028 /* MAC Address Low */
+#define VMXNET3_REG_MACH 0x0030 /* MAC Address High */
+#define VMXNET3_REG_ICR 0x0038 /* Interrupt Cause Register */
+#define VMXNET3_REG_ECR 0x0040 /* Event Cause Register */
+
+#define VMXNET3_VLAN_LEN 4
+#define VMXNET3_FCS_LEN 4
+#define VMXNET3_MTU (1514 + VMXNET3_VLAN_LEN + VMXNET3_FCS_LEN)
+
+#define VMXNET3_RXF_BTYPE (1 << 14) /* rx body buffer type */
+#define VMXNET3_RXF_GEN (1 << 31) /* rx generation */
+#define VMXNET3_RXCF_GEN (1 << 31) /* rx completion generation */
+#define VMXNET3_RXC_INDEX (0xFFF) /* rx completion index mask */
+
+#define VMXNET3_TXF_GEN (1 << 14) /* tx generation */
+#define VMXNET3_TXF_EOP (1 << 12) /* tx end of packet */
+#define VMXNET3_TXF_CQ (1 << 13) /* tx completion request */
+#define VMXNET3_TXCF_GEN (1 << 31) /* tx completion generation */
+#define VMXNET3_TXC_INDEX (0xFFF) /* tx completion index mask */
+
+#define VMXNET3_RX_RING_SIZE 2
+#define VMXNET3_INPUT_REFILL_THRESHOLD 32
+#define VMXNET3_NUM_TX_DESC 1024
+#define VMXNET3_NUM_TX_COMP VMXNET3_NUM_TX_DESC
+#define VMXNET3_NUM_RX_DESC 1024
+#define VMXNET3_NUM_RX_COMP VMXNET3_NUM_RX_DESC
+
+#define VMXNET3_VERSION_MAGIC 0x69505845
+#define VMXNET3_SHARED_MAGIC 0xbabefee1
+#define VMXNET3_VERSION_SELECT 1
+#define VMXNET3_UPT_VERSION_SELECT 1
+#define VMXNET3_MAX_INTRS 25
+#define VMXNET3_IC_DISABLE_ALL 0x1
+
+#define VMXNET3_GOS_BITS_32 (1 << 0)
+#define VMXNET3_GOS_BITS_64 (2 << 0)
+#define VMXNET3_GOS_TYPE_LINUX (1 << 2)
+#define VMXNET3_RXCL_LEN_MASK (0x3FFF) // 14 bits
+#define VMXNET3_RXCL_ERROR (1 << 14)
+#define VMXNET3_RXCI_EOP (1 << 14)
+#define VMXNET3_RXCI_SOP (1 << 15)
+
+#define foreach_vmxnet3_device_flags \
+ _(0, INITIALIZED, "initialized") \
+ _(1, ERROR, "error") \
+ _(2, ADMIN_UP, "admin-up") \
+ _(3, IOVA, "iova") \
+ _(4, LINK_UP, "link-up") \
+ _(5, SHARED_TXQ_LOCK, "shared-txq-lock") \
+ _(6, ELOG, "elog")
+
+enum
+{
+#define _(a, b, c) VMXNET3_DEVICE_F_##b = (1 << a),
+ foreach_vmxnet3_device_flags
+#undef _
+};
+
+#define foreach_vmxnet3_set_cmds \
+ _(0, ACTIVATE_DEV, "activate device") \
+ _(1, QUIESCE_DEV, "quiesce device") \
+ _(2, RESET_DEV, "reset device") \
+ _(3, UPDATE_RX_MODE, "update rx mode") \
+ _(4, UPDATE_MAC_FILTERS, "update mac filters") \
+ _(5, UPDATE_VLAN_FILTERS, "update vlan filters") \
+ _(6, UPDATE_RSSIDT, "update rss idt") \
+ _(7, UPDATE_IML, "update iml") \
+ _(8, UPDATE_PMCFG, "update pm cfg") \
+ _(9, UPDATE_FEATURE, "update feature") \
+ _(10, STOP_EMULATION, "stop emulation") \
+ _(11, LOAD_PLUGIN, "load plugin") \
+ _(12, ACTIVATE_VF, "activate vf") \
+ _(13, RESERVED3, "reserved 3") \
+ _(14, RESERVED4, "reservced 4") \
+ _(15, REGISTER_MEMREGS, "register mem regs")
+
+enum
+{
+#define _(a, b, c) VMXNET3_CMD_##b = (a + 0xCAFE0000),
+ foreach_vmxnet3_set_cmds
+#undef _
+};
+
+#define foreach_vmxnet3_get_cmds \
+ _(0, GET_QUEUE_STATUS, "get queue status") \
+ _(1, GET_STATS, "get stats") \
+ _(2, GET_LINK, "get link") \
+ _(3, GET_PERM_MAC_LO, "get perm mac lo") \
+ _(4, GET_PERM_MAC_HI, "get perm mac hi") \
+ _(5, GET_DID_LO, "get did lo") \
+ _(6, GET_DID_HI, "get did hi") \
+ _(7, GET_DEV_EXTRA_INFO, "get dev extra info") \
+ _(8, GET_CONF_INTR, "get conf intr") \
+ _(9, GET_ADAPTIVE_RING_INFO, "get adaptive ring info") \
+ _(10, GET_TXDATA_DESC_SIZE, "gte txdata desc size") \
+ _(11, RESERVED5, "reserved5")
+
+enum
+{
+#define _(a, b, c) VMXNET3_CMD_##b = (a + 0xF00D0000),
+ foreach_vmxnet3_get_cmds
+#undef _
+};
+
+typedef CLIB_PACKED (struct
+ {
+ u32 version; u32 guest_info; u32 version_support;
+ u32 upt_version_support; u64 upt_features;
+ u64 driver_data_address; u64 queue_desc_address;
+ u32 driver_data_len; u32 queue_desc_len;
+ u32 mtu;
+ u16 max_num_rx_sg; u8 num_tx_queues; u8 num_rx_queues;
+ u32 pad[4];
+ }) vmxnet3_misc_config;
+
+typedef CLIB_PACKED (struct
+ {
+ u8 mask_mode;
+ u8 num_intrs;
+ u8 event_intr_index;
+ u8 moderation_level[VMXNET3_MAX_INTRS]; u32 control;
+ u32 pad[2];
+ }) vmxnet3_interrupt_config;
+
+typedef CLIB_PACKED (struct
+ {
+ u32 mode;
+ u16 multicast_len;
+ u16 pad; u64 multicast_address; u8 vlan_filter[512];
+ }) vmxnet3_rx_filter_config;
+
+typedef CLIB_PACKED (struct
+ {
+ u32 version; u32 length;
+ u64 address;
+ }) vmxnet3_variable_config;
+
+typedef CLIB_PACKED (struct
+ {
+ u32 magic;
+ u32 pad;
+ vmxnet3_misc_config misc;
+ vmxnet3_interrupt_config interrupt;
+ vmxnet3_rx_filter_config rx_filter;
+ vmxnet3_variable_config rss;
+ vmxnet3_variable_config pattern;
+ vmxnet3_variable_config plugin; u32 ecr;
+ u32 pad1[5];
+ }) vmxnet3_shared;
+
+typedef CLIB_PACKED (struct
+ {
+ u8 stopped;
+ u8 pad[3];
+ u32 error;
+ }) vmxnet3_queue_status;
+
+typedef CLIB_PACKED (struct
+ {
+ u32 num_deferred; u32 threshold;
+ u64 pad;
+ }) vmxnet3_tx_queue_control;
+
+typedef CLIB_PACKED (struct
+ {
+ u64 desc_address;
+ u64 data_address;
+ u64 comp_address; u64 driver_data_address; u64 pad;
+ u32 num_desc;
+ u32 num_data;
+ u32 num_comp; u32 driver_data_len; u8 intr_index;
+ u8 pad1[7];
+ }) vmxnet3_tx_queue_config;
+
+typedef CLIB_PACKED (struct
+ {
+ u64 tso_pkts;
+ u64 tso_bytes;
+ u64 ucast_pkts; u64 ucast_bytes; u64 mcast_pkts;
+ u64 mcast_bytes;
+ u64 bcast_pkts; u64 bcast_bytes; u64 error_pkts;
+ u64 discard_pkts;
+ }) vmxnet3_tx_stats;
+
+typedef CLIB_PACKED (struct
+ {
+ vmxnet3_tx_queue_control ctrl;
+ vmxnet3_tx_queue_config cfg;
+ vmxnet3_queue_status status; vmxnet3_tx_stats stats;
+ u8 pad[88];
+ }) vmxnet3_tx_queue;
+
+typedef CLIB_PACKED (struct
+ {
+ u8 update_prod; u8 pad[7];
+ u64 pad1;
+ }) vmxnet3_rx_queue_control;
+
+typedef CLIB_PACKED (struct
+ {
+ u64 desc_address[2];
+ u64 comp_address; u64 driver_data_address; u64 pad;
+ u32 num_desc[2];
+ u32 num_comp; u32 driver_data_len; u8 intr_index;
+ u8 pad1[7];
+ }) vmxnet3_rx_queue_config;
+
+typedef CLIB_PACKED (struct
+ {
+ u64 lro_pkts;
+ u64 lro_bytes;
+ u64 ucast_pkts; u64 ucast_bytes; u64 mcast_pkts;
+ u64 mcast_bytes;
+ u64 bcast_pkts; u64 bcast_bytes; u64 nobuf_pkts;
+ u64 error_pkts;
+ }) vmxnet3_rx_stats;
+
+typedef CLIB_PACKED (struct
+ {
+ vmxnet3_rx_queue_control ctrl;
+ vmxnet3_rx_queue_config cfg;
+ vmxnet3_queue_status status; vmxnet3_rx_stats stats;
+ u8 pad[88];
+ }) vmxnet3_rx_queue;
+
+typedef CLIB_PACKED (struct
+ {
+ vmxnet3_tx_queue tx; vmxnet3_rx_queue rx;
+ }) vmxnet3_queues;
+
+/*
+ * flags:
+ * buffer length -- bits 0-13
+ * buffer type -- bit 14
+ * descriptor type -- bit 15
+ * reserved -- bits 16-30
+ * generation -- bit 31
+ */
+typedef CLIB_PACKED (struct
+ {
+ u64 address;
+ u32 flags;
+ u32 pad;
+ }) vmxnet3_rx_desc;
+
+/*
+ * index:
+ * RX desc index -- bits 0-11
+ * ext1 -- bits 12-13
+ * end of packet -- bit 14
+ * start of packet -- bit 15
+ * ring ID -- bits 16-25
+ * RSS hash type -- bits 26-29
+ * checksum not calculated -- bit 30
+ * ext2 -- bit 31
+ *
+ * rss: RSS hash value
+ *
+ * len:
+ * data length -- bits 0-13
+ * error -- bit 14
+ * tag is stripped -- bit 15
+ * tag stripped -- bits 16-31
+ *
+ * flags:
+ * checksum -- bits 0 - 15
+ * tcp/udp checksum correct-- bit 16
+ * udp packet -- bit 17
+ * tcp packet -- bit 18
+ * ip checksum correct -- bit 19
+ * ipv6 -- bit 20
+ * ipv4 -- bit 21
+ * ip fragment -- bit 22
+ * frame crc correct -- bit 23
+ * completion type -- bits 24-30
+ * generation -- bit 31
+ */
+typedef CLIB_PACKED (struct
+ {
+ u32 index; u32 rss;
+ u32 len;
+ u32 flags;
+ }) vmxnet3_rx_comp;
+
+/*
+ * index:
+ * TX desc index -- bits 0-11
+ * ext1 -- bits 12-31
+ *
+ * flags:
+ * reserved -- bits 0-23
+ * completion type -- bits 24-30
+ * generation -- bit 31
+ */
+typedef CLIB_PACKED (struct
+ {
+ u32 index;
+ u32 pad[2];
+ u32 flags;
+ }) vmxnet3_tx_comp;
+
+/*
+ * flags[0]:
+ * length -- bits 0-13
+ * generation -- bit 14
+ * reserved -- bit 15
+ * descriptor type -- bit 16
+ * ext1 -- bit 17
+ * MSS, checksum offset -- bits 18-31
+ * flags[1]:
+ * header length -- bits 0-9
+ * offload mode -- bits 10-11
+ * end of packet -- bit 12
+ * completion request -- bit 13
+ * ext2 -- bit 14
+ * vlan tag insertion -- bit 15
+ * tag to insert -- bits 16-31
+ */
+typedef CLIB_PACKED (struct
+ {
+ u64 address;
+ u32 flags[2];
+ }) vmxnet3_tx_desc;
+
+typedef struct
+{
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+ u32 *bufs;
+ u32 gen;
+ u16 fill;
+ u16 rid;
+ u16 produce;
+ u16 consume;
+} vmxnet3_rx_ring;
+
+typedef struct
+{
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+ u64 next;
+ u32 gen;
+} vmxnet3_rx_comp_ring;
+
+typedef struct
+{
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+ u16 size;
+ u8 int_mode;
+ vmxnet3_rx_ring rx_ring[VMXNET3_RX_RING_SIZE];
+ vmxnet3_rx_desc *rx_desc[VMXNET3_RX_RING_SIZE];
+ vmxnet3_rx_comp *rx_comp;
+ vmxnet3_rx_comp_ring rx_comp_ring;
+} vmxnet3_rxq_t;
+
+typedef struct
+{
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+ u32 *bufs;
+ u32 gen;
+ u16 produce;
+ u16 consume;
+} vmxnet3_tx_ring;
+
+typedef struct
+{
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+ u64 next;
+ u32 gen;
+} vmxnet3_tx_comp_ring;
+
+typedef struct
+{
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+ u16 size;
+ clib_spinlock_t lock;
+
+ vmxnet3_tx_desc *tx_desc;
+ vmxnet3_tx_comp *tx_comp;
+ vmxnet3_tx_ring tx_ring;
+ vmxnet3_tx_comp_ring tx_comp_ring;
+} vmxnet3_txq_t;
+
+typedef CLIB_PACKED (struct
+ {
+ vmxnet3_queues queues; vmxnet3_shared shared;
+ }) vmxnet3_dma;
+
+typedef struct
+{
+ CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
+ u32 flags;
+ u32 per_interface_next_index;
+
+ u32 dev_instance;
+ u32 sw_if_index;
+ u32 hw_if_index;
+ vlib_pci_dev_handle_t pci_dev_handle;
+ vlib_pci_addr_t pci_addr;
+ void *bar[2];
+
+ /* queues */
+ vmxnet3_rxq_t *rxqs;
+ vmxnet3_txq_t *txqs;
+
+ u16 num_tx_queues;
+ u16 num_rx_queues;
+ u16 num_intrs;
+
+ u8 version;
+ u8 mac_addr[6];
+
+ /* error */
+ clib_error_t *error;
+
+ vmxnet3_dma *dma;
+
+} vmxnet3_device_t;
+
+typedef struct
+{
+ vmxnet3_device_t *devices;
+ vlib_physmem_region_index_t physmem_region;
+ u32 physmem_region_alloc;
+ u16 msg_id_base;
+} vmxnet3_main_t;
+
+extern vmxnet3_main_t vmxnet3_main;
+
+typedef struct
+{
+ vlib_pci_addr_t addr;
+ u32 enable_elog;
+ u16 rxq_size;
+ u16 txq_size;
+ /* return */
+ i32 rv;
+ u32 sw_if_index;
+ clib_error_t *error;
+} vmxnet3_create_if_args_t;
+
+typedef struct
+{
+ u32 next_index;
+ u32 hw_if_index;
+ vlib_buffer_t buffer;
+} vmxnet3_input_trace_t;
+
+void vmxnet3_create_if (vlib_main_t * vm, vmxnet3_create_if_args_t * args);
+void vmxnet3_delete_if (vlib_main_t * vm, vmxnet3_device_t * ad);
+
+extern clib_error_t *vmxnet3_plugin_api_hookup (vlib_main_t * vm);
+extern vlib_node_registration_t vmxnet3_input_node;
+extern vnet_device_class_t vmxnet3_device_class;
+
+/* format.c */
+format_function_t format_vmxnet3_device;
+format_function_t format_vmxnet3_device_name;
+format_function_t format_vmxnet3_input_trace;
+
+static_always_inline void
+vmxnet3_reg_write (vmxnet3_device_t * vd, u8 bar, u32 addr, u32 val)
+{
+ *(volatile u32 *) ((u8 *) vd->bar[bar] + addr) = val;
+}
+
+static_always_inline u32
+vmxnet3_reg_read (vmxnet3_device_t * vd, u8 bar, u32 addr)
+{
+ return *(volatile u32 *) (vd->bar[bar] + addr);
+}
+
+static_always_inline uword
+vmxnet3_dma_addr (vlib_main_t * vm, vmxnet3_device_t * vd, void *p)
+{
+ vmxnet3_main_t *vmxm = &vmxnet3_main;
+
+ return (vd->flags & VMXNET3_DEVICE_F_IOVA) ? pointer_to_uword (p) :
+ vlib_physmem_virtual_to_physical (vm, vmxm->physmem_region, p);
+}
+
+static_always_inline void
+vmxnet3_rx_ring_advance_produce (vmxnet3_rxq_t * rxq, vmxnet3_rx_ring * ring)
+{
+ ring->produce++;
+ if (PREDICT_FALSE (ring->produce == rxq->size))
+ {
+ ring->produce = 0;
+ ring->gen ^= VMXNET3_RXF_GEN;
+ }
+}
+
+static_always_inline clib_error_t *
+vmxnet3_rxq_refill_ring0 (vlib_main_t * vm, vmxnet3_device_t * vd,
+ vmxnet3_rxq_t * rxq)
+{
+ vmxnet3_rx_desc *rxd;
+ u16 n_refill, n_alloc;
+ vmxnet3_rx_ring *ring;
+
+ ring = &rxq->rx_ring[0];
+ n_refill = rxq->size - ring->fill;
+
+ if (PREDICT_TRUE (n_refill <= VMXNET3_INPUT_REFILL_THRESHOLD))
+ return 0;
+
+ n_alloc =
+ vlib_buffer_alloc_to_ring (vm, ring->bufs, ring->produce, rxq->size,
+ n_refill);
+ if (PREDICT_FALSE (n_alloc != n_refill))
+ {
+ if (n_alloc)
+ vlib_buffer_free_from_ring (vm, ring->bufs, ring->produce, rxq->size,
+ n_alloc);
+ return clib_error_return (0, "buffer alloc failed");
+ }
+
+ while (n_alloc)
+ {
+ rxd = &rxq->rx_desc[0][ring->produce];
+ rxd->address =
+ vlib_get_buffer_data_physical_address (vm, ring->bufs[ring->produce]);
+ rxd->flags = ring->gen | VLIB_BUFFER_DATA_SIZE;
+
+ vmxnet3_rx_ring_advance_produce (rxq, ring);
+ ring->fill++;
+ n_alloc--;
+ }
+
+ vmxnet3_reg_write (vd, 0, VMXNET3_REG_RXPROD, ring->produce);
+
+ return 0;
+}
+
+static_always_inline clib_error_t *
+vmxnet3_rxq_refill_ring1 (vlib_main_t * vm, vmxnet3_device_t * vd,
+ vmxnet3_rxq_t * rxq)
+{
+ vmxnet3_rx_desc *rxd;
+ u16 n_refill, n_alloc;
+ vmxnet3_rx_ring *ring;
+
+ ring = &rxq->rx_ring[1];
+ n_refill = rxq->size - ring->fill;
+
+ if (PREDICT_TRUE (n_refill <= VMXNET3_INPUT_REFILL_THRESHOLD))
+ return 0;
+
+ n_alloc =
+ vlib_buffer_alloc_to_ring (vm, ring->bufs, ring->produce, rxq->size,
+ n_refill);
+ if (PREDICT_FALSE (n_alloc != n_refill))
+ {
+ if (n_alloc)
+ vlib_buffer_free_from_ring (vm, ring->bufs, ring->produce, rxq->size,
+ n_alloc);
+ return clib_error_return (0, "buffer alloc failed");
+ }
+
+ while (n_alloc)
+ {
+ rxd = &rxq->rx_desc[1][ring->produce];
+ rxd->address =
+ vlib_get_buffer_data_physical_address (vm, ring->bufs[ring->produce]);
+ rxd->flags = ring->gen | VLIB_BUFFER_DATA_SIZE | VMXNET3_RXF_BTYPE;
+
+ vmxnet3_rx_ring_advance_produce (rxq, ring);
+ ring->fill++;
+ n_alloc--;
+ }
+
+ vmxnet3_reg_write (vd, 0, VMXNET3_REG_RXPROD2, ring->produce);
+
+ return 0;
+}
+
+#endif /* __included_vmnet_vmnet_h__ */
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */