root/drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mlxsw_sp1_acl_ctcam_region_entry_insert
  2. mlxsw_sp1_acl_ctcam_region_entry_remove
  3. mlxsw_sp1_acl_tcam_init
  4. mlxsw_sp1_acl_tcam_fini
  5. mlxsw_sp1_acl_ctcam_region_catchall_add
  6. mlxsw_sp1_acl_ctcam_region_catchall_del
  7. mlxsw_sp1_acl_tcam_region_init
  8. mlxsw_sp1_acl_tcam_region_fini
  9. mlxsw_sp1_acl_tcam_region_associate
  10. mlxsw_sp1_acl_tcam_chunk_init
  11. mlxsw_sp1_acl_tcam_chunk_fini
  12. mlxsw_sp1_acl_tcam_entry_add
  13. mlxsw_sp1_acl_tcam_entry_del
  14. mlxsw_sp1_acl_tcam_entry_action_replace
  15. mlxsw_sp1_acl_tcam_region_entry_activity_get
  16. mlxsw_sp1_acl_tcam_entry_activity_get

   1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
   2 /* Copyright (c) 2017-2018 Mellanox Technologies. All rights reserved */
   3 
   4 #include <linux/kernel.h>
   5 #include <linux/slab.h>
   6 
   7 #include "reg.h"
   8 #include "core.h"
   9 #include "spectrum.h"
  10 #include "spectrum_acl_tcam.h"
  11 
  12 struct mlxsw_sp1_acl_tcam_region {
  13         struct mlxsw_sp_acl_ctcam_region cregion;
  14         struct mlxsw_sp_acl_tcam_region *region;
  15         struct {
  16                 struct mlxsw_sp_acl_ctcam_chunk cchunk;
  17                 struct mlxsw_sp_acl_ctcam_entry centry;
  18                 struct mlxsw_sp_acl_rule_info *rulei;
  19         } catchall;
  20 };
  21 
  22 struct mlxsw_sp1_acl_tcam_chunk {
  23         struct mlxsw_sp_acl_ctcam_chunk cchunk;
  24 };
  25 
  26 struct mlxsw_sp1_acl_tcam_entry {
  27         struct mlxsw_sp_acl_ctcam_entry centry;
  28 };
  29 
  30 static int
  31 mlxsw_sp1_acl_ctcam_region_entry_insert(struct mlxsw_sp_acl_ctcam_region *cregion,
  32                                         struct mlxsw_sp_acl_ctcam_entry *centry,
  33                                         const char *mask)
  34 {
  35         return 0;
  36 }
  37 
  38 static void
  39 mlxsw_sp1_acl_ctcam_region_entry_remove(struct mlxsw_sp_acl_ctcam_region *cregion,
  40                                         struct mlxsw_sp_acl_ctcam_entry *centry)
  41 {
  42 }
  43 
  44 static const struct mlxsw_sp_acl_ctcam_region_ops
  45 mlxsw_sp1_acl_ctcam_region_ops = {
  46         .entry_insert = mlxsw_sp1_acl_ctcam_region_entry_insert,
  47         .entry_remove = mlxsw_sp1_acl_ctcam_region_entry_remove,
  48 };
  49 
  50 static int mlxsw_sp1_acl_tcam_init(struct mlxsw_sp *mlxsw_sp, void *priv,
  51                                    struct mlxsw_sp_acl_tcam *tcam)
  52 {
  53         return 0;
  54 }
  55 
  56 static void mlxsw_sp1_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp, void *priv)
  57 {
  58 }
  59 
  60 static int
  61 mlxsw_sp1_acl_ctcam_region_catchall_add(struct mlxsw_sp *mlxsw_sp,
  62                                         struct mlxsw_sp1_acl_tcam_region *region)
  63 {
  64         struct mlxsw_sp_acl_rule_info *rulei;
  65         int err;
  66 
  67         mlxsw_sp_acl_ctcam_chunk_init(&region->cregion,
  68                                       &region->catchall.cchunk,
  69                                       MLXSW_SP_ACL_TCAM_CATCHALL_PRIO);
  70         rulei = mlxsw_sp_acl_rulei_create(mlxsw_sp->acl, NULL);
  71         if (IS_ERR(rulei)) {
  72                 err = PTR_ERR(rulei);
  73                 goto err_rulei_create;
  74         }
  75         err = mlxsw_sp_acl_rulei_act_continue(rulei);
  76         if (WARN_ON(err))
  77                 goto err_rulei_act_continue;
  78         err = mlxsw_sp_acl_rulei_commit(rulei);
  79         if (err)
  80                 goto err_rulei_commit;
  81         err = mlxsw_sp_acl_ctcam_entry_add(mlxsw_sp, &region->cregion,
  82                                            &region->catchall.cchunk,
  83                                            &region->catchall.centry,
  84                                            rulei, false);
  85         if (err)
  86                 goto err_entry_add;
  87         region->catchall.rulei = rulei;
  88         return 0;
  89 
  90 err_entry_add:
  91 err_rulei_commit:
  92 err_rulei_act_continue:
  93         mlxsw_sp_acl_rulei_destroy(rulei);
  94 err_rulei_create:
  95         mlxsw_sp_acl_ctcam_chunk_fini(&region->catchall.cchunk);
  96         return err;
  97 }
  98 
  99 static void
 100 mlxsw_sp1_acl_ctcam_region_catchall_del(struct mlxsw_sp *mlxsw_sp,
 101                                         struct mlxsw_sp1_acl_tcam_region *region)
 102 {
 103         struct mlxsw_sp_acl_rule_info *rulei = region->catchall.rulei;
 104 
 105         mlxsw_sp_acl_ctcam_entry_del(mlxsw_sp, &region->cregion,
 106                                      &region->catchall.cchunk,
 107                                      &region->catchall.centry);
 108         mlxsw_sp_acl_rulei_destroy(rulei);
 109         mlxsw_sp_acl_ctcam_chunk_fini(&region->catchall.cchunk);
 110 }
 111 
 112 static int
 113 mlxsw_sp1_acl_tcam_region_init(struct mlxsw_sp *mlxsw_sp, void *region_priv,
 114                                void *tcam_priv,
 115                                struct mlxsw_sp_acl_tcam_region *_region,
 116                                void *hints_priv)
 117 {
 118         struct mlxsw_sp1_acl_tcam_region *region = region_priv;
 119         int err;
 120 
 121         err = mlxsw_sp_acl_ctcam_region_init(mlxsw_sp, &region->cregion,
 122                                              _region,
 123                                              &mlxsw_sp1_acl_ctcam_region_ops);
 124         if (err)
 125                 return err;
 126         err = mlxsw_sp1_acl_ctcam_region_catchall_add(mlxsw_sp, region);
 127         if (err)
 128                 goto err_catchall_add;
 129         region->region = _region;
 130         return 0;
 131 
 132 err_catchall_add:
 133         mlxsw_sp_acl_ctcam_region_fini(&region->cregion);
 134         return err;
 135 }
 136 
 137 static void
 138 mlxsw_sp1_acl_tcam_region_fini(struct mlxsw_sp *mlxsw_sp, void *region_priv)
 139 {
 140         struct mlxsw_sp1_acl_tcam_region *region = region_priv;
 141 
 142         mlxsw_sp1_acl_ctcam_region_catchall_del(mlxsw_sp, region);
 143         mlxsw_sp_acl_ctcam_region_fini(&region->cregion);
 144 }
 145 
 146 static int
 147 mlxsw_sp1_acl_tcam_region_associate(struct mlxsw_sp *mlxsw_sp,
 148                                     struct mlxsw_sp_acl_tcam_region *region)
 149 {
 150         return 0;
 151 }
 152 
 153 static void mlxsw_sp1_acl_tcam_chunk_init(void *region_priv, void *chunk_priv,
 154                                           unsigned int priority)
 155 {
 156         struct mlxsw_sp1_acl_tcam_region *region = region_priv;
 157         struct mlxsw_sp1_acl_tcam_chunk *chunk = chunk_priv;
 158 
 159         mlxsw_sp_acl_ctcam_chunk_init(&region->cregion, &chunk->cchunk,
 160                                       priority);
 161 }
 162 
 163 static void mlxsw_sp1_acl_tcam_chunk_fini(void *chunk_priv)
 164 {
 165         struct mlxsw_sp1_acl_tcam_chunk *chunk = chunk_priv;
 166 
 167         mlxsw_sp_acl_ctcam_chunk_fini(&chunk->cchunk);
 168 }
 169 
 170 static int mlxsw_sp1_acl_tcam_entry_add(struct mlxsw_sp *mlxsw_sp,
 171                                         void *region_priv, void *chunk_priv,
 172                                         void *entry_priv,
 173                                         struct mlxsw_sp_acl_rule_info *rulei)
 174 {
 175         struct mlxsw_sp1_acl_tcam_region *region = region_priv;
 176         struct mlxsw_sp1_acl_tcam_chunk *chunk = chunk_priv;
 177         struct mlxsw_sp1_acl_tcam_entry *entry = entry_priv;
 178 
 179         return mlxsw_sp_acl_ctcam_entry_add(mlxsw_sp, &region->cregion,
 180                                             &chunk->cchunk, &entry->centry,
 181                                             rulei, false);
 182 }
 183 
 184 static void mlxsw_sp1_acl_tcam_entry_del(struct mlxsw_sp *mlxsw_sp,
 185                                          void *region_priv, void *chunk_priv,
 186                                          void *entry_priv)
 187 {
 188         struct mlxsw_sp1_acl_tcam_region *region = region_priv;
 189         struct mlxsw_sp1_acl_tcam_chunk *chunk = chunk_priv;
 190         struct mlxsw_sp1_acl_tcam_entry *entry = entry_priv;
 191 
 192         mlxsw_sp_acl_ctcam_entry_del(mlxsw_sp, &region->cregion,
 193                                      &chunk->cchunk, &entry->centry);
 194 }
 195 
 196 static int
 197 mlxsw_sp1_acl_tcam_entry_action_replace(struct mlxsw_sp *mlxsw_sp,
 198                                         void *region_priv, void *entry_priv,
 199                                         struct mlxsw_sp_acl_rule_info *rulei)
 200 {
 201         return -EOPNOTSUPP;
 202 }
 203 
 204 static int
 205 mlxsw_sp1_acl_tcam_region_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
 206                                              struct mlxsw_sp_acl_tcam_region *_region,
 207                                              unsigned int offset,
 208                                              bool *activity)
 209 {
 210         char ptce2_pl[MLXSW_REG_PTCE2_LEN];
 211         int err;
 212 
 213         mlxsw_reg_ptce2_pack(ptce2_pl, true, MLXSW_REG_PTCE2_OP_QUERY_CLEAR_ON_READ,
 214                              _region->tcam_region_info, offset, 0);
 215         err = mlxsw_reg_query(mlxsw_sp->core, MLXSW_REG(ptce2), ptce2_pl);
 216         if (err)
 217                 return err;
 218         *activity = mlxsw_reg_ptce2_a_get(ptce2_pl);
 219         return 0;
 220 }
 221 
 222 static int
 223 mlxsw_sp1_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
 224                                       void *region_priv, void *entry_priv,
 225                                       bool *activity)
 226 {
 227         struct mlxsw_sp1_acl_tcam_region *region = region_priv;
 228         struct mlxsw_sp1_acl_tcam_entry *entry = entry_priv;
 229         unsigned int offset;
 230 
 231         offset = mlxsw_sp_acl_ctcam_entry_offset(&entry->centry);
 232         return mlxsw_sp1_acl_tcam_region_entry_activity_get(mlxsw_sp,
 233                                                             region->region,
 234                                                             offset, activity);
 235 }
 236 
 237 const struct mlxsw_sp_acl_tcam_ops mlxsw_sp1_acl_tcam_ops = {
 238         .key_type               = MLXSW_REG_PTAR_KEY_TYPE_FLEX,
 239         .priv_size              = 0,
 240         .init                   = mlxsw_sp1_acl_tcam_init,
 241         .fini                   = mlxsw_sp1_acl_tcam_fini,
 242         .region_priv_size       = sizeof(struct mlxsw_sp1_acl_tcam_region),
 243         .region_init            = mlxsw_sp1_acl_tcam_region_init,
 244         .region_fini            = mlxsw_sp1_acl_tcam_region_fini,
 245         .region_associate       = mlxsw_sp1_acl_tcam_region_associate,
 246         .chunk_priv_size        = sizeof(struct mlxsw_sp1_acl_tcam_chunk),
 247         .chunk_init             = mlxsw_sp1_acl_tcam_chunk_init,
 248         .chunk_fini             = mlxsw_sp1_acl_tcam_chunk_fini,
 249         .entry_priv_size        = sizeof(struct mlxsw_sp1_acl_tcam_entry),
 250         .entry_add              = mlxsw_sp1_acl_tcam_entry_add,
 251         .entry_del              = mlxsw_sp1_acl_tcam_entry_del,
 252         .entry_action_replace   = mlxsw_sp1_acl_tcam_entry_action_replace,
 253         .entry_activity_get     = mlxsw_sp1_acl_tcam_entry_activity_get,
 254 };

/* [<][>][^][v][top][bottom][index][help] */