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