Enable support to create a mvtvm virtual device on system's
without a PCI based ML HW accelerator.

Signed-off-by: Srikanth Yalavarthi <syalavar...@marvell.com>
---
 drivers/ml/cnxk/cn10k_ml_dev.c |   8 ++
 drivers/ml/cnxk/cn10k_ml_dev.h |   3 +
 drivers/ml/cnxk/cnxk_ml_dev.c  |   3 +
 drivers/ml/cnxk/cnxk_ml_dev.h  |  21 ++++
 drivers/ml/cnxk/cnxk_ml_ops.c  |  86 ++++++++++----
 drivers/ml/cnxk/meson.build    |   2 +
 drivers/ml/cnxk/mvtvm_ml_dev.c | 198 +++++++++++++++++++++++++++++++++
 drivers/ml/cnxk/mvtvm_ml_dev.h |  40 +++++++
 drivers/ml/cnxk/mvtvm_ml_ops.c |  34 +++++-
 drivers/ml/cnxk/mvtvm_ml_ops.h |   2 +
 10 files changed, 372 insertions(+), 25 deletions(-)
 create mode 100644 drivers/ml/cnxk/mvtvm_ml_dev.c
 create mode 100644 drivers/ml/cnxk/mvtvm_ml_dev.h

diff --git a/drivers/ml/cnxk/cn10k_ml_dev.c b/drivers/ml/cnxk/cn10k_ml_dev.c
index 20c114b8bf7..e6dc87e3530 100644
--- a/drivers/ml/cnxk/cn10k_ml_dev.c
+++ b/drivers/ml/cnxk/cn10k_ml_dev.c
@@ -368,6 +368,12 @@ cn10k_ml_pci_probe(struct rte_pci_driver *pci_drv, struct 
rte_pci_device *pci_de
 
        PLT_SET_USED(pci_drv);
 
+       if (cnxk_ml_dev_initialized == 1) {
+               plt_err("ML CNXK device already initialized!");
+               plt_err("Cannot initialize CN10K PCI dev");
+               rte_exit(-EINVAL, "Invalid EAL arguments ");
+       }
+
        init_params = (struct rte_ml_dev_pmd_init_params){
                .socket_id = rte_socket_id(), .private_data_size = 
sizeof(struct cnxk_ml_dev)};
 
@@ -414,6 +420,8 @@ cn10k_ml_pci_probe(struct rte_pci_driver *pci_drv, struct 
rte_pci_device *pci_de
        dev->dequeue_burst = NULL;
        dev->op_error_get = NULL;
 
+       cnxk_ml_dev_initialized = 1;
+       cnxk_mldev->type = CNXK_ML_DEV_TYPE_PCI;
        cnxk_mldev->state = ML_CNXK_DEV_STATE_PROBED;
 
        return 0;
diff --git a/drivers/ml/cnxk/cn10k_ml_dev.h b/drivers/ml/cnxk/cn10k_ml_dev.h
index 2e7eb6c9ef9..cee405f3f5b 100644
--- a/drivers/ml/cnxk/cn10k_ml_dev.h
+++ b/drivers/ml/cnxk/cn10k_ml_dev.h
@@ -11,6 +11,9 @@
 
 #include "cnxk_ml_io.h"
 
+/* Device status */
+extern int cnxk_ml_dev_initialized;
+
 /* Dummy Device ops */
 extern struct rte_ml_dev_ops ml_dev_dummy_ops;
 
diff --git a/drivers/ml/cnxk/cnxk_ml_dev.c b/drivers/ml/cnxk/cnxk_ml_dev.c
index 63d1c9e417b..dc4512223ca 100644
--- a/drivers/ml/cnxk/cnxk_ml_dev.c
+++ b/drivers/ml/cnxk/cnxk_ml_dev.c
@@ -7,6 +7,9 @@
 
 #include "cnxk_ml_dev.h"
 
+/* Device status */
+int cnxk_ml_dev_initialized;
+
 /* Dummy operations for ML device */
 struct rte_ml_dev_ops ml_dev_dummy_ops = {0};
 
diff --git a/drivers/ml/cnxk/cnxk_ml_dev.h b/drivers/ml/cnxk/cnxk_ml_dev.h
index 382fca64bea..491c4c4aea5 100644
--- a/drivers/ml/cnxk/cnxk_ml_dev.h
+++ b/drivers/ml/cnxk/cnxk_ml_dev.h
@@ -9,6 +9,10 @@
 
 #include "cn10k_ml_dev.h"
 
+#ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
+#include "mvtvm_ml_dev.h"
+#endif
+
 #include "cnxk_ml_xstats.h"
 
 /* ML command timeout in seconds */
@@ -34,6 +38,15 @@ struct cnxk_ml_error_db {
        char str[RTE_ML_STR_MAX];
 };
 
+/* Device type */
+enum cnxk_ml_dev_type {
+       /* PCI based Marvell's ML HW accelerator device */
+       CNXK_ML_DEV_TYPE_PCI,
+
+       /* Generic Virtual device */
+       CNXK_ML_DEV_TYPE_VDEV,
+};
+
 /* Device configuration state enum */
 enum cnxk_ml_dev_state {
        /* Probed and not configured */
@@ -66,6 +79,9 @@ struct cnxk_ml_dev {
        /* RTE device */
        struct rte_ml_dev *mldev;
 
+       /* Device type */
+       enum cnxk_ml_dev_type type;
+
        /* Configuration state */
        enum cnxk_ml_dev_state state;
 
@@ -87,6 +103,11 @@ struct cnxk_ml_dev {
        /* CN10K device structure */
        struct cn10k_ml_dev cn10k_mldev;
 
+#ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
+       /* MVTVM device structure */
+       struct mvtvm_ml_dev mvtvm_mldev;
+#endif
+
        /* Maximum number of layers */
        uint64_t max_nb_layers;
 
diff --git a/drivers/ml/cnxk/cnxk_ml_ops.c b/drivers/ml/cnxk/cnxk_ml_ops.c
index c8491646da9..3525215e716 100644
--- a/drivers/ml/cnxk/cnxk_ml_ops.c
+++ b/drivers/ml/cnxk/cnxk_ml_ops.c
@@ -125,7 +125,8 @@ cnxk_ml_qp_create(const struct rte_ml_dev *dev, uint16_t 
qp_id, uint32_t nb_desc
        qp->stats.enqueue_err_count = 0;
        qp->stats.dequeue_err_count = 0;
 
-       cn10k_ml_qp_initialize(cnxk_mldev, qp);
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI)
+               cn10k_ml_qp_initialize(cnxk_mldev, qp);
 
        return qp;
 
@@ -604,7 +605,14 @@ cnxk_ml_dev_info_get(struct rte_ml_dev *dev, struct 
rte_ml_dev_info *dev_info)
        dev_info->driver_name = dev->device->driver->name;
        dev_info->max_models = ML_CNXK_MAX_MODELS;
 
-       return cn10k_ml_dev_info_get(cnxk_mldev, dev_info);
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI)
+               return cn10k_ml_dev_info_get(cnxk_mldev, dev_info);
+#ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
+       else
+               return mvtvm_ml_dev_info_get(cnxk_mldev, dev_info);
+#endif
+
+       return 0;
 }
 
 static int
@@ -642,9 +650,11 @@ cnxk_ml_dev_configure(struct rte_ml_dev *dev, const struct 
rte_ml_dev_config *co
                           conf->nb_queue_pairs, conf->nb_models);
 
                /* Load firmware */
-               ret = cn10k_ml_fw_load(cnxk_mldev);
-               if (ret != 0)
-                       return ret;
+               if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI) {
+                       ret = cn10k_ml_fw_load(cnxk_mldev);
+                       if (ret != 0)
+                               return ret;
+               }
        } else if (cnxk_mldev->state == ML_CNXK_DEV_STATE_CONFIGURED) {
                plt_ml_dbg("Re-configuring ML device, nb_queue_pairs = %u, 
nb_models = %u",
                           conf->nb_queue_pairs, conf->nb_models);
@@ -742,10 +752,12 @@ cnxk_ml_dev_configure(struct rte_ml_dev *dev, const 
struct rte_ml_dev_config *co
        }
        dev->data->nb_models = conf->nb_models;
 
-       ret = cn10k_ml_dev_configure(cnxk_mldev, conf);
-       if (ret != 0) {
-               plt_err("Failed to configure CN10K ML Device");
-               goto error;
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI) {
+               ret = cn10k_ml_dev_configure(cnxk_mldev, conf);
+               if (ret != 0) {
+                       plt_err("Failed to configure CN10K ML Device");
+                       goto error;
+               }
        }
 
 #ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
@@ -755,12 +767,17 @@ cnxk_ml_dev_configure(struct rte_ml_dev *dev, const 
struct rte_ml_dev_config *co
 #endif
 
        /* Set device capabilities */
-       cnxk_mldev->max_nb_layers =
-               
cnxk_mldev->cn10k_mldev.fw.req->cn10k_req.jd.fw_load.cap.s.max_models;
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI)
+               cnxk_mldev->max_nb_layers =
+                       
cnxk_mldev->cn10k_mldev.fw.req->cn10k_req.jd.fw_load.cap.s.max_models;
+       else
+               cnxk_mldev->max_nb_layers = ML_CNXK_MAX_MODELS;
 
        cnxk_mldev->mldev->enqueue_burst = cnxk_ml_enqueue_burst;
        cnxk_mldev->mldev->dequeue_burst = cnxk_ml_dequeue_burst;
-       cnxk_mldev->mldev->op_error_get = cn10k_ml_op_error_get;
+
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI)
+               cnxk_mldev->mldev->op_error_get = cn10k_ml_op_error_get;
 
        /* Allocate and initialize index_map */
        if (cnxk_mldev->index_map == NULL) {
@@ -823,8 +840,10 @@ cnxk_ml_dev_close(struct rte_ml_dev *dev)
                plt_err("Failed to close MVTVM ML Device");
 #endif
 
-       if (cn10k_ml_dev_close(cnxk_mldev) != 0)
-               plt_err("Failed to close CN10K ML Device");
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI) {
+               if (cn10k_ml_dev_close(cnxk_mldev) != 0)
+                       plt_err("Failed to close CN10K ML Device");
+       }
 
        if (cnxk_mldev->index_map)
                rte_free(cnxk_mldev->index_map);
@@ -876,10 +895,12 @@ cnxk_ml_dev_start(struct rte_ml_dev *dev)
 
        cnxk_mldev = dev->data->dev_private;
 
-       ret = cn10k_ml_dev_start(cnxk_mldev);
-       if (ret != 0) {
-               plt_err("Failed to start CN10K ML Device");
-               return ret;
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI) {
+               ret = cn10k_ml_dev_start(cnxk_mldev);
+               if (ret != 0) {
+                       plt_err("Failed to start CN10K ML Device");
+                       return ret;
+               }
        }
 
        cnxk_mldev->state = ML_CNXK_DEV_STATE_STARTED;
@@ -898,10 +919,12 @@ cnxk_ml_dev_stop(struct rte_ml_dev *dev)
 
        cnxk_mldev = dev->data->dev_private;
 
-       ret = cn10k_ml_dev_stop(cnxk_mldev);
-       if (ret != 0) {
-               plt_err("Failed to stop CN10K ML Device");
-               return ret;
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI) {
+               ret = cn10k_ml_dev_stop(cnxk_mldev);
+               if (ret != 0) {
+                       plt_err("Failed to stop CN10K ML Device");
+                       return ret;
+               }
        }
 
        cnxk_mldev->state = ML_CNXK_DEV_STATE_CONFIGURED;
@@ -928,7 +951,14 @@ cnxk_ml_dev_dump(struct rte_ml_dev *dev, FILE *fp)
                        cnxk_ml_model_dump(cnxk_mldev, model, fp);
        }
 
