Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 */
0002 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
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; /* bit array */
0016     unsigned int max_regions;
0017     unsigned long *used_groups;  /* bit array */
0018     unsigned int max_groups;
0019     unsigned int max_group_size;
0020     struct mutex lock; /* guards vregion list */
0021     struct list_head vregion_list;
0022     u32 vregion_rehash_intrvl;   /* ms */
0023     unsigned long priv[];
0024     /* priv has to be always the last item */
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; /* Member of a TCAM group */
0085     enum mlxsw_reg_ptar_key_type key_type;
0086     u16 id; /* ACL ID and region ID - they are same */
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     /* priv has to be always the last item */
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; /* A-TCAM only */
0163     struct list_head entries_list; /* A-TCAM only */
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]; /* Encoded
0175                                  * key.
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; /* Member in entries_list */
0187     struct mlxsw_sp_acl_atcam_entry_ht_key ht_key;
0188     char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key,
0189                                 * minus delta bits.
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