brintos

brintos / linux-shallow public Read only

0
0
Text · 7.2 KiB · dfcdd37 Raw
255 lines · c
1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.02/* 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 int31mlxsw_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 void39mlxsw_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_ops45mlxsw_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 int61mlxsw_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(mlxsw_sp, rulei);94err_rulei_create:95	mlxsw_sp_acl_ctcam_chunk_fini(&region->catchall.cchunk);96	return err;97}98 99static void100mlxsw_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(mlxsw_sp, rulei);109	mlxsw_sp_acl_ctcam_chunk_fini(&region->catchall.cchunk);110}111 112static int113mlxsw_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 void138mlxsw_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 int147mlxsw_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 int197mlxsw_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 int205mlxsw_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 int223mlxsw_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};255