dev: add support to configure driver arguments 56/42956/2
authorMonendra Singh Kushwaha <[email protected]>
Wed, 14 May 2025 11:56:16 +0000 (17:26 +0530)
committerDamjan Marion <[email protected]>
Mon, 19 May 2025 10:05:59 +0000 (10:05 +0000)
This patch adds support to configure driver specific global
arguments/options which are global for driver or not specific
to interface/port.

Driver specific arguments can be configures via startup config

devices {
    driver <driver name> {
args 'ARG1=<V1> ARG2=<V2>
    }
    ..
}

Type: feature

Change-Id: I6186531abda386aa02e4dc8784b4a5a02665aa20
Signed-off-by: Monendra Singh Kushwaha <[email protected]>
src/vnet/dev/config.c
src/vnet/dev/dev.h

index 8883e72..1e428a5 100644 (file)
@@ -53,6 +53,66 @@ vnet_dev_config_one_interface (vlib_main_t *vm, unformat_input_t *input,
     }
   return err;
 }
+
+static clib_error_t *
+vnet_dev_config_driver_args (vlib_main_t *vm, unformat_input_t *input,
+                            char *driver_name)
+{
+  vnet_dev_main_t *dm = &vnet_dev_main;
+  clib_error_t *err = 0;
+  u8 *args;
+
+  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
+    {
+      if (unformat (input, "args %U", unformat_single_quoted_string, &args))
+       ;
+      else
+       {
+         err = clib_error_return (0, "unknown input '%U'",
+                                  format_unformat_error, input);
+         break;
+       }
+    }
+
+  if (err == 0)
+    {
+      vnet_dev_driver_t *driver;
+      vnet_dev_rv_t rv = VNET_DEV_OK;
+
+      vec_foreach (driver, dm->drivers)
+       {
+         if (driver_name[0] &&
+             strcmp (driver_name, driver->registration->name))
+           continue;
+         if (driver->registration->drv_args)
+           {
+             for (vnet_dev_arg_t *a = driver->registration->drv_args;
+                  a->type != VNET_DEV_ARG_END; a++)
+               vec_add1 (driver->args, *a);
+
+             if (args)
+               {
+                 rv = vnet_dev_arg_parse (vm, NULL, driver->args, args);
+                 if (rv != VNET_DEV_OK)
+                   goto done;
+
+                 if (driver->ops.config_args)
+                   rv = driver->ops.config_args (vm, driver);
+                 break;
+               }
+           }
+       }
+    done:
+      vec_free (args);
+
+      if (rv != VNET_DEV_OK)
+       err = clib_error_return (0, "error: %U for driver '%s'",
+                                format_vnet_dev_rv, rv, driver_name);
+    }
+
+  return err;
+}
+
 static clib_error_t *
 vnet_dev_config_one_device (vlib_main_t *vm, unformat_input_t *input,
                            char *device_id)
@@ -128,6 +188,7 @@ dev_config_process_node_fn (vlib_main_t *vm, vlib_node_runtime_t *rt,
                            vlib_frame_t *f)
 {
   vnet_dev_main_t *dm = &vnet_dev_main;
+  vnet_dev_driver_name_t driver_name;
   unformat_input_t input;
   clib_error_t *err = 0;
 
@@ -156,6 +217,13 @@ dev_config_process_node_fn (vlib_main_t *vm, vlib_node_runtime_t *rt,
          err = vnet_dev_config_one_device (vm, &no_input, device_id);
          unformat_free (&no_input);
        }
+      else if (unformat (&input, "driver %U %U", unformat_c_string_array,
+                        driver_name, sizeof (driver_name),
+                        unformat_vlib_cli_sub_input, &sub_input))
+       {
+         err = vnet_dev_config_driver_args (vm, &sub_input, driver_name);
+         unformat_free (&sub_input);
+       }
       else
        err = clib_error_return (0, "unknown input '%U'",
                                 format_unformat_error, &input);
index ad2e793..7e0a3f2 100644 (file)
@@ -81,6 +81,7 @@ typedef union
 typedef struct vnet_dev_bus_registration vnet_dev_bus_registration_t;
 typedef struct vnet_dev_driver_registration vnet_dev_driver_registration_t;
 
+typedef struct vnet_dev_driver vnet_dev_driver_t;
 typedef struct vnet_dev vnet_dev_t;
 typedef struct vnet_dev_port vnet_dev_port_t;
 typedef struct vnet_dev_rx_queue vnet_dev_rx_queue_t;
@@ -91,6 +92,7 @@ typedef struct vnet_dev_counter vnet_dev_counter_t;
 typedef struct vnet_dev_counter_main vnet_dev_counter_main_t;
 typedef struct vnet_dev_port_cfg_change_req vnet_dev_port_cfg_change_req_t;
 
+typedef vnet_dev_rv_t (vnet_dev_drv_op_t) (vlib_main_t *, vnet_dev_driver_t *);
 typedef vnet_dev_rv_t (vnet_dev_op_t) (vlib_main_t *, vnet_dev_t *);
 typedef vnet_dev_rv_t (vnet_dev_port_op_t) (vlib_main_t *, vnet_dev_port_t *);
 typedef vnet_dev_rv_t (vnet_dev_port_cfg_change_op_t) (
@@ -234,6 +236,7 @@ typedef struct
 
 typedef struct
 {
+  vnet_dev_drv_op_t *config_args;
   vnet_dev_op_t *alloc;
   vnet_dev_op_t *init;
   vnet_dev_op_no_rv_t *deinit;
@@ -466,6 +469,7 @@ struct vnet_dev_driver_registration
   int priority;
   vnet_dev_ops_t ops;
   vnet_dev_arg_t *args;
+  vnet_dev_arg_t *drv_args;
 };
 
 typedef struct
@@ -475,7 +479,7 @@ typedef struct
   vnet_dev_bus_ops_t ops;
 } vnet_dev_bus_t;
 
-typedef struct
+typedef struct vnet_dev_driver
 {
   u32 index;
   void *dev_data;
@@ -483,6 +487,7 @@ typedef struct
   u32 dev_class_index;
   vnet_dev_bus_index_t bus_index;
   vnet_dev_ops_t ops;
+  vnet_dev_arg_t *args;
 } vnet_dev_driver_t;
 
 typedef struct