|
FD.io VPP
v21.06-3-gbb25fbf28
Vector Packet Processing
|
Go to the documentation of this file.
17 #include <sys/ioctl.h>
29 #define PCI_VENDOR_ID_VIRTIO 0x1af4
30 #define PCI_DEVICE_ID_VIRTIO_NIC 0x1000
32 #define PCI_DEVICE_ID_VIRTIO_NIC_MODERN 0x1041
34 #define PCI_CAPABILITY_LIST 0x34
35 #define PCI_CAP_ID_VNDR 0x09
36 #define PCI_CAP_ID_MSIX 0x11
38 #define PCI_MSIX_ENABLE 0x8000
61 u16 max_queue_pairs = 1;
69 if (max_queue_pairs < 1 || max_queue_pairs > 0x8000)
71 " should be in range [1, 0x8000]",
134 vif->
flags |= VIRTIO_IF_FLAG_ADMIN_UP;
140 vif->
flags &= ~VIRTIO_IF_FLAG_ADMIN_UP;
163 for (; line < vif->
num_rxqs; line++)
179 struct status_struct *status_entry;
180 static struct status_struct status_array[] = {
181 #define _(s,b) { .str = #s, .bit = b, },
189 status_entry = (
struct status_struct *) &status_array;
190 while (status_entry->str)
192 if (vif->
status & status_entry->bit)
210 u16 flags = 0, first_desc_flags = 0;
239 d->len =
sizeof (virtio_net_ctrl_hdr_t);
290 d->len =
sizeof (
data->status);
307 if (vring->
device_event->flags != VRING_EVENT_F_DISABLE)
369 d->
len =
sizeof (virtio_net_ctrl_hdr_t);
389 d->
len =
sizeof (
data->status);
508 int csum_offload_enabled)
533 else if (csum_offload_enabled
588 if (qsz < 64 || qsz > 4096)
607 if (queue_size > 32768)
617 (((queue_size *
sizeof (vring_packed_desc_t)) +
630 vring->
driver_event = ptr + (queue_size *
sizeof (vring_packed_desc_t));
636 (((queue_size *
sizeof (vring_packed_desc_t)) +
643 vring->
size = queue_size;
652 vring->queue_notify_offset =
656 queue_num, vring->queue_notify_offset);
678 if (queue_size > 32768)
703 vring->
size = queue_size;
745 if (queue_size > 32768)
794 vring->
size = queue_size;
819 if (queue_size > 32768)
841 (((queue_size *
sizeof (vring_packed_desc_t)) +
854 vring->
driver_event = ptr + (queue_size *
sizeof (vring_packed_desc_t));
860 (((queue_size *
sizeof (vring_packed_desc_t)) +
884 vring->
size = queue_size;
888 vring->queue_notify_offset =
892 queue_num, vring->queue_notify_offset);
939 supported_features |=
944 if (req_features == 0)
946 req_features = supported_features;
997 if ((status & VIRTIO_CONFIG_STATUS_ACK)
998 && (status & VIRTIO_CONFIG_STATUS_DRIVER))
1011 u8 pos, common_cfg = 0, notify = 0, dev_cfg = 0, isr = 0, pci_cfg = 0;
1018 "error in reading capabilty list position");
1027 "error in reading the capability at", pos);
1029 "error in reading the capability at [%2x]",
1035 u16 flags, table_size, table_size_mask = 0x07FF;
1041 "error in reading the capability at [%2x]",
1044 table_size =
flags & table_size_mask;
1046 "msix interrupt vector table-size", table_size);
1065 "skipping non VNDR cap id:", cap.
cap_vndr);
1070 "[%4x] cfg type: %u, bar: %u, offset: %04x, len: %u",
1073 if (cap.
bar >= 0 && cap.
bar <= 5)
1122 if (common_cfg == 0 || notify == 0 || dev_cfg == 0 || isr == 0)
1155 args->
rv = VNET_API_ERROR_UNSUPPORTED;
1162 args->
rv = VNET_API_ERROR_INIT_FAILED;
1174 "support VIRTIO_RING_F_INDIRECT_DESC features");
1179 "support VIRTIO_NET_F_MRG_RXBUF features");
1187 VIRTIO_CONFIG_STATUS_FEATURES_OK);
1189 if (!(status & VIRTIO_CONFIG_STATUS_FEATURES_OK))
1191 args->
rv = VNET_API_ERROR_UNSUPPORTED;
1193 "error encountered: Device doesn't support requested features");
1195 "Device doesn't support requested features");
1209 memcpy (vif->
mac_addr + 2, &rnd, sizeof (rnd));
1222 args->
rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
1231 "error MSIX lines (%u) <= Number of RXQs (%u)",
1234 "error MSIX lines (%u) <= Number of RXQs (%u)",
1244 args->
rv = VNET_API_ERROR_INIT_FAILED;
1269 "no VPP worker thread is available");
1275 args->
rv = VNET_API_ERROR_INIT_FAILED;
1333 RX_QUEUE (
i),
"msix vector is set at", j);
1355 u32 interrupt_count = 0;
1361 args->
rv = VNET_API_ERROR_ADDRESS_IN_USE;
1366 " PCI address in use");
1383 args->
rv = VNET_API_ERROR_INVALID_INTERFACE;
1389 "error encountered on pci device open");
1396 vif->
type = VIRTIO_IF_TYPE_PCI;
1405 for (
u32 i = 0;
i <= 5;
i++)
1426 if (interrupt_count > 1)
1431 args->
rv = VNET_API_ERROR_INVALID_REGISTRATION;
1433 "error encountered on pci register msix handler 0");
1441 args->
rv = VNET_API_ERROR_INVALID_REGISTRATION;
1443 "error encountered on pci register msix handler 1");
1466 "error encountered on pci register interrupt handler");
1493 args->
rv = VNET_API_ERROR_INVALID_REGISTRATION;
1495 "error encountered on ethernet register interface");
1511 args->
rv = VNET_API_ERROR_INIT_FAILED;
1513 "error encountered during packet buffering init");
1522 vif->
flags |= VIRTIO_IF_FLAG_ADMIN_UP;
1543 args->
rv = VNET_API_ERROR_INVALID_INTERFACE;
1554 if (vif->
type != VIRTIO_IF_TYPE_PCI)
1555 return VNET_API_ERROR_INVALID_INTERFACE;
1623 memset (vif, 0,
sizeof (*vif));
1632 int checksum_offload_enabled,
1633 int offloads_disabled)
1635 if (vif->
type != VIRTIO_IF_TYPE_PCI)
1636 return VNET_API_ERROR_INVALID_INTERFACE;
1640 else if (checksum_offload_enabled)
1642 else if (offloads_disabled)
static void clib_spinlock_init(clib_spinlock_t *p)
vnet_device_class_t virtio_device_class
void vlib_pci_set_private_data(vlib_main_t *vm, vlib_pci_dev_handle_t h, uword private_data)
virtio_net_ctrl_ack_t status
void virtio_pci_create_if(vlib_main_t *vm, virtio_pci_create_if_args_t *args)
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
#define PCI_DEVICE_ID_VIRTIO_NIC_MODERN
static int virtio_pci_enable_checksum_offload(vlib_main_t *vm, virtio_if_t *vif)
static pci_device_id_t virtio_pci_device_ids[]
clib_error_t * virtio_pci_vring_split_init(vlib_main_t *vm, virtio_if_t *vif, u16 queue_num)
static int virtio_pci_offloads(vlib_main_t *vm, virtio_if_t *vif, int gso_enabled, int csum_offload_enabled)
#define VIRTIO_PCI_CAP_DEVICE_CFG
gro_flow_table_t * flow_table
#define VIRTIO_MSI_NO_VECTOR
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS
static uword vlib_buffer_get_current_pa(vlib_main_t *vm, vlib_buffer_t *b)
#define VNET_HW_INTERFACE_CAP_SUPPORTS_L4_TX_CKSUM
vnet_hw_interface_capabilities_t caps
static int virtio_pci_send_ctrl_msg(vlib_main_t *vm, virtio_if_t *vif, virtio_ctrl_msg_t *data, u32 len)
u8 * format_vlib_pci_addr(u8 *s, va_list *va)
#define TX_QUEUE_ACCESS(X)
#define clib_memcpy(d, s, n)
#define VIRTIO_NET_CTRL_GUEST_OFFLOADS_SET
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static void virtio_pci_irq_queue_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
u32 vlib_pci_get_numa_node(vlib_main_t *vm, vlib_pci_dev_handle_t h)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
#define VIRTIO_RING_FLAG_MASK_INT
static_always_inline void virtio_kick(vlib_main_t *vm, virtio_vring_t *vring, virtio_if_t *vif)
#define clib_error_return(e, args...)
u32 vlib_pci_dev_handle_t
clib_error_t * vlib_pci_enable_msix_irq(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 start, u16 count)
u32 per_interface_next_index
virtio_net_ctrl_hdr_t ctrl
static clib_error_t * virtio_pci_device_init(vlib_main_t *vm, virtio_if_t *vif, virtio_pci_create_if_args_t *args, void **bar)
static void vlib_physmem_free(vlib_main_t *vm, void *p)
#define pool_put(P, E)
Free an object E in pool P.
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
#define VRING_DESC_F_USED
static int virtio_pci_enable_gso(vlib_main_t *vm, virtio_if_t *vif)
@ VNET_HW_INTERFACE_FLAG_LINK_UP
#define VIRTIO_FEATURE(X)
#define PCI_CAPABILITY_LIST
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)
#define VRING_DESC_F_WRITE
vlib_log_class_t log_default
static u32 virtio_pci_get_mac(vlib_main_t *vm, virtio_if_t *vif)
const virtio_pci_func_t * virtio_pci_func
clib_error_t * virtio_pci_vring_packed_init(vlib_main_t *vm, virtio_if_t *vif, u16 queue_num)
clib_error_t * vlib_pci_map_region(vlib_main_t *vm, vlib_pci_dev_handle_t h, u32 resource, void **result)
static void virtio_pci_set_mac(vlib_main_t *vm, virtio_if_t *vif)
clib_error_t * virtio_pci_read_caps(vlib_main_t *vm, virtio_if_t *vif, void **bar)
#define VIRTIO_NET_S_LINK_UP
static clib_error_t * vlib_pci_intr_enable(vlib_main_t *vm, vlib_pci_dev_handle_t h)
u32 notify_off_multiplier
clib_error_t * virtio_pci_control_vring_init(vlib_main_t *vm, virtio_if_t *vif, u16 queue_num)
static u32 random_u32(u32 *seed)
32-bit random number generator
@ VNET_HW_INTERFACE_CAP_SUPPORTS_TX_TCP_CKSUM
static_always_inline void gro_flow_table_free(gro_flow_table_t *flow_table)
static clib_error_t * vlib_pci_bus_master_enable(vlib_main_t *vm, vlib_pci_dev_handle_t h)
static uword round_pow2(uword x, uword pow2)
virtio_main_t virtio_main
#define STRUCT_OFFSET_OF(t, f)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
static u8 virtio_pci_queue_size_valid(u16 qsz)
#define pool_foreach(VAR, POOL)
Iterate through pool.
uword vlib_pci_get_private_data(vlib_main_t *vm, vlib_pci_dev_handle_t h)
static_always_inline void clib_memset_u32(void *p, u32 val, uword count)
static_always_inline u16 vring_size(u32 num, u32 align)
void device_status(vlib_main_t *vm, virtio_if_t *vif)
#define CLIB_MEMORY_STORE_BARRIER()
virtio_vring_t * txq_vrings
int virtio_pci_delete_if(vlib_main_t *vm, virtio_if_t *vif)
static __clib_warn_unused_result u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
#define VRING_DESC_F_AVAIL
clib_error_t * virtio_pci_control_vring_packed_init(vlib_main_t *vm, virtio_if_t *vif, u16 queue_num)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_main_t * vnet_get_main(void)
clib_error_t * vlib_pci_io_region(vlib_main_t *vm, vlib_pci_dev_handle_t h, u32 resource)
static u32 virtio_pci_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hw, u32 flags)
@ VNET_HW_INTERFACE_CAP_SUPPORTS_TCP_GSO
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
@ foreach_virtio_config_status_flags
#define vec_foreach_index(var, v)
Iterate over vector indices.
static heap_elt_t * last(heap_header_t *h)
#define VIRTIO_PCI_CAP_COMMON_CFG
static int virtio_pci_send_ctrl_msg_packed(vlib_main_t *vm, virtio_if_t *vif, virtio_ctrl_msg_t *data, u32 len)
#define VIRTIO_PCI_VRING_ALIGN
u8 checksum_offload_enabled
#define VRING_DESC_F_NEXT
void virtio_set_net_hdr_size(virtio_if_t *vif)
sll srl srl sll sra u16x4 i
static void clib_spinlock_free(clib_spinlock_t *p)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
static_always_inline void vnet_hw_if_rx_queue_set_int_pending(vnet_main_t *vnm, u32 queue_index)
#define VIRTIO_PCI_ISR_CONFIG
clib_error_t * vlib_pci_register_intx_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, pci_intx_handler_function_t *intx_handler)
#define CLIB_MEMORY_BARRIER()
clib_error_t * virtio_pci_control_vring_split_init(vlib_main_t *vm, virtio_if_t *vif, u16 queue_num)
#define CLIB_CACHE_LINE_BYTES
clib_error_t * vlib_pci_read_write_config(vlib_main_t *vm, vlib_pci_dev_handle_t h, vlib_read_or_write_t read_or_write, uword address, void *data, u32 n_bytes)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
u32 vlib_pci_get_num_msix_interrupts(vlib_main_t *vm, vlib_pci_dev_handle_t h)
static_always_inline void virtio_vring_buffering_free(vlib_main_t *vm, virtio_vring_buffering_t *buffering)
vring_desc_event_t * driver_event
static int virtio_pci_enable_multiqueue(vlib_main_t *vm, virtio_if_t *vif, u16 num_queues)
const virtio_pci_func_t virtio_pci_legacy_func
static int virtio_pci_send_ctrl_msg_split(vlib_main_t *vm, virtio_if_t *vif, virtio_ctrl_msg_t *data, u32 len)
#define PCI_DEVICE_ID_VIRTIO_NIC
#define VIRTIO_NET_CTRL_MQ
#define vec_free(V)
Free vector's memory (no header).
#define VIRTIO_PCI_CAP_PCI_CFG
#define virtio_log_debug(vif, f,...)
virtio_vring_t * cxq_vring
#define VIRTIO_PCI_CAP_NOTIFY_CFG
#define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET
#define RX_QUEUE_ACCESS(X)
#define virtio_log_warning(vif, f,...)
static void virtio_pci_irq_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h)
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
static int virtio_pci_disable_offload(vlib_main_t *vm, virtio_if_t *vif)
vring_packed_desc_t * packed_desc
#define VIRTIO_PCI_ISR_INTR
void vlib_log(vlib_log_level_t level, vlib_log_class_t class, char *fmt,...)
clib_error_t * virtio_pci_vring_init(vlib_main_t *vm, virtio_if_t *vif, u16 queue_num)
virtio_vring_t * rxq_vrings
static clib_error_t * vlib_physmem_last_error(struct vlib_main_t *vm)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
void virtio_free_buffers(vlib_main_t *vm, virtio_vring_t *vring)
static void virtio_pci_irq_config_handler(vlib_main_t *vm, vlib_pci_dev_handle_t h, u16 line)
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
static_always_inline void vring_init(vring_t *vr, u32 num, void *p, u32 align)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
vring_used_elem_t ring[0]
virtio_vring_buffering_t * buffering
int virtio_pci_enable_disable_offloads(vlib_main_t *vm, virtio_if_t *vif, int gso_enabled, int checksum_offload_enabled, int offloads_disabled)
@ VNET_HW_INTERFACE_CAP_SUPPORTS_TX_UDP_CKSUM
static void * vlib_physmem_alloc_aligned_on_numa(vlib_main_t *vm, uword n_bytes, uword alignment, u32 numa_node)
#define virtio_log_error(vif, f,...)
const virtio_pci_func_t virtio_pci_modern_func
#define clib_warning(format, args...)
clib_error_t * virtio_set_packet_buffering(virtio_if_t *vif, u16 buffering_size)
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)
@ VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE
#define clib_error_free(e)
static clib_error_t * virtio_pci_get_max_virtqueue_pairs(vlib_main_t *vm, virtio_if_t *vif)
static f64 vlib_time_now(vlib_main_t *vm)
vring_desc_event_t * device_event
void vlib_pci_device_close(vlib_main_t *vm, vlib_pci_dev_handle_t h)
static clib_error_t * vlib_pci_intr_disable(vlib_main_t *vm, vlib_pci_dev_handle_t h)
void virtio_vring_set_rx_queues(vlib_main_t *vm, virtio_if_t *vif)
static vlib_thread_main_t * vlib_get_thread_main()
static uword is_pow2(uword x)
static u16 virtio_pci_is_link_up(vlib_main_t *vm, virtio_if_t *vif)
static void virtio_negotiate_features(vlib_main_t *vm, virtio_if_t *vif, u64 req_features)
void virtio_pci_read_device_feature(vlib_main_t *vm, virtio_if_t *vif)
int virtio_pci_reset_device(vlib_main_t *vm, virtio_if_t *vif)
#define PCI_VENDOR_ID_VIRTIO
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)
#define VIRTIO_PCI_CAP_ISR_CFG
VLIB buffer representation.
vl_api_wireguard_peer_flags_t flags