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        unsigned long priv[0];
  21        /* priv has to be always the last item */
  22};
  23
  24size_t mlxsw_sp_acl_tcam_priv_size(struct mlxsw_sp *mlxsw_sp);
  25int mlxsw_sp_acl_tcam_init(struct mlxsw_sp *mlxsw_sp,
  26                           struct mlxsw_sp_acl_tcam *tcam);
  27void mlxsw_sp_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp,
  28                            struct mlxsw_sp_acl_tcam *tcam);
  29int mlxsw_sp_acl_tcam_priority_get(struct mlxsw_sp *mlxsw_sp,
  30                                   struct mlxsw_sp_acl_rule_info *rulei,
  31                                   u32 *priority, bool fillup_priority);
  32
  33struct mlxsw_sp_acl_profile_ops {
  34        size_t ruleset_priv_size;
  35        int (*ruleset_add)(struct mlxsw_sp *mlxsw_sp,
  36                           struct mlxsw_sp_acl_tcam *tcam, void *ruleset_priv,
  37                           struct mlxsw_afk_element_usage *tmplt_elusage);
  38        void (*ruleset_del)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv);
  39        int (*ruleset_bind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
  40                            struct mlxsw_sp_port *mlxsw_sp_port,
  41                            bool ingress);
  42        void (*ruleset_unbind)(struct mlxsw_sp *mlxsw_sp, void *ruleset_priv,
  43                               struct mlxsw_sp_port *mlxsw_sp_port,
  44                               bool ingress);
  45        u16 (*ruleset_group_id)(void *ruleset_priv);
  46        size_t (*rule_priv_size)(struct mlxsw_sp *mlxsw_sp);
  47        int (*rule_add)(struct mlxsw_sp *mlxsw_sp,
  48                        void *ruleset_priv, void *rule_priv,
  49                        struct mlxsw_sp_acl_rule_info *rulei);
  50        void (*rule_del)(struct mlxsw_sp *mlxsw_sp, void *rule_priv);
  51        int (*rule_activity_get)(struct mlxsw_sp *mlxsw_sp, void *rule_priv,
  52                                 bool *activity);
  53};
  54
  55const struct mlxsw_sp_acl_profile_ops *
  56mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
  57                              enum mlxsw_sp_acl_profile profile);
  58
  59#define MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT 16
  60#define MLXSW_SP_ACL_TCAM_REGION_RESIZE_STEP 16
  61
  62#define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U)
  63
  64#define MLXSW_SP_ACL_TCAM_MASK_LEN \
  65        (MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE)
  66
  67struct mlxsw_sp_acl_tcam_group;
  68
  69struct mlxsw_sp_acl_tcam_region {
  70        struct list_head list; /* Member of a TCAM group */
  71        struct list_head chunk_list; /* List of chunks under this region */
  72        struct mlxsw_sp_acl_tcam_group *group;
  73        enum mlxsw_reg_ptar_key_type key_type;
  74        u16 id; /* ACL ID and region ID - they are same */
  75        char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN];
  76        struct mlxsw_afk_key_info *key_info;
  77        struct mlxsw_sp *mlxsw_sp;
  78        unsigned long priv[0];
  79        /* priv has to be always the last item */
  80};
  81
  82struct mlxsw_sp_acl_ctcam_region {
  83        struct parman *parman;
  84        const struct mlxsw_sp_acl_ctcam_region_ops *ops;
  85        struct mlxsw_sp_acl_tcam_region *region;
  86};
  87
  88struct mlxsw_sp_acl_ctcam_chunk {
  89        struct parman_prio parman_prio;
  90};
  91
  92struct mlxsw_sp_acl_ctcam_entry {
  93        struct parman_item parman_item;
  94};
  95
  96struct mlxsw_sp_acl_ctcam_region_ops {
  97        int (*entry_insert)(struct mlxsw_sp_acl_ctcam_region *cregion,
  98                            struct mlxsw_sp_acl_ctcam_entry *centry,
  99                            const char *mask);
 100        void (*entry_remove)(struct mlxsw_sp_acl_ctcam_region *cregion,
 101                             struct mlxsw_sp_acl_ctcam_entry *centry);
 102};
 103
 104int
 105mlxsw_sp_acl_ctcam_region_init(struct mlxsw_sp *mlxsw_sp,
 106                               struct mlxsw_sp_acl_ctcam_region *cregion,
 107                               struct mlxsw_sp_acl_tcam_region *region,
 108                               const struct mlxsw_sp_acl_ctcam_region_ops *ops);
 109void mlxsw_sp_acl_ctcam_region_fini(struct mlxsw_sp_acl_ctcam_region *cregion);
 110void mlxsw_sp_acl_ctcam_chunk_init(struct mlxsw_sp_acl_ctcam_region *cregion,
 111                                   struct mlxsw_sp_acl_ctcam_chunk *cchunk,
 112                                   unsigned int priority);
 113void mlxsw_sp_acl_ctcam_chunk_fini(struct mlxsw_sp_acl_ctcam_chunk *cchunk);
 114int mlxsw_sp_acl_ctcam_entry_add(struct mlxsw_sp *mlxsw_sp,
 115                                 struct mlxsw_sp_acl_ctcam_region *cregion,
 116                                 struct mlxsw_sp_acl_ctcam_chunk *cchunk,
 117                                 struct mlxsw_sp_acl_ctcam_entry *centry,
 118                                 struct mlxsw_sp_acl_rule_info *rulei,
 119                                 bool fillup_priority);
 120void mlxsw_sp_acl_ctcam_entry_del(struct mlxsw_sp *mlxsw_sp,
 121                                  struct mlxsw_sp_acl_ctcam_region *cregion,
 122                                  struct mlxsw_sp_acl_ctcam_chunk *cchunk,
 123                                  struct mlxsw_sp_acl_ctcam_entry *centry);
 124static inline unsigned int
 125mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
 126{
 127        return centry->parman_item.index;
 128}
 129
 130enum mlxsw_sp_acl_atcam_region_type {
 131        MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB,
 132        MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB,
 133        MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB,
 134        MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB,
 135        __MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX,
 136};
 137
 138#define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \
 139        (__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1)
 140
 141struct mlxsw_sp_acl_atcam {
 142        struct mlxsw_sp_acl_erp_core *erp_core;
 143};
 144
 145struct mlxsw_sp_acl_atcam_region {
 146        struct rhashtable entries_ht; /* A-TCAM only */
 147        struct mlxsw_sp_acl_ctcam_region cregion;
 148        const struct mlxsw_sp_acl_atcam_region_ops *ops;
 149        struct mlxsw_sp_acl_tcam_region *region;
 150        struct mlxsw_sp_acl_atcam *atcam;
 151        enum mlxsw_sp_acl_atcam_region_type type;
 152        struct mlxsw_sp_acl_erp_table *erp_table;
 153        void *priv;
 154};
 155
 156struct mlxsw_sp_acl_atcam_entry_ht_key {
 157        char enc_key[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN]; /* Encoded key */
 158        u8 erp_id;
 159};
 160
 161struct mlxsw_sp_acl_atcam_chunk {
 162        struct mlxsw_sp_acl_ctcam_chunk cchunk;
 163};
 164
 165struct mlxsw_sp_acl_atcam_entry {
 166        struct rhash_head ht_node;
 167        struct mlxsw_sp_acl_atcam_entry_ht_key ht_key;
 168        struct mlxsw_sp_acl_ctcam_entry centry;
 169        struct mlxsw_sp_acl_atcam_lkey_id *lkey_id;
 170        struct mlxsw_sp_acl_erp *erp;
 171};
 172
 173static inline struct mlxsw_sp_acl_atcam_region *
 174mlxsw_sp_acl_tcam_cregion_aregion(struct mlxsw_sp_acl_ctcam_region *cregion)
 175{
 176        return container_of(cregion, struct mlxsw_sp_acl_atcam_region, cregion);
 177}
 178
 179static inline struct mlxsw_sp_acl_atcam_entry *
 180mlxsw_sp_acl_tcam_centry_aentry(struct mlxsw_sp_acl_ctcam_entry *centry)
 181{
 182        return container_of(centry, struct mlxsw_sp_acl_atcam_entry, centry);
 183}
 184
 185int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
 186                                        u16 region_id);
 187int
 188mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
 189                               struct mlxsw_sp_acl_atcam *atcam,
 190                               struct mlxsw_sp_acl_atcam_region *aregion,
 191                               struct mlxsw_sp_acl_tcam_region *region,
 192                               const struct mlxsw_sp_acl_ctcam_region_ops *ops);
 193void mlxsw_sp_acl_atcam_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
 194void mlxsw_sp_acl_atcam_chunk_init(struct mlxsw_sp_acl_atcam_region *aregion,
 195                                   struct mlxsw_sp_acl_atcam_chunk *achunk,
 196                                   unsigned int priority);
 197void mlxsw_sp_acl_atcam_chunk_fini(struct mlxsw_sp_acl_atcam_chunk *achunk);
 198int mlxsw_sp_acl_atcam_entry_add(struct mlxsw_sp *mlxsw_sp,
 199                                 struct mlxsw_sp_acl_atcam_region *aregion,
 200                                 struct mlxsw_sp_acl_atcam_chunk *achunk,
 201                                 struct mlxsw_sp_acl_atcam_entry *aentry,
 202                                 struct mlxsw_sp_acl_rule_info *rulei);
 203void mlxsw_sp_acl_atcam_entry_del(struct mlxsw_sp *mlxsw_sp,
 204                                  struct mlxsw_sp_acl_atcam_region *aregion,
 205                                  struct mlxsw_sp_acl_atcam_chunk *achunk,
 206                                  struct mlxsw_sp_acl_atcam_entry *aentry);
 207int mlxsw_sp_acl_atcam_init(struct mlxsw_sp *mlxsw_sp,
 208                            struct mlxsw_sp_acl_atcam *atcam);
 209void mlxsw_sp_acl_atcam_fini(struct mlxsw_sp *mlxsw_sp,
 210                             struct mlxsw_sp_acl_atcam *atcam);
 211
 212struct mlxsw_sp_acl_erp;
 213
 214bool mlxsw_sp_acl_erp_is_ctcam_erp(const struct mlxsw_sp_acl_erp *erp);
 215u8 mlxsw_sp_acl_erp_id(const struct mlxsw_sp_acl_erp *erp);
 216struct mlxsw_sp_acl_erp *
 217mlxsw_sp_acl_erp_get(struct mlxsw_sp_acl_atcam_region *aregion,
 218                     const char *mask, bool ctcam);
 219void mlxsw_sp_acl_erp_put(struct mlxsw_sp_acl_atcam_region *aregion,
 220                          struct mlxsw_sp_acl_erp *erp);
 221int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion);
 222void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
 223int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
 224                           struct mlxsw_sp_acl_atcam *atcam);
 225void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
 226                            struct mlxsw_sp_acl_atcam *atcam);
 227
 228#endif
 229