+/*
+ * Max number of actions per DV flow.
+ * See CREATE_FLOW_MAX_FLOW_ACTIONS_SUPPORTED
+ * in rdma-core file providers/mlx5/verbs.c.
+ */
+#define MLX5_DV_MAX_NUMBER_OF_ACTIONS 8
+
+/* ASO flow meter structures */
+/* Modify this value if enum rte_mtr_color changes. */
+#define RTE_MTR_DROPPED RTE_COLORS
+/* Yellow is now supported. */
+#define MLX5_MTR_RTE_COLORS (RTE_COLOR_YELLOW + 1)
+/* table_id 22 bits in mlx5_flow_tbl_key so limit policy number. */
+#define MLX5_MAX_SUB_POLICY_TBL_NUM 0x3FFFFF
+#define MLX5_INVALID_POLICY_ID UINT32_MAX
+/* Suffix table_id on MLX5_FLOW_TABLE_LEVEL_METER. */
+#define MLX5_MTR_TABLE_ID_SUFFIX 1
+/* Drop table_id on MLX5_FLOW_TABLE_LEVEL_METER. */
+#define MLX5_MTR_TABLE_ID_DROP 2
+/* Priority of the meter policy matcher. */
+#define MLX5_MTR_POLICY_MATCHER_PRIO 0
+/* Default policy. */
+#define MLX5_MTR_POLICY_MODE_DEF 1
+/* Only green color valid. */
+#define MLX5_MTR_POLICY_MODE_OG 2
+/* Only yellow color valid. */
+#define MLX5_MTR_POLICY_MODE_OY 3
+
+enum mlx5_meter_domain {
+ MLX5_MTR_DOMAIN_INGRESS,
+ MLX5_MTR_DOMAIN_EGRESS,
+ MLX5_MTR_DOMAIN_TRANSFER,
+ MLX5_MTR_DOMAIN_MAX,
+};
+#define MLX5_MTR_DOMAIN_INGRESS_BIT (1 << MLX5_MTR_DOMAIN_INGRESS)
+#define MLX5_MTR_DOMAIN_EGRESS_BIT (1 << MLX5_MTR_DOMAIN_EGRESS)
+#define MLX5_MTR_DOMAIN_TRANSFER_BIT (1 << MLX5_MTR_DOMAIN_TRANSFER)
+#define MLX5_MTR_ALL_DOMAIN_BIT (MLX5_MTR_DOMAIN_INGRESS_BIT | \
+ MLX5_MTR_DOMAIN_EGRESS_BIT | \
+ MLX5_MTR_DOMAIN_TRANSFER_BIT)
+
+/* The color tag rule structure. */
+struct mlx5_sub_policy_color_rule {
+ void *rule;
+ /* The color rule. */
+ struct mlx5_flow_dv_matcher *matcher;
+ /* The color matcher. */
+ TAILQ_ENTRY(mlx5_sub_policy_color_rule) next_port;
+ /**< Pointer to the next color rule structure. */
+ int32_t src_port;
+ /* On which src port this rule applied. */
+};
+
+TAILQ_HEAD(mlx5_sub_policy_color_rules, mlx5_sub_policy_color_rule);
+
+/*
+ * Meter sub-policy structure.
+ * Each RSS TIR in meter policy need its own sub-policy resource.
+ */
+struct mlx5_flow_meter_sub_policy {
+ uint32_t main_policy_id:1;
+ /* Main policy id is same as this sub_policy id. */
+ uint32_t idx:31;
+ /* Index to sub_policy ipool entity. */
+ void *main_policy;
+ /* Point to struct mlx5_flow_meter_policy. */
+ struct mlx5_flow_tbl_resource *tbl_rsc;
+ /* The sub-policy table resource. */
+ uint32_t rix_hrxq[MLX5_MTR_RTE_COLORS];
+ /* Index to TIR resource. */
+ struct mlx5_flow_tbl_resource *jump_tbl[MLX5_MTR_RTE_COLORS];
+ /* Meter jump/drop table. */
+ struct mlx5_sub_policy_color_rules color_rules[RTE_COLORS];
+ /* List for the color rules. */
+};
+
+struct mlx5_meter_policy_acts {
+ uint8_t actions_n;
+ /* Number of actions. */
+ void *dv_actions[MLX5_DV_MAX_NUMBER_OF_ACTIONS];
+ /* Action list. */
+};
+
+struct mlx5_meter_policy_action_container {
+ uint32_t rix_mark;
+ /* Index to the mark action. */
+ struct mlx5_flow_dv_modify_hdr_resource *modify_hdr;
+ /* Pointer to modify header resource in cache. */
+ uint8_t fate_action;
+ /* Fate action type. */
+ union {
+ struct rte_flow_action *rss;
+ /* Rss action configuration. */
+ uint32_t rix_port_id_action;
+ /* Index to port ID action resource. */
+ void *dr_jump_action[MLX5_MTR_DOMAIN_MAX];
+ /* Jump/drop action per color. */
+ uint16_t queue;
+ /* Queue action configuration. */
+ struct {
+ uint32_t next_mtr_id;
+ /* The next meter id. */
+ void *next_sub_policy;
+ /* Next meter's sub-policy. */
+ };
+ };
+};
+
+/* Flow meter policy parameter structure. */
+struct mlx5_flow_meter_policy {
+ struct rte_eth_dev *dev;
+ /* The port dev on which policy is created. */
+ uint32_t is_rss:1;
+ /* Is RSS policy table. */
+ uint32_t ingress:1;
+ /* Rule applies to ingress domain. */
+ uint32_t egress:1;
+ /* Rule applies to egress domain. */
+ uint32_t transfer:1;
+ /* Rule applies to transfer domain. */
+ uint32_t is_queue:1;
+ /* Is queue action in policy table. */
+ uint32_t is_hierarchy:1;
+ /* Is meter action in policy table. */
+ uint32_t skip_y:1;
+ /* If yellow color policy is skipped. */
+ uint32_t skip_g:1;
+ /* If green color policy is skipped. */
+ rte_spinlock_t sl;
+ uint32_t ref_cnt;
+ /* Use count. */
+ struct mlx5_meter_policy_action_container act_cnt[MLX5_MTR_RTE_COLORS];
+ /* Policy actions container. */
+ void *dr_drop_action[MLX5_MTR_DOMAIN_MAX];
+ /* drop action for red color. */
+ uint16_t sub_policy_num;
+ /* Count sub policy tables, 3 bits per domain. */
+ struct mlx5_flow_meter_sub_policy **sub_policys[MLX5_MTR_DOMAIN_MAX];
+ /* Sub policy table array must be the end of struct. */
+};
+
+/* The maximum sub policy is relate to struct mlx5_rss_hash_fields[]. */
+#define MLX5_MTR_RSS_MAX_SUB_POLICY 7
+#define MLX5_MTR_SUB_POLICY_NUM_SHIFT 3
+#define MLX5_MTR_SUB_POLICY_NUM_MASK 0x7
+#define MLX5_MTRS_DEFAULT_RULE_PRIORITY 0xFFFF
+#define MLX5_MTR_CHAIN_MAX_NUM 8
+
+/* Flow meter default policy parameter structure.
+ * Policy index 0 is reserved by default policy table.
+ * Action per color as below:
+ * green - do nothing, yellow - do nothing, red - drop
+ */
+struct mlx5_flow_meter_def_policy {
+ struct mlx5_flow_meter_sub_policy sub_policy;
+ /* Policy rules jump to other tables. */
+ void *dr_jump_action[RTE_COLORS];
+ /* Jump action per color. */
+};
+
+/* Meter parameter structure. */
+struct mlx5_flow_meter_info {
+ uint32_t meter_id;
+ /**< Meter id. */
+ uint32_t policy_id;
+ /* Policy id, the first sub_policy idx. */
+ struct mlx5_flow_meter_profile *profile;
+ /**< Meter profile parameters. */
+ rte_spinlock_t sl; /**< Meter action spinlock. */
+ /** Set of stats counters to be enabled.
+ * @see enum rte_mtr_stats_type
+ */
+ uint32_t bytes_dropped:1;
+ /** Set bytes dropped stats to be enabled. */
+ uint32_t pkts_dropped:1;
+ /** Set packets dropped stats to be enabled. */
+ uint32_t active_state:1;
+ /**< Meter hw active state. */
+ uint32_t shared:1;
+ /**< Meter shared or not. */
+ uint32_t is_enable:1;
+ /**< Meter disable/enable state. */
+ uint32_t ingress:1;
+ /**< Rule applies to egress traffic. */
+ uint32_t egress:1;
+ /**
+ * Instead of simply matching the properties of traffic as it would
+ * appear on a given DPDK port ID, enabling this attribute transfers
+ * a flow rule to the lowest possible level of any device endpoints
+ * found in the pattern.
+ *
+ * When supported, this effectively enables an application to
+ * re-route traffic not necessarily intended for it (e.g. coming
+ * from or addressed to different physical ports, VFs or
+ * applications) at the device level.
+ *
+ * It complements the behavior of some pattern items such as
+ * RTE_FLOW_ITEM_TYPE_PHY_PORT and is meaningless without them.
+ *
+ * When transferring flow rules, ingress and egress attributes keep
+ * their original meaning, as if processing traffic emitted or
+ * received by the application.
+ */
+ uint32_t transfer:1;
+ uint32_t def_policy:1;
+ /* Meter points to default policy. */
+ void *drop_rule[MLX5_MTR_DOMAIN_MAX];
+ /* Meter drop rule in drop table. */
+ uint32_t drop_cnt;
+ /**< Color counter for drop. */
+ uint32_t ref_cnt;
+ /**< Use count. */
+ struct mlx5_indexed_pool *flow_ipool;
+ /**< Index pool for flow id. */
+ void *meter_action;
+ /**< Flow meter action. */
+};
+
+/* PPS(packets per second) map to BPS(Bytes per second).
+ * HW treat packet as 128bytes in PPS mode
+ */
+#define MLX5_MTRS_PPS_MAP_BPS_SHIFT 7
+
+/* RFC2697 parameter structure. */
+struct mlx5_flow_meter_srtcm_rfc2697_prm {
+ rte_be32_t cbs_cir;
+ /*
+ * bit 24-28: cbs_exponent, bit 16-23 cbs_mantissa,
+ * bit 8-12: cir_exponent, bit 0-7 cir_mantissa.
+ */
+ rte_be32_t ebs_eir;
+ /*
+ * bit 24-28: ebs_exponent, bit 16-23 ebs_mantissa,
+ * bit 8-12: eir_exponent, bit 0-7 eir_mantissa.
+ */
+};
+
+/* Flow meter profile structure. */
+struct mlx5_flow_meter_profile {
+ TAILQ_ENTRY(mlx5_flow_meter_profile) next;
+ /**< Pointer to the next flow meter structure. */
+ uint32_t id; /**< Profile id. */
+ struct rte_mtr_meter_profile profile; /**< Profile detail. */
+ union {
+ struct mlx5_flow_meter_srtcm_rfc2697_prm srtcm_prm;
+ /**< srtcm_rfc2697 struct. */
+ };
+ uint32_t ref_cnt; /**< Use count. */
+ uint32_t g_support:1; /**< If G color will be generated. */
+ uint32_t y_support:1; /**< If Y color will be generated. */
+};
+
+/* 2 meters in each ASO cache line */
+#define MLX5_MTRS_CONTAINER_RESIZE 64
+/*
+ * The pool index and offset of meter in the pool array makes up the
+ * meter index. In case the meter is from pool 0 and offset 0, it
+ * should plus 1 to avoid index 0, since 0 means invalid meter index
+ * currently.
+ */
+#define MLX5_MAKE_MTR_IDX(pi, offset) \
+ ((pi) * MLX5_ASO_MTRS_PER_POOL + (offset) + 1)
+
+/*aso flow meter state*/
+enum mlx5_aso_mtr_state {
+ ASO_METER_FREE, /* In free list. */
+ ASO_METER_WAIT, /* ACCESS_ASO WQE in progress. */
+ ASO_METER_READY, /* CQE received. */
+};
+
+/* Generic aso_flow_meter information. */
+struct mlx5_aso_mtr {
+ LIST_ENTRY(mlx5_aso_mtr) next;
+ struct mlx5_flow_meter_info fm;
+ /**< Pointer to the next aso flow meter structure. */
+ uint8_t state; /**< ASO flow meter state. */
+ uint8_t offset;
+};
+
+/* Generic aso_flow_meter pool structure. */
+struct mlx5_aso_mtr_pool {
+ struct mlx5_aso_mtr mtrs[MLX5_ASO_MTRS_PER_POOL];
+ /*Must be the first in pool*/
+ struct mlx5_devx_obj *devx_obj;
+ /* The devx object of the minimum aso flow meter ID. */
+ uint32_t index; /* Pool index in management structure. */
+};
+
+LIST_HEAD(aso_meter_list, mlx5_aso_mtr);
+/* Pools management structure for ASO flow meter pools. */
+struct mlx5_aso_mtr_pools_mng {
+ volatile uint16_t n_valid; /* Number of valid pools. */
+ uint16_t n; /* Number of pools. */
+ rte_spinlock_t mtrsl; /* The ASO flow meter free list lock. */
+ struct aso_meter_list meters; /* Free ASO flow meter list. */
+ struct mlx5_aso_sq sq; /*SQ using by ASO flow meter. */
+ struct mlx5_aso_mtr_pool **pools; /* ASO flow meter pool array. */
+};
+
+/* Meter management structure for global flow meter resource. */
+struct mlx5_flow_mtr_mng {
+ struct mlx5_aso_mtr_pools_mng pools_mng;
+ /* Pools management structure for ASO flow meter pools. */
+ struct mlx5_flow_meter_def_policy *def_policy[MLX5_MTR_DOMAIN_MAX];
+ /* Default policy table. */
+ uint32_t def_policy_id;
+ /* Default policy id. */
+ uint32_t def_policy_ref_cnt;
+ /** def_policy meter use count. */
+ struct mlx5_flow_tbl_resource *drop_tbl[MLX5_MTR_DOMAIN_MAX];
+ /* Meter drop table. */
+ struct mlx5_flow_dv_matcher *
+ drop_matcher[MLX5_MTR_DOMAIN_MAX][MLX5_REG_BITS];
+ /* Matcher meter in drop table. */
+ struct mlx5_flow_dv_matcher *def_matcher[MLX5_MTR_DOMAIN_MAX];
+ /* Default matcher in drop table. */
+ void *def_rule[MLX5_MTR_DOMAIN_MAX];
+ /* Default rule in drop table. */
+ uint8_t max_mtr_bits;
+ /* Indicate how many bits are used by meter id at the most. */
+ uint8_t max_mtr_flow_bits;
+ /* Indicate how many bits are used by meter flow id at the most. */
+};
+