1 /*
2  * drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
3  * Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved.
4  * Copyright (c) 2017-2018 Jiri Pirko <jiri@mellanox.com>
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the names of the copyright holders nor the names of its
15  *    contributors may be used to endorse or promote products derived from
16  *    this software without specific prior written permission.
17  *
18  * Alternatively, this software may be distributed under the terms of the
19  * GNU General Public License ("GPL") version 2 as published by the Free
20  * Software Foundation.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
26  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #ifndef _MLXSW_SPECTRUM_ACL_TCAM_H
36 #define _MLXSW_SPECTRUM_ACL_TCAM_H
37 
38 #include <linux/list.h>
39 #include <linux/parman.h>
40 
41 #include "reg.h"
42 #include "spectrum.h"
43 #include "core_acl_flex_keys.h"
44 
45 struct mlxsw_sp_acl_tcam {
46 	unsigned long *used_regions; /* bit array */
47 	unsigned int max_regions;
48 	unsigned long *used_groups;  /* bit array */
49 	unsigned int max_groups;
50 	unsigned int max_group_size;
51 	unsigned long priv[0];
52 	/* priv has to be always the last item */
53 };
54 
55 size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp);
56 int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
57 			   struct mlxsw_sp_acl_tcam *tcam);
58 void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
59 			    struct mlxsw_sp_acl_tcam *tcam);
60 int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
61 				   struct mlxsw_sp_acl_rule_info *rulei,
62 				   u32 *priority, bool fillup_priority);
63 
64 struct mlxsw_sp_acl_profile_ops {
65 	size_t ruleset_priv_size;
66 	int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
67 			   struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv,
68 			   struct mlxsw_afk_element_usage *tmplt_elusage);
69 	void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv);
70 	int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
71 			    struct mlxsw_sp_port *mlxsw_sp_port,
72 			    bool ingress);
73 	void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
74 			       struct mlxsw_sp_port *mlxsw_sp_port,
75 			       bool ingress);
76 	u16 (*ruleset_group_id)(void *ruleset_priv);
77 	size_t (*rule_priv_size)(struct mlxsw_sp *mlxsw_sp);
78 	int (*rule_add)(struct mlxsw_sp *mlxsw_sp,
79 			void *ruleset_priv, void *rule_priv,
80 			struct mlxsw_sp_acl_rule_info *rulei);
81 	void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv);
82 	int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
83 				 bool *activity);
84 };
85 
86 const struct mlxsw_sp_acl_profile_ops *
87 mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
88 			      enum mlxsw_sp_acl_profile profile);
89 
90 #define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16
91 #define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16
92 
93 #define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U)
94 
95 struct mlxsw_sp_acl_tcam_group;
96 
97 struct mlxsw_sp_acl_tcam_region {
98 	struct list_head list; /* Member of a TCAM group */
99 	struct list_head chunk_list; /* List of chunks under this region */
100 	struct mlxsw_sp_acl_tcam_group *group;
101 	enum mlxsw_reg_ptar_key_type key_type;
102 	u16 id; /* ACL ID and region ID - they are same */
103 	char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN];
104 	struct mlxsw_afk_key_info *key_info;
105 	struct mlxsw_sp *mlxsw_sp;
106 	unsigned long priv[0];
107 	/* priv has to be always the last item */
108 };
109 
110 struct mlxsw_sp_acl_ctcam_region {
111 	struct parman *parman;
112 	struct mlxsw_sp_acl_tcam_region *region;
113 };
114 
115 struct mlxsw_sp_acl_ctcam_chunk {
116 	struct parman_prio parman_prio;
117 };
118 
119 struct mlxsw_sp_acl_ctcam_entry {
120 	struct parman_item parman_item;
121 };
122 
123 int mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp,
124 				   struct mlxsw_sp_acl_ctcam_region *cregion,
125 				   struct mlxsw_sp_acl_tcam_region *region);
126 void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion);
127 void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion,
128 				   struct mlxsw_sp_acl_ctcam_chunk *cchunk,
129 				   unsigned int priority);
130 void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk);
131 int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
132 				 struct mlxsw_sp_acl_ctcam_region *cregion,
133 				 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
134 				 struct mlxsw_sp_acl_ctcam_entry *centry,
135 				 struct mlxsw_sp_acl_rule_info *rulei,
136 				 bool fillup_priority);
137 void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
138 				  struct mlxsw_sp_acl_ctcam_region *cregion,
139 				  struct mlxsw_sp_acl_ctcam_chunk *cchunk,
140 				  struct mlxsw_sp_acl_ctcam_entry *centry);
141 static inline unsigned int
142 mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
143 {
144 	return centry->parman_item.index;
145 }
146 
147 int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
148 					u16 region_id);
149 int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
150 				   struct mlxsw_sp_acl_tcam_region *region);
151 
152 #endif
153