21 #include <vpp/app/version.h> 25 #define PCI_VENDOR_ID_VMWARE 0x15ad 26 #define PCI_DEVICE_ID_VMWARE_VMXNET3 0x07b0 46 if (vd->
flags & VMXNET3_DEVICE_F_ERROR)
53 vd->
flags |= VMXNET3_DEVICE_F_ADMIN_UP;
58 vd->
flags &= ~VMXNET3_DEVICE_F_ADMIN_UP;
138 .name =
"VMXNET3 interface",
172 vmxnet3_shared *shared;
192 tx->cfg.num_desc = txq->
size;
193 tx->cfg.num_comp = txq->
size;
205 rx->cfg.num_desc[rid] = rxq->
size;
208 rx->cfg.num_comp = rxq->
size;
209 rx->cfg.intr_index = qid;
216 if (
sizeof (
void *) == 4)
222 shared->misc.upt_features = VMXNET3_F_RXCSUM;
224 shared->misc.upt_features |= VMXNET3_F_LRO;
227 shared->misc.upt_features |= VMXNET3_F_RSS;
228 shared->rss.version = 1;
230 shared->rss.length =
sizeof (*vd->
rss);
232 shared->misc.max_num_rx_sg = 0;
235 shared->misc.queue_desc_len =
sizeof (*tx) * vd->
num_tx_queues +
240 shared->interrupt.num_intrs = vd->
num_intrs;
243 shared->rx_filter.mode = VMXNET3_RXMODE_UCAST | VMXNET3_RXMODE_BCAST |
244 VMXNET3_RXMODE_ALL_MULTI | VMXNET3_RXMODE_PROMISC;
279 vmxnet3_rx_stats *rxs;
325 vmxnet3_tx_stats *txs;
334 vd->
flags |= VMXNET3_DEVICE_F_SHARED_TXQ_LOCK;
348 size = qsz *
sizeof (*txq->
tx_desc);
354 memset (txq->
tx_desc, 0, size);
356 size = qsz *
sizeof (*txq->
tx_comp);
371 0x3b, 0x56, 0xd1, 0x56, 0x13, 0x4a, 0xe7, 0xac,
372 0xe8, 0x79, 0x09, 0x75, 0xe8, 0x65, 0x79, 0x28,
373 0x35, 0x12, 0xb9, 0x56, 0x7c, 0x76, 0x4b, 0x70,
374 0xd8, 0x56, 0xa3, 0x18, 0x9b, 0x0a, 0xee, 0xf3,
375 0x96, 0xa6, 0x9f, 0x8f, 0x9e, 0x8c, 0x90, 0xc9,
381 vmxnet3_rss_shared *rss;
382 size_t size =
sizeof (*rss);
392 VMXNET3_RSS_HASH_TYPE_IPV4 | VMXNET3_RSS_HASH_TYPE_TCP_IPV4 |
393 VMXNET3_RSS_HASH_TYPE_IPV6 | VMXNET3_RSS_HASH_TYPE_TCP_IPV6;
398 for (i = 0; i < rss->ind_table_sz; i++)
463 "GSO is not supported because hardware version" 464 " is %u. It must be >= 3", vd->
version);
473 vd->
flags |= VMXNET3_DEVICE_F_LINK_UP;
477 vd->
flags &= ~VMXNET3_DEVICE_F_LINK_UP;
562 vd->
flags |= VMXNET3_DEVICE_F_LINK_UP;
571 vd->
flags &= ~VMXNET3_DEVICE_F_LINK_UP;
579 if (qsz < 64 || qsz > 4096)
621 args->
rv = VNET_API_ERROR_INVALID_VALUE;
633 args->
rv = VNET_API_ERROR_INVALID_VALUE;
636 "number of tx queues must be <= %u and <= number of " 640 "number of tx queues must be <= %u and <= number of " 652 args->
rv = VNET_API_ERROR_INVALID_VALUE;
655 "queue size must be <= 4096, >= 64, " 656 "and multiples of 64");
659 "queue size must be <= 4096, >= 64, and multiples of 64");
665 if (vd->pci_addr.as_u32 == args->addr.as_u32)
667 args->rv = VNET_API_ERROR_ADDRESS_IN_USE;
669 clib_error_return (error,
"%U: %s", format_vlib_pci_addr,
670 &args->addr,
"pci address in use");
671 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default,
"%U: %s",
672 format_vlib_pci_addr, &args->addr,
"pci address in use");
683 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
687 "error encountered on binding pci device");
688 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default,
"%U: %s",
690 "error encountered on binding pci devicee");
698 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
702 "error encountered on pci device open");
703 vlib_log (VLIB_LOG_LEVEL_ERR, vmxm->log_default,
"%U: %s",
705 "error encountered on pci device open");
714 vd->num_tx_queues = args->txq_num;
715 vd->num_rx_queues = args->rxq_num;
716 vd->dev_instance = vd - vmxm->devices;
717 vd->per_interface_next_index = ~0;
718 vd->pci_addr = args->addr;
720 if (args->enable_elog)
721 vd->flags |= VMXNET3_DEVICE_F_ELOG;
723 vd->pci_dev_handle =
h;
725 vd->num_intrs = vd->num_rx_queues + 1;
748 if (num_intr < vd->num_rx_queues + 1)
751 "No sufficient interrupt lines (%u) for rx queues",
755 "No sufficient interrupt lines (%u) for rx queues",
763 "error encountered on pci register msix handler 0");
771 "error encountered on pci register msix handler 1");
795 vd->dev_instance, vd->mac_addr,
801 "error encountered on ethernet register interface");
834 vd->flags |= VMXNET3_DEVICE_F_INITIALIZED;
838 vd->link_speed * 1000);
839 if (vd->flags & VMXNET3_DEVICE_F_LINK_UP)
848 args->rv = VNET_API_ERROR_INVALID_INTERFACE;
888 desc_idx = (ring->
consume + 1) & mask;
909 while (desc_idx != end_idx)
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static char * vmxnet3_tx_func_error_strings[]
static_always_inline clib_error_t * vmxnet3_rxq_refill_ring0(vlib_main_t *vm, vmxnet3_device_t *vd, vmxnet3_rxq_t *rxq)
void vmxnet3_delete_if(vlib_main_t *vm, vmxnet3_device_t *vd)
#define vec_foreach_index(var, v)
Iterate over vector indices.
static clib_error_t * vlib_pci_intr_enable(vlib_main_t *vm, vlib_pci_dev_handle_t h)
static clib_error_t * vlib_pci_bus_master_enable(vlib_main_t *vm, vlib_pci_dev_handle_t h)
static void * vlib_physmem_alloc_aligned_on_numa(vlib_main_t *vm, uword n_bytes, uword alignment, u32 numa_node)
vl_api_wireguard_peer_flags_t flags
format_function_t format_vmxnet3_device_name
#define VMXNET3_GOS_BITS_32
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_main_t * vnet_get_main(void)
#define VMXNET3_REG_TXPROD
#define count_leading_zeros(x)
vmxnet3_rx_desc * rx_desc[VMXNET3_RX_RING_SIZE]
static_always_inline uword vmxnet3_dma_addr(vlib_main_t *vm, vmxnet3_device_t *vd, void *p)
vlib_pci_dev_handle_t pci_dev_handle
void vlib_pci_device_close(vlib_main_t *vm, vlib_pci_dev_handle_t h)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 vlib_pci_get_num_msix_interrupts(vlib_main_t *vm, vlib_pci_dev_handle_t h)
static clib_error_t * vlib_physmem_last_error(struct vlib_main_t *vm)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define foreach_vmxnet3_tx_func_error
#define VMXNET3_RX_START(vd)
vmxnet3_main_t vmxnet3_main
#define VMXNET3_NUM_TX_DESC
void vmxnet3_create_if(vlib_main_t *vm, vmxnet3_create_if_args_t *args)
clib_error_t * vlib_pci_enable_msix_irq(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 start, u16 count)
static void vmxnet3_event_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
vmxnet3_tx_stats * tx_stats
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
static clib_error_t * vmxnet3_rss_init(vlib_main_t *vm, vmxnet3_device_t *vd)
static clib_error_t * vmxnet3_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
vlib_main_t ** vlib_mains
static void vmxnet3_set_interface_next_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
static_always_inline void vmxnet3_reg_write(vmxnet3_device_t *vd, u8 bar, u32 addr, u32 val)
static void clib_spinlock_free(clib_spinlock_t *p)
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define clib_memcpy(d, s, n)
static_always_inline u32 vmxnet3_reg_read(vmxnet3_device_t *vd, u8 bar, u32 addr)
#define VMXNET3_VERSION_SELECT
vlib_log_class_t log_default
static void vmxnet3_clear_hw_interface_counters(u32 instance)
vnet_hw_interface_rx_mode
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
static void vmxnet3_rxq_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
static_always_inline void vnet_device_input_set_interrupt_pending(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
vnet_hw_interface_flags_t flags
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
#define VMXNET3_RSS_MAX_KEY_SZ
vmxnet3_shared * driver_shared
static clib_error_t * vmxnet3_rxq_init(vlib_main_t *vm, vmxnet3_device_t *vd, u16 qid, u16 qsz)
#define VMXNET3_RSS_HASH_FUNC_TOEPLITZ
static void clib_spinlock_init(clib_spinlock_t *p)
static void vlib_buffer_free_from_ring(vlib_main_t *vm, u32 *ring, u32 start, u32 ring_size, u32 n_buffers)
Free buffers from ring.
static clib_error_t * vmxnet3_interface_rx_mode_change(vnet_main_t *vnm, u32 hw_if_index, u32 qid, vnet_hw_interface_rx_mode mode)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
static_always_inline uword vnet_get_device_input_thread_index(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
static void vmxnet3_write_mac(vmxnet3_device_t *vd)
void vlib_pci_set_private_data(vlib_main_t *vm, vlib_pci_dev_handle_t h, uword private_data)
static u8 vmxnet3_queue_size_valid(u16 qsz)
clib_error_t * vlib_pci_bind_to_uio(vlib_main_t *vm, vlib_pci_addr_t *addr, char *uio_drv_name)
#define VMXNET3_GOS_TYPE_LINUX
#define VMXNET3_GOS_BITS_64
vmxnet3_rx_comp_ring rx_comp_ring
vmxnet3_tx_comp_ring tx_comp_ring
#define VMXNET3_UPT_VERSION_SELECT
#define VMXNET3_RX_RING_SIZE
#define pool_put(P, E)
Free an object E in pool P.
clib_error_t * vlib_pci_register_msix_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u32 start, u32 count, pci_msix_handler_function_t *msix_handler)
vmxnet3_tx_comp * tx_comp
uword vlib_pci_get_private_data(vlib_main_t *vm, vlib_pci_dev_handle_t h)
u32 vlib_pci_dev_handle_t
vl_api_tunnel_mode_t mode
#define VMXNET3_VERSION_MAGIC
static void vmxnet3_enable_interrupt(vmxnet3_device_t *vd)
u32 vlib_pci_get_numa_node(vlib_main_t *vm, vlib_pci_dev_handle_t h)
#define VMXNET3_IC_DISABLE_ALL
static void vlib_buffer_free_no_next(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers, does not free the buffer chain for each buffer.
static void vmxnet3_disable_interrupt(vmxnet3_device_t *vd)
static void vlib_physmem_free(vlib_main_t *vm, void *p)
sll srl srl sll sra u16x4 i
#define vec_free(V)
Free vector's memory (no header).
static const u8 vmxnet3_rss_key[VMXNET3_RSS_MAX_KEY_SZ]
void vlib_log(vlib_log_level_t level, vlib_log_class_t class, char *fmt,...)
#define PCI_VENDOR_ID_VMWARE
u32 per_interface_next_index
VNET_DEVICE_CLASS(vmxnet3_device_class,)
static clib_error_t * vmxnet3_device_init(vlib_main_t *vm, vmxnet3_device_t *vd, vmxnet3_create_if_args_t *args)
void vnet_hw_interface_assign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, uword thread_index)
format_function_t format_vmxnet3_device
vmxnet3_rx_stats * rx_stats
static vlib_main_t * vlib_get_main(void)
static u8 vmxnet3_rx_queue_num_valid(u16 num)
static clib_error_t * vmxnet3_provision_driver_shared(vlib_main_t *vm, vmxnet3_device_t *vd)
#define VMXNET3_SHARED_MAGIC
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define PCI_DEVICE_ID_VMWARE_VMXNET3
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, const u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
vmxnet3_tx_desc * tx_desc
#define VMXNET3_RSS_MAX_IND_TABLE_SZ
vnet_device_class_t vmxnet3_device_class
static u32 vmxnet3_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hw, u32 flags)
#define VMXNET3_TX_START(vd)
vmxnet3_rx_comp * rx_comp
#define clib_error_free(e)
vmxnet3_rx_ring rx_ring[VMXNET3_RX_RING_SIZE]
clib_error_t * vlib_pci_map_region(vlib_main_t *vm, vlib_pci_dev_handle_t h, u32 resource, void **result)
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
static vlib_thread_main_t * vlib_get_thread_main()
vmxnet3_device_t * devices
static_always_inline clib_error_t * vmxnet3_rxq_refill_ring1(vlib_main_t *vm, vmxnet3_device_t *vd, vmxnet3_rxq_t *rxq)
#define vmxnet3_log_error(dev, f,...)
static u8 vmxnet3_tx_queue_num_valid(u16 num)
#define VMXNET3_NUM_RX_DESC
#define CLIB_CACHE_LINE_BYTES
static u8 vlib_buffer_pool_get_default_for_numa(vlib_main_t *vm, u32 numa_node)
clib_error_t * vlib_pci_device_open(vlib_main_t *vm, vlib_pci_addr_t *addr, pci_device_id_t ids[], vlib_pci_dev_handle_t *handle)
static void vnet_hw_interface_set_link_speed(vnet_main_t *vnm, u32 hw_if_index, u32 link_speed)
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
static clib_error_t * vmxnet3_txq_init(vlib_main_t *vm, vmxnet3_device_t *vd, u16 qid, u16 qsz)
format_function_t format_vlib_pci_addr