xref: /linux/drivers/net/ethernet/marvell/prestera/prestera_acl.h (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
18b474a9fSSerhiy Boiko /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
247327e19SVolodymyr Mytnyk /* Copyright (c) 2020-2021 Marvell International Ltd. All rights reserved. */
38b474a9fSSerhiy Boiko 
48b474a9fSSerhiy Boiko #ifndef _PRESTERA_ACL_H_
58b474a9fSSerhiy Boiko #define _PRESTERA_ACL_H_
68b474a9fSSerhiy Boiko 
747327e19SVolodymyr Mytnyk #include <linux/types.h>
8adefefe5SVolodymyr Mytnyk #include "prestera_counter.h"
947327e19SVolodymyr Mytnyk 
1047327e19SVolodymyr Mytnyk #define PRESTERA_ACL_KEYMASK_PCL_ID		0x3FF
1147327e19SVolodymyr Mytnyk #define PRESTERA_ACL_KEYMASK_PCL_ID_USER			\
1247327e19SVolodymyr Mytnyk 	(PRESTERA_ACL_KEYMASK_PCL_ID & 0x00FF)
13fa5d824cSVolodymyr Mytnyk #define PRESTERA_ACL_KEYMASK_PCL_ID_CHAIN			\
14fa5d824cSVolodymyr Mytnyk 	(PRESTERA_ACL_KEYMASK_PCL_ID & 0xFF00)
15fa5d824cSVolodymyr Mytnyk #define PRESTERA_ACL_CHAIN_MASK					\
16fa5d824cSVolodymyr Mytnyk 	(PRESTERA_ACL_KEYMASK_PCL_ID >> 8)
17fa5d824cSVolodymyr Mytnyk 
18fa5d824cSVolodymyr Mytnyk #define PRESTERA_ACL_PCL_ID_MAKE(uid, chain_id)			\
19fa5d824cSVolodymyr Mytnyk 	(((uid) & PRESTERA_ACL_KEYMASK_PCL_ID_USER) |		\
20fa5d824cSVolodymyr Mytnyk 	(((chain_id) << 8) & PRESTERA_ACL_KEYMASK_PCL_ID_CHAIN))
2147327e19SVolodymyr Mytnyk 
2247327e19SVolodymyr Mytnyk #define rule_match_set_n(match_p, type, val_p, size)		\
2347327e19SVolodymyr Mytnyk 	memcpy(&(match_p)[PRESTERA_ACL_RULE_MATCH_TYPE_##type],	\
2447327e19SVolodymyr Mytnyk 	       val_p, size)
2547327e19SVolodymyr Mytnyk #define rule_match_set(match_p, type, val)			\
2647327e19SVolodymyr Mytnyk 	memcpy(&(match_p)[PRESTERA_ACL_RULE_MATCH_TYPE_##type],	\
2747327e19SVolodymyr Mytnyk 	       &(val), sizeof(val))
2847327e19SVolodymyr Mytnyk 
2947327e19SVolodymyr Mytnyk enum prestera_acl_match_type {
3047327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_PCL_ID,
3147327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_TYPE,
3247327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_DMAC_0,
3347327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_DMAC_1,
3447327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_SMAC_0,
3547327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_SMAC_1,
3647327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_IP_PROTO,
3747327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_SYS_PORT,
3847327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_SYS_DEV,
3947327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_IP_SRC,
4047327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_IP_DST,
4147327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_SRC,
4247327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_DST,
4347327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_RANGE_SRC,
4447327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_RANGE_DST,
4547327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_VLAN_ID,
4647327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_VLAN_TPID,
4747327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_ICMP_TYPE,
4847327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_MATCH_TYPE_ICMP_CODE,
4947327e19SVolodymyr Mytnyk 
5047327e19SVolodymyr Mytnyk 	__PRESTERA_ACL_RULE_MATCH_TYPE_MAX
518b474a9fSSerhiy Boiko };
528b474a9fSSerhiy Boiko 
538b474a9fSSerhiy Boiko enum prestera_acl_rule_action {
5447327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_ACTION_ACCEPT = 0,
5547327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_ACTION_DROP = 1,
5647327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_ACTION_TRAP = 2,
57fa5d824cSVolodymyr Mytnyk 	PRESTERA_ACL_RULE_ACTION_JUMP = 5,
5847327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_ACTION_COUNT = 7,
59dde2daa0SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_ACTION_POLICE = 8,
6047327e19SVolodymyr Mytnyk 
6147327e19SVolodymyr Mytnyk 	PRESTERA_ACL_RULE_ACTION_MAX
628b474a9fSSerhiy Boiko };
638b474a9fSSerhiy Boiko 
6447327e19SVolodymyr Mytnyk enum {
6547327e19SVolodymyr Mytnyk 	PRESTERA_ACL_IFACE_TYPE_PORT,
6647327e19SVolodymyr Mytnyk 	PRESTERA_ACL_IFACE_TYPE_INDEX
678b474a9fSSerhiy Boiko };
688b474a9fSSerhiy Boiko 
6947327e19SVolodymyr Mytnyk struct prestera_acl_match {
7047327e19SVolodymyr Mytnyk 	__be32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
7147327e19SVolodymyr Mytnyk 	__be32 mask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
728b474a9fSSerhiy Boiko };
738b474a9fSSerhiy Boiko 
74fa5d824cSVolodymyr Mytnyk struct prestera_acl_action_jump {
75fa5d824cSVolodymyr Mytnyk 	u32 index;
76fa5d824cSVolodymyr Mytnyk };
77fa5d824cSVolodymyr Mytnyk 
78dde2daa0SVolodymyr Mytnyk struct prestera_acl_action_police {
79dde2daa0SVolodymyr Mytnyk 	u32 id;
80dde2daa0SVolodymyr Mytnyk };
81dde2daa0SVolodymyr Mytnyk 
826e36c7bcSVolodymyr Mytnyk struct prestera_acl_action_count {
836e36c7bcSVolodymyr Mytnyk 	u32 id;
846e36c7bcSVolodymyr Mytnyk };
856e36c7bcSVolodymyr Mytnyk 
8647327e19SVolodymyr Mytnyk struct prestera_acl_rule_entry_key {
8747327e19SVolodymyr Mytnyk 	u32 prio;
8847327e19SVolodymyr Mytnyk 	struct prestera_acl_match match;
8947327e19SVolodymyr Mytnyk };
9047327e19SVolodymyr Mytnyk 
9147327e19SVolodymyr Mytnyk struct prestera_acl_hw_action_info {
928b474a9fSSerhiy Boiko 	enum prestera_acl_rule_action id;
936e36c7bcSVolodymyr Mytnyk 	union {
94dde2daa0SVolodymyr Mytnyk 		struct prestera_acl_action_police police;
956e36c7bcSVolodymyr Mytnyk 		struct prestera_acl_action_count count;
96fa5d824cSVolodymyr Mytnyk 		struct prestera_acl_action_jump jump;
976e36c7bcSVolodymyr Mytnyk 	};
988b474a9fSSerhiy Boiko };
998b474a9fSSerhiy Boiko 
10047327e19SVolodymyr Mytnyk /* This struct (arg) used only to be passed as parameter for
10147327e19SVolodymyr Mytnyk  * acl_rule_entry_create. Must be flat. Can contain object keys, which will be
10247327e19SVolodymyr Mytnyk  * resolved to object links, before saving to acl_rule_entry struct
10347327e19SVolodymyr Mytnyk  */
10447327e19SVolodymyr Mytnyk struct prestera_acl_rule_entry_arg {
10547327e19SVolodymyr Mytnyk 	u32 vtcam_id;
1068b474a9fSSerhiy Boiko 	struct {
1078b474a9fSSerhiy Boiko 		struct {
10847327e19SVolodymyr Mytnyk 			u8 valid:1;
10947327e19SVolodymyr Mytnyk 		} accept, drop, trap;
110adefefe5SVolodymyr Mytnyk 		struct {
111fa5d824cSVolodymyr Mytnyk 			struct prestera_acl_action_jump i;
112fa5d824cSVolodymyr Mytnyk 			u8 valid:1;
113fa5d824cSVolodymyr Mytnyk 		} jump;
114fa5d824cSVolodymyr Mytnyk 		struct {
115adefefe5SVolodymyr Mytnyk 			u8 valid:1;
116dde2daa0SVolodymyr Mytnyk 			u64 rate;
117dde2daa0SVolodymyr Mytnyk 			u64 burst;
118dde2daa0SVolodymyr Mytnyk 			bool ingress;
119dde2daa0SVolodymyr Mytnyk 		} police;
120dde2daa0SVolodymyr Mytnyk 		struct {
121dde2daa0SVolodymyr Mytnyk 			u8 valid:1;
122adefefe5SVolodymyr Mytnyk 			u32 client;
123adefefe5SVolodymyr Mytnyk 		} count;
1248b474a9fSSerhiy Boiko 	};
12547327e19SVolodymyr Mytnyk };
12647327e19SVolodymyr Mytnyk 
12747327e19SVolodymyr Mytnyk struct prestera_acl_rule {
12847327e19SVolodymyr Mytnyk 	struct rhash_head ht_node; /* Member of acl HT */
12947327e19SVolodymyr Mytnyk 	struct list_head list;
13047327e19SVolodymyr Mytnyk 	struct prestera_acl_ruleset *ruleset;
131fa5d824cSVolodymyr Mytnyk 	struct prestera_acl_ruleset *jump_ruleset;
13247327e19SVolodymyr Mytnyk 	unsigned long cookie;
133fa5d824cSVolodymyr Mytnyk 	u32 chain_index;
13447327e19SVolodymyr Mytnyk 	u32 priority;
13547327e19SVolodymyr Mytnyk 	struct prestera_acl_rule_entry_key re_key;
13647327e19SVolodymyr Mytnyk 	struct prestera_acl_rule_entry_arg re_arg;
13747327e19SVolodymyr Mytnyk 	struct prestera_acl_rule_entry *re;
13847327e19SVolodymyr Mytnyk };
13947327e19SVolodymyr Mytnyk 
14047327e19SVolodymyr Mytnyk struct prestera_acl_iface {
14147327e19SVolodymyr Mytnyk 	union {
14247327e19SVolodymyr Mytnyk 		struct prestera_port *port;
14347327e19SVolodymyr Mytnyk 		u32 index;
14447327e19SVolodymyr Mytnyk 	};
14547327e19SVolodymyr Mytnyk 	u8 type;
14647327e19SVolodymyr Mytnyk };
14747327e19SVolodymyr Mytnyk 
14847327e19SVolodymyr Mytnyk struct prestera_acl;
14947327e19SVolodymyr Mytnyk struct prestera_switch;
15047327e19SVolodymyr Mytnyk struct prestera_flow_block;
1518b474a9fSSerhiy Boiko 
1528b474a9fSSerhiy Boiko int prestera_acl_init(struct prestera_switch *sw);
1538b474a9fSSerhiy Boiko void prestera_acl_fini(struct prestera_switch *sw);
15447327e19SVolodymyr Mytnyk 
1558b474a9fSSerhiy Boiko struct prestera_acl_rule *
15647327e19SVolodymyr Mytnyk prestera_acl_rule_create(struct prestera_acl_ruleset *ruleset,
157fa5d824cSVolodymyr Mytnyk 			 unsigned long cookie, u32 chain_index);
1588b474a9fSSerhiy Boiko void prestera_acl_rule_priority_set(struct prestera_acl_rule *rule,
1598b474a9fSSerhiy Boiko 				    u32 priority);
1608b474a9fSSerhiy Boiko void prestera_acl_rule_destroy(struct prestera_acl_rule *rule);
1618b474a9fSSerhiy Boiko struct prestera_acl_rule *
1628b474a9fSSerhiy Boiko prestera_acl_rule_lookup(struct prestera_acl_ruleset *ruleset,
1638b474a9fSSerhiy Boiko 			 unsigned long cookie);
1648b474a9fSSerhiy Boiko int prestera_acl_rule_add(struct prestera_switch *sw,
1658b474a9fSSerhiy Boiko 			  struct prestera_acl_rule *rule);
1668b474a9fSSerhiy Boiko void prestera_acl_rule_del(struct prestera_switch *sw,
1678b474a9fSSerhiy Boiko 			   struct prestera_acl_rule *rule);
16847327e19SVolodymyr Mytnyk int prestera_acl_rule_get_stats(struct prestera_acl *acl,
1698b474a9fSSerhiy Boiko 				struct prestera_acl_rule *rule,
1708b474a9fSSerhiy Boiko 				u64 *packets, u64 *bytes, u64 *last_use);
17147327e19SVolodymyr Mytnyk struct prestera_acl_rule_entry *
17247327e19SVolodymyr Mytnyk prestera_acl_rule_entry_find(struct prestera_acl *acl,
17347327e19SVolodymyr Mytnyk 			     struct prestera_acl_rule_entry_key *key);
17447327e19SVolodymyr Mytnyk void prestera_acl_rule_entry_destroy(struct prestera_acl *acl,
17547327e19SVolodymyr Mytnyk 				     struct prestera_acl_rule_entry *e);
17647327e19SVolodymyr Mytnyk struct prestera_acl_rule_entry *
17747327e19SVolodymyr Mytnyk prestera_acl_rule_entry_create(struct prestera_acl *acl,
17847327e19SVolodymyr Mytnyk 			       struct prestera_acl_rule_entry_key *key,
17947327e19SVolodymyr Mytnyk 			       struct prestera_acl_rule_entry_arg *arg);
18047327e19SVolodymyr Mytnyk struct prestera_acl_ruleset *
18147327e19SVolodymyr Mytnyk prestera_acl_ruleset_get(struct prestera_acl *acl,
182fa5d824cSVolodymyr Mytnyk 			 struct prestera_flow_block *block,
183fa5d824cSVolodymyr Mytnyk 			 u32 chain_index);
18447327e19SVolodymyr Mytnyk struct prestera_acl_ruleset *
18547327e19SVolodymyr Mytnyk prestera_acl_ruleset_lookup(struct prestera_acl *acl,
186fa5d824cSVolodymyr Mytnyk 			    struct prestera_flow_block *block,
187fa5d824cSVolodymyr Mytnyk 			    u32 chain_index);
188*9e6fd874SJiasheng Jiang int prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
189604ba230SVolodymyr Mytnyk 				     void *keymask);
19047327e19SVolodymyr Mytnyk bool prestera_acl_ruleset_is_offload(struct prestera_acl_ruleset *ruleset);
19147327e19SVolodymyr Mytnyk int prestera_acl_ruleset_offload(struct prestera_acl_ruleset *ruleset);
19247327e19SVolodymyr Mytnyk void prestera_acl_ruleset_put(struct prestera_acl_ruleset *ruleset);
19347327e19SVolodymyr Mytnyk int prestera_acl_ruleset_bind(struct prestera_acl_ruleset *ruleset,
19447327e19SVolodymyr Mytnyk 			      struct prestera_port *port);
19547327e19SVolodymyr Mytnyk int prestera_acl_ruleset_unbind(struct prestera_acl_ruleset *ruleset,
19647327e19SVolodymyr Mytnyk 				struct prestera_port *port);
197fa5d824cSVolodymyr Mytnyk u32 prestera_acl_ruleset_index_get(const struct prestera_acl_ruleset *ruleset);
19844af9571SMaksym Glubokiy void prestera_acl_ruleset_prio_get(struct prestera_acl_ruleset *ruleset,
19944af9571SMaksym Glubokiy 				   u32 *prio_min, u32 *prio_max);
20047327e19SVolodymyr Mytnyk void
20147327e19SVolodymyr Mytnyk prestera_acl_rule_keymask_pcl_id_set(struct prestera_acl_rule *rule,
20247327e19SVolodymyr Mytnyk 				     u16 pcl_id);
20347327e19SVolodymyr Mytnyk 
204702e7014SMaksym Glubokiy int prestera_acl_vtcam_id_get(struct prestera_acl *acl, u8 lookup, u8 dir,
20547327e19SVolodymyr Mytnyk 			      void *keymask, u32 *vtcam_id);
20647327e19SVolodymyr Mytnyk int prestera_acl_vtcam_id_put(struct prestera_acl *acl, u32 vtcam_id);
207702e7014SMaksym Glubokiy int prestera_acl_chain_to_client(u32 chain_index, bool ingress, u32 *client);
2088b474a9fSSerhiy Boiko 
2098b474a9fSSerhiy Boiko #endif /* _PRESTERA_ACL_H_ */
210