xref: /dpdk/drivers/net/sfc/sfc_mae.h (revision 0cd91fd3)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2019-2021 Xilinx, Inc.
4  * Copyright(c) 2019 Solarflare Communications Inc.
5  *
6  * This software was jointly developed between OKTET Labs (under contract
7  * for Solarflare) and Solarflare Communications, Inc.
8  */
9 
10 #ifndef _SFC_MAE_H
11 #define _SFC_MAE_H
12 
13 #include <stdbool.h>
14 
15 #include <rte_spinlock.h>
16 
17 #include "efx.h"
18 
19 #include "sfc_stats.h"
20 
21 #ifdef __cplusplus
22 extern "C" {
23 #endif
24 
25 /** FW-allocatable resource context */
26 struct sfc_mae_fw_rsrc {
27 	unsigned int			refcnt;
28 	RTE_STD_C11
29 	union {
30 		efx_mae_aset_id_t	aset_id;
31 		efx_mae_rule_id_t	rule_id;
32 		efx_mae_eh_id_t		eh_id;
33 	};
34 };
35 
36 /** Outer rule registry entry */
37 struct sfc_mae_outer_rule {
38 	TAILQ_ENTRY(sfc_mae_outer_rule)	entries;
39 	unsigned int			refcnt;
40 	efx_mae_match_spec_t		*match_spec;
41 	efx_tunnel_protocol_t		encap_type;
42 	struct sfc_mae_fw_rsrc		fw_rsrc;
43 };
44 
45 TAILQ_HEAD(sfc_mae_outer_rules, sfc_mae_outer_rule);
46 
47 /** Encap. header registry entry */
48 struct sfc_mae_encap_header {
49 	TAILQ_ENTRY(sfc_mae_encap_header)	entries;
50 	unsigned int				refcnt;
51 	uint8_t					*buf;
52 	size_t					size;
53 	efx_tunnel_protocol_t			type;
54 	struct sfc_mae_fw_rsrc			fw_rsrc;
55 };
56 
57 TAILQ_HEAD(sfc_mae_encap_headers, sfc_mae_encap_header);
58 
59 /* Counter ID */
60 struct sfc_mae_counter_id {
61 	/* ID of a counter in MAE */
62 	efx_counter_t			mae_id;
63 	/* ID of a counter in RTE */
64 	uint32_t			rte_id;
65 	/* RTE counter ID validity status */
66 	bool				rte_id_valid;
67 
68 	/* Flow Tunnel (FT) GROUP hit counter (or NULL) */
69 	uint64_t			*ft_group_hit_counter;
70 	/* Flow Tunnel (FT) context (for JUMP rules; otherwise, NULL) */
71 	struct sfc_flow_tunnel		*ft;
72 };
73 
74 /** Action set registry entry */
75 struct sfc_mae_action_set {
76 	TAILQ_ENTRY(sfc_mae_action_set)	entries;
77 	unsigned int			refcnt;
78 	struct sfc_mae_counter_id	*counters;
79 	uint32_t			n_counters;
80 	efx_mae_actions_t		*spec;
81 	struct sfc_mae_encap_header	*encap_header;
82 	struct sfc_mae_fw_rsrc		fw_rsrc;
83 };
84 
85 TAILQ_HEAD(sfc_mae_action_sets, sfc_mae_action_set);
86 
87 /** Options for MAE support status */
88 enum sfc_mae_status {
89 	SFC_MAE_STATUS_UNKNOWN = 0,
90 	SFC_MAE_STATUS_UNSUPPORTED,
91 	SFC_MAE_STATUS_SUPPORTED,
92 	SFC_MAE_STATUS_ADMIN,
93 };
94 
95 /*
96  * Encap. header bounce buffer. It is used to store header data
97  * when parsing the header definition in the action VXLAN_ENCAP.
98  */
99 struct sfc_mae_bounce_eh {
100 	uint8_t				*buf;
101 	size_t				buf_size;
102 	size_t				size;
103 	efx_tunnel_protocol_t		type;
104 };
105 
106 /** Counter collection entry */
107 struct sfc_mae_counter {
108 	bool				inuse;
109 	uint32_t			generation_count;
110 	union sfc_pkts_bytes		value;
111 	union sfc_pkts_bytes		reset;
112 
113 	uint64_t			*ft_group_hit_counter;
114 };
115 
116 struct sfc_mae_counters_xstats {
117 	uint64_t			not_inuse_update;
118 	uint64_t			realloc_update;
119 };
120 
121 struct sfc_mae_counters {
122 	/** An array of all MAE counters */
123 	struct sfc_mae_counter		*mae_counters;
124 	/** Extra statistics for counters */
125 	struct sfc_mae_counters_xstats	xstats;
126 	/** Count of all MAE counters */
127 	unsigned int			n_mae_counters;
128 };
129 
130 /** Options for MAE counter polling mode */
131 enum sfc_mae_counter_polling_mode {
132 	SFC_MAE_COUNTER_POLLING_OFF = 0,
133 	SFC_MAE_COUNTER_POLLING_SERVICE,
134 	SFC_MAE_COUNTER_POLLING_THREAD,
135 };
136 
137 struct sfc_mae_counter_registry {
138 	/* Common counter information */
139 	/** Counters collection */
140 	struct sfc_mae_counters		counters;
141 
142 	/* Information used by counter update service */
143 	/** Callback to get packets from RxQ */
144 	eth_rx_burst_t			rx_pkt_burst;
145 	/** Data for the callback to get packets */
146 	struct sfc_dp_rxq		*rx_dp;
147 	/** Number of buffers pushed to the RxQ */
148 	unsigned int			pushed_n_buffers;
149 	/** Are credits used by counter stream */
150 	bool				use_credits;
151 
152 	/* Information used by configuration routines */
153 	enum sfc_mae_counter_polling_mode polling_mode;
154 	union {
155 		struct {
156 			/** Counter service core ID */
157 			uint32_t			core_id;
158 			/** Counter service ID */
159 			uint32_t			id;
160 		} service;
161 		struct {
162 			/** Counter thread ID */
163 			pthread_t			id;
164 			/** The thread should keep running */
165 			bool				run;
166 		} thread;
167 	} polling;
168 };
169 
170 /**
171  * MAE rules used to capture traffic generated by VFs and direct it to
172  * representors (one for each VF).
173  */
174 #define SFC_MAE_NB_REPR_RULES_MAX	(64)
175 
176 /** Rules to forward traffic from PHY port to PF and from PF to PHY port */
177 #define SFC_MAE_NB_SWITCHDEV_RULES	(2)
178 /** Maximum required internal MAE rules */
179 #define SFC_MAE_NB_RULES_MAX		(SFC_MAE_NB_SWITCHDEV_RULES + \
180 					 SFC_MAE_NB_REPR_RULES_MAX)
181 
182 struct sfc_mae_rule {
183 	efx_mae_match_spec_t		*spec;
184 	efx_mae_actions_t		*actions;
185 	efx_mae_aset_id_t		action_set;
186 	efx_mae_rule_id_t		rule_id;
187 };
188 
189 struct sfc_mae_internal_rules {
190 	/*
191 	 * Rules required to sustain switchdev mode or to provide
192 	 * port representor functionality.
193 	 */
194 	struct sfc_mae_rule		rules[SFC_MAE_NB_RULES_MAX];
195 };
196 
197 struct sfc_mae {
198 	/** Assigned switch domain identifier */
199 	uint16_t			switch_domain_id;
200 	/** Assigned switch port identifier */
201 	uint16_t			switch_port_id;
202 	/** NIC support for MAE status */
203 	enum sfc_mae_status		status;
204 	/** Priority level limit for MAE outer rules */
205 	unsigned int			nb_outer_rule_prios_max;
206 	/** Priority level limit for MAE action rules */
207 	unsigned int			nb_action_rule_prios_max;
208 	/** Encapsulation support status */
209 	uint32_t			encap_types_supported;
210 	/** Outer rule registry */
211 	struct sfc_mae_outer_rules	outer_rules;
212 	/** Encap. header registry */
213 	struct sfc_mae_encap_headers	encap_headers;
214 	/** Action set registry */
215 	struct sfc_mae_action_sets	action_sets;
216 	/** Encap. header bounce buffer */
217 	struct sfc_mae_bounce_eh	bounce_eh;
218 	/** Flag indicating whether counter-only RxQ is running */
219 	bool				counter_rxq_running;
220 	/** Counter registry */
221 	struct sfc_mae_counter_registry	counter_registry;
222 	/** Driver-internal flow rules */
223 	struct sfc_mae_internal_rules	internal_rules;
224 	/**
225 	 * Switchdev default rules. They forward traffic from PHY port
226 	 * to PF and vice versa.
227 	 */
228 	struct sfc_mae_rule		*switchdev_rule_pf_to_ext;
229 	struct sfc_mae_rule		*switchdev_rule_ext_to_pf;
230 };
231 
232 struct sfc_adapter;
233 struct sfc_flow_spec;
234 
235 /** This implementation supports double-tagging */
236 #define SFC_MAE_MATCH_VLAN_MAX_NTAGS	(2)
237 
238 /** It is possible to keep track of one item ETH and two items VLAN */
239 #define SFC_MAE_L2_MAX_NITEMS		(SFC_MAE_MATCH_VLAN_MAX_NTAGS + 1)
240 
241 /** Auxiliary entry format to keep track of L2 "type" ("inner_type") */
242 struct sfc_mae_ethertype {
243 	rte_be16_t	value;
244 	rte_be16_t	mask;
245 };
246 
247 struct sfc_mae_pattern_data {
248 	/**
249 	 * Keeps track of "type" ("inner_type") mask and value for each
250 	 * parsed L2 item in a pattern. These values/masks get filled
251 	 * in MAE match specification at the end of parsing. Also, this
252 	 * information is used to conduct consistency checks:
253 	 *
254 	 * - If an item ETH is followed by a single item VLAN,
255 	 *   the former must have "type" set to one of supported
256 	 *   TPID values (0x8100, 0x88a8, 0x9100, 0x9200, 0x9300),
257 	 *   or 0x0000/0x0000.
258 	 *
259 	 * - If an item ETH is followed by two items VLAN, the
260 	 *   item ETH must have "type" set to one of supported TPID
261 	 *   values (0x88a8, 0x9100, 0x9200, 0x9300), or 0x0000/0x0000,
262 	 *   and the outermost VLAN item must have "inner_type" set
263 	 *   to TPID value 0x8100, or 0x0000/0x0000
264 	 *
265 	 * - If a L2 item is followed by a L3 one, the former must
266 	 *   indicate "type" ("inner_type") which corresponds to
267 	 *   the protocol used in the L3 item, or 0x0000/0x0000.
268 	 *
269 	 * In turn, mapping between RTE convention (above requirements) and
270 	 * MAE fields is non-trivial. The following scheme indicates
271 	 * which item EtherTypes go to which MAE fields in the case
272 	 * of single tag:
273 	 *
274 	 * ETH	(0x8100)	--> VLAN0_PROTO_BE
275 	 * VLAN	(L3 EtherType)	--> ETHER_TYPE_BE
276 	 *
277 	 * Similarly, in the case of double tagging:
278 	 *
279 	 * ETH	(0x88a8)	--> VLAN0_PROTO_BE
280 	 * VLAN	(0x8100)	--> VLAN1_PROTO_BE
281 	 * VLAN	(L3 EtherType)	--> ETHER_TYPE_BE
282 	 */
283 	struct sfc_mae_ethertype	ethertypes[SFC_MAE_L2_MAX_NITEMS];
284 
285 	rte_be16_t			tci_masks[SFC_MAE_MATCH_VLAN_MAX_NTAGS];
286 
287 	unsigned int			nb_vlan_tags;
288 
289 	/**
290 	 * L3 requirement for the innermost L2 item's "type" ("inner_type").
291 	 * This contains one of:
292 	 * - 0x0800/0xffff: IPV4
293 	 * - 0x86dd/0xffff: IPV6
294 	 * - 0x0000/0x0000: no L3 item
295 	 */
296 	struct sfc_mae_ethertype	innermost_ethertype_restriction;
297 
298 	/**
299 	 * The following two fields keep track of L3 "proto" mask and value.
300 	 * The corresponding fields get filled in MAE match specification
301 	 * at the end of parsing. Also, the information is used by a
302 	 * post-check to enforce consistency requirements:
303 	 *
304 	 * - If a L3 item is followed by an item TCP, the former has
305 	 *   its "proto" set to either 0x06/0xff or 0x00/0x00.
306 	 *
307 	 * - If a L3 item is followed by an item UDP, the former has
308 	 *   its "proto" set to either 0x11/0xff or 0x00/0x00.
309 	 */
310 	uint8_t				l3_next_proto_value;
311 	uint8_t				l3_next_proto_mask;
312 
313 	/*
314 	 * L4 requirement for L3 item's "proto".
315 	 * This contains one of:
316 	 * - 0x06/0xff: TCP
317 	 * - 0x11/0xff: UDP
318 	 * - 0x00/0x00: no L4 item
319 	 */
320 	uint8_t				l3_next_proto_restriction_value;
321 	uint8_t				l3_next_proto_restriction_mask;
322 
323 	/* Projected state of EFX_MAE_FIELD_HAS_OVLAN match bit */
324 	bool				has_ovlan_value;
325 	bool				has_ovlan_mask;
326 
327 	/* Projected state of EFX_MAE_FIELD_HAS_IVLAN match bit */
328 	bool				has_ivlan_value;
329 	bool				has_ivlan_mask;
330 };
331 
332 struct sfc_mae_parse_ctx {
333 	struct sfc_adapter		*sa;
334 	efx_mae_match_spec_t		*match_spec_action;
335 	efx_mae_match_spec_t		*match_spec_outer;
336 	/*
337 	 * This points to either of the above two specifications depending
338 	 * on which part of the pattern is being parsed (outer / inner).
339 	 */
340 	efx_mae_match_spec_t		*match_spec;
341 	/*
342 	 * This points to either "field_ids_remap_to_encap"
343 	 * or "field_ids_no_remap" (see sfc_mae.c) depending on
344 	 * which part of the pattern is being parsed.
345 	 */
346 	const efx_mae_field_id_t	*field_ids_remap;
347 	/* These two fields correspond to the tunnel-specific default mask. */
348 	size_t				tunnel_def_mask_size;
349 	const void			*tunnel_def_mask;
350 	bool				match_mport_set;
351 	enum sfc_flow_tunnel_rule_type	ft_rule_type;
352 	struct sfc_mae_pattern_data	pattern_data;
353 	efx_tunnel_protocol_t		encap_type;
354 	const struct rte_flow_item	*pattern;
355 	unsigned int			priority;
356 	struct sfc_flow_tunnel		*ft;
357 };
358 
359 int sfc_mae_attach(struct sfc_adapter *sa);
360 void sfc_mae_detach(struct sfc_adapter *sa);
361 sfc_flow_cleanup_cb_t sfc_mae_flow_cleanup;
362 int sfc_mae_rule_parse_pattern(struct sfc_adapter *sa,
363 			       const struct rte_flow_item pattern[],
364 			       struct sfc_flow_spec_mae *spec,
365 			       struct rte_flow_error *error);
366 int sfc_mae_rule_parse_actions(struct sfc_adapter *sa,
367 			       const struct rte_flow_action actions[],
368 			       struct sfc_flow_spec_mae *spec_mae,
369 			       struct rte_flow_error *error);
370 sfc_flow_verify_cb_t sfc_mae_flow_verify;
371 sfc_flow_insert_cb_t sfc_mae_flow_insert;
372 sfc_flow_remove_cb_t sfc_mae_flow_remove;
373 sfc_flow_query_cb_t sfc_mae_flow_query;
374 
375 /**
376  * The value used to represent the lowest priority.
377  * Used in MAE rule API.
378  */
379 #define SFC_MAE_RULE_PRIO_LOWEST	(-1)
380 
381 /**
382  * Insert a driver-internal flow rule that matches traffic originating from
383  * some m-port selector and redirects it to another one
384  * (eg. PF --> PHY, PHY --> PF).
385  *
386  * If requested priority is negative, use the lowest priority.
387  */
388 int sfc_mae_rule_add_mport_match_deliver(struct sfc_adapter *sa,
389 					 const efx_mport_sel_t *mport_match,
390 					 const efx_mport_sel_t *mport_deliver,
391 					 int prio, struct sfc_mae_rule **rulep);
392 void sfc_mae_rule_del(struct sfc_adapter *sa, struct sfc_mae_rule *rule);
393 int sfc_mae_switchdev_init(struct sfc_adapter *sa);
394 void sfc_mae_switchdev_fini(struct sfc_adapter *sa);
395 
396 #ifdef __cplusplus
397 }
398 #endif
399 #endif /* _SFC_MAE_H */
400