MLX5_INDIRECT_ACTION_TYPE_RSS,
MLX5_INDIRECT_ACTION_TYPE_AGE,
MLX5_INDIRECT_ACTION_TYPE_COUNT,
+ MLX5_INDIRECT_ACTION_TYPE_CT,
};
+/* Now, the maximal ports will be supported is 256, action number is 4M. */
+#define MLX5_INDIRECT_ACT_CT_MAX_PORT 0x100
+
+#define MLX5_INDIRECT_ACT_CT_OWNER_SHIFT 22
+#define MLX5_INDIRECT_ACT_CT_OWNER_MASK (MLX5_INDIRECT_ACT_CT_MAX_PORT - 1)
+
+/* 30-31: type, 22-29: owner port, 0-21: index. */
+#define MLX5_INDIRECT_ACT_CT_GEN_IDX(owner, index) \
+ ((MLX5_INDIRECT_ACTION_TYPE_CT << MLX5_INDIRECT_ACTION_TYPE_OFFSET) | \
+ (((owner) & MLX5_INDIRECT_ACT_CT_OWNER_MASK) << \
+ MLX5_INDIRECT_ACT_CT_OWNER_SHIFT) | (index))
+
+#define MLX5_INDIRECT_ACT_CT_GET_OWNER(index) \
+ (((index) >> MLX5_INDIRECT_ACT_CT_OWNER_SHIFT) & \
+ MLX5_INDIRECT_ACT_CT_OWNER_MASK)
+
+#define MLX5_INDIRECT_ACT_CT_GET_IDX(index) \
+ ((index) & ((1 << MLX5_INDIRECT_ACT_CT_OWNER_SHIFT) - 1))
+
/* Matches on selected register. */
struct mlx5_rte_flow_item_tag {
enum modify_reg id;
/* INTEGRITY item bit */
#define MLX5_FLOW_ITEM_INTEGRITY (UINT64_C(1) << 34)
+/* Conntrack item. */
+#define MLX5_FLOW_LAYER_ASO_CT (UINT64_C(1) << 35)
+
/* Outer Masks. */
#define MLX5_FLOW_LAYER_OUTER_L3 \
(MLX5_FLOW_LAYER_OUTER_L3_IPV4 | MLX5_FLOW_LAYER_OUTER_L3_IPV6)
#define MLX5_FLOW_ACTION_TUNNEL_MATCH (1ull << 38)
#define MLX5_FLOW_ACTION_MODIFY_FIELD (1ull << 39)
#define MLX5_FLOW_ACTION_METER_WITH_TERMINATED_POLICY (1ull << 40)
+#define MLX5_FLOW_ACTION_CT (1ull << 41)
#define MLX5_FLOW_FATE_ACTIONS \
(MLX5_FLOW_ACTION_DROP | MLX5_FLOW_ACTION_QUEUE | \
/* Maximum number of fields to modify in MODIFY_FIELD */
#define MLX5_ACT_MAX_MOD_FIELDS 5
+/* Syndrome bits definition for connection tracking. */
+#define MLX5_CT_SYNDROME_VALID (0x0 << 6)
+#define MLX5_CT_SYNDROME_INVALID (0x1 << 6)
+#define MLX5_CT_SYNDROME_TRAP (0x2 << 6)
+#define MLX5_CT_SYNDROME_STATE_CHANGE (0x1 << 1)
+#define MLX5_CT_SYNDROME_BAD_PACKET (0x1 << 0)
+
enum mlx5_flow_drv_type {
MLX5_FLOW_TYPE_MIN,
MLX5_FLOW_TYPE_DV,
#define MLX5_ASO_WQE_CQE_RESPONSE_DELAY 10u
#define MLX5_MTR_POLL_WQE_CQE_TIMES 100000u
+#define MLX5_CT_POLL_WQE_CQE_TIMES MLX5_MTR_POLL_WQE_CQE_TIMES
+
#define MLX5_MAN_WIDTH 8
/* Legacy Meter parameter structure. */
struct mlx5_legacy_flow_meter {
uint32_t drv_type:2; /**< Driver type. */
uint32_t tunnel:1;
uint32_t meter:24; /**< Holds flow meter id. */
+ uint32_t indirect_type:2; /**< Indirect action type. */
uint32_t rix_mreg_copy;
/**< Index to metadata register copy table resource. */
uint32_t counter; /**< Holds flow counter. */
uint32_t tunnel_id; /**< Tunnel id */
- uint32_t age; /**< Holds ASO age bit index. */
+ union {
+ uint32_t age; /**< Holds ASO age bit index. */
+ uint32_t ct; /**< Holds ASO CT index. */
+ };
uint32_t geneve_tlv_option; /**< Holds Geneve TLV option id. > */
} __rte_packed;
return (test.value == 0);
}
+/*
+ * Get ASO CT action by device and index.
+ *
+ * @param[in] dev
+ * Pointer to the Ethernet device structure.
+ * @param[in] idx
+ * Index to the ASO CT action.
+ *
+ * @return
+ * The specified ASO CT action pointer.
+ */
+static inline struct mlx5_aso_ct_action *
+flow_aso_ct_get_by_dev_idx(struct rte_eth_dev *dev, uint32_t idx)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_aso_ct_pools_mng *mng = priv->sh->ct_mng;
+ struct mlx5_aso_ct_pool *pool;
+
+ idx--;
+ MLX5_ASSERT((idx / MLX5_ASO_CT_ACTIONS_PER_POOL) < mng->n);
+ /* Bit operation AND could be used. */
+ rte_rwlock_read_lock(&mng->resize_rwl);
+ pool = mng->pools[idx / MLX5_ASO_CT_ACTIONS_PER_POOL];
+ rte_rwlock_read_unlock(&mng->resize_rwl);
+ return &pool->actions[idx % MLX5_ASO_CT_ACTIONS_PER_POOL];
+}
+
+/*
+ * Get ASO CT action by owner & index.
+ *
+ * @param[in] dev
+ * Pointer to the Ethernet device structure.
+ * @param[in] idx
+ * Index to the ASO CT action and owner port combination.
+ *
+ * @return
+ * The specified ASO CT action pointer.
+ */
+static inline struct mlx5_aso_ct_action *
+flow_aso_ct_get_by_idx(struct rte_eth_dev *dev, uint32_t own_idx)
+{
+ struct mlx5_priv *priv = dev->data->dev_private;
+ struct mlx5_aso_ct_action *ct;
+ uint16_t owner = (uint16_t)MLX5_INDIRECT_ACT_CT_GET_OWNER(own_idx);
+ uint32_t idx = MLX5_INDIRECT_ACT_CT_GET_IDX(own_idx);
+
+ if (owner == PORT_ID(priv)) {
+ ct = flow_aso_ct_get_by_dev_idx(dev, idx);
+ } else {
+ struct rte_eth_dev *owndev = &rte_eth_devices[owner];
+
+ MLX5_ASSERT(owner < RTE_MAX_ETHPORTS);
+ if (dev->data->dev_started != 1)
+ return NULL;
+ ct = flow_aso_ct_get_by_dev_idx(owndev, idx);
+ if (ct->peer != PORT_ID(priv))
+ return NULL;
+ }
+ return ct;
+}
+
int mlx5_flow_group_to_table(struct rte_eth_dev *dev,
const struct mlx5_flow_tunnel *tunnel,
uint32_t group, uint32_t *table,