#include "mlx5_flow_os.h"
#include "mlx5_rxtx.h"
#include "mlx5_common_os.h"
+#include "rte_pmd_mlx5.h"
static struct mlx5_flow_tunnel *
mlx5_find_tunnel_id(struct rte_eth_dev *dev, uint32_t id);
RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL, NULL);
}
+static int
+flow_null_sync_domain(struct rte_eth_dev *dev __rte_unused,
+ uint32_t domains __rte_unused,
+ uint32_t flags __rte_unused)
+{
+ return 0;
+}
+
/* Void driver to protect from null pointer reference. */
const struct mlx5_flow_driver_ops mlx5_flow_null_drv_ops = {
.validate = flow_null_validate,
.remove = flow_null_remove,
.destroy = flow_null_destroy,
.query = flow_null_query,
+ .sync_domain = flow_null_sync_domain,
};
/**
mlx5_free(thub);
return err;
}
+
+#ifndef HAVE_MLX5DV_DR
+#define MLX5_DOMAIN_SYNC_FLOW ((1 << 0) | (1 << 1))
+#else
+#define MLX5_DOMAIN_SYNC_FLOW \
+ (MLX5DV_DR_DOMAIN_SYNC_FLAGS_SW | MLX5DV_DR_DOMAIN_SYNC_FLAGS_HW)
+#endif
+
+int rte_pmd_mlx5_sync_flow(uint16_t port_id, uint32_t domains)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ const struct mlx5_flow_driver_ops *fops;
+ int ret;
+ struct rte_flow_attr attr = { .transfer = 0 };
+
+ fops = flow_get_drv_ops(flow_get_drv_type(dev, &attr));
+ ret = fops->sync_domain(dev, domains, MLX5_DOMAIN_SYNC_FLOW);
+ if (ret > 0)
+ ret = -ret;
+ return ret;
+}
struct rte_flow_shared_action *action,
const void *action_conf,
struct rte_flow_error *error);
+typedef int (*mlx5_flow_sync_domain_t)
+ (struct rte_eth_dev *dev,
+ uint32_t domains,
+ uint32_t flags);
struct mlx5_flow_driver_ops {
mlx5_flow_validate_t validate;
mlx5_flow_prepare_t prepare;
mlx5_flow_action_create_t action_create;
mlx5_flow_action_destroy_t action_destroy;
mlx5_flow_action_update_t action_update;
+ mlx5_flow_sync_domain_t sync_domain;
};
/* mlx5_flow.c */
#include "mlx5_flow.h"
#include "mlx5_flow_os.h"
#include "mlx5_rxtx.h"
+#include "rte_pmd_mlx5.h"
#ifdef HAVE_IBV_FLOW_DV_SUPPORT
return ret;
}
+static int
+flow_dv_sync_domain(struct rte_eth_dev *dev, uint32_t domains, uint32_t flags)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ int ret = 0;
+
+ if ((domains & MLX5_DOMAIN_BIT_NIC_RX) && priv->sh->rx_domain != NULL) {
+ ret = mlx5_glue->dr_sync_domain(priv->sh->rx_domain,
+ flags);
+ if (ret != 0)
+ return ret;
+ }
+ if ((domains & MLX5_DOMAIN_BIT_NIC_TX) && priv->sh->tx_domain != NULL) {
+ ret = mlx5_glue->dr_sync_domain(priv->sh->tx_domain, flags);
+ if (ret != 0)
+ return ret;
+ }
+ if ((domains & MLX5_DOMAIN_BIT_FDB) && priv->sh->fdb_domain != NULL) {
+ ret = mlx5_glue->dr_sync_domain(priv->sh->fdb_domain, flags);
+ if (ret != 0)
+ return ret;
+ }
+ return 0;
+}
+
const struct mlx5_flow_driver_ops mlx5_flow_dv_drv_ops = {
.validate = flow_dv_validate,
.prepare = flow_dv_prepare,
.action_create = flow_dv_action_create,
.action_destroy = flow_dv_action_destroy,
.action_update = flow_dv_action_update,
+ .sync_domain = flow_dv_sync_domain,
};
#endif /* HAVE_IBV_FLOW_DV_SUPPORT */
return ret;
}
+static int
+flow_verbs_sync_domain(struct rte_eth_dev *dev, uint32_t domains,
+ uint32_t flags)
+{
+ RTE_SET_USED(dev);
+ RTE_SET_USED(domains);
+ RTE_SET_USED(flags);
+
+ return 0;
+}
+
const struct mlx5_flow_driver_ops mlx5_flow_verbs_drv_ops = {
.validate = flow_verbs_validate,
.prepare = flow_verbs_prepare,
.remove = flow_verbs_remove,
.destroy = flow_verbs_destroy,
.query = flow_verbs_query,
+ .sync_domain = flow_verbs_sync_domain,
};
__rte_experimental
int rte_pmd_mlx5_get_dyn_flag_names(char *names[], unsigned int n);
+#define MLX5_DOMAIN_BIT_NIC_RX (1 << 0) /**< NIC RX domain bit mask. */
+#define MLX5_DOMAIN_BIT_NIC_TX (1 << 1) /**< NIC TX domain bit mask. */
+#define MLX5_DOMAIN_BIT_FDB (1 << 2) /**< FDB (TX + RX) domain bit mask. */
+
+/**
+ * Synchronize the flows to make them take effort on hardware.
+ * It only supports DR flows now. For DV and Verbs flows, there is no need to
+ * call this function, and a success will return directly in case of Verbs.
+ *
+ * @param[in] port_id
+ * The port identifier of the Ethernet device.
+ * @param[in] domains
+ * Refer to "/usr/include/infiniband/mlx5dv.h".
+ * Bitmask of domains in which the synchronization will be done.
+ * MLX5_DOMAIN_BIT* macros are used to specify the domains.
+ * An ADD or OR operation could be used to synchronize flows in more than
+ * one domain per call.
+ *
+ * @return
+ * - (0) if successful.
+ * - Negative value if an error.
+ */
+__rte_experimental
+int rte_pmd_mlx5_sync_flow(uint16_t port_id, uint32_t domains);
+
#endif
# added in 20.02
rte_pmd_mlx5_get_dyn_flag_names;
+ # added in 20.11
+ rte_pmd_mlx5_sync_flow;
};