162306a36Sopenharmony_ci/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
262306a36Sopenharmony_ci/* Copyright (c) 2020-2021 Marvell International Ltd. All rights reserved. */
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#ifndef _PRESTERA_ACL_H_
562306a36Sopenharmony_ci#define _PRESTERA_ACL_H_
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#include <linux/types.h>
862306a36Sopenharmony_ci#include "prestera_counter.h"
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#define PRESTERA_ACL_KEYMASK_PCL_ID		0x3FF
1162306a36Sopenharmony_ci#define PRESTERA_ACL_KEYMASK_PCL_ID_USER			\
1262306a36Sopenharmony_ci	(PRESTERA_ACL_KEYMASK_PCL_ID & 0x00FF)
1362306a36Sopenharmony_ci#define PRESTERA_ACL_KEYMASK_PCL_ID_CHAIN			\
1462306a36Sopenharmony_ci	(PRESTERA_ACL_KEYMASK_PCL_ID & 0xFF00)
1562306a36Sopenharmony_ci#define PRESTERA_ACL_CHAIN_MASK					\
1662306a36Sopenharmony_ci	(PRESTERA_ACL_KEYMASK_PCL_ID >> 8)
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#define PRESTERA_ACL_PCL_ID_MAKE(uid, chain_id)			\
1962306a36Sopenharmony_ci	(((uid) & PRESTERA_ACL_KEYMASK_PCL_ID_USER) |		\
2062306a36Sopenharmony_ci	(((chain_id) << 8) & PRESTERA_ACL_KEYMASK_PCL_ID_CHAIN))
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define rule_match_set_n(match_p, type, val_p, size)		\
2362306a36Sopenharmony_ci	memcpy(&(match_p)[PRESTERA_ACL_RULE_MATCH_TYPE_##type],	\
2462306a36Sopenharmony_ci	       val_p, size)
2562306a36Sopenharmony_ci#define rule_match_set(match_p, type, val)			\
2662306a36Sopenharmony_ci	memcpy(&(match_p)[PRESTERA_ACL_RULE_MATCH_TYPE_##type],	\
2762306a36Sopenharmony_ci	       &(val), sizeof(val))
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_cienum prestera_acl_match_type {
3062306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_PCL_ID,
3162306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_TYPE,
3262306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_DMAC_0,
3362306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_DMAC_1,
3462306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_SMAC_0,
3562306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_ETH_SMAC_1,
3662306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_IP_PROTO,
3762306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_SYS_PORT,
3862306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_SYS_DEV,
3962306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_IP_SRC,
4062306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_IP_DST,
4162306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_SRC,
4262306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_DST,
4362306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_RANGE_SRC,
4462306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_L4_PORT_RANGE_DST,
4562306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_VLAN_ID,
4662306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_VLAN_TPID,
4762306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_ICMP_TYPE,
4862306a36Sopenharmony_ci	PRESTERA_ACL_RULE_MATCH_TYPE_ICMP_CODE,
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	__PRESTERA_ACL_RULE_MATCH_TYPE_MAX
5162306a36Sopenharmony_ci};
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_cienum prestera_acl_rule_action {
5462306a36Sopenharmony_ci	PRESTERA_ACL_RULE_ACTION_ACCEPT = 0,
5562306a36Sopenharmony_ci	PRESTERA_ACL_RULE_ACTION_DROP = 1,
5662306a36Sopenharmony_ci	PRESTERA_ACL_RULE_ACTION_TRAP = 2,
5762306a36Sopenharmony_ci	PRESTERA_ACL_RULE_ACTION_JUMP = 5,
5862306a36Sopenharmony_ci	PRESTERA_ACL_RULE_ACTION_COUNT = 7,
5962306a36Sopenharmony_ci	PRESTERA_ACL_RULE_ACTION_POLICE = 8,
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	PRESTERA_ACL_RULE_ACTION_MAX
6262306a36Sopenharmony_ci};
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_cienum {
6562306a36Sopenharmony_ci	PRESTERA_ACL_IFACE_TYPE_PORT,
6662306a36Sopenharmony_ci	PRESTERA_ACL_IFACE_TYPE_INDEX
6762306a36Sopenharmony_ci};
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistruct prestera_acl_match {
7062306a36Sopenharmony_ci	__be32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
7162306a36Sopenharmony_ci	__be32 mask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
7262306a36Sopenharmony_ci};
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistruct prestera_acl_action_jump {
7562306a36Sopenharmony_ci	u32 index;
7662306a36Sopenharmony_ci};
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_cistruct prestera_acl_action_police {
7962306a36Sopenharmony_ci	u32 id;
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistruct prestera_acl_action_count {
8362306a36Sopenharmony_ci	u32 id;
8462306a36Sopenharmony_ci};
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_cistruct prestera_acl_rule_entry_key {
8762306a36Sopenharmony_ci	u32 prio;
8862306a36Sopenharmony_ci	struct prestera_acl_match match;
8962306a36Sopenharmony_ci};
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_cistruct prestera_acl_hw_action_info {
9262306a36Sopenharmony_ci	enum prestera_acl_rule_action id;
9362306a36Sopenharmony_ci	union {
9462306a36Sopenharmony_ci		struct prestera_acl_action_police police;
9562306a36Sopenharmony_ci		struct prestera_acl_action_count count;
9662306a36Sopenharmony_ci		struct prestera_acl_action_jump jump;
9762306a36Sopenharmony_ci	};
9862306a36Sopenharmony_ci};
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci/* This struct (arg) used only to be passed as parameter for
10162306a36Sopenharmony_ci * acl_rule_entry_create. Must be flat. Can contain object keys, which will be
10262306a36Sopenharmony_ci * resolved to object links, before saving to acl_rule_entry struct
10362306a36Sopenharmony_ci */
10462306a36Sopenharmony_cistruct prestera_acl_rule_entry_arg {
10562306a36Sopenharmony_ci	u32 vtcam_id;
10662306a36Sopenharmony_ci	struct {
10762306a36Sopenharmony_ci		struct {
10862306a36Sopenharmony_ci			u8 valid:1;
10962306a36Sopenharmony_ci		} accept, drop, trap;
11062306a36Sopenharmony_ci		struct {
11162306a36Sopenharmony_ci			struct prestera_acl_action_jump i;
11262306a36Sopenharmony_ci			u8 valid:1;
11362306a36Sopenharmony_ci		} jump;
11462306a36Sopenharmony_ci		struct {
11562306a36Sopenharmony_ci			u8 valid:1;
11662306a36Sopenharmony_ci			u64 rate;
11762306a36Sopenharmony_ci			u64 burst;
11862306a36Sopenharmony_ci			bool ingress;
11962306a36Sopenharmony_ci		} police;
12062306a36Sopenharmony_ci		struct {
12162306a36Sopenharmony_ci			u8 valid:1;
12262306a36Sopenharmony_ci			u32 client;
12362306a36Sopenharmony_ci		} count;
12462306a36Sopenharmony_ci	};
12562306a36Sopenharmony_ci};
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cistruct prestera_acl_rule {
12862306a36Sopenharmony_ci	struct rhash_head ht_node; /* Member of acl HT */
12962306a36Sopenharmony_ci	struct list_head list;
13062306a36Sopenharmony_ci	struct prestera_acl_ruleset *ruleset;
13162306a36Sopenharmony_ci	struct prestera_acl_ruleset *jump_ruleset;
13262306a36Sopenharmony_ci	unsigned long cookie;
13362306a36Sopenharmony_ci	u32 chain_index;
13462306a36Sopenharmony_ci	u32 priority;
13562306a36Sopenharmony_ci	struct prestera_acl_rule_entry_key re_key;
13662306a36Sopenharmony_ci	struct prestera_acl_rule_entry_arg re_arg;
13762306a36Sopenharmony_ci	struct prestera_acl_rule_entry *re;
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistruct prestera_acl_iface {
14162306a36Sopenharmony_ci	union {
14262306a36Sopenharmony_ci		struct prestera_port *port;
14362306a36Sopenharmony_ci		u32 index;
14462306a36Sopenharmony_ci	};
14562306a36Sopenharmony_ci	u8 type;
14662306a36Sopenharmony_ci};
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_cistruct prestera_acl;
14962306a36Sopenharmony_cistruct prestera_switch;
15062306a36Sopenharmony_cistruct prestera_flow_block;
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ciint prestera_acl_init(struct prestera_switch *sw);
15362306a36Sopenharmony_civoid prestera_acl_fini(struct prestera_switch *sw);
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cistruct prestera_acl_rule *
15662306a36Sopenharmony_ciprestera_acl_rule_create(struct prestera_acl_ruleset *ruleset,
15762306a36Sopenharmony_ci			 unsigned long cookie, u32 chain_index);
15862306a36Sopenharmony_civoid prestera_acl_rule_priority_set(struct prestera_acl_rule *rule,
15962306a36Sopenharmony_ci				    u32 priority);
16062306a36Sopenharmony_civoid prestera_acl_rule_destroy(struct prestera_acl_rule *rule);
16162306a36Sopenharmony_cistruct prestera_acl_rule *
16262306a36Sopenharmony_ciprestera_acl_rule_lookup(struct prestera_acl_ruleset *ruleset,
16362306a36Sopenharmony_ci			 unsigned long cookie);
16462306a36Sopenharmony_ciint prestera_acl_rule_add(struct prestera_switch *sw,
16562306a36Sopenharmony_ci			  struct prestera_acl_rule *rule);
16662306a36Sopenharmony_civoid prestera_acl_rule_del(struct prestera_switch *sw,
16762306a36Sopenharmony_ci			   struct prestera_acl_rule *rule);
16862306a36Sopenharmony_ciint prestera_acl_rule_get_stats(struct prestera_acl *acl,
16962306a36Sopenharmony_ci				struct prestera_acl_rule *rule,
17062306a36Sopenharmony_ci				u64 *packets, u64 *bytes, u64 *last_use);
17162306a36Sopenharmony_cistruct prestera_acl_rule_entry *
17262306a36Sopenharmony_ciprestera_acl_rule_entry_find(struct prestera_acl *acl,
17362306a36Sopenharmony_ci			     struct prestera_acl_rule_entry_key *key);
17462306a36Sopenharmony_civoid prestera_acl_rule_entry_destroy(struct prestera_acl *acl,
17562306a36Sopenharmony_ci				     struct prestera_acl_rule_entry *e);
17662306a36Sopenharmony_cistruct prestera_acl_rule_entry *
17762306a36Sopenharmony_ciprestera_acl_rule_entry_create(struct prestera_acl *acl,
17862306a36Sopenharmony_ci			       struct prestera_acl_rule_entry_key *key,
17962306a36Sopenharmony_ci			       struct prestera_acl_rule_entry_arg *arg);
18062306a36Sopenharmony_cistruct prestera_acl_ruleset *
18162306a36Sopenharmony_ciprestera_acl_ruleset_get(struct prestera_acl *acl,
18262306a36Sopenharmony_ci			 struct prestera_flow_block *block,
18362306a36Sopenharmony_ci			 u32 chain_index);
18462306a36Sopenharmony_cistruct prestera_acl_ruleset *
18562306a36Sopenharmony_ciprestera_acl_ruleset_lookup(struct prestera_acl *acl,
18662306a36Sopenharmony_ci			    struct prestera_flow_block *block,
18762306a36Sopenharmony_ci			    u32 chain_index);
18862306a36Sopenharmony_ciint prestera_acl_ruleset_keymask_set(struct prestera_acl_ruleset *ruleset,
18962306a36Sopenharmony_ci				     void *keymask);
19062306a36Sopenharmony_cibool prestera_acl_ruleset_is_offload(struct prestera_acl_ruleset *ruleset);
19162306a36Sopenharmony_ciint prestera_acl_ruleset_offload(struct prestera_acl_ruleset *ruleset);
19262306a36Sopenharmony_civoid prestera_acl_ruleset_put(struct prestera_acl_ruleset *ruleset);
19362306a36Sopenharmony_ciint prestera_acl_ruleset_bind(struct prestera_acl_ruleset *ruleset,
19462306a36Sopenharmony_ci			      struct prestera_port *port);
19562306a36Sopenharmony_ciint prestera_acl_ruleset_unbind(struct prestera_acl_ruleset *ruleset,
19662306a36Sopenharmony_ci				struct prestera_port *port);
19762306a36Sopenharmony_ciu32 prestera_acl_ruleset_index_get(const struct prestera_acl_ruleset *ruleset);
19862306a36Sopenharmony_civoid prestera_acl_ruleset_prio_get(struct prestera_acl_ruleset *ruleset,
19962306a36Sopenharmony_ci				   u32 *prio_min, u32 *prio_max);
20062306a36Sopenharmony_civoid
20162306a36Sopenharmony_ciprestera_acl_rule_keymask_pcl_id_set(struct prestera_acl_rule *rule,
20262306a36Sopenharmony_ci				     u16 pcl_id);
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ciint prestera_acl_vtcam_id_get(struct prestera_acl *acl, u8 lookup, u8 dir,
20562306a36Sopenharmony_ci			      void *keymask, u32 *vtcam_id);
20662306a36Sopenharmony_ciint prestera_acl_vtcam_id_put(struct prestera_acl *acl, u32 vtcam_id);
20762306a36Sopenharmony_ciint prestera_acl_chain_to_client(u32 chain_index, bool ingress, u32 *client);
20862306a36Sopenharmony_ci
20962306a36Sopenharmony_ci#endif /* _PRESTERA_ACL_H_ */
210