1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
2 /* Copyright (c) 2020-2021 Marvell International Ltd. All rights reserved. */
3 
4 #ifndef _PRESTERA_ACL_H_
5 #define _PRESTERA_ACL_H_
6 
7 #include <linux/types.h>
8 #include "prestera_counter.h"
9 
10 #define PRESTERA_ACL_KEYMASK_PCL_ID		0x3FF
11 #define PRESTERA_ACL_KEYMASK_PCL_ID_USER			\
12 	(PRESTERA_ACL_KEYMASK_PCL_ID & 0x00FF)
13 #define PRESTERA_ACL_KEYMASK_PCL_ID_CHAIN			\
14 	(PRESTERA_ACL_KEYMASK_PCL_ID & 0xFF00)
15 #define PRESTERA_ACL_CHAIN_MASK					\
16 	(PRESTERA_ACL_KEYMASK_PCL_ID >> 8)
17 
18 #define PRESTERA_ACL_PCL_ID_MAKE(uid, chain_id)			\
19 	(((uid) & PRESTERA_ACL_KEYMASK_PCL_ID_USER) |		\
20 	(((chain_id) << 8) & PRESTERA_ACL_KEYMASK_PCL_ID_CHAIN))
21 
22 #define rule_match_set_n(match_p, type, val_p, size)		\
23 	memcpy(&(match_p)[PRESTERA_ACL_RULE_MATCH_TYPE_##type],	\
24 	       val_p, size)
25 #define rule_match_set(match_p, type, val)			\
26 	memcpy(&(match_p)[PRESTERA_ACL_RULE_MATCH_TYPE_##type],	\
27 	       &(val), sizeof(val))
28 
29 enum prestera_acl_match_type {
30 	PRESTERA_ACL_RULE_MATCH_TYPE_PCL_ID,
31 	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_TYPE,
32 	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_DMAC_0,
33 	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_DMAC_1,
34 	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_SMAC_0,
35 	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_SMAC_1,
36 	PRESTERA_ACL_RULE_MATCH_TYPE_IP_PROTO,
37 	PRESTERA_ACL_RULE_MATCH_TYPE_SYS_PORT,
38 	PRESTERA_ACL_RULE_MATCH_TYPE_SYS_DEV,
39 	PRESTERA_ACL_RULE_MATCH_TYPE_IP_SRC,
40 	PRESTERA_ACL_RULE_MATCH_TYPE_IP_DST,
41 	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_SRC,
42 	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_DST,
43 	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_RANGE_SRC,
44 	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_RANGE_DST,
45 	PRESTERA_ACL_RULE_MATCH_TYPE_VLAN_ID,
46 	PRESTERA_ACL_RULE_MATCH_TYPE_VLAN_TPID,
47 	PRESTERA_ACL_RULE_MATCH_TYPE_ICMP_TYPE,
48 	PRESTERA_ACL_RULE_MATCH_TYPE_ICMP_CODE,
49 
50 	__PRESTERA_ACL_RULE_MATCH_TYPE_MAX
51 };
52 
53 enum prestera_acl_rule_action {
54 	PRESTERA_ACL_RULE_ACTION_ACCEPT = 0,
55 	PRESTERA_ACL_RULE_ACTION_DROP = 1,
56 	PRESTERA_ACL_RULE_ACTION_TRAP = 2,
57 	PRESTERA_ACL_RULE_ACTION_JUMP = 5,
58 	PRESTERA_ACL_RULE_ACTION_COUNT = 7,
59 
60 	PRESTERA_ACL_RULE_ACTION_MAX
61 };
62 
63 enum {
64 	PRESTERA_ACL_IFACE_TYPE_PORT,
65 	PRESTERA_ACL_IFACE_TYPE_INDEX
66 };
67 
68 struct prestera_acl_match {
69 	__be32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
70 	__be32 mask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
71 };
72 
73 struct prestera_acl_action_jump {
74 	u32 index;
75 };
76 
77 struct prestera_acl_action_count {
78 	u32 id;
79 };
80 
81 struct prestera_acl_rule_entry_key {
82 	u32 prio;
83 	struct prestera_acl_match match;
84 };
85 
86 struct prestera_acl_hw_action_info {
87 	enum prestera_acl_rule_action id;
88 	union {
89 		struct prestera_acl_action_count count;
90 		struct prestera_acl_action_jump jump;
91 	};
92 };
93 
94 /* This struct (arg) used only to be passed as parameter for
95  * acl_rule_entry_create. Must be flat. Can contain object keys, which will be
96  * resolved to object links, before saving to acl_rule_entry struct
97  */
98 struct prestera_acl_rule_entry_arg {
99 	u32 vtcam_id;
100 	struct {
101 		struct {
102 			u8 valid:1;
103 		} accept, drop, trap;
104 		struct {
105 			struct prestera_acl_action_jump i;
106 			u8 valid:1;
107 		} jump;
108 		struct {
109 			u8 valid:1;
110 			u32 client;
111 		} count;
112 	};
113 };
114 
115 struct prestera_acl_rule {
116 	struct rhash_head ht_node; /* Member of acl HT */
117 	struct list_head list;
118 	struct prestera_acl_ruleset *ruleset;
119 	struct prestera_acl_ruleset *jump_ruleset;
120 	unsigned long cookie;
121 	u32 chain_index;
122 	u32 priority;
123 	struct prestera_acl_rule_entry_key re_key;
124 	struct prestera_acl_rule_entry_arg re_arg;
125 	struct prestera_acl_rule_entry *re;
126 };
127 
128 struct prestera_acl_iface {
129 	union {
130 		struct prestera_port *port;
131 		u32 index;
132 	};
133 	u8 type;
134 };
135 
136 struct prestera_acl;
137 struct prestera_switch;
138 struct prestera_flow_block;
139 
140 int prestera_acl_init(struct prestera_switch *sw);
141 void prestera_acl_fini(struct prestera_switch *sw);
142 
143 struct prestera_acl_rule *
144 prestera_acl_rule_create(struct prestera_acl_ruleset *ruleset,
145 			 unsigned long cookie, u32 chain_index);
146 void prestera_acl_rule_priority_set(struct prestera_acl_rule *rule,
147 				    u32 priority);
148 void prestera_acl_rule_destroy(struct prestera_acl_rule *rule);
149 struct prestera_acl_rule *
150 prestera_acl_rule_lookup(struct prestera_acl_ruleset *ruleset,
151 			 unsigned long cookie);
152 int prestera_acl_rule_add(struct prestera_switch *sw,
153 			  struct prestera_acl_rule *rule);
154 void prestera_acl_rule_del(struct prestera_switch *sw,
155 			   struct prestera_acl_rule *rule);
156 int prestera_acl_rule_get_stats(struct prestera_acl *acl,
157 				struct prestera_acl_rule *rule,
158 				u64 *packets, u64 *bytes, u64 *last_use);
159 struct prestera_acl_rule_entry *
160 prestera_acl_rule_entry_find(struct prestera_acl *acl,
161 			     struct prestera_acl_rule_entry_key *key);
162 void prestera_acl_rule_entry_destroy(struct prestera_acl *acl,
163 				     struct prestera_acl_rule_entry *e);
164 struct prestera_acl_rule_entry *
165 prestera_acl_rule_entry_create(struct prestera_acl *acl,
166 			       struct prestera_acl_rule_entry_key *key,
167 			       struct prestera_acl_rule_entry_arg *arg);
168 struct prestera_acl_ruleset *
169 prestera_acl_ruleset_get(struct prestera_acl *acl,
170 			 struct prestera_flow_block *block,
171 			 u32 chain_index);
172 struct prestera_acl_ruleset *
173 prestera_acl_ruleset_lookup(struct prestera_acl *acl,
174 			    struct prestera_flow_block *block,
175 			    u32 chain_index);
176 void prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
177 				      void *keymask);
178 bool prestera_acl_ruleset_is_offload(struct prestera_acl_ruleset *ruleset);
179 int prestera_acl_ruleset_offload(struct prestera_acl_ruleset *ruleset);
180 void prestera_acl_ruleset_put(struct prestera_acl_ruleset *ruleset);
181 int prestera_acl_ruleset_bind(struct prestera_acl_ruleset *ruleset,
182 			      struct prestera_port *port);
183 int prestera_acl_ruleset_unbind(struct prestera_acl_ruleset *ruleset,
184 				struct prestera_port *port);
185 u32 prestera_acl_ruleset_index_get(const struct prestera_acl_ruleset *ruleset);
186 void
187 prestera_acl_rule_keymask_pcl_id_set(struct prestera_acl_rule *rule,
188 				     u16 pcl_id);
189 
190 int prestera_acl_vtcam_id_get(struct prestera_acl *acl, u8 lookup,
191 			      void *keymask, u32 *vtcam_id);
192 int prestera_acl_vtcam_id_put(struct prestera_acl *acl, u32 vtcam_id);
193 int prestera_acl_chain_to_client(u32 chain_index, u32 *client);
194 
195 #endif /* _PRESTERA_ACL_H_ */
196