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