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