xref: /linux/drivers/net/ethernet/mellanox/mlx5/core/en/tc_priv.h (revision 675956237b3818c3a9deeabf7be678cf31699e72)
1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2 /* Copyright (c) 2021 Mellanox Technologies. */
3 
4 #ifndef __MLX5_EN_TC_PRIV_H__
5 #define __MLX5_EN_TC_PRIV_H__
6 
7 #include "en_tc.h"
8 #include "en/tc/act/act.h"
9 
10 #define MLX5E_TC_FLOW_BASE (MLX5E_TC_FLAG_LAST_EXPORTED_BIT + 1)
11 
12 #define MLX5E_TC_MAX_SPLITS 1
13 
14 
15 enum {
16 	MLX5E_TC_FLOW_FLAG_INGRESS               = MLX5E_TC_FLAG_INGRESS_BIT,
17 	MLX5E_TC_FLOW_FLAG_EGRESS                = MLX5E_TC_FLAG_EGRESS_BIT,
18 	MLX5E_TC_FLOW_FLAG_ESWITCH               = MLX5E_TC_FLAG_ESW_OFFLOAD_BIT,
19 	MLX5E_TC_FLOW_FLAG_FT                    = MLX5E_TC_FLAG_FT_OFFLOAD_BIT,
20 	MLX5E_TC_FLOW_FLAG_NIC                   = MLX5E_TC_FLAG_NIC_OFFLOAD_BIT,
21 	MLX5E_TC_FLOW_FLAG_OFFLOADED             = MLX5E_TC_FLOW_BASE,
22 	MLX5E_TC_FLOW_FLAG_HAIRPIN               = MLX5E_TC_FLOW_BASE + 1,
23 	MLX5E_TC_FLOW_FLAG_HAIRPIN_RSS           = MLX5E_TC_FLOW_BASE + 2,
24 	MLX5E_TC_FLOW_FLAG_SLOW                  = MLX5E_TC_FLOW_BASE + 3,
25 	MLX5E_TC_FLOW_FLAG_DUP                   = MLX5E_TC_FLOW_BASE + 4,
26 	MLX5E_TC_FLOW_FLAG_NOT_READY             = MLX5E_TC_FLOW_BASE + 5,
27 	MLX5E_TC_FLOW_FLAG_DELETED               = MLX5E_TC_FLOW_BASE + 6,
28 	MLX5E_TC_FLOW_FLAG_L3_TO_L2_DECAP        = MLX5E_TC_FLOW_BASE + 7,
29 	MLX5E_TC_FLOW_FLAG_TUN_RX                = MLX5E_TC_FLOW_BASE + 8,
30 	MLX5E_TC_FLOW_FLAG_FAILED                = MLX5E_TC_FLOW_BASE + 9,
31 	MLX5E_TC_FLOW_FLAG_SAMPLE                = MLX5E_TC_FLOW_BASE + 10,
32 	MLX5E_TC_FLOW_FLAG_USE_ACT_STATS         = MLX5E_TC_FLOW_BASE + 11,
33 	MLX5E_TC_FLOW_FLAG_PEER                  = MLX5E_TC_FLOW_BASE + 12,
34 };
35 
36 struct mlx5e_tc_flow_parse_attr {
37 	const struct ip_tunnel_info *tun_info[MLX5_MAX_FLOW_FWD_VPORTS];
38 	struct mlx5e_mpls_info mpls_info[MLX5_MAX_FLOW_FWD_VPORTS];
39 	struct net_device *filter_dev;
40 	struct mlx5_flow_spec spec;
41 	struct pedit_headers_action hdrs[__PEDIT_CMD_MAX];
42 	struct mlx5e_tc_mod_hdr_acts mod_hdr_acts;
43 	int mirred_ifindex[MLX5_MAX_FLOW_FWD_VPORTS];
44 	struct mlx5e_tc_act_parse_state parse_state;
45 };
46 
47 struct mlx5_fs_chains *mlx5e_nic_chains(struct mlx5e_tc_table *tc);
48 
49 /* Helper struct for accessing a struct containing list_head array.
50  * Containing struct
51  *   |- Helper array
52  *      [0] Helper item 0
53  *          |- list_head item 0
54  *          |- index (0)
55  *      [1] Helper item 1
56  *          |- list_head item 1
57  *          |- index (1)
58  * To access the containing struct from one of the list_head items:
59  * 1. Get the helper item from the list_head item using
60  *    helper item =
61  *        container_of(list_head item, helper struct type, list_head field)
62  * 2. Get the contining struct from the helper item and its index in the array:
63  *    containing struct =
64  *        container_of(helper item, containing struct type, helper field[index])
65  */
66 struct encap_flow_item {
67 	struct mlx5e_encap_entry *e; /* attached encap instance */
68 	struct list_head list;
69 	int index;
70 };
71 
72 struct encap_route_flow_item {
73 	struct mlx5e_route_entry *r; /* attached route instance */
74 	int index;
75 };
76 
77 struct mlx5e_tc_flow {
78 	struct rhash_head node;
79 	struct mlx5e_priv *priv;
80 	u64 cookie;
81 	unsigned long flags;
82 	struct mlx5_flow_handle *rule[MLX5E_TC_MAX_SPLITS + 1];
83 
84 	/* flows sharing the same reformat object - currently mpls decap */
85 	struct list_head l3_to_l2_reformat;
86 	struct mlx5e_decap_entry *decap_reformat;
87 
88 	/* flows sharing same route entry */
89 	struct list_head decap_routes;
90 	struct mlx5e_route_entry *decap_route;
91 	struct encap_route_flow_item encap_routes[MLX5_MAX_FLOW_FWD_VPORTS];
92 
93 	/* Flow can be associated with multiple encap IDs.
94 	 * The number of encaps is bounded by the number of supported
95 	 * destinations.
96 	 */
97 	struct encap_flow_item encaps[MLX5_MAX_FLOW_FWD_VPORTS];
98 	struct mlx5e_hairpin_entry *hpe; /* attached hairpin instance */
99 	struct list_head hairpin; /* flows sharing the same hairpin */
100 	struct list_head peer; /* dup: node in origin esw's peer_flows */
101 	struct list_head unready; /* flows not ready to be offloaded (e.g
102 				   * due to missing route)
103 				   */
104 
105 	/* origin: its dups; dup: node on that list */
106 	struct list_head peer_flows;
107 	struct mlx5e_tc_flow *peer_orig; /* dup: back-ref to origin flow */
108 	struct net_device *orig_dev; /* netdev adding flow first */
109 	int tmp_entry_index;
110 	struct list_head tmp_list; /* temporary flow list used by neigh update */
111 	refcount_t refcnt;
112 	struct rcu_head rcu_head;
113 	struct completion init_done;
114 	struct completion del_hw_done;
115 	struct mlx5_flow_attr *attr;
116 	struct mlx5_flow_attr *extra_split_attr;
117 	struct list_head attrs;
118 	u32 chain_mapping;
119 };
120 
121 struct mlx5_flow_handle *
122 mlx5e_tc_rule_offload(struct mlx5e_priv *priv,
123 		      struct mlx5_flow_spec *spec,
124 		      struct mlx5_flow_attr *attr);
125 
126 void
127 mlx5e_tc_rule_unoffload(struct mlx5e_priv *priv,
128 			struct mlx5_flow_handle *rule,
129 			struct mlx5_flow_attr *attr);
130 
131 u8 mlx5e_tc_get_ip_version(struct mlx5_flow_spec *spec, bool outer);
132 
133 struct mlx5_flow_handle *
134 mlx5e_tc_offload_fdb_rules(struct mlx5_eswitch *esw,
135 			   struct mlx5e_tc_flow *flow,
136 			   struct mlx5_flow_spec *spec,
137 			   struct mlx5_flow_attr *attr);
138 
139 struct mlx5_flow_attr *
140 mlx5e_tc_get_encap_attr(struct mlx5e_tc_flow *flow);
141 
142 void mlx5e_tc_unoffload_flow_post_acts(struct mlx5e_tc_flow *flow);
143 int mlx5e_tc_offload_flow_post_acts(struct mlx5e_tc_flow *flow);
144 
145 bool mlx5e_is_eswitch_flow(struct mlx5e_tc_flow *flow);
146 bool mlx5e_is_ft_flow(struct mlx5e_tc_flow *flow);
147 bool mlx5e_is_offloaded_flow(struct mlx5e_tc_flow *flow);
148 int mlx5e_get_flow_namespace(struct mlx5e_tc_flow *flow);
149 bool mlx5e_same_hw_devs(struct mlx5e_priv *priv, struct mlx5e_priv *peer_priv);
150 
151 static inline void __flow_flag_set(struct mlx5e_tc_flow *flow, unsigned long flag)
152 {
153 	/* Complete all memory stores before setting bit. */
154 	smp_mb__before_atomic();
155 	set_bit(flag, &flow->flags);
156 }
157 
158 #define flow_flag_set(flow, flag) __flow_flag_set(flow, MLX5E_TC_FLOW_FLAG_##flag)
159 
160 static inline bool __flow_flag_test_and_set(struct mlx5e_tc_flow *flow,
161 					    unsigned long flag)
162 {
163 	/* test_and_set_bit() provides all necessary barriers */
164 	return test_and_set_bit(flag, &flow->flags);
165 }
166 
167 #define flow_flag_test_and_set(flow, flag)			\
168 	__flow_flag_test_and_set(flow,				\
169 				 MLX5E_TC_FLOW_FLAG_##flag)
170 
171 static inline void __flow_flag_clear(struct mlx5e_tc_flow *flow, unsigned long flag)
172 {
173 	/* Complete all memory stores before clearing bit. */
174 	smp_mb__before_atomic();
175 	clear_bit(flag, &flow->flags);
176 }
177 
178 #define flow_flag_clear(flow, flag) __flow_flag_clear(flow,		\
179 						      MLX5E_TC_FLOW_FLAG_##flag)
180 
181 static inline bool __flow_flag_test(struct mlx5e_tc_flow *flow, unsigned long flag)
182 {
183 	bool ret = test_bit(flag, &flow->flags);
184 
185 	/* Read fields of flow structure only after checking flags. */
186 	smp_mb__after_atomic();
187 	return ret;
188 }
189 
190 #define flow_flag_test(flow, flag) __flow_flag_test(flow,		\
191 						    MLX5E_TC_FLOW_FLAG_##flag)
192 
193 void mlx5e_tc_unoffload_from_slow_path(struct mlx5_eswitch *esw,
194 				       struct mlx5e_tc_flow *flow);
195 struct mlx5_flow_handle *
196 mlx5e_tc_offload_to_slow_path(struct mlx5_eswitch *esw,
197 			      struct mlx5e_tc_flow *flow,
198 			      struct mlx5_flow_spec *spec);
199 
200 void mlx5e_tc_unoffload_fdb_rules(struct mlx5_eswitch *esw,
201 				  struct mlx5e_tc_flow *flow,
202 				  struct mlx5_flow_attr *attr);
203 
204 struct mlx5e_tc_flow *mlx5e_flow_get(struct mlx5e_tc_flow *flow);
205 void mlx5e_flow_put(struct mlx5e_priv *priv, struct mlx5e_tc_flow *flow);
206 
207 struct mlx5_fc *mlx5e_tc_get_counter(struct mlx5e_tc_flow *flow);
208 
209 struct mlx5e_tc_int_port_priv *
210 mlx5e_get_int_port_priv(struct mlx5e_priv *priv);
211 
212 struct mlx5e_flow_meters *mlx5e_get_flow_meters(struct mlx5_core_dev *dev);
213 
214 void *mlx5e_get_match_headers_value(u32 flags, struct mlx5_flow_spec *spec);
215 void *mlx5e_get_match_headers_criteria(u32 flags, struct mlx5_flow_spec *spec);
216 
217 #endif /* __MLX5_EN_TC_PRIV_H__ */
218