0001
0002
0003
0004 #ifndef _MLXSW_SPECTRUM_ACL_TCAM_H
0005 #define _MLXSW_SPECTRUM_ACL_TCAM_H
0006
0007 #include <linux/list.h>
0008 #include <linux/parman.h>
0009
0010 #include "reg.h"
0011 #include "spectrum.h"
0012 #include "core_acl_flex_keys.h"
0013
0014 struct mlxsw_sp_acl_tcam {
0015 unsigned long *used_regions;
0016 unsigned int max_regions;
0017 unsigned long *used_groups;
0018 unsigned int max_groups;
0019 unsigned int max_group_size;
0020 struct mutex lock;
0021 struct list_head vregion_list;
0022 u32 vregion_rehash_intrvl;
0023 unsigned long priv[];
0024
0025 };
0026
0027 size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp);
0028 int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
0029 struct mlxsw_sp_acl_tcam *tcam);
0030 void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
0031 struct mlxsw_sp_acl_tcam *tcam);
0032 u32 mlxsw_sp_acl_tcam_vregion_rehash_intrvl_get(struct mlxsw_sp *mlxsw_sp,
0033 struct mlxsw_sp_acl_tcam *tcam);
0034 int mlxsw_sp_acl_tcam_vregion_rehash_intrvl_set(struct mlxsw_sp *mlxsw_sp,
0035 struct mlxsw_sp_acl_tcam *tcam,
0036 u32 val);
0037 int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
0038 struct mlxsw_sp_acl_rule_info *rulei,
0039 u32 *priority, bool fillup_priority);
0040
0041 struct mlxsw_sp_acl_profile_ops {
0042 size_t ruleset_priv_size;
0043 int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
0044 struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv,
0045 struct mlxsw_afk_element_usage *tmplt_elusage,
0046 unsigned int *p_min_prio, unsigned int *p_max_prio);
0047 void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv);
0048 int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
0049 struct mlxsw_sp_port *mlxsw_sp_port,
0050 bool ingress);
0051 void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
0052 struct mlxsw_sp_port *mlxsw_sp_port,
0053 bool ingress);
0054 u16 (*ruleset_group_id)(void *ruleset_priv);
0055 size_t rule_priv_size;
0056 int (*rule_add)(struct mlxsw_sp *mlxsw_sp,
0057 void *ruleset_priv, void *rule_priv,
0058 struct mlxsw_sp_acl_rule_info *rulei);
0059 void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv);
0060 int (*rule_action_replace)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
0061 struct mlxsw_sp_acl_rule_info *rulei);
0062 int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
0063 bool *activity);
0064 };
0065
0066 const struct mlxsw_sp_acl_profile_ops *
0067 mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
0068 enum mlxsw_sp_acl_profile profile);
0069
0070 #define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16
0071 #define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16
0072
0073 #define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U)
0074
0075 #define MLXSW_SP_ACL_TCAM_MASK_LEN \
0076 (MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE)
0077
0078 struct mlxsw_sp_acl_tcam_group;
0079 struct mlxsw_sp_acl_tcam_vregion;
0080
0081 struct mlxsw_sp_acl_tcam_region {
0082 struct mlxsw_sp_acl_tcam_vregion *vregion;
0083 struct mlxsw_sp_acl_tcam_group *group;
0084 struct list_head list;
0085 enum mlxsw_reg_ptar_key_type key_type;
0086 u16 id;
0087 char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN];
0088 struct mlxsw_afk_key_info *key_info;
0089 struct mlxsw_sp *mlxsw_sp;
0090 unsigned long priv[];
0091
0092 };
0093
0094 struct mlxsw_sp_acl_ctcam_region {
0095 struct parman *parman;
0096 const struct mlxsw_sp_acl_ctcam_region_ops *ops;
0097 struct mlxsw_sp_acl_tcam_region *region;
0098 };
0099
0100 struct mlxsw_sp_acl_ctcam_chunk {
0101 struct parman_prio parman_prio;
0102 };
0103
0104 struct mlxsw_sp_acl_ctcam_entry {
0105 struct parman_item parman_item;
0106 };
0107
0108 struct mlxsw_sp_acl_ctcam_region_ops {
0109 int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion,
0110 struct mlxsw_sp_acl_ctcam_entry *centry,
0111 const char *mask);
0112 void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion,
0113 struct mlxsw_sp_acl_ctcam_entry *centry);
0114 };
0115
0116 int
0117 mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp,
0118 struct mlxsw_sp_acl_ctcam_region *cregion,
0119 struct mlxsw_sp_acl_tcam_region *region,
0120 const struct mlxsw_sp_acl_ctcam_region_ops *ops);
0121 void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion);
0122 void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion,
0123 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
0124 unsigned int priority);
0125 void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk);
0126 int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
0127 struct mlxsw_sp_acl_ctcam_region *cregion,
0128 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
0129 struct mlxsw_sp_acl_ctcam_entry *centry,
0130 struct mlxsw_sp_acl_rule_info *rulei,
0131 bool fillup_priority);
0132 void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
0133 struct mlxsw_sp_acl_ctcam_region *cregion,
0134 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
0135 struct mlxsw_sp_acl_ctcam_entry *centry);
0136 int mlxsw_sp_acl_ctcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
0137 struct mlxsw_sp_acl_ctcam_region *cregion,
0138 struct mlxsw_sp_acl_ctcam_entry *centry,
0139 struct mlxsw_sp_acl_rule_info *rulei);
0140 static inline unsigned int
0141 mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
0142 {
0143 return centry->parman_item.index;
0144 }
0145
0146 enum mlxsw_sp_acl_atcam_region_type {
0147 MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB,
0148 MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB,
0149 MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB,
0150 MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB,
0151 __MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX,
0152 };
0153
0154 #define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \
0155 (__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1)
0156
0157 struct mlxsw_sp_acl_atcam {
0158 struct mlxsw_sp_acl_erp_core *erp_core;
0159 };
0160
0161 struct mlxsw_sp_acl_atcam_region {
0162 struct rhashtable entries_ht;
0163 struct list_head entries_list;
0164 struct mlxsw_sp_acl_ctcam_region cregion;
0165 const struct mlxsw_sp_acl_atcam_region_ops *ops;
0166 struct mlxsw_sp_acl_tcam_region *region;
0167 struct mlxsw_sp_acl_atcam *atcam;
0168 enum mlxsw_sp_acl_atcam_region_type type;
0169 struct mlxsw_sp_acl_erp_table *erp_table;
0170 void *priv;
0171 };
0172
0173 struct mlxsw_sp_acl_atcam_entry_ht_key {
0174 char full_enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN];
0175
0176
0177 u8 erp_id;
0178 };
0179
0180 struct mlxsw_sp_acl_atcam_chunk {
0181 struct mlxsw_sp_acl_ctcam_chunk cchunk;
0182 };
0183
0184 struct mlxsw_sp_acl_atcam_entry {
0185 struct rhash_head ht_node;
0186 struct list_head list;
0187 struct mlxsw_sp_acl_atcam_entry_ht_key ht_key;
0188 char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN];
0189
0190
0191 struct {
0192 u16 start;
0193 u8 mask;
0194 u8 value;
0195 } delta_info;
0196 struct mlxsw_sp_acl_ctcam_entry centry;
0197 struct mlxsw_sp_acl_atcam_lkey_id *lkey_id;
0198 struct mlxsw_sp_acl_erp_mask *erp_mask;
0199 };
0200
0201 static inline struct mlxsw_sp_acl_atcam_region *
0202 mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion)
0203 {
0204 return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion);
0205 }
0206
0207 static inline struct mlxsw_sp_acl_atcam_entry *
0208 mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry)
0209 {
0210 return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry);
0211 }
0212
0213 int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
0214 u16 region_id);
0215 int
0216 mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
0217 struct mlxsw_sp_acl_atcam *atcam,
0218 struct mlxsw_sp_acl_atcam_region *aregion,
0219 struct mlxsw_sp_acl_tcam_region *region,
0220 void *hints_priv,
0221 const struct mlxsw_sp_acl_ctcam_region_ops *ops);
0222 void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
0223 void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion,
0224 struct mlxsw_sp_acl_atcam_chunk *achunk,
0225 unsigned int priority);
0226 void mlxsw_sp_acl_atcam_chunk_fini(struct mlxsw_sp_acl_atcam_chunk *achunk);
0227 int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
0228 struct mlxsw_sp_acl_atcam_region *aregion,
0229 struct mlxsw_sp_acl_atcam_chunk *achunk,
0230 struct mlxsw_sp_acl_atcam_entry *aentry,
0231 struct mlxsw_sp_acl_rule_info *rulei);
0232 void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
0233 struct mlxsw_sp_acl_atcam_region *aregion,
0234 struct mlxsw_sp_acl_atcam_chunk *achunk,
0235 struct mlxsw_sp_acl_atcam_entry *aentry);
0236 int mlxsw_sp_acl_atcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
0237 struct mlxsw_sp_acl_atcam_region *aregion,
0238 struct mlxsw_sp_acl_atcam_entry *aentry,
0239 struct mlxsw_sp_acl_rule_info *rulei);
0240 int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
0241 struct mlxsw_sp_acl_atcam *atcam);
0242 void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,
0243 struct mlxsw_sp_acl_atcam *atcam);
0244 void *
0245 mlxsw_sp_acl_atcam_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion);
0246 void mlxsw_sp_acl_atcam_rehash_hints_put(void *hints_priv);
0247
0248 struct mlxsw_sp_acl_erp_delta;
0249
0250 u16 mlxsw_sp_acl_erp_delta_start(const struct mlxsw_sp_acl_erp_delta *delta);
0251 u8 mlxsw_sp_acl_erp_delta_mask(const struct mlxsw_sp_acl_erp_delta *delta);
0252 u8 mlxsw_sp_acl_erp_delta_value(const struct mlxsw_sp_acl_erp_delta *delta,
0253 const char *enc_key);
0254 void mlxsw_sp_acl_erp_delta_clear(const struct mlxsw_sp_acl_erp_delta *delta,
0255 const char *enc_key);
0256
0257 struct mlxsw_sp_acl_erp_mask;
0258
0259 bool
0260 mlxsw_sp_acl_erp_mask_is_ctcam(const struct mlxsw_sp_acl_erp_mask *erp_mask);
0261 u8 mlxsw_sp_acl_erp_mask_erp_id(const struct mlxsw_sp_acl_erp_mask *erp_mask);
0262 const struct mlxsw_sp_acl_erp_delta *
0263 mlxsw_sp_acl_erp_delta(const struct mlxsw_sp_acl_erp_mask *erp_mask);
0264 struct mlxsw_sp_acl_erp_mask *
0265 mlxsw_sp_acl_erp_mask_get(struct mlxsw_sp_acl_atcam_region *aregion,
0266 const char *mask, bool ctcam);
0267 void mlxsw_sp_acl_erp_mask_put(struct mlxsw_sp_acl_atcam_region *aregion,
0268 struct mlxsw_sp_acl_erp_mask *erp_mask);
0269 int mlxsw_sp_acl_erp_bf_insert(struct mlxsw_sp *mlxsw_sp,
0270 struct mlxsw_sp_acl_atcam_region *aregion,
0271 struct mlxsw_sp_acl_erp_mask *erp_mask,
0272 struct mlxsw_sp_acl_atcam_entry *aentry);
0273 void mlxsw_sp_acl_erp_bf_remove(struct mlxsw_sp *mlxsw_sp,
0274 struct mlxsw_sp_acl_atcam_region *aregion,
0275 struct mlxsw_sp_acl_erp_mask *erp_mask,
0276 struct mlxsw_sp_acl_atcam_entry *aentry);
0277 void *
0278 mlxsw_sp_acl_erp_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion);
0279 void mlxsw_sp_acl_erp_rehash_hints_put(void *hints_priv);
0280 int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion,
0281 void *hints_priv);
0282 void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
0283 int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
0284 struct mlxsw_sp_acl_atcam *atcam);
0285 void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
0286 struct mlxsw_sp_acl_atcam *atcam);
0287
0288 struct mlxsw_sp_acl_bf;
0289
0290 struct mlxsw_sp_acl_bf_ops {
0291 unsigned int (*index_get)(struct mlxsw_sp_acl_bf *bf,
0292 struct mlxsw_sp_acl_atcam_region *aregion,
0293 struct mlxsw_sp_acl_atcam_entry *aentry);
0294 };
0295
0296 int
0297 mlxsw_sp_acl_bf_entry_add(struct mlxsw_sp *mlxsw_sp,
0298 struct mlxsw_sp_acl_bf *bf,
0299 struct mlxsw_sp_acl_atcam_region *aregion,
0300 unsigned int erp_bank,
0301 struct mlxsw_sp_acl_atcam_entry *aentry);
0302 void
0303 mlxsw_sp_acl_bf_entry_del(struct mlxsw_sp *mlxsw_sp,
0304 struct mlxsw_sp_acl_bf *bf,
0305 struct mlxsw_sp_acl_atcam_region *aregion,
0306 unsigned int erp_bank,
0307 struct mlxsw_sp_acl_atcam_entry *aentry);
0308 struct mlxsw_sp_acl_bf *
0309 mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks);
0310 void mlxsw_sp_acl_bf_fini(struct mlxsw_sp_acl_bf *bf);
0311
0312 #endif