+/**
+ * DR flow drop action support detect.
+ *
+ * @param dev
+ * Pointer to rte_eth_dev structure.
+ *
+ */
+static void
+mlx5_flow_drop_action_config(struct rte_eth_dev *dev __rte_unused)
+{
+#ifdef HAVE_MLX5DV_DR
+ struct mlx5_priv *priv = dev->data->dev_private;
+
+ if (!priv->config.dv_flow_en || !priv->sh->dr_drop_action)
+ return;
+ /**
+ * DR supports drop action placeholder when it is supported;
+ * otherwise, use the queue drop action.
+ */
+ if (!priv->sh->drop_action_check_flag) {
+ if (!mlx5_flow_discover_dr_action_support(dev))
+ priv->sh->dr_drop_action_en = 1;
+ priv->sh->drop_action_check_flag = 1;
+ }
+ if (priv->sh->dr_drop_action_en)
+ priv->root_drop_action = priv->sh->dr_drop_action;
+ else
+ priv->root_drop_action = priv->drop_queue.hrxq->action;
+#endif
+}
+
+static void
+mlx5_queue_counter_id_prepare(struct rte_eth_dev *dev)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ void *ctx = priv->sh->cdev->ctx;
+
+ priv->q_counters = mlx5_devx_cmd_queue_counter_alloc(ctx);
+ if (!priv->q_counters) {
+ struct ibv_cq *cq = mlx5_glue->create_cq(ctx, 1, NULL, NULL, 0);
+ struct ibv_wq *wq;
+
+ DRV_LOG(DEBUG, "Port %d queue counter object cannot be created "
+ "by DevX - fall-back to use the kernel driver global "
+ "queue counter.", dev->data->port_id);
+ /* Create WQ by kernel and query its queue counter ID. */
+ if (cq) {
+ wq = mlx5_glue->create_wq(ctx,
+ &(struct ibv_wq_init_attr){
+ .wq_type = IBV_WQT_RQ,
+ .max_wr = 1,
+ .max_sge = 1,
+ .pd = priv->sh->cdev->pd,
+ .cq = cq,
+ });
+ if (wq) {
+ /* Counter is assigned only on RDY state. */
+ int ret = mlx5_glue->modify_wq(wq,
+ &(struct ibv_wq_attr){
+ .attr_mask = IBV_WQ_ATTR_STATE,
+ .wq_state = IBV_WQS_RDY,
+ });
+
+ if (ret == 0)
+ mlx5_devx_cmd_wq_query(wq,
+ &priv->counter_set_id);
+ claim_zero(mlx5_glue->destroy_wq(wq));
+ }
+ claim_zero(mlx5_glue->destroy_cq(cq));
+ }
+ } else {
+ priv->counter_set_id = priv->q_counters->id;
+ }
+ if (priv->counter_set_id == 0)
+ DRV_LOG(INFO, "Part of the port %d statistics will not be "
+ "available.", dev->data->port_id);
+}
+
+/**
+ * Check if representor spawn info match devargs.
+ *
+ * @param spawn
+ * Verbs device parameters (name, port, switch_info) to spawn.
+ * @param eth_da
+ * Device devargs to probe.
+ *
+ * @return
+ * Match result.
+ */
+static bool
+mlx5_representor_match(struct mlx5_dev_spawn_data *spawn,
+ struct rte_eth_devargs *eth_da)
+{
+ struct mlx5_switch_info *switch_info = &spawn->info;
+ unsigned int p, f;
+ uint16_t id;
+ uint16_t repr_id = mlx5_representor_id_encode(switch_info,
+ eth_da->type);
+
+ switch (eth_da->type) {
+ case RTE_ETH_REPRESENTOR_SF:
+ if (!(spawn->info.port_name == -1 &&
+ switch_info->name_type ==
+ MLX5_PHYS_PORT_NAME_TYPE_PFHPF) &&
+ switch_info->name_type != MLX5_PHYS_PORT_NAME_TYPE_PFSF) {
+ rte_errno = EBUSY;
+ return false;
+ }
+ break;
+ case RTE_ETH_REPRESENTOR_VF:
+ /* Allows HPF representor index -1 as exception. */
+ if (!(spawn->info.port_name == -1 &&
+ switch_info->name_type ==
+ MLX5_PHYS_PORT_NAME_TYPE_PFHPF) &&
+ switch_info->name_type != MLX5_PHYS_PORT_NAME_TYPE_PFVF) {
+ rte_errno = EBUSY;
+ return false;
+ }
+ break;
+ case RTE_ETH_REPRESENTOR_NONE:
+ rte_errno = EBUSY;
+ return false;
+ default:
+ rte_errno = ENOTSUP;
+ DRV_LOG(ERR, "unsupported representor type");
+ return false;
+ }
+ /* Check representor ID: */
+ for (p = 0; p < eth_da->nb_ports; ++p) {
+ if (spawn->pf_bond < 0) {
+ /* For non-LAG mode, allow and ignore pf. */
+ switch_info->pf_num = eth_da->ports[p];
+ repr_id = mlx5_representor_id_encode(switch_info,
+ eth_da->type);
+ }
+ for (f = 0; f < eth_da->nb_representor_ports; ++f) {
+ id = MLX5_REPRESENTOR_ID
+ (eth_da->ports[p], eth_da->type,
+ eth_da->representor_ports[f]);
+ if (repr_id == id)
+ return true;
+ }
+ }
+ rte_errno = EBUSY;
+ return false;
+}
+