+/* Function to query the rte flows. */
+static int32_t
+bnxt_ulp_flow_query(struct rte_eth_dev *eth_dev,
+ struct rte_flow *flow,
+ const struct rte_flow_action *action,
+ void *data,
+ struct rte_flow_error *error)
+{
+ int rc = 0;
+ struct bnxt_ulp_context *ulp_ctx;
+ struct rte_flow_query_count *count;
+ uint32_t flow_id;
+
+ ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
+ if (!ulp_ctx) {
+ BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Failed to query flow.");
+ return -EINVAL;
+ }
+
+ flow_id = (uint32_t)(uintptr_t)flow;
+
+ switch (action->type) {
+ case RTE_FLOW_ACTION_TYPE_COUNT:
+ count = data;
+ rc = ulp_fc_mgr_query_count_get(ulp_ctx, flow_id, count);
+ if (rc) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "Failed to query flow.");
+ }
+ break;
+ default:
+ rte_flow_error_set(error, -rc, RTE_FLOW_ERROR_TYPE_ACTION_NUM,
+ NULL, "Unsupported action item");
+ }
+
+ return rc;
+}
+
+/* Tunnel offload Apis */
+#define BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS 1
+
+static int
+bnxt_ulp_tunnel_decap_set(struct rte_eth_dev *eth_dev,
+ struct rte_flow_tunnel *tunnel,
+ struct rte_flow_action **pmd_actions,
+ uint32_t *num_of_actions,
+ struct rte_flow_error *error)
+{
+ struct bnxt_ulp_context *ulp_ctx;
+ struct bnxt_flow_app_tun_ent *tun_entry;
+ int32_t rc = 0;
+
+ ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
+ if (ulp_ctx == NULL) {
+ BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "ULP context uninitialized");
+ return -EINVAL;
+ }
+
+ if (tunnel == NULL) {
+ BNXT_TF_DBG(ERR, "No tunnel specified\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "no tunnel specified");
+ return -EINVAL;
+ }
+
+ if (tunnel->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
+ BNXT_TF_DBG(ERR, "Tunnel type unsupported\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "tunnel type unsupported");
+ return -EINVAL;
+ }
+
+ rc = ulp_app_tun_search_entry(ulp_ctx, tunnel, &tun_entry);
+ if (rc < 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "tunnel decap set failed");
+ return -EINVAL;
+ }
+
+ rc = ulp_app_tun_entry_set_decap_action(tun_entry);
+ if (rc < 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "tunnel decap set failed");
+ return -EINVAL;
+ }
+
+ *pmd_actions = &tun_entry->action;
+ *num_of_actions = BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS;
+ return 0;
+}
+
+static int
+bnxt_ulp_tunnel_match(struct rte_eth_dev *eth_dev,
+ struct rte_flow_tunnel *tunnel,
+ struct rte_flow_item **pmd_items,
+ uint32_t *num_of_items,
+ struct rte_flow_error *error)
+{
+ struct bnxt_ulp_context *ulp_ctx;
+ struct bnxt_flow_app_tun_ent *tun_entry;
+ int32_t rc = 0;
+
+ ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
+ if (ulp_ctx == NULL) {
+ BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "ULP context uninitialized");
+ return -EINVAL;
+ }
+
+ if (tunnel == NULL) {
+ BNXT_TF_DBG(ERR, "No tunnel specified\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "no tunnel specified");
+ return -EINVAL;
+ }
+
+ if (tunnel->type != RTE_FLOW_ITEM_TYPE_VXLAN) {
+ BNXT_TF_DBG(ERR, "Tunnel type unsupported\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "tunnel type unsupported");
+ return -EINVAL;
+ }
+
+ rc = ulp_app_tun_search_entry(ulp_ctx, tunnel, &tun_entry);
+ if (rc < 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "tunnel match set failed");
+ return -EINVAL;
+ }
+
+ rc = ulp_app_tun_entry_set_decap_item(tun_entry);
+ if (rc < 0) {
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "tunnel match set failed");
+ return -EINVAL;
+ }
+
+ *pmd_items = &tun_entry->item;
+ *num_of_items = BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS;
+ return 0;
+}
+
+static int
+bnxt_ulp_tunnel_decap_release(struct rte_eth_dev *eth_dev,
+ struct rte_flow_action *pmd_actions,
+ uint32_t num_actions,
+ struct rte_flow_error *error)
+{
+ struct bnxt_ulp_context *ulp_ctx;
+ struct bnxt_flow_app_tun_ent *tun_entry;
+ const struct rte_flow_action *action_item = pmd_actions;
+
+ ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
+ if (ulp_ctx == NULL) {
+ BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "ULP context uninitialized");
+ return -EINVAL;
+ }
+ if (num_actions != BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS) {
+ BNXT_TF_DBG(ERR, "num actions is invalid\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "num actions is invalid");
+ return -EINVAL;
+ }
+ while (action_item && action_item->type != RTE_FLOW_ACTION_TYPE_END) {
+ if (action_item->type == (typeof(tun_entry->action.type))
+ BNXT_RTE_FLOW_ACTION_TYPE_VXLAN_DECAP) {
+ tun_entry = ulp_app_tun_match_entry(ulp_ctx,
+ action_item->conf);
+ ulp_app_tun_entry_delete(tun_entry);
+ }
+ action_item++;
+ }
+ return 0;
+}
+
+static int
+bnxt_ulp_tunnel_item_release(struct rte_eth_dev *eth_dev,
+ struct rte_flow_item *pmd_items,
+ uint32_t num_items,
+ struct rte_flow_error *error)
+{
+ struct bnxt_ulp_context *ulp_ctx;
+ struct bnxt_flow_app_tun_ent *tun_entry;
+
+ ulp_ctx = bnxt_ulp_eth_dev_ptr2_cntxt_get(eth_dev);
+ if (ulp_ctx == NULL) {
+ BNXT_TF_DBG(ERR, "ULP context is not initialized\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_HANDLE, NULL,
+ "ULP context uninitialized");
+ return -EINVAL;
+ }
+ if (num_items != BNXT_ULP_TUNNEL_OFFLOAD_NUM_ITEMS) {
+ BNXT_TF_DBG(ERR, "num items is invalid\n");
+ rte_flow_error_set(error, EINVAL,
+ RTE_FLOW_ERROR_TYPE_ATTR, NULL,
+ "num items is invalid");
+ return -EINVAL;
+ }
+
+ tun_entry = ulp_app_tun_match_entry(ulp_ctx, pmd_items->spec);
+ ulp_app_tun_entry_delete(tun_entry);
+ return 0;
+}
+