-       return cn10k_ml_dev_dump(cnxk_mldev, fp);
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_PCI)
+               return cn10k_ml_dev_dump(cnxk_mldev, fp);
+#ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
+       else
+               return mvtvm_ml_dev_dump(cnxk_mldev, fp);
+#endif
+
+       return 0;
 }
 
 static int
@@ -941,6 +971,9 @@ cnxk_ml_dev_selftest(struct rte_ml_dev *dev)
 
        cnxk_mldev = dev->data->dev_private;
 
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_VDEV)
+               return -ENOTSUP;
+
        return cn10k_ml_dev_selftest(cnxk_mldev);
 }
 
@@ -1269,6 +1302,11 @@ cnxk_ml_model_load(struct rte_ml_dev *dev, struct 
rte_ml_model_params *params, u
                return -EINVAL;
        }
 
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_VDEV && type != 
ML_CNXK_MODEL_TYPE_TVM) {
+               plt_err("Unsupported model type");
+               return -ENOTSUP;
+       }
+
        /* Find model ID */
        found = false;
        for (lcl_model_id = 0; lcl_model_id < dev->data->nb_models; 
lcl_model_id++) {
@@ -1463,6 +1501,8 @@ cnxk_ml_model_params_update(struct rte_ml_dev *dev, 
uint16_t model_id, void *buf
                return -EINVAL;
 
        cnxk_mldev = dev->data->dev_private;
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_VDEV)
+               return -ENOTSUP;
 
        model = dev->data->models[model_id];
        if (model == NULL) {
diff --git a/drivers/ml/cnxk/meson.build b/drivers/ml/cnxk/meson.build
index 09a62b5c55a..f5989c5cafe 100644
--- a/drivers/ml/cnxk/meson.build
+++ b/drivers/ml/cnxk/meson.build
@@ -70,11 +70,13 @@ if enable_mvtvm
 dpdk_conf.set('RTE_MLDEV_CNXK_ENABLE_MVTVM', true)
 
 driver_sdk_headers += files(
+        'mvtvm_ml_dev.h',
         'mvtvm_ml_ops.h',
         'mvtvm_ml_model.h',
 )
 
 sources += files(
+        'mvtvm_ml_dev.c',
         'mvtvm_ml_ops.c',
         'mvtvm_ml_model.c',
 )
diff --git a/drivers/ml/cnxk/mvtvm_ml_dev.c b/drivers/ml/cnxk/mvtvm_ml_dev.c
new file mode 100644
index 00000000000..8ca0e959e35
--- /dev/null
+++ b/drivers/ml/cnxk/mvtvm_ml_dev.c
@@ -0,0 +1,198 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Marvell.
+ */
+
+#include <rte_kvargs.h>
+#include <rte_mldev.h>
+#include <rte_mldev_pmd.h>
+
+#include <bus_vdev_driver.h>
+
+#include <roc_api.h>
+
+#include "mvtvm_ml_dev.h"
+
+#include "cnxk_ml_dev.h"
+
+#define MVTVM_ML_DEV_MAX_QPS         "max_qps"
+#define MVTVM_ML_DEV_CACHE_MODEL_DATA "cache_model_data"
+
+#define MVTVM_ML_DEV_MAX_QPS_DEFAULT         32
+#define CN10K_ML_DEV_CACHE_MODEL_DATA_DEFAULT 1
+
+static const char *const valid_args[] = {MVTVM_ML_DEV_MAX_QPS, 
MVTVM_ML_DEV_CACHE_MODEL_DATA, NULL};
+
+static int
+parse_integer_arg(const char *key __rte_unused, const char *value, void 
*extra_args)
+{
+       int *i = (int *)extra_args;
+
+       *i = atoi(value);
+       if (*i < 0) {
+               plt_err("Argument has to be positive.");
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int
+parse_uint_arg(const char *key __rte_unused, const char *value, void 
*extra_args)
+{
+       int i;
+       char *end;
+       errno = 0;
+
+       i = strtol(value, &end, 10);
+       if (*end != 0 || errno != 0 || i < 0)
+               return -EINVAL;
+
+       *((uint32_t *)extra_args) = i;
+
+       return 0;
+}
+
+static int
+mvtvm_mldev_parse_devargs(const char *args, struct mvtvm_ml_dev *mvtvm_mldev)
+{
+       bool cache_model_data_set = false;
+       struct rte_kvargs *kvlist = NULL;
+       bool max_qps_set = false;
+       int ret = 0;
+
+       if (args == NULL)
+               goto check_args;
+
+       kvlist = rte_kvargs_parse(args, valid_args);
+       if (kvlist == NULL) {
+               plt_err("Error parsing %s devargs\n", "MLDEV_NAME_MVTVM_PMD");
+               return -EINVAL;
+       }
+
+       if (rte_kvargs_count(kvlist, MVTVM_ML_DEV_MAX_QPS) == 1) {
+               ret = rte_kvargs_process(kvlist, MVTVM_ML_DEV_MAX_QPS, 
&parse_uint_arg,
+                                        &mvtvm_mldev->max_nb_qpairs);
+               if (ret < 0) {
+                       plt_err("Error processing arguments, key = %s\n", 
MVTVM_ML_DEV_MAX_QPS);
+                       ret = -EINVAL;
+                       goto exit;
+               }
+               max_qps_set = true;
+       }
+
+       if (rte_kvargs_count(kvlist, MVTVM_ML_DEV_CACHE_MODEL_DATA) == 1) {
+               ret = rte_kvargs_process(kvlist, MVTVM_ML_DEV_CACHE_MODEL_DATA, 
&parse_integer_arg,
+                                        &mvtvm_mldev->cache_model_data);
+               if (ret < 0) {
+                       plt_err("Error processing arguments, key = %s\n",
+                               MVTVM_ML_DEV_CACHE_MODEL_DATA);
+                       ret = -EINVAL;
+                       goto exit;
+               }
+               cache_model_data_set = true;
+       }
+
+check_args:
+       if (!max_qps_set)
+               mvtvm_mldev->max_nb_qpairs = MVTVM_ML_DEV_MAX_QPS_DEFAULT;
+       plt_ml_dbg("ML: %s = %u", MVTVM_ML_DEV_MAX_QPS, 
mvtvm_mldev->max_nb_qpairs);
+
+       if (!cache_model_data_set) {
+               mvtvm_mldev->cache_model_data = 
CN10K_ML_DEV_CACHE_MODEL_DATA_DEFAULT;
+       } else {
+               if ((mvtvm_mldev->cache_model_data < 0) || 
(mvtvm_mldev->cache_model_data > 1)) {
+                       plt_err("Invalid argument, %s = %d\n", 
MVTVM_ML_DEV_CACHE_MODEL_DATA,
+                               mvtvm_mldev->cache_model_data);
+                       ret = -EINVAL;
+                       goto exit;
+               }
+       }
+       plt_ml_dbg("ML: %s = %d", MVTVM_ML_DEV_CACHE_MODEL_DATA, 
mvtvm_mldev->cache_model_data);
+
+exit:
+       if (kvlist)
+               rte_kvargs_free(kvlist);
+
+       return ret;
+}
+
+static int
+mvtvm_ml_vdev_probe(struct rte_vdev_device *vdev)
+{
+       struct rte_ml_dev_pmd_init_params init_params;
+       struct mvtvm_ml_dev *mvtvm_mldev;
+       struct cnxk_ml_dev *cnxk_mldev;
+       struct rte_ml_dev *dev;
+       const char *input_args;
+       const char *name;
+       int ret = 0;
+
+       if (cnxk_ml_dev_initialized == 1) {
+               plt_err("ML CNXK device already initialized!");
+               plt_err("Cannot initialize MVTVM vdev");
+               rte_exit(-EINVAL, "Invalid EAL arguments ");
+       }
+
+       init_params = (struct rte_ml_dev_pmd_init_params){
+               .socket_id = rte_socket_id(), .private_data_size = 
sizeof(struct cnxk_ml_dev)};
+
+       name = rte_vdev_device_name(vdev);
+       if (name == NULL)
+               return -EINVAL;
+       input_args = rte_vdev_device_args(vdev);
+
+       dev = rte_ml_dev_pmd_create(name, &vdev->device, &init_params);
+       if (dev == NULL) {
+               ret = -EFAULT;
+               goto error_exit;
+       }
+
+       cnxk_mldev = dev->data->dev_private;
+       cnxk_mldev->mldev = dev;
+       mvtvm_mldev = &cnxk_mldev->mvtvm_mldev;
+       mvtvm_mldev->vdev = vdev;
+
+       ret = mvtvm_mldev_parse_devargs(input_args, mvtvm_mldev);
+       if (ret < 0)
+               goto error_exit;
+
+       dev->dev_ops = &cnxk_ml_ops;
+       dev->enqueue_burst = NULL;
+       dev->dequeue_burst = NULL;
+       dev->op_error_get = NULL;
+
+       cnxk_ml_dev_initialized = 1;
+       cnxk_mldev->type = CNXK_ML_DEV_TYPE_VDEV;
+
+       return 0;
+
+error_exit:
+       plt_err("Could not create device: ml_mvtvm");
+
+       return ret;
+}
+
+static int
+mvtvm_ml_vdev_remove(struct rte_vdev_device *vdev)
+{
+       struct rte_ml_dev *dev;
+       const char *name;
+
+       name = rte_vdev_device_name(vdev);
+       if (name == NULL)
+               return -EINVAL;
+
+       dev = rte_ml_dev_pmd_get_named_dev(name);
+       if (dev == NULL)
+               return -ENODEV;
+
+       return rte_ml_dev_pmd_destroy(dev);
+}
+
+static struct rte_vdev_driver mvtvm_mldev_pmd = {.probe = mvtvm_ml_vdev_probe,
+                                                .remove = 
mvtvm_ml_vdev_remove};
+
+RTE_PMD_REGISTER_VDEV(MLDEV_NAME_MVTVM_PMD, mvtvm_mldev_pmd);
+
+RTE_PMD_REGISTER_PARAM_STRING(MLDEV_NAME_MVTVM_PMD,
+                             MVTVM_ML_DEV_MAX_QPS "=<int>" 
MVTVM_ML_DEV_CACHE_MODEL_DATA "=<0|1>");
diff --git a/drivers/ml/cnxk/mvtvm_ml_dev.h b/drivers/ml/cnxk/mvtvm_ml_dev.h
new file mode 100644
index 00000000000..6922c193372
--- /dev/null
+++ b/drivers/ml/cnxk/mvtvm_ml_dev.h
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Marvell.
+ */
+
+#ifndef _MVTVM_ML_DEV_H_
+#define _MVTVM_ML_DEV_H_
+
+#include <rte_mldev_core.h>
+
+/* Device status */
+extern int cnxk_ml_dev_initialized;
+
+/* CNXK Device ops */
+extern struct rte_ml_dev_ops cnxk_ml_ops;
+
+/* Marvell MVTVM ML PMD device name */
+#define MLDEV_NAME_MVTVM_PMD ml_mvtvm
+
+/* Maximum number of descriptors per queue-pair */
+#define ML_MVTVM_MAX_DESC_PER_QP 1024
+
+/* Maximum number of inputs / outputs per model */
+#define ML_MVTVM_MAX_INPUT_OUTPUT 32
+
+/* Maximum number of segments for IO data */
+#define ML_MVTVM_MAX_SEGMENTS 1
+
+/* Device private data */
+struct mvtvm_ml_dev {
+       /* Virtual device */
+       struct rte_vdev_device *vdev;
+
+       /* Maximum number of queue pairs */
+       uint16_t max_nb_qpairs;
+
+       /* Enable / disable model data caching */
+       int cache_model_data;
+};
+
+#endif /* _MVTVM_ML_DEV_H_ */
diff --git a/drivers/ml/cnxk/mvtvm_ml_ops.c b/drivers/ml/cnxk/mvtvm_ml_ops.c
index e8484b3bd92..dc9beb86e2e 100644
--- a/drivers/ml/cnxk/mvtvm_ml_ops.c
+++ b/drivers/ml/cnxk/mvtvm_ml_ops.c
@@ -11,8 +11,7 @@
 
 #include <mldev_utils.h>
 
-#include "cn10k_ml_ops.h"
-
+#include "mvtvm_ml_dev.h"
 #include "mvtvm_ml_model.h"
 #include "mvtvm_ml_ops.h"
 
@@ -29,6 +28,22 @@ mvtvm_ml_set_poll_addr(struct cnxk_ml_req *req)
        req->status = &req->mvtvm_req.status;
 }
 
+int
+mvtvm_ml_dev_info_get(struct cnxk_ml_dev *cnxk_mldev, struct rte_ml_dev_info 
*dev_info)
+{
+       struct mvtvm_ml_dev *mvtvm_mldev;
+
+       mvtvm_mldev = &cnxk_mldev->mvtvm_mldev;
+
+       dev_info->max_queue_pairs = mvtvm_mldev->max_nb_qpairs;
+       dev_info->max_desc = ML_MVTVM_MAX_DESC_PER_QP;
+       dev_info->max_io = ML_MVTVM_MAX_INPUT_OUTPUT;
+       dev_info->max_segments = ML_MVTVM_MAX_SEGMENTS;
+       dev_info->align_size = RTE_CACHE_LINE_SIZE;
+
+       return 0;
+}
+
 int
 mvtvm_ml_dev_configure(struct cnxk_ml_dev *cnxk_mldev, const struct 
rte_ml_dev_config *conf)
 {
@@ -59,6 +74,15 @@ mvtvm_ml_dev_close(struct cnxk_ml_dev *cnxk_mldev)
        return ret;
 }
 
+int
+mvtvm_ml_dev_dump(struct cnxk_ml_dev *cnxk_mldev, FILE *fp)
+{
+       RTE_SET_USED(cnxk_mldev);
+       RTE_SET_USED(fp);
+
+       return 0;
+}
+
 int
 mvtvm_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct rte_ml_model_params 
*params,
                    struct cnxk_ml_model *model)
@@ -169,6 +193,12 @@ mvtvm_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct 
rte_ml_model_params *
        else
                model->subtype = ML_CNXK_MODEL_SUBTYPE_TVM_HYBRID;
 
+       if (cnxk_mldev->type == CNXK_ML_DEV_TYPE_VDEV &&
+           model->subtype != ML_CNXK_MODEL_SUBTYPE_TVM_LLVM) {
+               plt_err("Unsupported model sub-type");
+               return -ENOTSUP;
+       }
+
        /* Set callback function array */
        if (model->subtype != ML_CNXK_MODEL_SUBTYPE_TVM_LLVM) {
                callback = &model->mvtvm.cb;
diff --git a/drivers/ml/cnxk/mvtvm_ml_ops.h b/drivers/ml/cnxk/mvtvm_ml_ops.h
index dba055c22e7..6cb8db92030 100644
--- a/drivers/ml/cnxk/mvtvm_ml_ops.h
+++ b/drivers/ml/cnxk/mvtvm_ml_ops.h
@@ -50,8 +50,10 @@ struct mvtvm_ml_req {
        struct mvtvm_ml_result result;
 };
 
+int mvtvm_ml_dev_info_get(struct cnxk_ml_dev *mldev, struct rte_ml_dev_info 
*dev_info);
 int mvtvm_ml_dev_configure(struct cnxk_ml_dev *cnxk_mldev, const struct 
rte_ml_dev_config *conf);
 int mvtvm_ml_dev_close(struct cnxk_ml_dev *cnxk_mldev);
+int mvtvm_ml_dev_dump(struct cnxk_ml_dev *cnxk_mldev, FILE *fp);
 int mvtvm_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct 
rte_ml_model_params *params,
                        struct cnxk_ml_model *model);
 int mvtvm_ml_model_unload(struct cnxk_ml_dev *cnxk_mldev, struct cnxk_ml_model 
*model);
-- 
2.41.0

Reply via email to