GNU Linux-libre 5.19-rc6-gnu
[releases.git] / drivers / net / ethernet / marvell / prestera / prestera_acl.h
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         PRESTERA_ACL_RULE_ACTION_POLICE = 8,
60
61         PRESTERA_ACL_RULE_ACTION_MAX
62 };
63
64 enum {
65         PRESTERA_ACL_IFACE_TYPE_PORT,
66         PRESTERA_ACL_IFACE_TYPE_INDEX
67 };
68
69 struct prestera_acl_match {
70         __be32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
71         __be32 mask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
72 };
73
74 struct prestera_acl_action_jump {
75         u32 index;
76 };
77
78 struct prestera_acl_action_police {
79         u32 id;
80 };
81
82 struct prestera_acl_action_count {
83         u32 id;
84 };
85
86 struct prestera_acl_rule_entry_key {
87         u32 prio;
88         struct prestera_acl_match match;
89 };
90
91 struct prestera_acl_hw_action_info {
92         enum prestera_acl_rule_action id;
93         union {
94                 struct prestera_acl_action_police police;
95                 struct prestera_acl_action_count count;
96                 struct prestera_acl_action_jump jump;
97         };
98 };
99
100 /* This struct (arg) used only to be passed as parameter for
101  * acl_rule_entry_create. Must be flat. Can contain object keys, which will be
102  * resolved to object links, before saving to acl_rule_entry struct
103  */
104 struct prestera_acl_rule_entry_arg {
105         u32 vtcam_id;
106         struct {
107                 struct {
108                         u8 valid:1;
109                 } accept, drop, trap;
110                 struct {
111                         struct prestera_acl_action_jump i;
112                         u8 valid:1;
113                 } jump;
114                 struct {
115                         u8 valid:1;
116                         u64 rate;
117                         u64 burst;
118                         bool ingress;
119                 } police;
120                 struct {
121                         u8 valid:1;
122                         u32 client;
123                 } count;
124         };
125 };
126
127 struct prestera_acl_rule {
128         struct rhash_head ht_node; /* Member of acl HT */
129         struct list_head list;
130         struct prestera_acl_ruleset *ruleset;
131         struct prestera_acl_ruleset *jump_ruleset;
132         unsigned long cookie;
133         u32 chain_index;
134         u32 priority;
135         struct prestera_acl_rule_entry_key re_key;
136         struct prestera_acl_rule_entry_arg re_arg;
137         struct prestera_acl_rule_entry *re;
138 };
139
140 struct prestera_acl_iface {
141         union {
142                 struct prestera_port *port;
143                 u32 index;
144         };
145         u8 type;
146 };
147
148 struct prestera_acl;
149 struct prestera_switch;
150 struct prestera_flow_block;
151
152 int prestera_acl_init(struct prestera_switch *sw);
153 void prestera_acl_fini(struct prestera_switch *sw);
154
155 struct prestera_acl_rule *
156 prestera_acl_rule_create(struct prestera_acl_ruleset *ruleset,
157                          unsigned long cookie, u32 chain_index);
158 void prestera_acl_rule_priority_set(struct prestera_acl_rule *rule,
159                                     u32 priority);
160 void prestera_acl_rule_destroy(struct prestera_acl_rule *rule);
161 struct prestera_acl_rule *
162 prestera_acl_rule_lookup(struct prestera_acl_ruleset *ruleset,
163                          unsigned long cookie);
164 int prestera_acl_rule_add(struct prestera_switch *sw,
165                           struct prestera_acl_rule *rule);
166 void prestera_acl_rule_del(struct prestera_switch *sw,
167                            struct prestera_acl_rule *rule);
168 int prestera_acl_rule_get_stats(struct prestera_acl *acl,
169                                 struct prestera_acl_rule *rule,
170                                 u64 *packets, u64 *bytes, u64 *last_use);
171 struct prestera_acl_rule_entry *
172 prestera_acl_rule_entry_find(struct prestera_acl *acl,
173                              struct prestera_acl_rule_entry_key *key);
174 void prestera_acl_rule_entry_destroy(struct prestera_acl *acl,
175                                      struct prestera_acl_rule_entry *e);
176 struct prestera_acl_rule_entry *
177 prestera_acl_rule_entry_create(struct prestera_acl *acl,
178                                struct prestera_acl_rule_entry_key *key,
179                                struct prestera_acl_rule_entry_arg *arg);
180 struct prestera_acl_ruleset *
181 prestera_acl_ruleset_get(struct prestera_acl *acl,
182                          struct prestera_flow_block *block,
183                          u32 chain_index);
184 struct prestera_acl_ruleset *
185 prestera_acl_ruleset_lookup(struct prestera_acl *acl,
186                             struct prestera_flow_block *block,
187                             u32 chain_index);
188 void prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
189                                       void *keymask);
190 bool prestera_acl_ruleset_is_offload(struct prestera_acl_ruleset *ruleset);
191 int prestera_acl_ruleset_offload(struct prestera_acl_ruleset *ruleset);
192 void prestera_acl_ruleset_put(struct prestera_acl_ruleset *ruleset);
193 int prestera_acl_ruleset_bind(struct prestera_acl_ruleset *ruleset,
194                               struct prestera_port *port);
195 int prestera_acl_ruleset_unbind(struct prestera_acl_ruleset *ruleset,
196                                 struct prestera_port *port);
197 u32 prestera_acl_ruleset_index_get(const struct prestera_acl_ruleset *ruleset);
198 void
199 prestera_acl_rule_keymask_pcl_id_set(struct prestera_acl_rule *rule,
200                                      u16 pcl_id);
201
202 int prestera_acl_vtcam_id_get(struct prestera_acl *acl, u8 lookup,
203                               void *keymask, u32 *vtcam_id);
204 int prestera_acl_vtcam_id_put(struct prestera_acl *acl, u32 vtcam_id);
205 int prestera_acl_chain_to_client(u32 chain_index, u32 *client);
206
207 #endif /* _PRESTERA_ACL_H_ */