summaryrefslogtreecommitdiff
path: root/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
diff options
context:
space:
mode:
authorIdo Schimmel <idosch@mellanox.com>2018-07-25 09:23:55 +0300
committerDavid S. Miller <davem@davemloft.net>2018-07-25 16:46:01 -0700
commitf465261aa1052bbcb5d1fdba3e9168f2ad86858f (patch)
tree2556ec8d6feb8430a577487815be15767290d79d /drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
parent489142eca9b530219dab77e86c0545e93ebf606a (diff)
mlxsw: spectrum_acl: Implement common eRP core
When rules are inserted into the A-TCAM they are associated with a mask, which is part of the lookup key: { masked key, mask ID, region ID }. These masks are called rule patterns (RP) and the aggregation of several masks into one (to be introduced in follow-up patch sets) is called an extended RP (eRP). When a packet undergoes a lookup in an ACL region it is masked by the current set of eRPs used by the region, looking for an exact match. Eventually, the rule with the highest priority is picked. These eRPs are stored in several global banks to allow for lookup to occur using several eRPs simultaneously. At first, an ACL region will only require a single mask - upon the insertion of the first rule. In this case, the region can use the "master RP" which is composed by OR-ing all the masks used by the region. This mask is a property of the region and thus there is no need to use the above mentioned banks. At some point, a second mask will be needed. In this case, the region will need to allocate an eRP table from the above mentioned banks and insert its masks there. >From now on, upon lookup, the eRP table used by the region will be fetched from the eRP banks - using {eRP bank, Index within the bank} - and the eRPs present in the table will be used to mask the packet. Note that masks with consecutive indexes are inserted into consecutive banks. When rules are deleted and a region only needs a single mask once again it can free its eRP table and use the master RP. The above logic is implemented in the eRP core and represented using the following state machine: +------------+ create mask - as master RP +---------------+ | +--------------------------------> | | no masks | | single mask | | <--------------------------------+ | +------------+ delete mask +-----+--^------+ | | | | create mask - | | delete mask - create mask transition to use eRP | | transition to +--------+ table | | use master RP | | | | | | | | +----v--------+----+ create mask +----v--+-----+ | <-------------------------------+ | | multiple masks | | two masks | | +-------------------------------> | +------------------+ delete mask - if two +-------------+ remaining The code that actually configures rules in the A-TCAM will interface with the eRP core by getting or putting an eRP based on the required mask used by the rule. Signed-off-by: Ido Schimmel <idosch@mellanox.com> Reviewed-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h')
-rw-r--r--drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
index 6403ec4f5267..af21f7c6c6df 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_tcam.h
@@ -92,6 +92,9 @@ mlxsw_sp_acl_tcam_profile_ops(struct mlxsw_sp *mlxsw_sp,
#define MLXSW_SP_ACL_TCAM_CATCHALL_PRIO (~0U)
+#define MLXSW_SP_ACL_TCAM_MASK_LEN \
+ (MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN * BITS_PER_BYTE)
+
struct mlxsw_sp_acl_tcam_group;
struct mlxsw_sp_acl_tcam_region {
@@ -144,9 +147,46 @@ mlxsw_sp_acl_ctcam_entry_offset(struct mlxsw_sp_acl_ctcam_entry *centry)
return centry->parman_item.index;
}
+enum mlxsw_sp_acl_atcam_region_type {
+ MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB,
+ MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB,
+ MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB,
+ MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB,
+ __MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX,
+};
+
+#define MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX \
+ (__MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX - 1)
+
+struct mlxsw_sp_acl_atcam {
+ struct mlxsw_sp_acl_erp_core *erp_core;
+};
+
+struct mlxsw_sp_acl_atcam_region {
+ struct mlxsw_sp_acl_tcam_region *region;
+ struct mlxsw_sp_acl_atcam *atcam;
+ enum mlxsw_sp_acl_atcam_region_type type;
+ struct mlxsw_sp_acl_erp_table *erp_table;
+};
+
int mlxsw_sp_acl_atcam_region_associate(struct mlxsw_sp *mlxsw_sp,
u16 region_id);
int mlxsw_sp_acl_atcam_region_init(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_tcam_region *region);
+struct mlxsw_sp_acl_erp;
+
+u8 mlxsw_sp_acl_erp_id(const struct mlxsw_sp_acl_erp *erp);
+struct mlxsw_sp_acl_erp *
+mlxsw_sp_acl_erp_get(struct mlxsw_sp_acl_atcam_region *aregion,
+ const char *mask);
+void mlxsw_sp_acl_erp_put(struct mlxsw_sp_acl_atcam_region *aregion,
+ struct mlxsw_sp_acl_erp *erp);
+int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion);
+void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion);
+int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_acl_atcam *atcam);
+void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
+ struct mlxsw_sp_acl_atcam *atcam);
+
#endif