19 #define foreach_ssvm_eth_tx_func_error \ 20 _(RING_FULL, "Tx packet drops (ring full)") \ 21 _(NO_BUFFERS, "Tx packet drops (no buffers)") \ 22 _(ADMIN_DOWN, "Tx packet drops (admin down)") 25 #define _(f,s) SSVM_ETH_TX_ERROR_##f, 58 goto create_vnet_interface;
102 create_vnet_interface:
106 memset (enet_addr, 0,
sizeof (enet_addr));
109 enet_addr[2] = is_master;
123 return VNET_API_ERROR_INVALID_INTERFACE;
156 else if (
unformat (input,
"%s", &name))
188 clib_warning (
"ssvm_eth_queue_elt_t size %d not a multiple of %d",
220 s =
format (s,
"ssvmEthernet%d", i);
226 s =
format (s,
"SSVM Ethernet");
232 s =
format (s,
"Unimplemented...");
250 u32 my_pid = intfc->my_pid;
253 u32 size_this_buffer;
254 u32 chunks_this_buffer;
255 u8 i_am_master = intfc->i_am_master;
257 int is_ring_full, interface_down;
259 volatile u32 *queue_lock;
261 u32 n_allocated, n_present_in_cache, n_available;
269 queue_lock = (
u32 *) q;
292 if (n_present_in_cache < n_left*2)
295 n_to_alloc + n_present_in_cache - 1);
297 n_allocated = n_to_alloc < n_available ? n_to_alloc : n_available;
302 &elt_indices[n_available - n_allocated],
303 sizeof(
u32) * n_allocated);
306 n_present_in_cache += n_allocated;
307 n_available -= n_allocated;
324 if (q->cursize >= q->maxsize)
332 for (i = 0; i < chunks_this_buffer; i++)
338 elt = elts + elt_index;
346 elt->
owner = !i_am_master;
363 while (__sync_lock_test_and_set (queue_lock, 1))
380 else if (interface_down)
445 if (node_index == ~0)
475 .no_flatten_output_chains = 1,
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
always_inline void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
sll srl srl sll sra u16x4 i
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
int ssvm_master_init(ssvm_private_t *ssvm, u32 master_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#define SSVM_BUFFER_NEXT_PRESENT
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
always_inline uword max_log2(uword x)
static char * ssvm_eth_tx_func_error_strings[]
ssvm_shared_header_t * sh
#define clib_error_report(e)
#define VNET_HW_INTERFACE_FLAG_LINK_UP
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
always_inline void ssvm_unlock(ssvm_shared_header_t *h)
static void ssvm_eth_set_interface_next_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
static u8 * format_ssvm_eth_device_name(u8 *s, va_list *args)
vnet_main_t * vnet_get_main(void)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
#define VLIB_INIT_FUNCTION(x)
always_inline void ssvm_lock(ssvm_shared_header_t *h, u32 my_pid, u32 tag)
int ssvm_eth_create(ssvm_eth_main_t *em, u8 *name, int is_master)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
always_inline void vlib_node_set_state(vlib_main_t *vm, u32 node_index, vlib_node_state_t new_state)
static void * ssvm_push_heap(ssvm_shared_header_t *sh)
VNET_DEVICE_CLASS(ssvm_eth_device_class)
always_inline uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
#define clib_warning(format, args...)
vnet_device_class_t ssvm_eth_device_class
vlib_node_registration_t ssvm_eth_input_node
(constructor) VLIB_REGISTER_NODE (ssvm_eth_input_node)
static void ssvm_pop_heap(void *oldheap)
always_inline void * vlib_frame_vector_args(vlib_frame_t *f)
static uword pointer_to_uword(const void *p)
#define VLIB_BUFFER_NEXT_PRESENT
static uword ssvm_eth_interface_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *f)
static u8 * format_ssvm_eth_tx_trace(u8 *s, va_list *args)
#define pool_elt_at_index(p, i)
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
u16 current_length
Nbytes between current data and the end of this buffer.
static void ssvm_eth_clear_hw_interface_counters(u32 instance)
u32 per_interface_next_index
int ssvm_slave_init(ssvm_private_t *ssvm, int timeout_in_seconds)
#define VLIB_CONFIG_FUNCTION(x, n,...)
static u8 * format_ssvm_eth_device(u8 *s, va_list *args)
#define uword_to_pointer(u, type)
#define clib_memcpy(a, b, c)
static clib_error_t * ssvm_eth_subif_add_del_function(vnet_main_t *vnm, u32 hw_if_index, struct vnet_sw_interface_t *st, int is_add)
always_inline vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
static clib_error_t * ssvm_eth_init(vlib_main_t *vm)
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
unix_shared_memory_queue_t * unix_shared_memory_queue_init(int nels, int elsize, int consumer_pid, int signal_when_queue_non_empty)
u32 next_buffer
Next buffer for this linked-list of buffers.
static clib_error_t * ssvm_eth_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
always_inline uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
u8 data[SSVM_BUFFER_SIZE]
int unix_shared_memory_queue_add_raw(unix_shared_memory_queue_t *q, u8 *elem)
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
ssvm_eth_main_t ssvm_eth_main
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u16 total_length_not_including_first_buffer
#define CLIB_MEMORY_BARRIER()
static clib_error_t * ssvm_config(vlib_main_t *vm, unformat_input_t *input)
#define clib_error_return(e, args...)
static u32 ssvm_eth_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
#define CLIB_CACHE_LINE_BYTES
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
#define foreach_ssvm_eth_tx_func_error
uword runtime_data[(128-1 *sizeof(vlib_node_function_t *)-1 *sizeof(vlib_error_t *)-11 *sizeof(u32)-5 *sizeof(u16))/sizeof(uword)]
always_inline vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
struct _unix_shared_memory_queue unix_shared_memory_queue_t