net/mlx5: add flow flush
[dpdk.git] / drivers / net / mlx5 / mlx5_flow.c
index 673e0ec..1672939 100644 (file)
@@ -827,6 +827,57 @@ static int
 mlx5_flow_pattern_template_destroy(struct rte_eth_dev *dev,
                                   struct rte_flow_pattern_template *template,
                                   struct rte_flow_error *error);
+static struct rte_flow_actions_template *
+mlx5_flow_actions_template_create(struct rte_eth_dev *dev,
+                       const struct rte_flow_actions_template_attr *attr,
+                       const struct rte_flow_action actions[],
+                       const struct rte_flow_action masks[],
+                       struct rte_flow_error *error);
+static int
+mlx5_flow_actions_template_destroy(struct rte_eth_dev *dev,
+                                  struct rte_flow_actions_template *template,
+                                  struct rte_flow_error *error);
+
+static struct rte_flow_template_table *
+mlx5_flow_table_create(struct rte_eth_dev *dev,
+                      const struct rte_flow_template_table_attr *attr,
+                      struct rte_flow_pattern_template *item_templates[],
+                      uint8_t nb_item_templates,
+                      struct rte_flow_actions_template *action_templates[],
+                      uint8_t nb_action_templates,
+                      struct rte_flow_error *error);
+static int
+mlx5_flow_table_destroy(struct rte_eth_dev *dev,
+                       struct rte_flow_template_table *table,
+                       struct rte_flow_error *error);
+static struct rte_flow *
+mlx5_flow_async_flow_create(struct rte_eth_dev *dev,
+                           uint32_t queue,
+                           const struct rte_flow_op_attr *attr,
+                           struct rte_flow_template_table *table,
+                           const struct rte_flow_item items[],
+                           uint8_t pattern_template_index,
+                           const struct rte_flow_action actions[],
+                           uint8_t action_template_index,
+                           void *user_data,
+                           struct rte_flow_error *error);
+static int
+mlx5_flow_async_flow_destroy(struct rte_eth_dev *dev,
+                            uint32_t queue,
+                            const struct rte_flow_op_attr *attr,
+                            struct rte_flow *flow,
+                            void *user_data,
+                            struct rte_flow_error *error);
+static int
+mlx5_flow_pull(struct rte_eth_dev *dev,
+              uint32_t queue,
+              struct rte_flow_op_result res[],
+              uint16_t n_res,
+              struct rte_flow_error *error);
+static int
+mlx5_flow_push(struct rte_eth_dev *dev,
+              uint32_t queue,
+              struct rte_flow_error *error);
 
 static const struct rte_flow_ops mlx5_flow_ops = {
        .validate = mlx5_flow_validate,
@@ -852,6 +903,14 @@ static const struct rte_flow_ops mlx5_flow_ops = {
        .configure = mlx5_flow_port_configure,
        .pattern_template_create = mlx5_flow_pattern_template_create,
        .pattern_template_destroy = mlx5_flow_pattern_template_destroy,
+       .actions_template_create = mlx5_flow_actions_template_create,
+       .actions_template_destroy = mlx5_flow_actions_template_destroy,
+       .template_table_create = mlx5_flow_table_create,
+       .template_table_destroy = mlx5_flow_table_destroy,
+       .async_create = mlx5_flow_async_flow_create,
+       .async_destroy = mlx5_flow_async_flow_destroy,
+       .pull = mlx5_flow_pull,
+       .push = mlx5_flow_push,
 };
 
 /* Tunnel information. */
@@ -6956,6 +7015,14 @@ mlx5_flow_list_flush(struct rte_eth_dev *dev, enum mlx5_flow_type type,
        uint32_t num_flushed = 0, fidx = 1;
        struct rte_flow *flow;
 
+#ifdef HAVE_IBV_FLOW_DV_SUPPORT
+       if (priv->sh->config.dv_flow_en == 2 &&
+           type == MLX5_FLOW_TYPE_GEN) {
+               flow_hw_q_flow_flush(dev, NULL);
+               return;
+       }
+#endif
+
        MLX5_IPOOL_FOREACH(priv->flows[type], fidx, flow) {
                flow_list_destroy(dev, type, fidx);
                num_flushed++;
@@ -8000,6 +8067,306 @@ mlx5_flow_pattern_template_destroy(struct rte_eth_dev *dev,
        return fops->pattern_template_destroy(dev, template, error);
 }
 
+/**
+ * Create flow item template.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] attr
+ *   Pointer to the action template attributes.
+ * @param[in] actions
+ *   Associated actions (list terminated by the END action).
+ * @param[in] masks
+ *   List of actions that marks which of the action's member is constant.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static struct rte_flow_actions_template *
+mlx5_flow_actions_template_create(struct rte_eth_dev *dev,
+                       const struct rte_flow_actions_template_attr *attr,
+                       const struct rte_flow_action actions[],
+                       const struct rte_flow_action masks[],
+                       struct rte_flow_error *error)
+{
+       const struct mlx5_flow_driver_ops *fops;
+
+       if (flow_get_drv_type(dev, NULL) != MLX5_FLOW_TYPE_HW) {
+               rte_flow_error_set(error, ENOTSUP,
+                               RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                               NULL,
+                               "action create with incorrect steering mode");
+               return NULL;
+       }
+       fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
+       return fops->actions_template_create(dev, attr, actions, masks, error);
+}
+
+/**
+ * Destroy flow action template.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] template
+ *   Pointer to the action template to be destroyed.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_actions_template_destroy(struct rte_eth_dev *dev,
+                                  struct rte_flow_actions_template *template,
+                                  struct rte_flow_error *error)
+{
+       const struct mlx5_flow_driver_ops *fops;
+
+       if (flow_get_drv_type(dev, NULL) != MLX5_FLOW_TYPE_HW)
+               return rte_flow_error_set(error, ENOTSUP,
+                               RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                               NULL,
+                               "action destroy with incorrect steering mode");
+       fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
+       return fops->actions_template_destroy(dev, template, error);
+}
+
+/**
+ * Create flow table.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] attr
+ *   Pointer to the table attributes.
+ * @param[in] item_templates
+ *   Item template array to be binded to the table.
+ * @param[in] nb_item_templates
+ *   Number of item template.
+ * @param[in] action_templates
+ *   Action template array to be binded to the table.
+ * @param[in] nb_action_templates
+ *   Number of action template.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *    Table on success, NULL otherwise and rte_errno is set.
+ */
+static struct rte_flow_template_table *
+mlx5_flow_table_create(struct rte_eth_dev *dev,
+                      const struct rte_flow_template_table_attr *attr,
+                      struct rte_flow_pattern_template *item_templates[],
+                      uint8_t nb_item_templates,
+                      struct rte_flow_actions_template *action_templates[],
+                      uint8_t nb_action_templates,
+                      struct rte_flow_error *error)
+{
+       const struct mlx5_flow_driver_ops *fops;
+
+       if (flow_get_drv_type(dev, NULL) != MLX5_FLOW_TYPE_HW) {
+               rte_flow_error_set(error, ENOTSUP,
+                               RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                               NULL,
+                               "table create with incorrect steering mode");
+               return NULL;
+       }
+       fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
+       return fops->template_table_create(dev,
+                                          attr,
+                                          item_templates,
+                                          nb_item_templates,
+                                          action_templates,
+                                          nb_action_templates,
+                                          error);
+}
+
+/**
+ * PMD destroy flow table.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] table
+ *   Pointer to the table to be destroyed.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *   0 on success, a negative errno value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_table_destroy(struct rte_eth_dev *dev,
+                       struct rte_flow_template_table *table,
+                       struct rte_flow_error *error)
+{
+       const struct mlx5_flow_driver_ops *fops;
+
+       if (flow_get_drv_type(dev, NULL) != MLX5_FLOW_TYPE_HW)
+               return rte_flow_error_set(error, ENOTSUP,
+                               RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                               NULL,
+                               "table destroy with incorrect steering mode");
+       fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
+       return fops->template_table_destroy(dev, table, error);
+}
+
+/**
+ * Enqueue flow creation.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] queue_id
+ *   The queue to create the flow.
+ * @param[in] attr
+ *   Pointer to the flow operation attributes.
+ * @param[in] items
+ *   Items with flow spec value.
+ * @param[in] pattern_template_index
+ *   The item pattern flow follows from the table.
+ * @param[in] actions
+ *   Action with flow spec value.
+ * @param[in] action_template_index
+ *   The action pattern flow follows from the table.
+ * @param[in] user_data
+ *   Pointer to the user_data.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *    Flow pointer on success, NULL otherwise and rte_errno is set.
+ */
+static struct rte_flow *
+mlx5_flow_async_flow_create(struct rte_eth_dev *dev,
+                           uint32_t queue_id,
+                           const struct rte_flow_op_attr *attr,
+                           struct rte_flow_template_table *table,
+                           const struct rte_flow_item items[],
+                           uint8_t pattern_template_index,
+                           const struct rte_flow_action actions[],
+                           uint8_t action_template_index,
+                           void *user_data,
+                           struct rte_flow_error *error)
+{
+       const struct mlx5_flow_driver_ops *fops;
+
+       if (flow_get_drv_type(dev, NULL) != MLX5_FLOW_TYPE_HW) {
+               rte_flow_error_set(error, ENOTSUP,
+                               RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                               NULL,
+                               "flow_q create with incorrect steering mode");
+               return NULL;
+       }
+       fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
+       return fops->async_flow_create(dev, queue_id, attr, table,
+                                      items, pattern_template_index,
+                                      actions, action_template_index,
+                                      user_data, error);
+}
+
+/**
+ * Enqueue flow destruction.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] queue
+ *   The queue to destroy the flow.
+ * @param[in] attr
+ *   Pointer to the flow operation attributes.
+ * @param[in] flow
+ *   Pointer to the flow to be destroyed.
+ * @param[in] user_data
+ *   Pointer to the user_data.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *    0 on success, negative value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_async_flow_destroy(struct rte_eth_dev *dev,
+                            uint32_t queue,
+                            const struct rte_flow_op_attr *attr,
+                            struct rte_flow *flow,
+                            void *user_data,
+                            struct rte_flow_error *error)
+{
+       const struct mlx5_flow_driver_ops *fops;
+
+       if (flow_get_drv_type(dev, NULL) != MLX5_FLOW_TYPE_HW)
+               return rte_flow_error_set(error, ENOTSUP,
+                               RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                               NULL,
+                               "flow_q destroy with incorrect steering mode");
+       fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
+       return fops->async_flow_destroy(dev, queue, attr, flow,
+                                       user_data, error);
+}
+
+/**
+ * Pull the enqueued flows.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] queue
+ *   The queue to pull the result.
+ * @param[in/out] res
+ *   Array to save the results.
+ * @param[in] n_res
+ *   Available result with the array.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *    Result number on success, negative value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_pull(struct rte_eth_dev *dev,
+              uint32_t queue,
+              struct rte_flow_op_result res[],
+              uint16_t n_res,
+              struct rte_flow_error *error)
+{
+       const struct mlx5_flow_driver_ops *fops;
+
+       if (flow_get_drv_type(dev, NULL) != MLX5_FLOW_TYPE_HW)
+               return rte_flow_error_set(error, ENOTSUP,
+                               RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                               NULL,
+                               "flow_q pull with incorrect steering mode");
+       fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
+       return fops->pull(dev, queue, res, n_res, error);
+}
+
+/**
+ * Push the enqueued flows.
+ *
+ * @param[in] dev
+ *   Pointer to the rte_eth_dev structure.
+ * @param[in] queue
+ *   The queue to push the flows.
+ * @param[out] error
+ *   Pointer to error structure.
+ *
+ * @return
+ *    0 on success, negative value otherwise and rte_errno is set.
+ */
+static int
+mlx5_flow_push(struct rte_eth_dev *dev,
+              uint32_t queue,
+              struct rte_flow_error *error)
+{
+       const struct mlx5_flow_driver_ops *fops;
+
+       if (flow_get_drv_type(dev, NULL) != MLX5_FLOW_TYPE_HW)
+               return rte_flow_error_set(error, ENOTSUP,
+                               RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+                               NULL,
+                               "flow_q push with incorrect steering mode");
+       fops = flow_get_drv_ops(MLX5_FLOW_TYPE_HW);
+       return fops->push(dev, queue, error);
+}
+
 /**
  * Allocate a new memory for the counter values wrapped by all the needed
  * management.