cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

spectrum1_acl_tcam.c (7314B)


      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
     12struct 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
     22struct mlxsw_sp1_acl_tcam_chunk {
     23	struct mlxsw_sp_acl_ctcam_chunk cchunk;
     24};
     25
     26struct mlxsw_sp1_acl_tcam_entry {
     27	struct mlxsw_sp_acl_ctcam_entry centry;
     28};
     29
     30static int
     31mlxsw_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
     38static void
     39mlxsw_sp1_acl_ctcam_region_entry_remove(struct mlxsw_sp_acl_ctcam_region *cregion,
     40					struct mlxsw_sp_acl_ctcam_entry *centry)
     41{
     42}
     43
     44static const struct mlxsw_sp_acl_ctcam_region_ops
     45mlxsw_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
     50static 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
     56static void mlxsw_sp1_acl_tcam_fini(struct mlxsw_sp *mlxsw_sp, void *priv)
     57{
     58}
     59
     60static int
     61mlxsw_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
     90err_entry_add:
     91err_rulei_commit:
     92err_rulei_act_continue:
     93	mlxsw_sp_acl_rulei_destroy(rulei);
     94err_rulei_create:
     95	mlxsw_sp_acl_ctcam_chunk_fini(&region->catchall.cchunk);
     96	return err;
     97}
     98
     99static void
    100mlxsw_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
    112static int
    113mlxsw_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
    132err_catchall_add:
    133	mlxsw_sp_acl_ctcam_region_fini(&region->cregion);
    134	return err;
    135}
    136
    137static void
    138mlxsw_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
    146static int
    147mlxsw_sp1_acl_tcam_region_associate(struct mlxsw_sp *mlxsw_sp,
    148				    struct mlxsw_sp_acl_tcam_region *region)
    149{
    150	return 0;
    151}
    152
    153static 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
    163static 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
    170static 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
    184static 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
    196static int
    197mlxsw_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
    204static int
    205mlxsw_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
    222static int
    223mlxsw_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
    237const 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};