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