If counter action initialization failed, the PMD used integer values,
primarily (-1) or errno, to notify upper layers.

The patch uses the `rte_flow_error` structure for counter
initialization failure notifications.

Fixes: 4d368e1da3a4 ("net/mlx5: support flow counter action for HWS")

Cc: sta...@dpdk.org

Signed-off-by: Gregory Etelson <getel...@nvidia.com>
Acked-by: Dariusz Sosnowski <dsosnow...@nvidia.com>
---
 drivers/net/mlx5/mlx5_flow_hw.c |  31 ++++++--
 drivers/net/mlx5/mlx5_hws_cnt.c | 123 ++++++++++++++++++++++++--------
 drivers/net/mlx5/mlx5_hws_cnt.h |   5 +-
 drivers/net/mlx5/mlx5_trigger.c |  10 ++-
 4 files changed, 128 insertions(+), 41 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_flow_hw.c b/drivers/net/mlx5/mlx5_flow_hw.c
index 5b34154bf1..6081ebc7e2 100644
--- a/drivers/net/mlx5/mlx5_flow_hw.c
+++ b/drivers/net/mlx5/mlx5_flow_hw.c
@@ -11669,6 +11669,7 @@ __flow_hw_configure(struct rte_eth_dev *dev,
        uint32_t action_flags;
        bool strict_queue = false;
 
+       error->type = RTE_FLOW_ERROR_TYPE_NONE;
        if (mlx5dr_rule_get_handle_size() != MLX5_DR_RULE_SIZE) {
                rte_errno = EINVAL;
                goto err;
@@ -11906,9 +11907,11 @@ __flow_hw_configure(struct rte_eth_dev *dev,
                        goto err;
        }
        if (port_attr->nb_counters || (host_priv && host_priv->hws_cpool)) {
-               if (mlx5_hws_cnt_pool_create(dev, port_attr->nb_counters,
-                                               nb_queue,
-                                               (host_priv ? 
host_priv->hws_cpool : NULL)))
+               struct mlx5_hws_cnt_pool *hws_cpool = host_priv ? 
host_priv->hws_cpool : NULL;
+
+               ret = mlx5_hws_cnt_pool_create(dev, port_attr->nb_counters,
+                                              nb_queue, hws_cpool, error);
+               if (ret)
                        goto err;
        }
        if (port_attr->nb_aging_objects) {
@@ -11957,7 +11960,7 @@ __flow_hw_configure(struct rte_eth_dev *dev,
        if (_queue_attr)
                mlx5_free(_queue_attr);
        /* Do not overwrite the internal errno information. */
-       if (ret)
+       if (ret && error->type != RTE_FLOW_ERROR_TYPE_NONE)
                return ret;
        return rte_flow_error_set(error, rte_errno,
                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
@@ -11988,6 +11991,10 @@ flow_hw_configure(struct rte_eth_dev *dev,
                  const struct rte_flow_queue_attr *queue_attr[],
                  struct rte_flow_error *error)
 {
+       struct rte_flow_error shadow_error = {0, };
+
+       if (!error)
+               error = &shadow_error;
        return __flow_hw_configure(dev, port_attr, nb_queue, queue_attr, false, 
error);
 }
 
@@ -12852,6 +12859,10 @@ flow_hw_action_validate(struct rte_eth_dev *dev,
                        const struct rte_flow_action *action,
                        struct rte_flow_error *err)
 {
+       struct rte_flow_error shadow_error = {0, };
+
+       if (!err)
+               err = &shadow_error;
        return flow_hw_action_handle_validate(dev, MLX5_HW_INV_QUEUE, NULL,
                                              conf, action, NULL, err);
 }
@@ -13606,6 +13617,7 @@ flow_hw_allocate_actions(struct rte_eth_dev *dev,
        int ret;
        uint obj_num;
 
+       error->type = RTE_FLOW_ERROR_TYPE_NONE;
        if (action_flags & MLX5_FLOW_ACTION_AGE) {
                /* If no age objects were previously allocated. */
                if (!priv->hws_age_req) {
@@ -13613,7 +13625,8 @@ flow_hw_allocate_actions(struct rte_eth_dev *dev,
                        if (!priv->hws_cpool) {
                                obj_num = MLX5_CNT_NT_MAX(priv);
                                ret = mlx5_hws_cnt_pool_create(dev, obj_num,
-                                                              priv->nb_queue, 
NULL);
+                                                              priv->nb_queue,
+                                                              NULL, error);
                                if (ret)
                                        goto err;
                        }
@@ -13629,7 +13642,8 @@ flow_hw_allocate_actions(struct rte_eth_dev *dev,
                if (!priv->hws_cpool) {
                        obj_num = MLX5_CNT_NT_MAX(priv);
                        ret = mlx5_hws_cnt_pool_create(dev, obj_num,
-                                                      priv->nb_queue, NULL);
+                                                      priv->nb_queue, NULL,
+                                                      error);
                        if (ret)
                                goto err;
                }
@@ -13655,6 +13669,8 @@ flow_hw_allocate_actions(struct rte_eth_dev *dev,
        }
        return 0;
 err:
+       if (ret && error->type != RTE_FLOW_ERROR_TYPE_NONE)
+               return ret;
        return rte_flow_error_set(error, ret,
                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
                                  NULL, "fail to allocate actions");
@@ -13927,6 +13943,7 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev 
*dev,
                        .actions = actions,
                },
        };
+       struct rte_flow_error shadow_error = {0, };
 
        /*
         * TODO: add a call to flow_hw_validate function once it exist.
@@ -13934,6 +13951,8 @@ static uintptr_t flow_hw_list_create(struct rte_eth_dev 
*dev,
         */
 
        RTE_SET_USED(encap_idx);
+       if (!error)
+               error = &shadow_error;
        split = mlx5_flow_nta_split_metadata(dev, attr, actions, qrss, 
action_flags,
                                             actions_n, external, &resource, 
error);
        if (split < 0)
diff --git a/drivers/net/mlx5/mlx5_hws_cnt.c b/drivers/net/mlx5/mlx5_hws_cnt.c
index a46a4bd94e..def0b19deb 100644
--- a/drivers/net/mlx5/mlx5_hws_cnt.c
+++ b/drivers/net/mlx5/mlx5_hws_cnt.c
@@ -258,7 +258,8 @@ mlx5_hws_cnt_raw_data_free(struct mlx5_dev_ctx_shared *sh,
 
 __rte_unused
 static struct mlx5_hws_cnt_raw_data_mng *
-mlx5_hws_cnt_raw_data_alloc(struct mlx5_dev_ctx_shared *sh, uint32_t n)
+mlx5_hws_cnt_raw_data_alloc(struct mlx5_dev_ctx_shared *sh, uint32_t n,
+                           struct rte_flow_error *error)
 {
        struct mlx5_hws_cnt_raw_data_mng *mng = NULL;
        int ret;
@@ -268,16 +269,26 @@ mlx5_hws_cnt_raw_data_alloc(struct mlx5_dev_ctx_shared 
*sh, uint32_t n)
        MLX5_ASSERT(pgsz > 0);
        mng = mlx5_malloc(MLX5_MEM_ANY | MLX5_MEM_ZERO, sizeof(*mng), 0,
                        SOCKET_ID_ANY);
-       if (mng == NULL)
+       if (mng == NULL) {
+               rte_flow_error_set(error, ENOMEM,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                  NULL, "failed to allocate counters memory 
manager");
                goto error;
+       }
        mng->raw = mlx5_malloc(MLX5_MEM_ANY | MLX5_MEM_ZERO, sz, pgsz,
                        SOCKET_ID_ANY);
-       if (mng->raw == NULL)
+       if (mng->raw == NULL) {
+               rte_flow_error_set(error, ENOMEM,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                  NULL, "failed to allocate raw counters 
memory");
                goto error;
+       }
        ret = sh->cdev->mr_scache.reg_mr_cb(sh->cdev->pd, mng->raw, sz,
                                            &mng->mr);
        if (ret) {
-               rte_errno = errno;
+               rte_flow_error_set(error, errno,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                  NULL, "failed to register counters memory 
region");
                goto error;
        }
        return mng;
@@ -391,7 +402,8 @@ mlx5_hws_cnt_cache_init(const struct mlx5_hws_cnt_pool_cfg 
*pcfg,
 static struct mlx5_hws_cnt_pool *
 mlx5_hws_cnt_pool_init(struct mlx5_dev_ctx_shared *sh,
                       const struct mlx5_hws_cnt_pool_cfg *pcfg,
-                      const struct mlx5_hws_cache_param *ccfg)
+                      const struct mlx5_hws_cache_param *ccfg,
+                      struct rte_flow_error *error)
 {
        char mz_name[RTE_MEMZONE_NAMESIZE];
        struct mlx5_hws_cnt_pool *cntp;
@@ -401,8 +413,12 @@ mlx5_hws_cnt_pool_init(struct mlx5_dev_ctx_shared *sh,
        MLX5_ASSERT(ccfg);
        cntp = mlx5_malloc(MLX5_MEM_ANY | MLX5_MEM_ZERO, sizeof(*cntp), 0,
                           SOCKET_ID_ANY);
-       if (cntp == NULL)
+       if (cntp == NULL) {
+               rte_flow_error_set(error, ENOMEM,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+                                  "failed to allocate counter pool context");
                return NULL;
+       }
 
        cntp->cfg = *pcfg;
        if (cntp->cfg.host_cpool)
@@ -411,12 +427,18 @@ mlx5_hws_cnt_pool_init(struct mlx5_dev_ctx_shared *sh,
                DRV_LOG(ERR, "Counter number %u "
                        "is greater than the maximum supported (%u).",
                        pcfg->request_num, sh->hws_max_nb_counters);
+               rte_flow_error_set(error, EINVAL,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+                                  "requested counters number exceeds supported 
capacity");
                goto error;
        }
        cnt_num = pcfg->request_num * (100 + pcfg->alloc_factor) / 100;
        if (cnt_num > UINT32_MAX) {
                DRV_LOG(ERR, "counter number %"PRIu64" is out of 32bit range",
                        cnt_num);
+               rte_flow_error_set(error, EINVAL,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+                                  "counters number must fit in 32 bits");
                goto error;
        }
        /*
@@ -427,15 +449,21 @@ mlx5_hws_cnt_pool_init(struct mlx5_dev_ctx_shared *sh,
        cntp->pool = mlx5_malloc(MLX5_MEM_ANY | MLX5_MEM_ZERO,
                                 sizeof(struct mlx5_hws_cnt) * cnt_num,
                                 0, SOCKET_ID_ANY);
-       if (cntp->pool == NULL)
+       if (cntp->pool == NULL) {
+               rte_flow_error_set(error, ENOMEM,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+                                  "failed to allocate counter pool context");
                goto error;
+       }
        snprintf(mz_name, sizeof(mz_name), "%s_F_RING", pcfg->name);
        cntp->free_list = rte_ring_create_elem(mz_name, sizeof(cnt_id_t),
                                (uint32_t)cnt_num, SOCKET_ID_ANY,
                                RING_F_MP_HTS_ENQ | RING_F_MC_HTS_DEQ |
                                RING_F_EXACT_SZ);
        if (cntp->free_list == NULL) {
-               DRV_LOG(ERR, "failed to create free list ring");
+               rte_flow_error_set(error, ENOMEM,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+                                  "failed to allocate free counters ring");
                goto error;
        }
        snprintf(mz_name, sizeof(mz_name), "%s_R_RING", pcfg->name);
@@ -443,7 +471,9 @@ mlx5_hws_cnt_pool_init(struct mlx5_dev_ctx_shared *sh,
                        (uint32_t)cnt_num, SOCKET_ID_ANY,
                        RING_F_MP_HTS_ENQ | RING_F_SC_DEQ | RING_F_EXACT_SZ);
        if (cntp->wait_reset_list == NULL) {
-               DRV_LOG(ERR, "failed to create wait reset list ring");
+               rte_flow_error_set(error, ENOMEM,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+                                  "failed to allocate counters wait reset 
ring");
                goto error;
        }
        snprintf(mz_name, sizeof(mz_name), "%s_U_RING", pcfg->name);
@@ -451,14 +481,20 @@ mlx5_hws_cnt_pool_init(struct mlx5_dev_ctx_shared *sh,
                        (uint32_t)cnt_num, SOCKET_ID_ANY,
                        RING_F_MP_HTS_ENQ | RING_F_MC_HTS_DEQ | 
RING_F_EXACT_SZ);
        if (cntp->reuse_list == NULL) {
-               DRV_LOG(ERR, "failed to create reuse list ring");
+               rte_flow_error_set(error, ENOMEM,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+                                  "failed to allocate counters reuse ring");
                goto error;
        }
        /* Allocate counter cache only if needed. */
        if (mlx5_hws_cnt_should_enable_cache(pcfg, ccfg)) {
                cntp->cache = mlx5_hws_cnt_cache_init(pcfg, ccfg);
-               if (cntp->cache == NULL)
+               if (cntp->cache == NULL) {
+                       rte_flow_error_set(error, ENOMEM,
+                                          RTE_FLOW_ERROR_TYPE_UNSPECIFIED, 
NULL,
+                                          "failed to allocate counters cache");
                        goto error;
+               }
        }
        /* Initialize the time for aging-out calculation. */
        cntp->time_of_last_age_check = MLX5_CURR_TIME_SEC;
@@ -506,7 +542,8 @@ mlx5_hws_cnt_service_thread_destroy(struct 
mlx5_dev_ctx_shared *sh)
 
 static int
 mlx5_hws_cnt_pool_dcs_alloc(struct mlx5_dev_ctx_shared *sh,
-                           struct mlx5_hws_cnt_pool *cpool)
+                           struct mlx5_hws_cnt_pool *cpool,
+                           struct rte_flow_error *error)
 {
        struct mlx5_hca_attr *hca_attr = &sh->cdev->config.hca_attr;
        uint32_t max_log_bulk_sz = sh->hws_max_log_bulk_sz;
@@ -517,10 +554,10 @@ mlx5_hws_cnt_pool_dcs_alloc(struct mlx5_dev_ctx_shared 
*sh,
        struct mlx5_devx_obj *dcs;
 
        MLX5_ASSERT(cpool->cfg.host_cpool == NULL);
-       if (hca_attr->flow_counter_bulk_log_max_alloc == 0) {
-               DRV_LOG(ERR, "Fw doesn't support bulk log max alloc");
-               return -1;
-       }
+       if (hca_attr->flow_counter_bulk_log_max_alloc == 0)
+               return rte_flow_error_set(error, ENOTSUP,
+                                         RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                         NULL, "FW doesn't support bulk log 
max alloc");
        cnt_num = RTE_ALIGN_CEIL(cnt_num, 4); /* minimal 4 counter in bulk. */
        log_bulk_sz = RTE_MIN(max_log_bulk_sz, rte_log2_u32(cnt_num));
        attr.pd = sh->cdev->pdn;
@@ -529,8 +566,12 @@ mlx5_hws_cnt_pool_dcs_alloc(struct mlx5_dev_ctx_shared *sh,
        attr.flow_counter_bulk_log_size = log_bulk_sz;
        idx = 0;
        dcs = mlx5_devx_cmd_flow_counter_alloc_general(sh->cdev->ctx, &attr);
-       if (dcs == NULL)
+       if (dcs == NULL) {
+               rte_flow_error_set(error, rte_errno,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                  NULL, "FW failed to allocate counters");
                goto error;
+       }
        cpool->dcs_mng.dcs[idx].obj = dcs;
        cpool->dcs_mng.dcs[idx].batch_sz = (1 << log_bulk_sz);
        cpool->dcs_mng.batch_total++;
@@ -545,8 +586,12 @@ mlx5_hws_cnt_pool_dcs_alloc(struct mlx5_dev_ctx_shared *sh,
                                continue;
                        dcs = mlx5_devx_cmd_flow_counter_alloc_general
                                (sh->cdev->ctx, &attr);
-                       if (dcs == NULL)
+                       if (dcs == NULL) {
+                               rte_flow_error_set(error, rte_errno,
+                                                  
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                                  NULL, "FW failed to allocate 
counters");
                                goto error;
+                       }
                        cpool->dcs_mng.dcs[idx].obj = dcs;
                        cpool->dcs_mng.dcs[idx].batch_sz = alloc_candidate;
                        cpool->dcs_mng.dcs[idx].iidx = alloced;
@@ -633,15 +678,16 @@ mlx5_hws_cnt_pool_action_create(struct mlx5_priv *priv,
 
 int
 mlx5_hws_cnt_pool_create(struct rte_eth_dev *dev,
-               uint32_t nb_counters, uint16_t nb_queue,
-               struct mlx5_hws_cnt_pool *chost)
+                        uint32_t nb_counters, uint16_t nb_queue,
+                        struct mlx5_hws_cnt_pool *chost,
+                        struct rte_flow_error *error)
 {
        struct mlx5_hws_cnt_pool *cpool = NULL;
        struct mlx5_priv *priv = dev->data->dev_private;
        struct mlx5_hws_cache_param cparam = {0};
        struct mlx5_hws_cnt_pool_cfg pcfg = {0};
        char *mp_name;
-       int ret = -1;
+       int ret = 0;
        size_t sz;
 
        mp_name = mlx5_malloc(MLX5_MEM_ZERO, RTE_MEMZONE_NAMESIZE, 0, 
SOCKET_ID_ANY);
@@ -653,17 +699,21 @@ mlx5_hws_cnt_pool_create(struct rte_eth_dev *dev,
        pcfg.alloc_factor = HWS_CNT_ALLOC_FACTOR_DEFAULT;
        if (chost) {
                pcfg.host_cpool = chost;
-               cpool = mlx5_hws_cnt_pool_init(priv->sh, &pcfg, &cparam);
+               cpool = mlx5_hws_cnt_pool_init(priv->sh, &pcfg, &cparam, error);
                if (cpool == NULL)
                        goto error;
                ret = mlx5_hws_cnt_pool_action_create(priv, cpool);
-               if (ret != 0)
+               if (ret != 0) {
+                       rte_flow_error_set(error, -ret,
+                                          RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                          NULL, "failed to allocate counter 
actions on guest port");
                        goto error;
+               }
                goto success;
        }
        /* init cnt service if not. */
        if (priv->sh->cnt_svc == NULL) {
-               ret = mlx5_hws_cnt_svc_init(priv->sh);
+               ret = mlx5_hws_cnt_svc_init(priv->sh, error);
                if (ret)
                        return ret;
        }
@@ -672,14 +722,14 @@ mlx5_hws_cnt_pool_create(struct rte_eth_dev *dev,
        cparam.q_num = nb_queue;
        cparam.threshold = HWS_CNT_CACHE_THRESHOLD_DEFAULT;
        cparam.size = HWS_CNT_CACHE_SZ_DEFAULT;
-       cpool = mlx5_hws_cnt_pool_init(priv->sh, &pcfg, &cparam);
+       cpool = mlx5_hws_cnt_pool_init(priv->sh, &pcfg, &cparam, error);
        if (cpool == NULL)
                goto error;
-       ret = mlx5_hws_cnt_pool_dcs_alloc(priv->sh, cpool);
+       ret = mlx5_hws_cnt_pool_dcs_alloc(priv->sh, cpool, error);
        if (ret != 0)
                goto error;
        sz = RTE_ALIGN_CEIL(mlx5_hws_cnt_pool_get_size(cpool), 4);
-       cpool->raw_mng = mlx5_hws_cnt_raw_data_alloc(priv->sh, sz);
+       cpool->raw_mng = mlx5_hws_cnt_raw_data_alloc(priv->sh, sz, error);
        if (cpool->raw_mng == NULL)
                goto error;
        __hws_cnt_id_load(cpool);
@@ -691,8 +741,12 @@ mlx5_hws_cnt_pool_create(struct rte_eth_dev *dev,
         */
        cpool->query_gen = 1;
        ret = mlx5_hws_cnt_pool_action_create(priv, cpool);
-       if (ret != 0)
+       if (ret != 0) {
+               rte_flow_error_set(error, -ret,
+                                  RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                  NULL, "failed to allocate counter actions");
                goto error;
+       }
        priv->sh->cnt_svc->refcnt++;
        cpool->priv = priv;
        rte_spinlock_lock(&priv->sh->cpool_lock);
@@ -702,6 +756,7 @@ mlx5_hws_cnt_pool_create(struct rte_eth_dev *dev,
        priv->hws_cpool = cpool;
        return 0;
 error:
+       MLX5_ASSERT(ret);
        mlx5_hws_cnt_pool_destroy(priv->sh, cpool);
        priv->hws_cpool = NULL;
        return ret;
@@ -736,21 +791,22 @@ mlx5_hws_cnt_pool_destroy(struct mlx5_dev_ctx_shared *sh,
 }
 
 int
-mlx5_hws_cnt_svc_init(struct mlx5_dev_ctx_shared *sh)
+mlx5_hws_cnt_svc_init(struct mlx5_dev_ctx_shared *sh,
+                     struct rte_flow_error *error)
 {
        int ret;
 
        sh->cnt_svc = mlx5_malloc(MLX5_MEM_ANY | MLX5_MEM_ZERO,
                        sizeof(*sh->cnt_svc), 0, SOCKET_ID_ANY);
        if (sh->cnt_svc == NULL)
-               return -1;
+               goto err;
        sh->cnt_svc->query_interval = sh->config.cnt_svc.cycle_time;
        sh->cnt_svc->service_core = sh->config.cnt_svc.service_core;
        ret = mlx5_aso_cnt_queue_init(sh);
        if (ret != 0) {
                mlx5_free(sh->cnt_svc);
                sh->cnt_svc = NULL;
-               return -1;
+               goto err;
        }
        ret = mlx5_hws_cnt_service_thread_create(sh);
        if (ret != 0) {
@@ -759,6 +815,11 @@ mlx5_hws_cnt_svc_init(struct mlx5_dev_ctx_shared *sh)
                sh->cnt_svc = NULL;
        }
        return 0;
+err:
+       return rte_flow_error_set(error, ENOMEM,
+                                 RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                                 NULL, "failed to init counters service");
+
 }
 
 void
diff --git a/drivers/net/mlx5/mlx5_hws_cnt.h b/drivers/net/mlx5/mlx5_hws_cnt.h
index 996ac8dd9a..d8da9dfcdd 100644
--- a/drivers/net/mlx5/mlx5_hws_cnt.h
+++ b/drivers/net/mlx5/mlx5_hws_cnt.h
@@ -715,14 +715,15 @@ mlx5_hws_cnt_service_thread_destroy(struct 
mlx5_dev_ctx_shared *sh);
 int
 mlx5_hws_cnt_pool_create(struct rte_eth_dev *dev,
                uint32_t nb_counters, uint16_t nb_queue,
-               struct mlx5_hws_cnt_pool *chost);
+               struct mlx5_hws_cnt_pool *chost, struct rte_flow_error *error);
 
 void
 mlx5_hws_cnt_pool_destroy(struct mlx5_dev_ctx_shared *sh,
                struct mlx5_hws_cnt_pool *cpool);
 
 int
-mlx5_hws_cnt_svc_init(struct mlx5_dev_ctx_shared *sh);
+mlx5_hws_cnt_svc_init(struct mlx5_dev_ctx_shared *sh,
+                     struct rte_flow_error *error);
 
 void
 mlx5_hws_cnt_svc_deinit(struct mlx5_dev_ctx_shared *sh);
diff --git a/drivers/net/mlx5/mlx5_trigger.c b/drivers/net/mlx5/mlx5_trigger.c
index cac532b1a1..79b3d4d982 100644
--- a/drivers/net/mlx5/mlx5_trigger.c
+++ b/drivers/net/mlx5/mlx5_trigger.c
@@ -1160,11 +1160,17 @@ mlx5_dev_start(struct rte_eth_dev *dev)
        DRV_LOG(DEBUG, "port %u starting device", dev->data->port_id);
 #ifdef HAVE_MLX5_HWS_SUPPORT
        if (priv->sh->config.dv_flow_en == 2) {
+               struct rte_flow_error error = { 0, };
+
                /*If previous configuration does not exist. */
                if (!(priv->dr_ctx)) {
-                       ret = flow_hw_init(dev, NULL);
-                       if (ret)
+                       ret = flow_hw_init(dev, &error);
+                       if (ret) {
+                               DRV_LOG(ERR, "Failed to start port %u %s: %s",
+                                       dev->data->port_id, dev->data->name,
+                                       error.message);
                                return ret;
+                       }
                }
                /* If there is no E-Switch, then there are no start/stop order 
limitations. */
                if (!priv->sh->config.dv_esw_en)
-- 
2.43.0

Reply via email to