u32 head;
f64 t0, suspend_time = AVF_SEND_TO_PF_SUSPEND_TIME;
+ /* adminq operations should be only done from process node after device
+ * is initialized */
+ ASSERT ((ad->flags & AVF_DEVICE_F_INITIALIZED) == 0 ||
+ vlib_get_current_process_node_index (vm) == avf_process_node.index);
+
/* suppress interrupt in the next adminq receive slot
as we are going to wait for response
we only need interrupts when event is received */
{
vlib_main_t *vm = vlib_get_main ();
avf_device_t *ad = avf_get_device (hw->dev_instance);
- clib_error_t *error;
u8 promisc_enabled;
switch (flags)
}
promisc_enabled = ((ad->flags & AVF_DEVICE_F_PROMISC) != 0);
- if ((error = avf_config_promisc_mode (vm, ad, promisc_enabled)))
- {
- avf_log_err (ad, "%s: %U", format_clib_error, error);
- clib_error_free (error);
- return ~0;
- }
+ vlib_process_signal_event (vm, avf_process_node.index,
+ promisc_enabled ?
+ AVF_PROCESS_EVENT_SET_PROMISC_ENABLE :
+ AVF_PROCESS_EVENT_SET_PROMISC_DISABLE,
+ hw->dev_instance);
return 0;
}
case AVF_PROCESS_EVENT_AQ_INT:
irq = 1;
break;
+ case AVF_PROCESS_EVENT_SET_PROMISC_ENABLE:
+ case AVF_PROCESS_EVENT_SET_PROMISC_DISABLE:
+ for (int i = 0; i < vec_len (event_data); i++)
+ {
+ avf_device_t *ad = avf_get_device (event_data[i]);
+ clib_error_t *err;
+ int is_enable = 0;
+
+ if (event_type == AVF_PROCESS_EVENT_SET_PROMISC_ENABLE)
+ is_enable = 1;
+
+ if ((err = avf_config_promisc_mode (vm, ad, is_enable)))
+ {
+ avf_log_err (ad, "error: %U", format_clib_error, err);
+ clib_error_free (err);
+ }
+ }
+ break;
+
default:
ASSERT (0);
}
clib_mem_free (ad);
}
-void
-avf_create_if (vlib_main_t * vm, avf_create_if_args_t * args)
+static u8
+avf_validate_queue_size (avf_create_if_args_t * args)
{
- vnet_main_t *vnm = vnet_get_main ();
- avf_main_t *am = &avf_main;
- avf_device_t *ad, **adp;
- vlib_pci_dev_handle_t h;
clib_error_t *error = 0;
- int i;
- /* check input args */
args->rxq_size = (args->rxq_size == 0) ? AVF_RXQ_SZ : args->rxq_size;
args->txq_size = (args->txq_size == 0) ? AVF_TXQ_SZ : args->txq_size;
- if ((args->rxq_size & (args->rxq_size - 1))
- || (args->txq_size & (args->txq_size - 1)))
+ if ((args->rxq_size > AVF_QUEUE_SZ_MAX)
+ || (args->txq_size > AVF_QUEUE_SZ_MAX))
+ {
+ args->rv = VNET_API_ERROR_INVALID_VALUE;
+ args->error =
+ clib_error_return (error, "queue size must not be greater than %u",
+ AVF_QUEUE_SZ_MAX);
+ return 1;
+ }
+ if ((args->rxq_size < AVF_QUEUE_SZ_MIN)
+ || (args->txq_size < AVF_QUEUE_SZ_MIN))
+ {
+ args->rv = VNET_API_ERROR_INVALID_VALUE;
+ args->error =
+ clib_error_return (error, "queue size must not be smaller than %u",
+ AVF_QUEUE_SZ_MIN);
+ return 1;
+ }
+ if ((args->rxq_size & (args->rxq_size - 1)) ||
+ (args->txq_size & (args->txq_size - 1)))
{
args->rv = VNET_API_ERROR_INVALID_VALUE;
args->error =
clib_error_return (error, "queue size must be a power of two");
- return;
+ return 1;
}
+ return 0;
+}
+
+void
+avf_create_if (vlib_main_t * vm, avf_create_if_args_t * args)
+{
+ vnet_main_t *vnm = vnet_get_main ();
+ avf_main_t *am = &avf_main;
+ avf_device_t *ad, **adp;
+ vlib_pci_dev_handle_t h;
+ clib_error_t *error = 0;
+ int i;
+
+ /* check input args */
+ if (avf_validate_queue_size (args) != 0)
+ return;
pool_get (am->devices, adp);
adp[0] = ad = clib_mem_alloc_aligned (sizeof (avf_device_t),