* Enable default hairpin egress flow. * * @param dev * Pointer to Ethernet device. * @param sq_num * The SQ hw number. * * @return * 0 on success, a negative errno value otherwise and rte_errno is set. */
| 8345 | * 0 on success, a negative errno value otherwise and rte_errno is set. |
| 8346 | */ |
| 8347 | int |
| 8348 | mlx5_ctrl_flow_source_queue(struct rte_eth_dev *dev, |
| 8349 | uint32_t sq_num) |
| 8350 | { |
| 8351 | const struct rte_flow_attr attr = { |
| 8352 | .egress = 1, |
| 8353 | .priority = 0, |
| 8354 | }; |
| 8355 | struct mlx5_rte_flow_item_sq queue_spec = { |
| 8356 | .queue = sq_num, |
| 8357 | }; |
| 8358 | struct mlx5_rte_flow_item_sq queue_mask = { |
| 8359 | .queue = UINT32_MAX, |
| 8360 | }; |
| 8361 | struct rte_flow_item items[] = { |
| 8362 | { |
| 8363 | .type = (enum rte_flow_item_type) |
| 8364 | MLX5_RTE_FLOW_ITEM_TYPE_SQ, |
| 8365 | .spec = &queue_spec, |
| 8366 | .last = NULL, |
| 8367 | .mask = &queue_mask, |
| 8368 | }, |
| 8369 | { |
| 8370 | .type = RTE_FLOW_ITEM_TYPE_END, |
| 8371 | }, |
| 8372 | }; |
| 8373 | struct rte_flow_action_jump jump = { |
| 8374 | .group = MLX5_HAIRPIN_TX_TABLE, |
| 8375 | }; |
| 8376 | struct rte_flow_action actions[2]; |
| 8377 | uint32_t flow_idx; |
| 8378 | struct rte_flow_error error; |
| 8379 | |
| 8380 | actions[0].type = RTE_FLOW_ACTION_TYPE_JUMP; |
| 8381 | actions[0].conf = &jump; |
| 8382 | actions[1].type = RTE_FLOW_ACTION_TYPE_END; |
| 8383 | flow_idx = flow_list_create(dev, MLX5_FLOW_TYPE_CTL, |
| 8384 | &attr, items, actions, false, &error); |
| 8385 | if (!flow_idx) { |
| 8386 | DRV_LOG(DEBUG, |
| 8387 | "Failed to create ctrl flow: rte_errno(%d)," |
| 8388 | " type(%d), message(%s)", |
| 8389 | rte_errno, error.type, |
| 8390 | error.message ? error.message : " (no stated reason)"); |
| 8391 | return -rte_errno; |
| 8392 | } |
| 8393 | return 0; |
| 8394 | } |
| 8395 | |
| 8396 | /** |
| 8397 | * Enable a control flow configured from the control plane. |
no test coverage detected