linux/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
<<
>>
Prefs
   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
 290int
 291mlxsw_sp_acl_bf_entry_add(struct mlxsw_sp *mlxsw_sp,
 292                          struct mlxsw_sp_acl_bf *bf,
 293                          struct mlxsw_sp_acl_atcam_region *aregion,
 294                          unsigned int erp_bank,
 295                          struct mlxsw_sp_acl_atcam_entry *aentry);
 296void
 297mlxsw_sp_acl_bf_entry_del(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);
 302struct mlxsw_sp_acl_bf *
 303mlxsw_sp_acl_bf_init(struct mlxsw_sp *mlxsw_sp, unsigned int num_erp_banks);
 304void mlxsw_sp_acl_bf_fini(struct mlxsw_sp_acl_bf *bf);
 305
 306#endif
 307