1 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */ 2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */ 3 4 #ifndef _MLXSW_SPECTRUM_ACL_TCAM_H 5 #define _MLXSW_SPECTRUM_ACL_TCAM_H 6 7 #include <linux/list.h> 8 #include <linux/parman.h> 9 10 #include "reg.h" 11 #include "spectrum.h" 12 #include "core_acl_flex_keys.h" 13 14 struct mlxsw_sp_acl_tcam { 15 unsigned long *used_regions; /* bit array */ 16 unsigned int max_regions; 17 unsigned long *used_groups; /* bit array */ 18 unsigned int max_groups; 19 unsigned int max_group_size; 20 struct mutex lock; /* guards vregion list */ 21 struct list_head vregion_list; 22 u32 vregion_rehash_intrvl; /* ms */ 23 unsigned long priv[0]; 24 /* priv has to be always the last item */ 25 }; 26 27 size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp); 28 int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, 29 struct mlxsw_sp_acl_tcam *tcam); 30 void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp, 31 struct mlxsw_sp_acl_tcam *tcam); 32 u32 mlxsw_sp_acl_tcam_vregion_rehash_intrvl_get(struct mlxsw_sp *mlxsw_sp, 33 struct mlxsw_sp_acl_tcam *tcam); 34 int mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp, 35 struct mlxsw_sp_acl_tcam *tcam, 36 u32 val); 37 int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp, 38 struct mlxsw_sp_acl_rule_info *rulei, 39 u32 *priority, bool fillup_priority); 40 41 struct mlxsw_sp_acl_profile_ops { 42 size_t ruleset_priv_size; 43 int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp, 44 struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv, 45 struct mlxsw_afk_element_usage *tmplt_elusage); 46 void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv); 47 int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv, 48 struct mlxsw_sp_port *mlxsw_sp_port, 49 bool ingress); 50 void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv, 51 struct mlxsw_sp_port *mlxsw_sp_port, 52 bool ingress); 53 u16 (*ruleset_group_id)(void *ruleset_priv); 54 size_t rule_priv_size; 55 int (*rule_add)(struct mlxsw_sp *mlxsw_sp, 56 void *ruleset_priv, void *rule_priv, 57 struct mlxsw_sp_acl_rule_info *rulei); 58 void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv); 59 int (*rule_action_replace)(struct mlxsw_sp *mlxsw_sp, void *rule_priv, 60 struct mlxsw_sp_acl_rule_info *rulei); 61 int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv, 62 bool *activity); 63 }; 64 65 const struct mlxsw_sp_acl_profile_ops * 66 mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp, 67 enum mlxsw_sp_acl_profile profile); 68 69 #define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16 70 #define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16 71 72 #define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U) 73 74 #define MLXSW_SP_ACL_TCAM_MASK_LEN \ 75 (MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE) 76 77 struct mlxsw_sp_acl_tcam_group; 78 struct mlxsw_sp_acl_tcam_vregion; 79 80 struct mlxsw_sp_acl_tcam_region { 81 struct mlxsw_sp_acl_tcam_vregion *vregion; 82 struct mlxsw_sp_acl_tcam_group *group; 83 struct list_head list; /* Member of a TCAM group */ 84 enum mlxsw_reg_ptar_key_type key_type; 85 u16 id; /* ACL ID and region ID - they are same */ 86 char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN]; 87 struct mlxsw_afk_key_info *key_info; 88 struct mlxsw_sp *mlxsw_sp; 89 unsigned long priv[0]; 90 /* priv has to be always the last item */ 91 }; 92 93 struct mlxsw_sp_acl_ctcam_region { 94 struct parman *parman; 95 const struct mlxsw_sp_acl_ctcam_region_ops *ops; 96 struct mlxsw_sp_acl_tcam_region *region; 97 }; 98 99 struct mlxsw_sp_acl_ctcam_chunk { 100 struct parman_prio parman_prio; 101 }; 102 103 struct mlxsw_sp_acl_ctcam_entry { 104 struct parman_item parman_item; 105 }; 106 107 struct mlxsw_sp_acl_ctcam_region_ops { 108 int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion, 109 struct mlxsw_sp_acl_ctcam_entry *centry, 110 const char *mask); 111 void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion, 112 struct mlxsw_sp_acl_ctcam_entry *centry); 113 }; 114 115 int 116 mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp, 117 struct mlxsw_sp_acl_ctcam_region *cregion, 118 struct mlxsw_sp_acl_tcam_region *region, 119 const struct mlxsw_sp_acl_ctcam_region_ops *ops); 120 void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion); 121 void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion, 122 struct mlxsw_sp_acl_ctcam_chunk *cchunk, 123 unsigned int priority); 124 void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk); 125 int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp, 126 struct mlxsw_sp_acl_ctcam_region *cregion, 127 struct mlxsw_sp_acl_ctcam_chunk *cchunk, 128 struct mlxsw_sp_acl_ctcam_entry *centry, 129 struct mlxsw_sp_acl_rule_info *rulei, 130 bool fillup_priority); 131 void mlxsw_sp_acl_ctcam_entry_del(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 int mlxsw_sp_acl_ctcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp, 136 struct mlxsw_sp_acl_ctcam_region *cregion, 137 struct mlxsw_sp_acl_ctcam_entry *centry, 138 struct mlxsw_sp_acl_rule_info *rulei); 139 static inline unsigned int 140 mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry) 141 { 142 return centry->parman_item.index; 143 } 144 145 enum mlxsw_sp_acl_atcam_region_type { 146 MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB, 147 MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB, 148 MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB, 149 MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB, 150 __MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX, 151 }; 152 153 #define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \ 154 (__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1) 155 156 struct mlxsw_sp_acl_atcam { 157 struct mlxsw_sp_acl_erp_core *erp_core; 158 }; 159 160 struct mlxsw_sp_acl_atcam_region { 161 struct rhashtable entries_ht; /* A-TCAM only */ 162 struct list_head entries_list; /* A-TCAM only */ 163 struct mlxsw_sp_acl_ctcam_region cregion; 164 const struct mlxsw_sp_acl_atcam_region_ops *ops; 165 struct mlxsw_sp_acl_tcam_region *region; 166 struct mlxsw_sp_acl_atcam *atcam; 167 enum mlxsw_sp_acl_atcam_region_type type; 168 struct mlxsw_sp_acl_erp_table *erp_table; 169 void *priv; 170 }; 171 172 struct mlxsw_sp_acl_atcam_entry_ht_key { 173 char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded 174 * key. 175 */ 176 u8 erp_id; 177 }; 178 179 struct mlxsw_sp_acl_atcam_chunk { 180 struct mlxsw_sp_acl_ctcam_chunk cchunk; 181 }; 182 183 struct mlxsw_sp_acl_atcam_entry { 184 struct rhash_head ht_node; 185 struct list_head list; /* Member in entries_list */ 186 struct mlxsw_sp_acl_atcam_entry_ht_key ht_key; 187 char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key, 188 * minus delta bits. 189 */ 190 struct { 191 u16 start; 192 u8 mask; 193 u8 value; 194 } delta_info; 195 struct mlxsw_sp_acl_ctcam_entry centry; 196 struct mlxsw_sp_acl_atcam_lkey_id *lkey_id; 197 struct mlxsw_sp_acl_erp_mask *erp_mask; 198 }; 199 200 static inline struct mlxsw_sp_acl_atcam_region * 201 mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion) 202 { 203 return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion); 204 } 205 206 static inline struct mlxsw_sp_acl_atcam_entry * 207 mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry) 208 { 209 return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry); 210 } 211 212 int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp, 213 u16 region_id); 214 int 215 mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp, 216 struct mlxsw_sp_acl_atcam *atcam, 217 struct mlxsw_sp_acl_atcam_region *aregion, 218 struct mlxsw_sp_acl_tcam_region *region, 219 void *hints_priv, 220 const struct mlxsw_sp_acl_ctcam_region_ops *ops); 221 void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion); 222 void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion, 223 struct mlxsw_sp_acl_atcam_chunk *achunk, 224 unsigned int priority); 225 void mlxsw_sp_acl_atcam_chunk_fini(struct mlxsw_sp_acl_atcam_chunk *achunk); 226 int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp, 227 struct mlxsw_sp_acl_atcam_region *aregion, 228 struct mlxsw_sp_acl_atcam_chunk *achunk, 229 struct mlxsw_sp_acl_atcam_entry *aentry, 230 struct mlxsw_sp_acl_rule_info *rulei); 231 void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp, 232 struct mlxsw_sp_acl_atcam_region *aregion, 233 struct mlxsw_sp_acl_atcam_chunk *achunk, 234 struct mlxsw_sp_acl_atcam_entry *aentry); 235 int mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp, 236 struct mlxsw_sp_acl_atcam_region *aregion, 237 struct mlxsw_sp_acl_atcam_entry *aentry, 238 struct mlxsw_sp_acl_rule_info *rulei); 239 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp, 240 struct mlxsw_sp_acl_atcam *atcam); 241 void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp, 242 struct mlxsw_sp_acl_atcam *atcam); 243 void * 244 mlxsw_sp_acl_atcam_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion); 245 void mlxsw_sp_acl_atcam_rehash_hints_put(void *hints_priv); 246 247 struct mlxsw_sp_acl_erp_delta; 248 249 u16 mlxsw_sp_acl_erp_delta_start(const struct mlxsw_sp_acl_erp_delta *delta); 250 u8 mlxsw_sp_acl_erp_delta_mask(const struct mlxsw_sp_acl_erp_delta *delta); 251 u8 mlxsw_sp_acl_erp_delta_value(const struct mlxsw_sp_acl_erp_delta *delta, 252 const char *enc_key); 253 void mlxsw_sp_acl_erp_delta_clear(const struct mlxsw_sp_acl_erp_delta *delta, 254 const char *enc_key); 255 256 struct mlxsw_sp_acl_erp_mask; 257 258 bool 259 mlxsw_sp_acl_erp_mask_is_ctcam(const struct mlxsw_sp_acl_erp_mask *erp_mask); 260 u8 mlxsw_sp_acl_erp_mask_erp_id(const struct mlxsw_sp_acl_erp_mask *erp_mask); 261 const struct mlxsw_sp_acl_erp_delta * 262 mlxsw_sp_acl_erp_delta(const struct mlxsw_sp_acl_erp_mask *erp_mask); 263 struct mlxsw_sp_acl_erp_mask * 264 mlxsw_sp_acl_erp_mask_get(struct mlxsw_sp_acl_atcam_region *aregion, 265 const char *mask, bool ctcam); 266 void mlxsw_sp_acl_erp_mask_put(struct mlxsw_sp_acl_atcam_region *aregion, 267 struct mlxsw_sp_acl_erp_mask *erp_mask); 268 int mlxsw_sp_acl_erp_bf_insert(struct mlxsw_sp *mlxsw_sp, 269 struct mlxsw_sp_acl_atcam_region *aregion, 270 struct mlxsw_sp_acl_erp_mask *erp_mask, 271 struct mlxsw_sp_acl_atcam_entry *aentry); 272 void mlxsw_sp_acl_erp_bf_remove(struct mlxsw_sp *mlxsw_sp, 273 struct mlxsw_sp_acl_atcam_region *aregion, 274 struct mlxsw_sp_acl_erp_mask *erp_mask, 275 struct mlxsw_sp_acl_atcam_entry *aentry); 276 void * 277 mlxsw_sp_acl_erp_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion); 278 void mlxsw_sp_acl_erp_rehash_hints_put(void *hints_priv); 279 int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion, 280 void *hints_priv); 281 void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion); 282 int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp, 283 struct mlxsw_sp_acl_atcam *atcam); 284 void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp, 285 struct mlxsw_sp_acl_atcam *atcam); 286 287 struct mlxsw_sp_acl_bf; 288 289 int 290 mlxsw_sp_acl_bf_entry_add(struct mlxsw_sp *mlxsw_sp, 291 struct mlxsw_sp_acl_bf *bf, 292 struct mlxsw_sp_acl_atcam_region *aregion, 293 unsigned int erp_bank, 294 struct mlxsw_sp_acl_atcam_entry *aentry); 295 void 296 mlxsw_sp_acl_bf_entry_del(struct mlxsw_sp *mlxsw_sp, 297 struct mlxsw_sp_acl_bf *bf, 298 struct mlxsw_sp_acl_atcam_region *aregion, 299 unsigned int erp_bank, 300 struct mlxsw_sp_acl_atcam_entry *aentry); 301 struct mlxsw_sp_acl_bf * 302 mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks); 303 void mlxsw_sp_acl_bf_fini(struct mlxsw_sp_acl_bf *bf); 304 305 #endif 306