xref: /dpdk/drivers/net/sfc/sfc_mae.h (revision 5f701365ca2d867467026d72581f47d3f1ca60e0)
102b234adSIvan Malov /* SPDX-License-Identifier: BSD-3-Clause
202b234adSIvan Malov  *
398d26ef7SAndrew Rybchenko  * Copyright(c) 2019-2021 Xilinx, Inc.
402b234adSIvan Malov  * Copyright(c) 2019 Solarflare Communications Inc.
502b234adSIvan Malov  *
602b234adSIvan Malov  * This software was jointly developed between OKTET Labs (under contract
702b234adSIvan Malov  * for Solarflare) and Solarflare Communications, Inc.
802b234adSIvan Malov  */
902b234adSIvan Malov 
1002b234adSIvan Malov #ifndef _SFC_MAE_H
1102b234adSIvan Malov #define _SFC_MAE_H
1202b234adSIvan Malov 
1302b234adSIvan Malov #include <stdbool.h>
1402b234adSIvan Malov 
151e7fbdf0SIvan Malov #include <rte_spinlock.h>
161e7fbdf0SIvan Malov 
1702b234adSIvan Malov #include "efx.h"
1802b234adSIvan Malov 
1996fd2bd6SIgor Romanov #include "sfc_stats.h"
2096fd2bd6SIgor Romanov 
2102b234adSIvan Malov #ifdef __cplusplus
2202b234adSIvan Malov extern "C" {
2302b234adSIvan Malov #endif
2402b234adSIvan Malov 
25041f22ecSIvan Malov /** FW-allocatable resource context */
26041f22ecSIvan Malov struct sfc_mae_fw_rsrc {
27041f22ecSIvan Malov 	unsigned int			refcnt;
28041f22ecSIvan Malov 	union {
29002f591fSIvan Malov 		efx_mae_aset_list_id_t	aset_list_id;
30dffc1de1SIvan Malov 		efx_counter_t		counter_id;
31041f22ecSIvan Malov 		efx_mae_aset_id_t	aset_id;
32dadff137SIvan Malov 		efx_mae_rule_id_t	rule_id;
334c600599SIvan Malov 		efx_mae_mac_id_t	mac_id;
341bbd1ec2SIvan Malov 		efx_mae_eh_id_t		eh_id;
35041f22ecSIvan Malov 	};
36041f22ecSIvan Malov };
37041f22ecSIvan Malov 
38dadff137SIvan Malov /** Outer rule registry entry */
39dadff137SIvan Malov struct sfc_mae_outer_rule {
40dadff137SIvan Malov 	TAILQ_ENTRY(sfc_mae_outer_rule)	entries;
41dadff137SIvan Malov 	unsigned int			refcnt;
42dadff137SIvan Malov 	efx_mae_match_spec_t		*match_spec;
43dadff137SIvan Malov 	efx_tunnel_protocol_t		encap_type;
44dadff137SIvan Malov 	struct sfc_mae_fw_rsrc		fw_rsrc;
45dadff137SIvan Malov };
46dadff137SIvan Malov 
47dadff137SIvan Malov TAILQ_HEAD(sfc_mae_outer_rules, sfc_mae_outer_rule);
48dadff137SIvan Malov 
494c600599SIvan Malov /** MAC address registry entry */
504c600599SIvan Malov struct sfc_mae_mac_addr {
514c600599SIvan Malov 	TAILQ_ENTRY(sfc_mae_mac_addr)	entries;
524c600599SIvan Malov 	unsigned int			refcnt;
534c600599SIvan Malov 	uint8_t				addr_bytes[EFX_MAC_ADDR_LEN];
544c600599SIvan Malov 	struct sfc_mae_fw_rsrc		fw_rsrc;
554c600599SIvan Malov };
564c600599SIvan Malov 
574c600599SIvan Malov TAILQ_HEAD(sfc_mae_mac_addrs, sfc_mae_mac_addr);
584c600599SIvan Malov 
591bbd1ec2SIvan Malov /** Encap. header registry entry */
601bbd1ec2SIvan Malov struct sfc_mae_encap_header {
611bbd1ec2SIvan Malov 	TAILQ_ENTRY(sfc_mae_encap_header)	entries;
621bbd1ec2SIvan Malov 	unsigned int				refcnt;
6359641944SIvan Malov 	bool					indirect;
641bbd1ec2SIvan Malov 	uint8_t					*buf;
651bbd1ec2SIvan Malov 	size_t					size;
661bbd1ec2SIvan Malov 	efx_tunnel_protocol_t			type;
671bbd1ec2SIvan Malov 	struct sfc_mae_fw_rsrc			fw_rsrc;
681bbd1ec2SIvan Malov };
691bbd1ec2SIvan Malov 
701bbd1ec2SIvan Malov TAILQ_HEAD(sfc_mae_encap_headers, sfc_mae_encap_header);
711bbd1ec2SIvan Malov 
72dffc1de1SIvan Malov /* Counter object registry entry */
734a06eacbSIvan Malov struct sfc_mae_counter {
74dffc1de1SIvan Malov 	TAILQ_ENTRY(sfc_mae_counter)	entries;
75dffc1de1SIvan Malov 	unsigned int			refcnt;
76dffc1de1SIvan Malov 
7796fd2bd6SIgor Romanov 	/* ID of a counter in RTE */
7896fd2bd6SIgor Romanov 	uint32_t			rte_id;
799df2d8f5SIvan Malov 	/* RTE counter ID validity status */
809df2d8f5SIvan Malov 	bool				rte_id_valid;
819df2d8f5SIvan Malov 
82f55fe01fSIvan Malov 	/* Flow Tunnel (FT) SWITCH hit counter (or NULL) */
83f55fe01fSIvan Malov 	uint64_t			*ft_switch_hit_counter;
84f55fe01fSIvan Malov 	/* Flow Tunnel (FT) context (for TUNNEL rules; otherwise, NULL) */
85f55fe01fSIvan Malov 	struct sfc_ft_ctx		*ft_ctx;
86dffc1de1SIvan Malov 
87dffc1de1SIvan Malov 	struct sfc_mae_fw_rsrc		fw_rsrc;
886676ae6aSIvan Malov 
896676ae6aSIvan Malov 	bool				indirect;
901c941a5fSIvan Malov 	efx_counter_type_t		type;
9196fd2bd6SIgor Romanov };
9296fd2bd6SIgor Romanov 
93dffc1de1SIvan Malov TAILQ_HEAD(sfc_mae_counters, sfc_mae_counter);
94dffc1de1SIvan Malov 
95662286aeSIvan Malov /** Action set registry entry */
96662286aeSIvan Malov struct sfc_mae_action_set {
97662286aeSIvan Malov 	TAILQ_ENTRY(sfc_mae_action_set)	entries;
98662286aeSIvan Malov 	unsigned int			refcnt;
99662286aeSIvan Malov 	efx_mae_actions_t		*spec;
1001bbd1ec2SIvan Malov 	struct sfc_mae_encap_header	*encap_header;
1014c600599SIvan Malov 	struct sfc_mae_mac_addr		*dst_mac_addr;
1024c600599SIvan Malov 	struct sfc_mae_mac_addr		*src_mac_addr;
103dffc1de1SIvan Malov 	struct sfc_mae_counter		*counter;
104041f22ecSIvan Malov 	struct sfc_mae_fw_rsrc		fw_rsrc;
105662286aeSIvan Malov };
106662286aeSIvan Malov 
107662286aeSIvan Malov TAILQ_HEAD(sfc_mae_action_sets, sfc_mae_action_set);
108662286aeSIvan Malov 
109002f591fSIvan Malov /** Action set list registry entry */
110002f591fSIvan Malov struct sfc_mae_action_set_list {
111002f591fSIvan Malov 	TAILQ_ENTRY(sfc_mae_action_set_list)	entries;
112002f591fSIvan Malov 	unsigned int				refcnt;
113002f591fSIvan Malov 	unsigned int				nb_action_sets;
114002f591fSIvan Malov 	struct sfc_mae_action_set		**action_sets;
115002f591fSIvan Malov 	struct sfc_mae_fw_rsrc			fw_rsrc;
116002f591fSIvan Malov };
117002f591fSIvan Malov 
118002f591fSIvan Malov TAILQ_HEAD(sfc_mae_action_set_lists, sfc_mae_action_set_list);
119002f591fSIvan Malov 
12073e01736SIvan Malov /** Action rule registry entry */
12173e01736SIvan Malov struct sfc_mae_action_rule {
12273e01736SIvan Malov 	TAILQ_ENTRY(sfc_mae_action_rule)	entries;
123c6fa506cSIvan Malov 	uint32_t				ct_mark;
12473e01736SIvan Malov 	struct sfc_mae_outer_rule		*outer_rule;
125002f591fSIvan Malov 	/*
126002f591fSIvan Malov 	 * When action_set_list != NULL, action_set is NULL, and vice versa.
127002f591fSIvan Malov 	 */
12873e01736SIvan Malov 	struct sfc_mae_action_set		*action_set;
129002f591fSIvan Malov 	struct sfc_mae_action_set_list		*action_set_list;
13073e01736SIvan Malov 	efx_mae_match_spec_t			*match_spec;
13173e01736SIvan Malov 	struct sfc_mae_fw_rsrc			fw_rsrc;
13273e01736SIvan Malov 	unsigned int				refcnt;
13373e01736SIvan Malov };
13473e01736SIvan Malov TAILQ_HEAD(sfc_mae_action_rules, sfc_mae_action_rule);
13573e01736SIvan Malov 
13602b234adSIvan Malov /** Options for MAE support status */
13702b234adSIvan Malov enum sfc_mae_status {
13802b234adSIvan Malov 	SFC_MAE_STATUS_UNKNOWN = 0,
13902b234adSIvan Malov 	SFC_MAE_STATUS_UNSUPPORTED,
1402f577f0eSViacheslav Galaktionov 	SFC_MAE_STATUS_SUPPORTED,
1412f577f0eSViacheslav Galaktionov 	SFC_MAE_STATUS_ADMIN,
14202b234adSIvan Malov };
14302b234adSIvan Malov 
1441bbd1ec2SIvan Malov /*
1451bbd1ec2SIvan Malov  * Encap. header bounce buffer. It is used to store header data
1461bbd1ec2SIvan Malov  * when parsing the header definition in the action VXLAN_ENCAP.
1471bbd1ec2SIvan Malov  */
1481bbd1ec2SIvan Malov struct sfc_mae_bounce_eh {
1491bbd1ec2SIvan Malov 	uint8_t				*buf;
1501bbd1ec2SIvan Malov 	size_t				buf_size;
1511bbd1ec2SIvan Malov 	size_t				size;
1521bbd1ec2SIvan Malov 	efx_tunnel_protocol_t		type;
1531bbd1ec2SIvan Malov };
1541bbd1ec2SIvan Malov 
15596fd2bd6SIgor Romanov /** Counter collection entry */
1564a06eacbSIvan Malov struct sfc_mae_counter_record {
15796fd2bd6SIgor Romanov 	bool				inuse;
15896fd2bd6SIgor Romanov 	uint32_t			generation_count;
15996fd2bd6SIgor Romanov 	union sfc_pkts_bytes		value;
16096fd2bd6SIgor Romanov 	union sfc_pkts_bytes		reset;
1619df2d8f5SIvan Malov 
162f55fe01fSIvan Malov 	uint64_t			*ft_switch_hit_counter;
16396fd2bd6SIgor Romanov };
16496fd2bd6SIgor Romanov 
16596fd2bd6SIgor Romanov struct sfc_mae_counters_xstats {
16696fd2bd6SIgor Romanov 	uint64_t			not_inuse_update;
16796fd2bd6SIgor Romanov 	uint64_t			realloc_update;
16896fd2bd6SIgor Romanov };
16996fd2bd6SIgor Romanov 
1704a06eacbSIvan Malov struct sfc_mae_counter_records {
17196fd2bd6SIgor Romanov 	/** An array of all MAE counters */
1724a06eacbSIvan Malov 	struct sfc_mae_counter_record	*mae_counters;
17396fd2bd6SIgor Romanov 	/** Extra statistics for counters */
17496fd2bd6SIgor Romanov 	struct sfc_mae_counters_xstats	xstats;
17596fd2bd6SIgor Romanov 	/** Count of all MAE counters */
17696fd2bd6SIgor Romanov 	unsigned int			n_mae_counters;
1771c941a5fSIvan Malov 	/** Counter type, for logging */
1781c941a5fSIvan Malov 	efx_counter_type_t		type;
17996fd2bd6SIgor Romanov };
18096fd2bd6SIgor Romanov 
181ce1f72dcSViacheslav Galaktionov /** Options for MAE counter polling mode */
182ce1f72dcSViacheslav Galaktionov enum sfc_mae_counter_polling_mode {
183ce1f72dcSViacheslav Galaktionov 	SFC_MAE_COUNTER_POLLING_OFF = 0,
184ce1f72dcSViacheslav Galaktionov 	SFC_MAE_COUNTER_POLLING_SERVICE,
185ce1f72dcSViacheslav Galaktionov 	SFC_MAE_COUNTER_POLLING_THREAD,
186ce1f72dcSViacheslav Galaktionov };
187ce1f72dcSViacheslav Galaktionov 
18896fd2bd6SIgor Romanov struct sfc_mae_counter_registry {
18996fd2bd6SIgor Romanov 	/* Common counter information */
1901c941a5fSIvan Malov 	/** Action rule counter record collection */
1911c941a5fSIvan Malov 	struct sfc_mae_counter_records	action_counters;
1921588d135SIvan Malov 	/** Conntrack counter record collection */
1931588d135SIvan Malov 	struct sfc_mae_counter_records	conntrack_counters;
19496fd2bd6SIgor Romanov 
19596fd2bd6SIgor Romanov 	/* Information used by counter update service */
19696fd2bd6SIgor Romanov 	/** Callback to get packets from RxQ */
19796fd2bd6SIgor Romanov 	eth_rx_burst_t			rx_pkt_burst;
19896fd2bd6SIgor Romanov 	/** Data for the callback to get packets */
19996fd2bd6SIgor Romanov 	struct sfc_dp_rxq		*rx_dp;
20096fd2bd6SIgor Romanov 	/** Number of buffers pushed to the RxQ */
20196fd2bd6SIgor Romanov 	unsigned int			pushed_n_buffers;
20296fd2bd6SIgor Romanov 	/** Are credits used by counter stream */
20396fd2bd6SIgor Romanov 	bool				use_credits;
20496fd2bd6SIgor Romanov 
20596fd2bd6SIgor Romanov 	/* Information used by configuration routines */
206ce1f72dcSViacheslav Galaktionov 	enum sfc_mae_counter_polling_mode polling_mode;
207ce1f72dcSViacheslav Galaktionov 	union {
208ce1f72dcSViacheslav Galaktionov 		struct {
20996fd2bd6SIgor Romanov 			/** Counter service core ID */
210ce1f72dcSViacheslav Galaktionov 			uint32_t			core_id;
21196fd2bd6SIgor Romanov 			/** Counter service ID */
212ce1f72dcSViacheslav Galaktionov 			uint32_t			id;
213ce1f72dcSViacheslav Galaktionov 		} service;
214ce1f72dcSViacheslav Galaktionov 		struct {
215ce1f72dcSViacheslav Galaktionov 			/** Counter thread ID */
216a7ba40b2SThomas Monjalon 			rte_thread_t			id;
217ce1f72dcSViacheslav Galaktionov 			/** The thread should keep running */
218ce1f72dcSViacheslav Galaktionov 			bool				run;
219ce1f72dcSViacheslav Galaktionov 		} thread;
220ce1f72dcSViacheslav Galaktionov 	} polling;
22196fd2bd6SIgor Romanov };
22296fd2bd6SIgor Romanov 
223002f591fSIvan Malov /* Entry format for the action parsing bounce buffer */
224002f591fSIvan Malov struct sfc_mae_aset_ctx {
225002f591fSIvan Malov 	struct sfc_mae_encap_header	*encap_header;
226002f591fSIvan Malov 	struct sfc_mae_counter		*counter;
227002f591fSIvan Malov 	struct sfc_mae_mac_addr		*dst_mac;
228002f591fSIvan Malov 	struct sfc_mae_mac_addr		*src_mac;
229002f591fSIvan Malov 
230*5f701365SIvan Malov 	bool				counter_implicit;
231002f591fSIvan Malov 	bool				fate_set;
232002f591fSIvan Malov 
233002f591fSIvan Malov 	efx_mae_actions_t		*spec;
234002f591fSIvan Malov };
235002f591fSIvan Malov 
23602b234adSIvan Malov struct sfc_mae {
2371e7fbdf0SIvan Malov 	/** Assigned switch domain identifier */
2381e7fbdf0SIvan Malov 	uint16_t			switch_domain_id;
2391e7fbdf0SIvan Malov 	/** Assigned switch port identifier */
2401e7fbdf0SIvan Malov 	uint16_t			switch_port_id;
24102b234adSIvan Malov 	/** NIC support for MAE status */
24202b234adSIvan Malov 	enum sfc_mae_status		status;
243dadff137SIvan Malov 	/** Priority level limit for MAE outer rules */
244dadff137SIvan Malov 	unsigned int			nb_outer_rule_prios_max;
24501628fc5SIvan Malov 	/** Priority level limit for MAE action rules */
24601628fc5SIvan Malov 	unsigned int			nb_action_rule_prios_max;
247dadff137SIvan Malov 	/** Encapsulation support status */
248dadff137SIvan Malov 	uint32_t			encap_types_supported;
249dadff137SIvan Malov 	/** Outer rule registry */
250dadff137SIvan Malov 	struct sfc_mae_outer_rules	outer_rules;
2511bbd1ec2SIvan Malov 	/** Encap. header registry */
2521bbd1ec2SIvan Malov 	struct sfc_mae_encap_headers	encap_headers;
2534c600599SIvan Malov 	/** MAC address registry */
2544c600599SIvan Malov 	struct sfc_mae_mac_addrs	mac_addrs;
255662286aeSIvan Malov 	/** Action set registry */
256662286aeSIvan Malov 	struct sfc_mae_action_sets	action_sets;
257002f591fSIvan Malov 	/** Action set list registry */
258002f591fSIvan Malov 	struct sfc_mae_action_set_lists	action_set_lists;
25973e01736SIvan Malov 	/** Action rule registry */
26073e01736SIvan Malov 	struct sfc_mae_action_rules	action_rules;
2611bbd1ec2SIvan Malov 	/** Encap. header bounce buffer */
2621bbd1ec2SIvan Malov 	struct sfc_mae_bounce_eh	bounce_eh;
263002f591fSIvan Malov 	/**
264002f591fSIvan Malov 	 * Action parsing bounce buffers
265002f591fSIvan Malov 	 */
266002f591fSIvan Malov 	struct sfc_mae_action_set	**bounce_aset_ptrs;
267002f591fSIvan Malov 	struct sfc_mae_aset_ctx		*bounce_aset_ctxs;
268002f591fSIvan Malov 	efx_mae_aset_id_t		*bounce_aset_ids;
269002f591fSIvan Malov 	unsigned int			nb_bounce_asets;
27096fd2bd6SIgor Romanov 	/** Flag indicating whether counter-only RxQ is running */
27196fd2bd6SIgor Romanov 	bool				counter_rxq_running;
2724a06eacbSIvan Malov 	/** Counter record registry */
27396fd2bd6SIgor Romanov 	struct sfc_mae_counter_registry	counter_registry;
274dffc1de1SIvan Malov 	/** Counter object registry */
275dffc1de1SIvan Malov 	struct sfc_mae_counters		counters;
276c8617ddaSIgor Romanov 	/**
277c8617ddaSIgor Romanov 	 * Switchdev default rules. They forward traffic from PHY port
278c8617ddaSIgor Romanov 	 * to PF and vice versa.
279c8617ddaSIgor Romanov 	 */
280671f47e1SIvan Malov 	struct rte_flow			*switchdev_rule_pf_to_ext;
281671f47e1SIvan Malov 	struct rte_flow			*switchdev_rule_ext_to_pf;
28202b234adSIvan Malov };
28302b234adSIvan Malov 
28402b234adSIvan Malov struct sfc_adapter;
2857a25bc98SIvan Malov struct sfc_flow_spec;
2867a25bc98SIvan Malov 
287900d0c1bSIvan Malov /** This implementation supports double-tagging */
288900d0c1bSIvan Malov #define SFC_MAE_MATCH_VLAN_MAX_NTAGS	(2)
289900d0c1bSIvan Malov 
290900d0c1bSIvan Malov /** It is possible to keep track of one item ETH and two items VLAN */
291900d0c1bSIvan Malov #define SFC_MAE_L2_MAX_NITEMS		(SFC_MAE_MATCH_VLAN_MAX_NTAGS + 1)
292900d0c1bSIvan Malov 
293900d0c1bSIvan Malov /** Auxiliary entry format to keep track of L2 "type" ("inner_type") */
294900d0c1bSIvan Malov struct sfc_mae_ethertype {
295900d0c1bSIvan Malov 	rte_be16_t	value;
296900d0c1bSIvan Malov 	rte_be16_t	mask;
297900d0c1bSIvan Malov };
298900d0c1bSIvan Malov 
299900d0c1bSIvan Malov struct sfc_mae_pattern_data {
300900d0c1bSIvan Malov 	/**
301900d0c1bSIvan Malov 	 * Keeps track of "type" ("inner_type") mask and value for each
302900d0c1bSIvan Malov 	 * parsed L2 item in a pattern. These values/masks get filled
303900d0c1bSIvan Malov 	 * in MAE match specification at the end of parsing. Also, this
304900d0c1bSIvan Malov 	 * information is used to conduct consistency checks:
305900d0c1bSIvan Malov 	 *
306900d0c1bSIvan Malov 	 * - If an item ETH is followed by a single item VLAN,
307900d0c1bSIvan Malov 	 *   the former must have "type" set to one of supported
308d96dccbcSIvan Malov 	 *   TPID values (0x8100, 0x88a8, 0x9100, 0x9200, 0x9300),
309d96dccbcSIvan Malov 	 *   or 0x0000/0x0000.
310900d0c1bSIvan Malov 	 *
311900d0c1bSIvan Malov 	 * - If an item ETH is followed by two items VLAN, the
312900d0c1bSIvan Malov 	 *   item ETH must have "type" set to one of supported TPID
313d96dccbcSIvan Malov 	 *   values (0x88a8, 0x9100, 0x9200, 0x9300), or 0x0000/0x0000,
314d96dccbcSIvan Malov 	 *   and the outermost VLAN item must have "inner_type" set
315d96dccbcSIvan Malov 	 *   to TPID value 0x8100, or 0x0000/0x0000
316900d0c1bSIvan Malov 	 *
317bcf8dda8SIvan Malov 	 * - If a L2 item is followed by a L3 one, the former must
318bcf8dda8SIvan Malov 	 *   indicate "type" ("inner_type") which corresponds to
319bcf8dda8SIvan Malov 	 *   the protocol used in the L3 item, or 0x0000/0x0000.
320bcf8dda8SIvan Malov 	 *
321900d0c1bSIvan Malov 	 * In turn, mapping between RTE convention (above requirements) and
322900d0c1bSIvan Malov 	 * MAE fields is non-trivial. The following scheme indicates
323900d0c1bSIvan Malov 	 * which item EtherTypes go to which MAE fields in the case
324900d0c1bSIvan Malov 	 * of single tag:
325900d0c1bSIvan Malov 	 *
326900d0c1bSIvan Malov 	 * ETH	(0x8100)	--> VLAN0_PROTO_BE
327900d0c1bSIvan Malov 	 * VLAN	(L3 EtherType)	--> ETHER_TYPE_BE
328900d0c1bSIvan Malov 	 *
329900d0c1bSIvan Malov 	 * Similarly, in the case of double tagging:
330900d0c1bSIvan Malov 	 *
331900d0c1bSIvan Malov 	 * ETH	(0x88a8)	--> VLAN0_PROTO_BE
332900d0c1bSIvan Malov 	 * VLAN	(0x8100)	--> VLAN1_PROTO_BE
333900d0c1bSIvan Malov 	 * VLAN	(L3 EtherType)	--> ETHER_TYPE_BE
334900d0c1bSIvan Malov 	 */
335900d0c1bSIvan Malov 	struct sfc_mae_ethertype	ethertypes[SFC_MAE_L2_MAX_NITEMS];
336d96dccbcSIvan Malov 
337d96dccbcSIvan Malov 	rte_be16_t			tci_masks[SFC_MAE_MATCH_VLAN_MAX_NTAGS];
338d96dccbcSIvan Malov 
339900d0c1bSIvan Malov 	unsigned int			nb_vlan_tags;
340bcf8dda8SIvan Malov 
341bcf8dda8SIvan Malov 	/**
342bcf8dda8SIvan Malov 	 * L3 requirement for the innermost L2 item's "type" ("inner_type").
343bcf8dda8SIvan Malov 	 * This contains one of:
344bcf8dda8SIvan Malov 	 * - 0x0800/0xffff: IPV4
345e191e0d5SIvan Malov 	 * - 0x86dd/0xffff: IPV6
346bcf8dda8SIvan Malov 	 * - 0x0000/0x0000: no L3 item
347bcf8dda8SIvan Malov 	 */
348bcf8dda8SIvan Malov 	struct sfc_mae_ethertype	innermost_ethertype_restriction;
349bcf8dda8SIvan Malov 
350bcf8dda8SIvan Malov 	/**
351bcf8dda8SIvan Malov 	 * The following two fields keep track of L3 "proto" mask and value.
352bcf8dda8SIvan Malov 	 * The corresponding fields get filled in MAE match specification
353e0eb90cbSIvan Malov 	 * at the end of parsing. Also, the information is used by a
354e0eb90cbSIvan Malov 	 * post-check to enforce consistency requirements:
355e0eb90cbSIvan Malov 	 *
356e0eb90cbSIvan Malov 	 * - If a L3 item is followed by an item TCP, the former has
357e0eb90cbSIvan Malov 	 *   its "proto" set to either 0x06/0xff or 0x00/0x00.
358c50442b0SIvan Malov 	 *
359c50442b0SIvan Malov 	 * - If a L3 item is followed by an item UDP, the former has
360c50442b0SIvan Malov 	 *   its "proto" set to either 0x11/0xff or 0x00/0x00.
361bcf8dda8SIvan Malov 	 */
362bcf8dda8SIvan Malov 	uint8_t				l3_next_proto_value;
363bcf8dda8SIvan Malov 	uint8_t				l3_next_proto_mask;
364e0eb90cbSIvan Malov 
365e0eb90cbSIvan Malov 	/*
366e0eb90cbSIvan Malov 	 * L4 requirement for L3 item's "proto".
367e0eb90cbSIvan Malov 	 * This contains one of:
368e0eb90cbSIvan Malov 	 * - 0x06/0xff: TCP
369c50442b0SIvan Malov 	 * - 0x11/0xff: UDP
370e0eb90cbSIvan Malov 	 * - 0x00/0x00: no L4 item
371e0eb90cbSIvan Malov 	 */
372e0eb90cbSIvan Malov 	uint8_t				l3_next_proto_restriction_value;
373e0eb90cbSIvan Malov 	uint8_t				l3_next_proto_restriction_mask;
374d96dccbcSIvan Malov 
375f79ce621SArtemii Morozov 	rte_be16_t			l3_frag_ofst_value;
376f79ce621SArtemii Morozov 	rte_be16_t			l3_frag_ofst_mask;
377f79ce621SArtemii Morozov 	rte_be16_t			l3_frag_ofst_last;
378f79ce621SArtemii Morozov 
379d96dccbcSIvan Malov 	/* Projected state of EFX_MAE_FIELD_HAS_OVLAN match bit */
380d96dccbcSIvan Malov 	bool				has_ovlan_value;
381d96dccbcSIvan Malov 	bool				has_ovlan_mask;
382d96dccbcSIvan Malov 
383d96dccbcSIvan Malov 	/* Projected state of EFX_MAE_FIELD_HAS_IVLAN match bit */
384d96dccbcSIvan Malov 	bool				has_ivlan_value;
385d96dccbcSIvan Malov 	bool				has_ivlan_mask;
386900d0c1bSIvan Malov };
387900d0c1bSIvan Malov 
3887a25bc98SIvan Malov struct sfc_mae_parse_ctx {
3892ada1448SIvan Malov 	struct sfc_adapter		*sa;
3907a25bc98SIvan Malov 	efx_mae_match_spec_t		*match_spec_action;
391dadff137SIvan Malov 	efx_mae_match_spec_t		*match_spec_outer;
392dadff137SIvan Malov 	/*
393dadff137SIvan Malov 	 * This points to either of the above two specifications depending
394dadff137SIvan Malov 	 * on which part of the pattern is being parsed (outer / inner).
395dadff137SIvan Malov 	 */
396dadff137SIvan Malov 	efx_mae_match_spec_t		*match_spec;
397dadff137SIvan Malov 	/*
398dadff137SIvan Malov 	 * This points to either "field_ids_remap_to_encap"
399dadff137SIvan Malov 	 * or "field_ids_no_remap" (see sfc_mae.c) depending on
400dadff137SIvan Malov 	 * which part of the pattern is being parsed.
401dadff137SIvan Malov 	 */
402dadff137SIvan Malov 	const efx_mae_field_id_t	*field_ids_remap;
40305cc6e33SIvan Malov 	/* These two fields correspond to the tunnel-specific default mask. */
40405cc6e33SIvan Malov 	size_t				tunnel_def_mask_size;
405dadff137SIvan Malov 	const void			*tunnel_def_mask;
4069ca45fd1SIvan Malov 	bool				match_mport_set;
4078cff0013SIvan Malov 	bool				internal;
408f55fe01fSIvan Malov 	enum sfc_ft_rule_type		ft_rule_type;
409900d0c1bSIvan Malov 	struct sfc_mae_pattern_data	pattern_data;
410dadff137SIvan Malov 	efx_tunnel_protocol_t		encap_type;
4110ead0983SIvan Malov 	const struct rte_flow_item	*pattern;
412dadff137SIvan Malov 	unsigned int			priority;
413f55fe01fSIvan Malov 	struct sfc_ft_ctx		*ft_ctx;
4147a25bc98SIvan Malov };
41502b234adSIvan Malov 
41602b234adSIvan Malov int sfc_mae_attach(struct sfc_adapter *sa);
41702b234adSIvan Malov void sfc_mae_detach(struct sfc_adapter *sa);
4183f10e0e9SIvan Malov 
4193f10e0e9SIvan Malov int sfc_mae_rule_parse(struct sfc_adapter *sa,
4207a25bc98SIvan Malov 		       const struct rte_flow_item pattern[],
421662286aeSIvan Malov 		       const struct rte_flow_action actions[],
4223f10e0e9SIvan Malov 		       struct rte_flow *flow, struct rte_flow_error *error);
4233f10e0e9SIvan Malov 
4243f10e0e9SIvan Malov sfc_flow_cleanup_cb_t sfc_mae_flow_cleanup;
4258b61dd99SIvan Malov sfc_flow_verify_cb_t sfc_mae_flow_verify;
426041f22ecSIvan Malov sfc_flow_insert_cb_t sfc_mae_flow_insert;
427041f22ecSIvan Malov sfc_flow_remove_cb_t sfc_mae_flow_remove;
4285cb47462SIgor Romanov sfc_flow_query_cb_t sfc_mae_flow_query;
42902b234adSIvan Malov 
430c8617ddaSIgor Romanov /**
431c8617ddaSIgor Romanov  * The value used to represent the lowest priority.
432c8617ddaSIgor Romanov  * Used in MAE rule API.
433c8617ddaSIgor Romanov  */
434c8617ddaSIgor Romanov #define SFC_MAE_RULE_PRIO_LOWEST	(-1)
435c8617ddaSIgor Romanov 
436c8617ddaSIgor Romanov /**
437c8617ddaSIgor Romanov  * Insert a driver-internal flow rule that matches traffic originating from
438671f47e1SIvan Malov  * a source port (REPRESENTED_PORT or PORT_REPRESENTOR) and directs it to
439671f47e1SIvan Malov  * its destination counterpart (PORT_REPRESENTOR or REPRESENTED_PORT).
440c8617ddaSIgor Romanov  *
441671f47e1SIvan Malov  * If the prio argument is negative, the lowest level will be picked.
442c8617ddaSIgor Romanov  */
443671f47e1SIvan Malov struct rte_flow *sfc_mae_repr_flow_create(struct sfc_adapter *sa,
444671f47e1SIvan Malov 					  int prio, uint16_t port_id,
445671f47e1SIvan Malov 					  enum rte_flow_action_type dst_type,
446671f47e1SIvan Malov 					  enum rte_flow_item_type src_type);
447671f47e1SIvan Malov 
448671f47e1SIvan Malov void sfc_mae_repr_flow_destroy(struct sfc_adapter *sa, struct rte_flow *flow);
449671f47e1SIvan Malov 
450c8617ddaSIgor Romanov int sfc_mae_switchdev_init(struct sfc_adapter *sa);
451c8617ddaSIgor Romanov void sfc_mae_switchdev_fini(struct sfc_adapter *sa);
452c8617ddaSIgor Romanov 
4536676ae6aSIvan Malov int sfc_mae_indir_action_create(struct sfc_adapter *sa,
4546676ae6aSIvan Malov 				const struct rte_flow_action *action,
4556676ae6aSIvan Malov 				struct rte_flow_action_handle *handle,
4566676ae6aSIvan Malov 				struct rte_flow_error *error);
4576676ae6aSIvan Malov 
4586676ae6aSIvan Malov int sfc_mae_indir_action_destroy(struct sfc_adapter *sa,
4596676ae6aSIvan Malov 				 const struct rte_flow_action_handle *handle,
4606676ae6aSIvan Malov 				 struct rte_flow_error *error);
4616676ae6aSIvan Malov 
4628763593fSIvan Malov int sfc_mae_indir_action_update(struct sfc_adapter *sa,
4638763593fSIvan Malov 				struct rte_flow_action_handle *handle,
4648763593fSIvan Malov 				const void *update,
4658763593fSIvan Malov 				struct rte_flow_error *error);
4668763593fSIvan Malov 
4676676ae6aSIvan Malov int sfc_mae_indir_action_query(struct sfc_adapter *sa,
4686676ae6aSIvan Malov 			       const struct rte_flow_action_handle *handle,
4696676ae6aSIvan Malov 			       void *data, struct rte_flow_error *error);
4706676ae6aSIvan Malov 
47102b234adSIvan Malov #ifdef __cplusplus
47202b234adSIvan Malov }
47302b234adSIvan Malov #endif
47402b234adSIvan Malov #endif /* _SFC_MAE_H */
475