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