2018-08-09 11:59:11 +03:00
|
|
|
// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
|
|
|
|
|
/* Copyright (c) 2018 Mellanox Technologies. All rights reserved */
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
|
|
|
|
|
#include <linux/bitmap.h>
|
|
|
|
|
#include <linux/errno.h>
|
|
|
|
|
#include <linux/genalloc.h>
|
|
|
|
|
#include <linux/gfp.h>
|
|
|
|
|
#include <linux/kernel.h>
|
|
|
|
|
#include <linux/list.h>
|
2019-02-24 06:46:28 +00:00
|
|
|
#include <linux/mutex.h>
|
2018-11-14 08:22:29 +00:00
|
|
|
#include <linux/objagg.h>
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
#include <linux/rtnetlink.h>
|
|
|
|
|
#include <linux/slab.h>
|
|
|
|
|
|
|
|
|
|
#include "core.h"
|
|
|
|
|
#include "reg.h"
|
|
|
|
|
#include "spectrum.h"
|
|
|
|
|
#include "spectrum_acl_tcam.h"
|
|
|
|
|
|
|
|
|
|
/* gen_pool_alloc() returns 0 when allocation fails, so use an offset */
|
|
|
|
|
#define MLXSW_SP_ACL_ERP_GENALLOC_OFFSET 0x100
|
|
|
|
|
#define MLXSW_SP_ACL_ERP_MAX_PER_REGION 16
|
|
|
|
|
|
|
|
|
|
struct mlxsw_sp_acl_erp_core {
|
|
|
|
|
unsigned int erpt_entries_size[MLXSW_SP_ACL_ATCAM_REGION_TYPE_MAX + 1];
|
|
|
|
|
struct gen_pool *erp_tables;
|
|
|
|
|
struct mlxsw_sp *mlxsw_sp;
|
2018-12-16 08:49:26 +00:00
|
|
|
struct mlxsw_sp_acl_bf *bf;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
unsigned int num_erp_banks;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct mlxsw_sp_acl_erp_key {
|
|
|
|
|
char mask[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN];
|
2018-11-14 08:22:35 +00:00
|
|
|
#define __MASK_LEN 0x38
|
|
|
|
|
#define __MASK_IDX(i) (__MASK_LEN - (i) - 1)
|
2018-07-25 09:23:57 +03:00
|
|
|
bool ctcam;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct mlxsw_sp_acl_erp {
|
|
|
|
|
struct mlxsw_sp_acl_erp_key key;
|
|
|
|
|
u8 id;
|
|
|
|
|
u8 index;
|
|
|
|
|
DECLARE_BITMAP(mask_bitmap, MLXSW_SP_ACL_TCAM_MASK_LEN);
|
|
|
|
|
struct list_head list;
|
|
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct mlxsw_sp_acl_erp_master_mask {
|
|
|
|
|
DECLARE_BITMAP(bitmap, MLXSW_SP_ACL_TCAM_MASK_LEN);
|
|
|
|
|
unsigned int count[MLXSW_SP_ACL_TCAM_MASK_LEN];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct mlxsw_sp_acl_erp_table {
|
|
|
|
|
struct mlxsw_sp_acl_erp_master_mask master_mask;
|
|
|
|
|
DECLARE_BITMAP(erp_id_bitmap, MLXSW_SP_ACL_ERP_MAX_PER_REGION);
|
|
|
|
|
DECLARE_BITMAP(erp_index_bitmap, MLXSW_SP_ACL_ERP_MAX_PER_REGION);
|
|
|
|
|
struct list_head atcam_erps_list;
|
|
|
|
|
struct mlxsw_sp_acl_erp_core *erp_core;
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion;
|
|
|
|
|
const struct mlxsw_sp_acl_erp_table_ops *ops;
|
|
|
|
|
unsigned long base_index;
|
|
|
|
|
unsigned int num_atcam_erps;
|
|
|
|
|
unsigned int num_max_atcam_erps;
|
2018-07-25 09:23:57 +03:00
|
|
|
unsigned int num_ctcam_erps;
|
2018-11-14 08:22:35 +00:00
|
|
|
unsigned int num_deltas;
|
2018-11-14 08:22:29 +00:00
|
|
|
struct objagg *objagg;
|
2019-02-24 06:46:28 +00:00
|
|
|
struct mutex objagg_lock; /* guards objagg manipulation */
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct mlxsw_sp_acl_erp_table_ops {
|
|
|
|
|
struct mlxsw_sp_acl_erp *
|
|
|
|
|
(*erp_create)(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp_key *key);
|
|
|
|
|
void (*erp_destroy)(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static struct mlxsw_sp_acl_erp *
|
|
|
|
|
mlxsw_sp_acl_erp_mask_create(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp_key *key);
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_mask_destroy(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp);
|
|
|
|
|
static struct mlxsw_sp_acl_erp *
|
|
|
|
|
mlxsw_sp_acl_erp_second_mask_create(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp_key *key);
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_second_mask_destroy(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp);
|
|
|
|
|
static struct mlxsw_sp_acl_erp *
|
|
|
|
|
mlxsw_sp_acl_erp_first_mask_create(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp_key *key);
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_first_mask_destroy(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp);
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_no_mask_destroy(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp);
|
|
|
|
|
|
|
|
|
|
static const struct mlxsw_sp_acl_erp_table_ops erp_multiple_masks_ops = {
|
|
|
|
|
.erp_create = mlxsw_sp_acl_erp_mask_create,
|
|
|
|
|
.erp_destroy = mlxsw_sp_acl_erp_mask_destroy,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const struct mlxsw_sp_acl_erp_table_ops erp_two_masks_ops = {
|
|
|
|
|
.erp_create = mlxsw_sp_acl_erp_mask_create,
|
|
|
|
|
.erp_destroy = mlxsw_sp_acl_erp_second_mask_destroy,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const struct mlxsw_sp_acl_erp_table_ops erp_single_mask_ops = {
|
|
|
|
|
.erp_create = mlxsw_sp_acl_erp_second_mask_create,
|
|
|
|
|
.erp_destroy = mlxsw_sp_acl_erp_first_mask_destroy,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const struct mlxsw_sp_acl_erp_table_ops erp_no_mask_ops = {
|
|
|
|
|
.erp_create = mlxsw_sp_acl_erp_first_mask_create,
|
|
|
|
|
.erp_destroy = mlxsw_sp_acl_erp_no_mask_destroy,
|
|
|
|
|
};
|
|
|
|
|
|
2018-12-16 08:49:29 +00:00
|
|
|
static bool
|
|
|
|
|
mlxsw_sp_acl_erp_table_is_used(const struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
return erp_table->ops != &erp_single_mask_ops &&
|
|
|
|
|
erp_table->ops != &erp_no_mask_ops;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static unsigned int
|
|
|
|
|
mlxsw_sp_acl_erp_bank_get(const struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
return erp->index % erp->erp_table->erp_core->num_erp_banks;
|
|
|
|
|
}
|
|
|
|
|
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
static unsigned int
|
|
|
|
|
mlxsw_sp_acl_erp_table_entry_size(const struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion = erp_table->aregion;
|
|
|
|
|
struct mlxsw_sp_acl_erp_core *erp_core = erp_table->erp_core;
|
|
|
|
|
|
|
|
|
|
return erp_core->erpt_entries_size[aregion->type];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mlxsw_sp_acl_erp_id_get(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
u8 *p_id)
|
|
|
|
|
{
|
|
|
|
|
u8 id;
|
|
|
|
|
|
|
|
|
|
id = find_first_zero_bit(erp_table->erp_id_bitmap,
|
|
|
|
|
MLXSW_SP_ACL_ERP_MAX_PER_REGION);
|
|
|
|
|
if (id < MLXSW_SP_ACL_ERP_MAX_PER_REGION) {
|
|
|
|
|
__set_bit(id, erp_table->erp_id_bitmap);
|
|
|
|
|
*p_id = id;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -ENOBUFS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mlxsw_sp_acl_erp_id_put(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
u8 id)
|
|
|
|
|
{
|
|
|
|
|
__clear_bit(id, erp_table->erp_id_bitmap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_master_mask_bit_set(unsigned long bit,
|
|
|
|
|
struct mlxsw_sp_acl_erp_master_mask *mask)
|
|
|
|
|
{
|
|
|
|
|
if (mask->count[bit]++ == 0)
|
|
|
|
|
__set_bit(bit, mask->bitmap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_master_mask_bit_clear(unsigned long bit,
|
|
|
|
|
struct mlxsw_sp_acl_erp_master_mask *mask)
|
|
|
|
|
{
|
|
|
|
|
if (--mask->count[bit] == 0)
|
|
|
|
|
__clear_bit(bit, mask->bitmap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_master_mask_update(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_tcam_region *region = erp_table->aregion->region;
|
|
|
|
|
struct mlxsw_sp *mlxsw_sp = region->mlxsw_sp;
|
|
|
|
|
char percr_pl[MLXSW_REG_PERCR_LEN];
|
|
|
|
|
char *master_mask;
|
|
|
|
|
|
|
|
|
|
mlxsw_reg_percr_pack(percr_pl, region->id);
|
|
|
|
|
master_mask = mlxsw_reg_percr_master_mask_data(percr_pl);
|
|
|
|
|
bitmap_to_arr32((u32 *) master_mask, erp_table->master_mask.bitmap,
|
|
|
|
|
MLXSW_SP_ACL_TCAM_MASK_LEN);
|
|
|
|
|
|
|
|
|
|
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(percr), percr_pl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_master_mask_set(struct mlxsw_sp_acl_erp_table *erp_table,
|
2018-11-14 08:22:30 +00:00
|
|
|
struct mlxsw_sp_acl_erp_key *key)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
{
|
2018-11-14 08:22:30 +00:00
|
|
|
DECLARE_BITMAP(mask_bitmap, MLXSW_SP_ACL_TCAM_MASK_LEN);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
unsigned long bit;
|
|
|
|
|
int err;
|
|
|
|
|
|
2018-11-14 08:22:30 +00:00
|
|
|
bitmap_from_arr32(mask_bitmap, (u32 *) key->mask,
|
|
|
|
|
MLXSW_SP_ACL_TCAM_MASK_LEN);
|
|
|
|
|
for_each_set_bit(bit, mask_bitmap, MLXSW_SP_ACL_TCAM_MASK_LEN)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
mlxsw_sp_acl_erp_master_mask_bit_set(bit,
|
|
|
|
|
&erp_table->master_mask);
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_master_mask_update(erp_table);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_master_mask_update;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_master_mask_update:
|
2018-11-14 08:22:30 +00:00
|
|
|
for_each_set_bit(bit, mask_bitmap, MLXSW_SP_ACL_TCAM_MASK_LEN)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
mlxsw_sp_acl_erp_master_mask_bit_clear(bit,
|
|
|
|
|
&erp_table->master_mask);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_master_mask_clear(struct mlxsw_sp_acl_erp_table *erp_table,
|
2018-11-14 08:22:30 +00:00
|
|
|
struct mlxsw_sp_acl_erp_key *key)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
{
|
2018-11-14 08:22:30 +00:00
|
|
|
DECLARE_BITMAP(mask_bitmap, MLXSW_SP_ACL_TCAM_MASK_LEN);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
unsigned long bit;
|
|
|
|
|
int err;
|
|
|
|
|
|
2018-11-14 08:22:30 +00:00
|
|
|
bitmap_from_arr32(mask_bitmap, (u32 *) key->mask,
|
|
|
|
|
MLXSW_SP_ACL_TCAM_MASK_LEN);
|
|
|
|
|
for_each_set_bit(bit, mask_bitmap, MLXSW_SP_ACL_TCAM_MASK_LEN)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
mlxsw_sp_acl_erp_master_mask_bit_clear(bit,
|
|
|
|
|
&erp_table->master_mask);
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_master_mask_update(erp_table);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_master_mask_update;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_master_mask_update:
|
2018-11-14 08:22:30 +00:00
|
|
|
for_each_set_bit(bit, mask_bitmap, MLXSW_SP_ACL_TCAM_MASK_LEN)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
mlxsw_sp_acl_erp_master_mask_bit_set(bit,
|
|
|
|
|
&erp_table->master_mask);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct mlxsw_sp_acl_erp *
|
|
|
|
|
mlxsw_sp_acl_erp_generic_create(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp_key *key)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
erp = kzalloc(sizeof(*erp), GFP_KERNEL);
|
|
|
|
|
if (!erp)
|
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_id_get(erp_table, &erp->id);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_erp_id_get;
|
|
|
|
|
|
|
|
|
|
memcpy(&erp->key, key, sizeof(*key));
|
|
|
|
|
list_add(&erp->list, &erp_table->atcam_erps_list);
|
|
|
|
|
erp_table->num_atcam_erps++;
|
|
|
|
|
erp->erp_table = erp_table;
|
|
|
|
|
|
2018-11-14 08:22:30 +00:00
|
|
|
err = mlxsw_sp_acl_erp_master_mask_set(erp_table, &erp->key);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
if (err)
|
|
|
|
|
goto err_master_mask_set;
|
|
|
|
|
|
|
|
|
|
return erp;
|
|
|
|
|
|
|
|
|
|
err_master_mask_set:
|
|
|
|
|
erp_table->num_atcam_erps--;
|
|
|
|
|
list_del(&erp->list);
|
|
|
|
|
mlxsw_sp_acl_erp_id_put(erp_table, erp->id);
|
|
|
|
|
err_erp_id_get:
|
|
|
|
|
kfree(erp);
|
|
|
|
|
return ERR_PTR(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_generic_destroy(struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = erp->erp_table;
|
|
|
|
|
|
2018-11-14 08:22:30 +00:00
|
|
|
mlxsw_sp_acl_erp_master_mask_clear(erp_table, &erp->key);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
erp_table->num_atcam_erps--;
|
|
|
|
|
list_del(&erp->list);
|
|
|
|
|
mlxsw_sp_acl_erp_id_put(erp_table, erp->id);
|
|
|
|
|
kfree(erp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_table_alloc(struct mlxsw_sp_acl_erp_core *erp_core,
|
|
|
|
|
unsigned int num_erps,
|
|
|
|
|
enum mlxsw_sp_acl_atcam_region_type region_type,
|
|
|
|
|
unsigned long *p_index)
|
|
|
|
|
{
|
|
|
|
|
unsigned int num_rows, entry_size;
|
|
|
|
|
|
|
|
|
|
/* We only allow allocations of entire rows */
|
|
|
|
|
if (num_erps % erp_core->num_erp_banks != 0)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
entry_size = erp_core->erpt_entries_size[region_type];
|
|
|
|
|
num_rows = num_erps / erp_core->num_erp_banks;
|
|
|
|
|
|
|
|
|
|
*p_index = gen_pool_alloc(erp_core->erp_tables, num_rows * entry_size);
|
|
|
|
|
if (*p_index == 0)
|
|
|
|
|
return -ENOBUFS;
|
|
|
|
|
*p_index -= MLXSW_SP_ACL_ERP_GENALLOC_OFFSET;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_table_free(struct mlxsw_sp_acl_erp_core *erp_core,
|
|
|
|
|
unsigned int num_erps,
|
|
|
|
|
enum mlxsw_sp_acl_atcam_region_type region_type,
|
|
|
|
|
unsigned long index)
|
|
|
|
|
{
|
|
|
|
|
unsigned long base_index;
|
|
|
|
|
unsigned int entry_size;
|
|
|
|
|
size_t size;
|
|
|
|
|
|
|
|
|
|
entry_size = erp_core->erpt_entries_size[region_type];
|
|
|
|
|
base_index = index + MLXSW_SP_ACL_ERP_GENALLOC_OFFSET;
|
|
|
|
|
size = num_erps / erp_core->num_erp_banks * entry_size;
|
|
|
|
|
gen_pool_free(erp_core->erp_tables, base_index, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct mlxsw_sp_acl_erp *
|
|
|
|
|
mlxsw_sp_acl_erp_table_master_rp(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
if (!list_is_singular(&erp_table->atcam_erps_list))
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
return list_first_entry(&erp_table->atcam_erps_list,
|
|
|
|
|
struct mlxsw_sp_acl_erp, list);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mlxsw_sp_acl_erp_index_get(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
u8 *p_index)
|
|
|
|
|
{
|
|
|
|
|
u8 index;
|
|
|
|
|
|
|
|
|
|
index = find_first_zero_bit(erp_table->erp_index_bitmap,
|
|
|
|
|
erp_table->num_max_atcam_erps);
|
|
|
|
|
if (index < erp_table->num_max_atcam_erps) {
|
|
|
|
|
__set_bit(index, erp_table->erp_index_bitmap);
|
|
|
|
|
*p_index = index;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -ENOBUFS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mlxsw_sp_acl_erp_index_put(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
u8 index)
|
|
|
|
|
{
|
|
|
|
|
__clear_bit(index, erp_table->erp_index_bitmap);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_table_locate(const struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
const struct mlxsw_sp_acl_erp *erp,
|
|
|
|
|
u8 *p_erpt_bank, u8 *p_erpt_index)
|
|
|
|
|
{
|
|
|
|
|
unsigned int entry_size = mlxsw_sp_acl_erp_table_entry_size(erp_table);
|
|
|
|
|
struct mlxsw_sp_acl_erp_core *erp_core = erp_table->erp_core;
|
|
|
|
|
unsigned int row;
|
|
|
|
|
|
|
|
|
|
*p_erpt_bank = erp->index % erp_core->num_erp_banks;
|
|
|
|
|
row = erp->index / erp_core->num_erp_banks;
|
|
|
|
|
*p_erpt_index = erp_table->base_index + row * entry_size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_table_erp_add(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp *mlxsw_sp = erp_table->erp_core->mlxsw_sp;
|
|
|
|
|
enum mlxsw_reg_perpt_key_size key_size;
|
|
|
|
|
char perpt_pl[MLXSW_REG_PERPT_LEN];
|
|
|
|
|
u8 erpt_bank, erpt_index;
|
|
|
|
|
|
|
|
|
|
mlxsw_sp_acl_erp_table_locate(erp_table, erp, &erpt_bank, &erpt_index);
|
|
|
|
|
key_size = (enum mlxsw_reg_perpt_key_size) erp_table->aregion->type;
|
|
|
|
|
mlxsw_reg_perpt_pack(perpt_pl, erpt_bank, erpt_index, key_size, erp->id,
|
|
|
|
|
0, erp_table->base_index, erp->index,
|
|
|
|
|
erp->key.mask);
|
|
|
|
|
mlxsw_reg_perpt_erp_vector_pack(perpt_pl, erp_table->erp_index_bitmap,
|
|
|
|
|
MLXSW_SP_ACL_ERP_MAX_PER_REGION);
|
|
|
|
|
mlxsw_reg_perpt_erp_vector_set(perpt_pl, erp->index, true);
|
|
|
|
|
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(perpt), perpt_pl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mlxsw_sp_acl_erp_table_erp_del(struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
char empty_mask[MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN] = { 0 };
|
|
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = erp->erp_table;
|
|
|
|
|
struct mlxsw_sp *mlxsw_sp = erp_table->erp_core->mlxsw_sp;
|
|
|
|
|
enum mlxsw_reg_perpt_key_size key_size;
|
|
|
|
|
char perpt_pl[MLXSW_REG_PERPT_LEN];
|
|
|
|
|
u8 erpt_bank, erpt_index;
|
|
|
|
|
|
|
|
|
|
mlxsw_sp_acl_erp_table_locate(erp_table, erp, &erpt_bank, &erpt_index);
|
|
|
|
|
key_size = (enum mlxsw_reg_perpt_key_size) erp_table->aregion->type;
|
|
|
|
|
mlxsw_reg_perpt_pack(perpt_pl, erpt_bank, erpt_index, key_size, erp->id,
|
|
|
|
|
0, erp_table->base_index, erp->index, empty_mask);
|
|
|
|
|
mlxsw_reg_perpt_erp_vector_pack(perpt_pl, erp_table->erp_index_bitmap,
|
|
|
|
|
MLXSW_SP_ACL_ERP_MAX_PER_REGION);
|
|
|
|
|
mlxsw_reg_perpt_erp_vector_set(perpt_pl, erp->index, false);
|
|
|
|
|
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(perpt), perpt_pl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
2018-07-25 09:23:57 +03:00
|
|
|
mlxsw_sp_acl_erp_table_enable(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
bool ctcam_le)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_tcam_region *region = erp_table->aregion->region;
|
|
|
|
|
struct mlxsw_sp *mlxsw_sp = erp_table->erp_core->mlxsw_sp;
|
|
|
|
|
char pererp_pl[MLXSW_REG_PERERP_LEN];
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
mlxsw_reg_pererp_pack(pererp_pl, region->id, ctcam_le, true, 0,
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
erp_table->base_index, 0);
|
|
|
|
|
mlxsw_reg_pererp_erp_vector_pack(pererp_pl, erp_table->erp_index_bitmap,
|
|
|
|
|
MLXSW_SP_ACL_ERP_MAX_PER_REGION);
|
|
|
|
|
|
|
|
|
|
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pererp), pererp_pl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_table_disable(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_tcam_region *region = erp_table->aregion->region;
|
|
|
|
|
struct mlxsw_sp *mlxsw_sp = erp_table->erp_core->mlxsw_sp;
|
|
|
|
|
char pererp_pl[MLXSW_REG_PERERP_LEN];
|
|
|
|
|
struct mlxsw_sp_acl_erp *master_rp;
|
|
|
|
|
|
|
|
|
|
master_rp = mlxsw_sp_acl_erp_table_master_rp(erp_table);
|
2018-07-25 09:23:57 +03:00
|
|
|
/* It is possible we do not have a master RP when we disable the
|
|
|
|
|
* table when there are no rules in the A-TCAM and the last C-TCAM
|
|
|
|
|
* rule is deleted
|
|
|
|
|
*/
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
mlxsw_reg_pererp_pack(pererp_pl, region->id, false, false, 0, 0,
|
2018-07-25 09:23:57 +03:00
|
|
|
master_rp ? master_rp->id : 0);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pererp), pererp_pl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_table_relocate(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
list_for_each_entry(erp, &erp_table->atcam_erps_list, list) {
|
|
|
|
|
err = mlxsw_sp_acl_erp_table_erp_add(erp_table, erp);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_table_erp_add;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_table_erp_add:
|
|
|
|
|
list_for_each_entry_continue_reverse(erp, &erp_table->atcam_erps_list,
|
|
|
|
|
list)
|
|
|
|
|
mlxsw_sp_acl_erp_table_erp_del(erp);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_table_expand(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
unsigned int num_erps, old_num_erps = erp_table->num_max_atcam_erps;
|
|
|
|
|
struct mlxsw_sp_acl_erp_core *erp_core = erp_table->erp_core;
|
|
|
|
|
unsigned long old_base_index = erp_table->base_index;
|
2018-07-25 09:23:57 +03:00
|
|
|
bool ctcam_le = erp_table->num_ctcam_erps > 0;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
if (erp_table->num_atcam_erps < erp_table->num_max_atcam_erps)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (erp_table->num_max_atcam_erps == MLXSW_SP_ACL_ERP_MAX_PER_REGION)
|
|
|
|
|
return -ENOBUFS;
|
|
|
|
|
|
|
|
|
|
num_erps = old_num_erps + erp_core->num_erp_banks;
|
|
|
|
|
err = mlxsw_sp_acl_erp_table_alloc(erp_core, num_erps,
|
|
|
|
|
erp_table->aregion->type,
|
|
|
|
|
&erp_table->base_index);
|
|
|
|
|
if (err)
|
|
|
|
|
return err;
|
|
|
|
|
erp_table->num_max_atcam_erps = num_erps;
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_table_relocate(erp_table);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_table_relocate;
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
err = mlxsw_sp_acl_erp_table_enable(erp_table, ctcam_le);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
if (err)
|
|
|
|
|
goto err_table_enable;
|
|
|
|
|
|
|
|
|
|
mlxsw_sp_acl_erp_table_free(erp_core, old_num_erps,
|
|
|
|
|
erp_table->aregion->type, old_base_index);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_table_enable:
|
|
|
|
|
err_table_relocate:
|
|
|
|
|
erp_table->num_max_atcam_erps = old_num_erps;
|
|
|
|
|
mlxsw_sp_acl_erp_table_free(erp_core, num_erps,
|
|
|
|
|
erp_table->aregion->type,
|
|
|
|
|
erp_table->base_index);
|
|
|
|
|
erp_table->base_index = old_base_index;
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-16 08:49:32 +00:00
|
|
|
static int
|
|
|
|
|
mlxsw_acl_erp_table_bf_add(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion = erp_table->aregion;
|
|
|
|
|
unsigned int erp_bank = mlxsw_sp_acl_erp_bank_get(erp);
|
|
|
|
|
struct mlxsw_sp_acl_atcam_entry *aentry;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
list_for_each_entry(aentry, &aregion->entries_list, list) {
|
|
|
|
|
err = mlxsw_sp_acl_bf_entry_add(aregion->region->mlxsw_sp,
|
|
|
|
|
erp_table->erp_core->bf,
|
|
|
|
|
aregion, erp_bank, aentry);
|
|
|
|
|
if (err)
|
|
|
|
|
goto bf_entry_add_err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
bf_entry_add_err:
|
|
|
|
|
list_for_each_entry_continue_reverse(aentry, &aregion->entries_list,
|
|
|
|
|
list)
|
|
|
|
|
mlxsw_sp_acl_bf_entry_del(aregion->region->mlxsw_sp,
|
|
|
|
|
erp_table->erp_core->bf,
|
|
|
|
|
aregion, erp_bank, aentry);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_acl_erp_table_bf_del(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion = erp_table->aregion;
|
|
|
|
|
unsigned int erp_bank = mlxsw_sp_acl_erp_bank_get(erp);
|
|
|
|
|
struct mlxsw_sp_acl_atcam_entry *aentry;
|
|
|
|
|
|
|
|
|
|
list_for_each_entry_reverse(aentry, &aregion->entries_list, list)
|
|
|
|
|
mlxsw_sp_acl_bf_entry_del(aregion->region->mlxsw_sp,
|
|
|
|
|
erp_table->erp_core->bf,
|
|
|
|
|
aregion, erp_bank, aentry);
|
|
|
|
|
}
|
|
|
|
|
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_region_table_trans(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp_core *erp_core = erp_table->erp_core;
|
|
|
|
|
struct mlxsw_sp_acl_erp *master_rp;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
/* Initially, allocate a single eRP row. Expand later as needed */
|
|
|
|
|
err = mlxsw_sp_acl_erp_table_alloc(erp_core, erp_core->num_erp_banks,
|
|
|
|
|
erp_table->aregion->type,
|
|
|
|
|
&erp_table->base_index);
|
|
|
|
|
if (err)
|
|
|
|
|
return err;
|
|
|
|
|
erp_table->num_max_atcam_erps = erp_core->num_erp_banks;
|
|
|
|
|
|
|
|
|
|
/* Transition the sole RP currently configured (the master RP)
|
|
|
|
|
* to the eRP table
|
|
|
|
|
*/
|
|
|
|
|
master_rp = mlxsw_sp_acl_erp_table_master_rp(erp_table);
|
|
|
|
|
if (!master_rp) {
|
|
|
|
|
err = -EINVAL;
|
|
|
|
|
goto err_table_master_rp;
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-16 08:49:33 +00:00
|
|
|
/* Make sure the master RP is using a valid index, as
|
|
|
|
|
* only a single eRP row is currently allocated.
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
*/
|
2018-12-16 08:49:33 +00:00
|
|
|
master_rp->index = 0;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
__set_bit(master_rp->index, erp_table->erp_index_bitmap);
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_table_erp_add(erp_table, master_rp);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_table_master_rp_add;
|
|
|
|
|
|
2018-12-16 08:49:32 +00:00
|
|
|
/* Update Bloom filter before enabling eRP table, as rules
|
|
|
|
|
* on the master RP were not set to Bloom filter up to this
|
|
|
|
|
* point.
|
|
|
|
|
*/
|
|
|
|
|
err = mlxsw_acl_erp_table_bf_add(erp_table, master_rp);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_table_bf_add;
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
err = mlxsw_sp_acl_erp_table_enable(erp_table, false);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
if (err)
|
|
|
|
|
goto err_table_enable;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_table_enable:
|
2018-12-16 08:49:32 +00:00
|
|
|
mlxsw_acl_erp_table_bf_del(erp_table, master_rp);
|
|
|
|
|
err_table_bf_add:
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
mlxsw_sp_acl_erp_table_erp_del(master_rp);
|
|
|
|
|
err_table_master_rp_add:
|
|
|
|
|
__clear_bit(master_rp->index, erp_table->erp_index_bitmap);
|
|
|
|
|
err_table_master_rp:
|
|
|
|
|
mlxsw_sp_acl_erp_table_free(erp_core, erp_table->num_max_atcam_erps,
|
|
|
|
|
erp_table->aregion->type,
|
|
|
|
|
erp_table->base_index);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_region_master_mask_trans(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp_core *erp_core = erp_table->erp_core;
|
|
|
|
|
struct mlxsw_sp_acl_erp *master_rp;
|
|
|
|
|
|
|
|
|
|
mlxsw_sp_acl_erp_table_disable(erp_table);
|
|
|
|
|
master_rp = mlxsw_sp_acl_erp_table_master_rp(erp_table);
|
|
|
|
|
if (!master_rp)
|
|
|
|
|
return;
|
2018-12-16 08:49:32 +00:00
|
|
|
mlxsw_acl_erp_table_bf_del(erp_table, master_rp);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
mlxsw_sp_acl_erp_table_erp_del(master_rp);
|
|
|
|
|
__clear_bit(master_rp->index, erp_table->erp_index_bitmap);
|
|
|
|
|
mlxsw_sp_acl_erp_table_free(erp_core, erp_table->num_max_atcam_erps,
|
|
|
|
|
erp_table->aregion->type,
|
|
|
|
|
erp_table->base_index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_region_erp_add(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_tcam_region *region = erp_table->aregion->region;
|
|
|
|
|
struct mlxsw_sp *mlxsw_sp = erp_table->erp_core->mlxsw_sp;
|
2018-07-25 09:23:57 +03:00
|
|
|
bool ctcam_le = erp_table->num_ctcam_erps > 0;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
char pererp_pl[MLXSW_REG_PERERP_LEN];
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
mlxsw_reg_pererp_pack(pererp_pl, region->id, ctcam_le, true, 0,
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
erp_table->base_index, 0);
|
|
|
|
|
mlxsw_reg_pererp_erp_vector_pack(pererp_pl, erp_table->erp_index_bitmap,
|
|
|
|
|
MLXSW_SP_ACL_ERP_MAX_PER_REGION);
|
|
|
|
|
mlxsw_reg_pererp_erpt_vector_set(pererp_pl, erp->index, true);
|
|
|
|
|
|
|
|
|
|
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pererp), pererp_pl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mlxsw_sp_acl_erp_region_erp_del(struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = erp->erp_table;
|
|
|
|
|
struct mlxsw_sp_acl_tcam_region *region = erp_table->aregion->region;
|
|
|
|
|
struct mlxsw_sp *mlxsw_sp = erp_table->erp_core->mlxsw_sp;
|
2018-07-25 09:23:57 +03:00
|
|
|
bool ctcam_le = erp_table->num_ctcam_erps > 0;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
char pererp_pl[MLXSW_REG_PERERP_LEN];
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
mlxsw_reg_pererp_pack(pererp_pl, region->id, ctcam_le, true, 0,
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
erp_table->base_index, 0);
|
|
|
|
|
mlxsw_reg_pererp_erp_vector_pack(pererp_pl, erp_table->erp_index_bitmap,
|
|
|
|
|
MLXSW_SP_ACL_ERP_MAX_PER_REGION);
|
|
|
|
|
mlxsw_reg_pererp_erpt_vector_set(pererp_pl, erp->index, false);
|
|
|
|
|
|
|
|
|
|
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pererp), pererp_pl);
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_region_ctcam_enable(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
/* No need to re-enable lookup in the C-TCAM */
|
|
|
|
|
if (erp_table->num_ctcam_erps > 1)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return mlxsw_sp_acl_erp_table_enable(erp_table, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_region_ctcam_disable(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
/* Only disable C-TCAM lookup when last C-TCAM eRP is deleted */
|
|
|
|
|
if (erp_table->num_ctcam_erps > 1)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
mlxsw_sp_acl_erp_table_enable(erp_table, false);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-14 08:22:34 +00:00
|
|
|
static int
|
|
|
|
|
__mlxsw_sp_acl_erp_table_other_inc(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
unsigned int *inc_num)
|
|
|
|
|
{
|
|
|
|
|
int err;
|
|
|
|
|
|
2018-11-14 08:22:35 +00:00
|
|
|
/* If there are C-TCAM eRP or deltas in use we need to transition
|
2018-11-14 08:22:34 +00:00
|
|
|
* the region to use eRP table, if it is not already done
|
|
|
|
|
*/
|
2018-12-16 08:49:29 +00:00
|
|
|
if (!mlxsw_sp_acl_erp_table_is_used(erp_table)) {
|
2018-11-14 08:22:34 +00:00
|
|
|
err = mlxsw_sp_acl_erp_region_table_trans(erp_table);
|
|
|
|
|
if (err)
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-14 08:22:35 +00:00
|
|
|
/* When C-TCAM or deltas are used, the eRP table must be used */
|
2018-11-14 08:22:34 +00:00
|
|
|
if (erp_table->ops != &erp_multiple_masks_ops)
|
|
|
|
|
erp_table->ops = &erp_multiple_masks_ops;
|
|
|
|
|
|
|
|
|
|
(*inc_num)++;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mlxsw_sp_acl_erp_ctcam_inc(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
return __mlxsw_sp_acl_erp_table_other_inc(erp_table,
|
|
|
|
|
&erp_table->num_ctcam_erps);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-14 08:22:35 +00:00
|
|
|
static int mlxsw_sp_acl_erp_delta_inc(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
return __mlxsw_sp_acl_erp_table_other_inc(erp_table,
|
|
|
|
|
&erp_table->num_deltas);
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
static void
|
2018-11-14 08:22:34 +00:00
|
|
|
__mlxsw_sp_acl_erp_table_other_dec(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
unsigned int *dec_num)
|
2018-07-25 09:23:57 +03:00
|
|
|
{
|
2018-11-14 08:22:34 +00:00
|
|
|
(*dec_num)--;
|
|
|
|
|
|
2018-11-14 08:22:35 +00:00
|
|
|
/* If there are no C-TCAM eRP or deltas in use, the state we
|
2018-11-14 08:22:34 +00:00
|
|
|
* transition to depends on the number of A-TCAM eRPs currently
|
|
|
|
|
* in use.
|
|
|
|
|
*/
|
2018-11-14 08:22:35 +00:00
|
|
|
if (erp_table->num_ctcam_erps > 0 || erp_table->num_deltas > 0)
|
2018-11-14 08:22:34 +00:00
|
|
|
return;
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
switch (erp_table->num_atcam_erps) {
|
|
|
|
|
case 2:
|
|
|
|
|
/* Keep using the eRP table, but correctly set the
|
|
|
|
|
* operations pointer so that when an A-TCAM eRP is
|
|
|
|
|
* deleted we will transition to use the master mask
|
|
|
|
|
*/
|
|
|
|
|
erp_table->ops = &erp_two_masks_ops;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
/* We only kept the eRP table because we had C-TCAM
|
|
|
|
|
* eRPs in use. Now that the last C-TCAM eRP is gone we
|
|
|
|
|
* can stop using the table and transition to use the
|
|
|
|
|
* master mask
|
|
|
|
|
*/
|
|
|
|
|
mlxsw_sp_acl_erp_region_master_mask_trans(erp_table);
|
|
|
|
|
erp_table->ops = &erp_single_mask_ops;
|
|
|
|
|
break;
|
|
|
|
|
case 0:
|
|
|
|
|
/* There are no more eRPs of any kind used by the region
|
|
|
|
|
* so free its eRP table and transition to initial state
|
|
|
|
|
*/
|
|
|
|
|
mlxsw_sp_acl_erp_table_disable(erp_table);
|
|
|
|
|
mlxsw_sp_acl_erp_table_free(erp_table->erp_core,
|
|
|
|
|
erp_table->num_max_atcam_erps,
|
|
|
|
|
erp_table->aregion->type,
|
|
|
|
|
erp_table->base_index);
|
|
|
|
|
erp_table->ops = &erp_no_mask_ops;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-14 08:22:34 +00:00
|
|
|
static void mlxsw_sp_acl_erp_ctcam_dec(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
__mlxsw_sp_acl_erp_table_other_dec(erp_table,
|
|
|
|
|
&erp_table->num_ctcam_erps);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-14 08:22:35 +00:00
|
|
|
static void mlxsw_sp_acl_erp_delta_dec(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
__mlxsw_sp_acl_erp_table_other_dec(erp_table,
|
|
|
|
|
&erp_table->num_deltas);
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
static struct mlxsw_sp_acl_erp *
|
2018-11-14 08:22:34 +00:00
|
|
|
mlxsw_sp_acl_erp_ctcam_mask_create(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp_key *key)
|
2018-07-25 09:23:57 +03:00
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
erp = kzalloc(sizeof(*erp), GFP_KERNEL);
|
|
|
|
|
if (!erp)
|
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
|
|
|
|
memcpy(&erp->key, key, sizeof(*key));
|
|
|
|
|
bitmap_from_arr32(erp->mask_bitmap, (u32 *) key->mask,
|
|
|
|
|
MLXSW_SP_ACL_TCAM_MASK_LEN);
|
2018-11-14 08:22:34 +00:00
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_ctcam_inc(erp_table);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_erp_ctcam_inc;
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
erp->erp_table = erp_table;
|
|
|
|
|
|
2018-11-14 08:22:30 +00:00
|
|
|
err = mlxsw_sp_acl_erp_master_mask_set(erp_table, &erp->key);
|
2018-07-25 09:23:57 +03:00
|
|
|
if (err)
|
|
|
|
|
goto err_master_mask_set;
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_region_ctcam_enable(erp_table);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_erp_region_ctcam_enable;
|
|
|
|
|
|
|
|
|
|
return erp;
|
|
|
|
|
|
|
|
|
|
err_erp_region_ctcam_enable:
|
2018-11-14 08:22:30 +00:00
|
|
|
mlxsw_sp_acl_erp_master_mask_clear(erp_table, &erp->key);
|
2018-07-25 09:23:57 +03:00
|
|
|
err_master_mask_set:
|
2018-11-14 08:22:34 +00:00
|
|
|
mlxsw_sp_acl_erp_ctcam_dec(erp_table);
|
|
|
|
|
err_erp_ctcam_inc:
|
2018-07-25 09:23:57 +03:00
|
|
|
kfree(erp);
|
|
|
|
|
return ERR_PTR(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_ctcam_mask_destroy(struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = erp->erp_table;
|
|
|
|
|
|
|
|
|
|
mlxsw_sp_acl_erp_region_ctcam_disable(erp_table);
|
2018-11-14 08:22:30 +00:00
|
|
|
mlxsw_sp_acl_erp_master_mask_clear(erp_table, &erp->key);
|
2018-11-14 08:22:34 +00:00
|
|
|
mlxsw_sp_acl_erp_ctcam_dec(erp_table);
|
2018-07-25 09:23:57 +03:00
|
|
|
kfree(erp);
|
|
|
|
|
}
|
|
|
|
|
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
static struct mlxsw_sp_acl_erp *
|
|
|
|
|
mlxsw_sp_acl_erp_mask_create(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp_key *key)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp;
|
|
|
|
|
int err;
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
if (key->ctcam)
|
2018-11-14 08:22:34 +00:00
|
|
|
return mlxsw_sp_acl_erp_ctcam_mask_create(erp_table, key);
|
2018-07-25 09:23:57 +03:00
|
|
|
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
/* Expand the eRP table for the new eRP, if needed */
|
|
|
|
|
err = mlxsw_sp_acl_erp_table_expand(erp_table);
|
|
|
|
|
if (err)
|
|
|
|
|
return ERR_PTR(err);
|
|
|
|
|
|
|
|
|
|
erp = mlxsw_sp_acl_erp_generic_create(erp_table, key);
|
|
|
|
|
if (IS_ERR(erp))
|
|
|
|
|
return erp;
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_index_get(erp_table, &erp->index);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_erp_index_get;
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_table_erp_add(erp_table, erp);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_table_erp_add;
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_region_erp_add(erp_table, erp);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_region_erp_add;
|
|
|
|
|
|
|
|
|
|
erp_table->ops = &erp_multiple_masks_ops;
|
|
|
|
|
|
|
|
|
|
return erp;
|
|
|
|
|
|
|
|
|
|
err_region_erp_add:
|
|
|
|
|
mlxsw_sp_acl_erp_table_erp_del(erp);
|
|
|
|
|
err_table_erp_add:
|
|
|
|
|
mlxsw_sp_acl_erp_index_put(erp_table, erp->index);
|
|
|
|
|
err_erp_index_get:
|
|
|
|
|
mlxsw_sp_acl_erp_generic_destroy(erp);
|
|
|
|
|
return ERR_PTR(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_mask_destroy(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
2018-07-25 09:23:57 +03:00
|
|
|
if (erp->key.ctcam)
|
|
|
|
|
return mlxsw_sp_acl_erp_ctcam_mask_destroy(erp);
|
|
|
|
|
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
mlxsw_sp_acl_erp_region_erp_del(erp);
|
|
|
|
|
mlxsw_sp_acl_erp_table_erp_del(erp);
|
|
|
|
|
mlxsw_sp_acl_erp_index_put(erp_table, erp->index);
|
|
|
|
|
mlxsw_sp_acl_erp_generic_destroy(erp);
|
|
|
|
|
|
2018-11-14 08:22:35 +00:00
|
|
|
if (erp_table->num_atcam_erps == 2 && erp_table->num_ctcam_erps == 0 &&
|
|
|
|
|
erp_table->num_deltas == 0)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
erp_table->ops = &erp_two_masks_ops;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct mlxsw_sp_acl_erp *
|
|
|
|
|
mlxsw_sp_acl_erp_second_mask_create(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp_key *key)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp;
|
|
|
|
|
int err;
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
if (key->ctcam)
|
|
|
|
|
return mlxsw_sp_acl_erp_ctcam_mask_create(erp_table, key);
|
|
|
|
|
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
/* Transition to use eRP table instead of master mask */
|
|
|
|
|
err = mlxsw_sp_acl_erp_region_table_trans(erp_table);
|
|
|
|
|
if (err)
|
|
|
|
|
return ERR_PTR(err);
|
|
|
|
|
|
|
|
|
|
erp = mlxsw_sp_acl_erp_generic_create(erp_table, key);
|
|
|
|
|
if (IS_ERR(erp)) {
|
|
|
|
|
err = PTR_ERR(erp);
|
|
|
|
|
goto err_erp_create;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_index_get(erp_table, &erp->index);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_erp_index_get;
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_table_erp_add(erp_table, erp);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_table_erp_add;
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_region_erp_add(erp_table, erp);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_region_erp_add;
|
|
|
|
|
|
|
|
|
|
erp_table->ops = &erp_two_masks_ops;
|
|
|
|
|
|
|
|
|
|
return erp;
|
|
|
|
|
|
|
|
|
|
err_region_erp_add:
|
|
|
|
|
mlxsw_sp_acl_erp_table_erp_del(erp);
|
|
|
|
|
err_table_erp_add:
|
|
|
|
|
mlxsw_sp_acl_erp_index_put(erp_table, erp->index);
|
|
|
|
|
err_erp_index_get:
|
|
|
|
|
mlxsw_sp_acl_erp_generic_destroy(erp);
|
|
|
|
|
err_erp_create:
|
|
|
|
|
mlxsw_sp_acl_erp_region_master_mask_trans(erp_table);
|
|
|
|
|
return ERR_PTR(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_second_mask_destroy(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
2018-07-25 09:23:57 +03:00
|
|
|
if (erp->key.ctcam)
|
|
|
|
|
return mlxsw_sp_acl_erp_ctcam_mask_destroy(erp);
|
|
|
|
|
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
mlxsw_sp_acl_erp_region_erp_del(erp);
|
|
|
|
|
mlxsw_sp_acl_erp_table_erp_del(erp);
|
|
|
|
|
mlxsw_sp_acl_erp_index_put(erp_table, erp->index);
|
|
|
|
|
mlxsw_sp_acl_erp_generic_destroy(erp);
|
|
|
|
|
/* Transition to use master mask instead of eRP table */
|
|
|
|
|
mlxsw_sp_acl_erp_region_master_mask_trans(erp_table);
|
|
|
|
|
|
|
|
|
|
erp_table->ops = &erp_single_mask_ops;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct mlxsw_sp_acl_erp *
|
|
|
|
|
mlxsw_sp_acl_erp_first_mask_create(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp_key *key)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp;
|
|
|
|
|
|
2018-07-25 09:23:57 +03:00
|
|
|
if (key->ctcam)
|
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
|
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
erp = mlxsw_sp_acl_erp_generic_create(erp_table, key);
|
|
|
|
|
if (IS_ERR(erp))
|
|
|
|
|
return erp;
|
|
|
|
|
|
|
|
|
|
erp_table->ops = &erp_single_mask_ops;
|
|
|
|
|
|
|
|
|
|
return erp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_first_mask_destroy(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
mlxsw_sp_acl_erp_generic_destroy(erp);
|
|
|
|
|
erp_table->ops = &erp_no_mask_ops;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_no_mask_destroy(struct mlxsw_sp_acl_erp_table *erp_table,
|
|
|
|
|
struct mlxsw_sp_acl_erp *erp)
|
|
|
|
|
{
|
|
|
|
|
WARN_ON(1);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-14 08:22:29 +00:00
|
|
|
struct mlxsw_sp_acl_erp_mask *
|
|
|
|
|
mlxsw_sp_acl_erp_mask_get(struct mlxsw_sp_acl_atcam_region *aregion,
|
|
|
|
|
const char *mask, bool ctcam)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
{
|
2019-02-24 06:46:28 +00:00
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = aregion->erp_table;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
struct mlxsw_sp_acl_erp_key key;
|
2018-11-14 08:22:29 +00:00
|
|
|
struct objagg_obj *objagg_obj;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
|
|
|
|
|
memcpy(key.mask, mask, MLXSW_REG_PTCEX_FLEX_KEY_BLOCKS_LEN);
|
2018-07-25 09:23:57 +03:00
|
|
|
key.ctcam = ctcam;
|
2019-02-24 06:46:28 +00:00
|
|
|
mutex_lock(&erp_table->objagg_lock);
|
|
|
|
|
objagg_obj = objagg_obj_get(erp_table->objagg, &key);
|
|
|
|
|
mutex_unlock(&erp_table->objagg_lock);
|
2018-11-14 08:22:29 +00:00
|
|
|
if (IS_ERR(objagg_obj))
|
|
|
|
|
return ERR_CAST(objagg_obj);
|
|
|
|
|
return (struct mlxsw_sp_acl_erp_mask *) objagg_obj;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mlxsw_sp_acl_erp_mask_put(struct mlxsw_sp_acl_atcam_region *aregion,
|
|
|
|
|
struct mlxsw_sp_acl_erp_mask *erp_mask)
|
|
|
|
|
{
|
|
|
|
|
struct objagg_obj *objagg_obj = (struct objagg_obj *) erp_mask;
|
2019-02-24 06:46:28 +00:00
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = aregion->erp_table;
|
2018-11-14 08:22:29 +00:00
|
|
|
|
2019-02-24 06:46:28 +00:00
|
|
|
mutex_lock(&erp_table->objagg_lock);
|
|
|
|
|
objagg_obj_put(erp_table->objagg, objagg_obj);
|
|
|
|
|
mutex_unlock(&erp_table->objagg_lock);
|
2018-11-14 08:22:29 +00:00
|
|
|
}
|
|
|
|
|
|
2018-12-16 08:49:29 +00:00
|
|
|
int mlxsw_sp_acl_erp_bf_insert(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion,
|
|
|
|
|
struct mlxsw_sp_acl_erp_mask *erp_mask,
|
|
|
|
|
struct mlxsw_sp_acl_atcam_entry *aentry)
|
|
|
|
|
{
|
|
|
|
|
struct objagg_obj *objagg_obj = (struct objagg_obj *) erp_mask;
|
|
|
|
|
const struct mlxsw_sp_acl_erp *erp = objagg_obj_root_priv(objagg_obj);
|
|
|
|
|
unsigned int erp_bank;
|
|
|
|
|
|
|
|
|
|
if (!mlxsw_sp_acl_erp_table_is_used(erp->erp_table))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
erp_bank = mlxsw_sp_acl_erp_bank_get(erp);
|
|
|
|
|
return mlxsw_sp_acl_bf_entry_add(mlxsw_sp,
|
|
|
|
|
erp->erp_table->erp_core->bf,
|
|
|
|
|
aregion, erp_bank, aentry);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mlxsw_sp_acl_erp_bf_remove(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion,
|
|
|
|
|
struct mlxsw_sp_acl_erp_mask *erp_mask,
|
|
|
|
|
struct mlxsw_sp_acl_atcam_entry *aentry)
|
|
|
|
|
{
|
|
|
|
|
struct objagg_obj *objagg_obj = (struct objagg_obj *) erp_mask;
|
|
|
|
|
const struct mlxsw_sp_acl_erp *erp = objagg_obj_root_priv(objagg_obj);
|
|
|
|
|
unsigned int erp_bank;
|
|
|
|
|
|
|
|
|
|
if (!mlxsw_sp_acl_erp_table_is_used(erp->erp_table))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
erp_bank = mlxsw_sp_acl_erp_bank_get(erp);
|
|
|
|
|
mlxsw_sp_acl_bf_entry_del(mlxsw_sp,
|
|
|
|
|
erp->erp_table->erp_core->bf,
|
|
|
|
|
aregion, erp_bank, aentry);
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-14 08:22:29 +00:00
|
|
|
bool
|
|
|
|
|
mlxsw_sp_acl_erp_mask_is_ctcam(const struct mlxsw_sp_acl_erp_mask *erp_mask)
|
|
|
|
|
{
|
|
|
|
|
struct objagg_obj *objagg_obj = (struct objagg_obj *) erp_mask;
|
|
|
|
|
const struct mlxsw_sp_acl_erp_key *key = objagg_obj_raw(objagg_obj);
|
|
|
|
|
|
|
|
|
|
return key->ctcam;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u8 mlxsw_sp_acl_erp_mask_erp_id(const struct mlxsw_sp_acl_erp_mask *erp_mask)
|
|
|
|
|
{
|
|
|
|
|
struct objagg_obj *objagg_obj = (struct objagg_obj *) erp_mask;
|
|
|
|
|
const struct mlxsw_sp_acl_erp *erp = objagg_obj_root_priv(objagg_obj);
|
|
|
|
|
|
|
|
|
|
return erp->id;
|
|
|
|
|
}
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
|
2018-11-14 08:22:35 +00:00
|
|
|
struct mlxsw_sp_acl_erp_delta {
|
|
|
|
|
struct mlxsw_sp_acl_erp_key key;
|
|
|
|
|
u16 start;
|
|
|
|
|
u8 mask;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
u16 mlxsw_sp_acl_erp_delta_start(const struct mlxsw_sp_acl_erp_delta *delta)
|
|
|
|
|
{
|
|
|
|
|
return delta->start;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u8 mlxsw_sp_acl_erp_delta_mask(const struct mlxsw_sp_acl_erp_delta *delta)
|
|
|
|
|
{
|
|
|
|
|
return delta->mask;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
u8 mlxsw_sp_acl_erp_delta_value(const struct mlxsw_sp_acl_erp_delta *delta,
|
|
|
|
|
const char *enc_key)
|
|
|
|
|
{
|
|
|
|
|
u16 start = delta->start;
|
|
|
|
|
u8 mask = delta->mask;
|
|
|
|
|
u16 tmp;
|
|
|
|
|
|
|
|
|
|
if (!mask)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
tmp = (unsigned char) enc_key[__MASK_IDX(start / 8)];
|
|
|
|
|
if (start / 8 + 1 < __MASK_LEN)
|
|
|
|
|
tmp |= (unsigned char) enc_key[__MASK_IDX(start / 8 + 1)] << 8;
|
|
|
|
|
tmp >>= start % 8;
|
|
|
|
|
tmp &= mask;
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mlxsw_sp_acl_erp_delta_clear(const struct mlxsw_sp_acl_erp_delta *delta,
|
|
|
|
|
const char *enc_key)
|
|
|
|
|
{
|
|
|
|
|
u16 start = delta->start;
|
|
|
|
|
u8 mask = delta->mask;
|
|
|
|
|
unsigned char *byte;
|
|
|
|
|
u16 tmp;
|
|
|
|
|
|
|
|
|
|
tmp = mask;
|
|
|
|
|
tmp <<= start % 8;
|
|
|
|
|
tmp = ~tmp;
|
|
|
|
|
|
|
|
|
|
byte = (unsigned char *) &enc_key[__MASK_IDX(start / 8)];
|
|
|
|
|
*byte &= tmp & 0xff;
|
|
|
|
|
if (start / 8 + 1 < __MASK_LEN) {
|
|
|
|
|
byte = (unsigned char *) &enc_key[__MASK_IDX(start / 8 + 1)];
|
|
|
|
|
*byte &= (tmp >> 8) & 0xff;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static const struct mlxsw_sp_acl_erp_delta
|
|
|
|
|
mlxsw_sp_acl_erp_delta_default = {};
|
|
|
|
|
|
|
|
|
|
const struct mlxsw_sp_acl_erp_delta *
|
|
|
|
|
mlxsw_sp_acl_erp_delta(const struct mlxsw_sp_acl_erp_mask *erp_mask)
|
|
|
|
|
{
|
|
|
|
|
struct objagg_obj *objagg_obj = (struct objagg_obj *) erp_mask;
|
|
|
|
|
const struct mlxsw_sp_acl_erp_delta *delta;
|
|
|
|
|
|
|
|
|
|
delta = objagg_obj_delta_priv(objagg_obj);
|
|
|
|
|
if (!delta)
|
|
|
|
|
delta = &mlxsw_sp_acl_erp_delta_default;
|
|
|
|
|
return delta;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_delta_fill(const struct mlxsw_sp_acl_erp_key *parent_key,
|
|
|
|
|
const struct mlxsw_sp_acl_erp_key *key,
|
|
|
|
|
u16 *delta_start, u8 *delta_mask)
|
|
|
|
|
{
|
|
|
|
|
int offset = 0;
|
|
|
|
|
int si = -1;
|
|
|
|
|
u16 pmask;
|
|
|
|
|
u16 mask;
|
|
|
|
|
int i;
|
|
|
|
|
|
|
|
|
|
/* The difference between 2 masks can be up to 8 consecutive bits. */
|
|
|
|
|
for (i = 0; i < __MASK_LEN; i++) {
|
|
|
|
|
if (parent_key->mask[__MASK_IDX(i)] == key->mask[__MASK_IDX(i)])
|
|
|
|
|
continue;
|
|
|
|
|
if (si == -1)
|
|
|
|
|
si = i;
|
|
|
|
|
else if (si != i - 1)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
if (si == -1) {
|
2019-05-29 10:59:44 +03:00
|
|
|
/* The masks are the same, this can happen in case eRPs with
|
|
|
|
|
* the same mask were created in both A-TCAM and C-TCAM.
|
|
|
|
|
* The only possible condition under which this can happen
|
|
|
|
|
* is identical rule insertion. Delta is not possible here.
|
2018-11-14 08:22:35 +00:00
|
|
|
*/
|
2019-05-29 10:59:44 +03:00
|
|
|
return -EINVAL;
|
2018-11-14 08:22:35 +00:00
|
|
|
}
|
|
|
|
|
pmask = (unsigned char) parent_key->mask[__MASK_IDX(si)];
|
|
|
|
|
mask = (unsigned char) key->mask[__MASK_IDX(si)];
|
|
|
|
|
if (si + 1 < __MASK_LEN) {
|
|
|
|
|
pmask |= (unsigned char) parent_key->mask[__MASK_IDX(si + 1)] << 8;
|
|
|
|
|
mask |= (unsigned char) key->mask[__MASK_IDX(si + 1)] << 8;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((pmask ^ mask) & pmask)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
mask &= ~pmask;
|
|
|
|
|
while (!(mask & (1 << offset)))
|
|
|
|
|
offset++;
|
|
|
|
|
while (!(mask & 1))
|
|
|
|
|
mask >>= 1;
|
|
|
|
|
if (mask & 0xff00)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
|
|
*delta_start = si * 8 + offset;
|
|
|
|
|
*delta_mask = mask;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-07 11:22:46 +00:00
|
|
|
static bool mlxsw_sp_acl_erp_delta_check(void *priv, const void *parent_obj,
|
|
|
|
|
const void *obj)
|
|
|
|
|
{
|
|
|
|
|
const struct mlxsw_sp_acl_erp_key *parent_key = parent_obj;
|
|
|
|
|
const struct mlxsw_sp_acl_erp_key *key = obj;
|
|
|
|
|
u16 delta_start;
|
|
|
|
|
u8 delta_mask;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_delta_fill(parent_key, key,
|
|
|
|
|
&delta_start, &delta_mask);
|
|
|
|
|
return err ? false : true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mlxsw_sp_acl_erp_hints_obj_cmp(const void *obj1, const void *obj2)
|
|
|
|
|
{
|
|
|
|
|
const struct mlxsw_sp_acl_erp_key *key1 = obj1;
|
|
|
|
|
const struct mlxsw_sp_acl_erp_key *key2 = obj2;
|
|
|
|
|
|
|
|
|
|
/* For hints purposes, two objects are considered equal
|
|
|
|
|
* in case the masks are the same. Does not matter what
|
|
|
|
|
* the "ctcam" value is.
|
|
|
|
|
*/
|
|
|
|
|
return memcmp(key1->mask, key2->mask, sizeof(key1->mask));
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-14 08:22:29 +00:00
|
|
|
static void *mlxsw_sp_acl_erp_delta_create(void *priv, void *parent_obj,
|
|
|
|
|
void *obj)
|
|
|
|
|
{
|
2018-11-14 08:22:35 +00:00
|
|
|
struct mlxsw_sp_acl_erp_key *parent_key = parent_obj;
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion = priv;
|
|
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = aregion->erp_table;
|
|
|
|
|
struct mlxsw_sp_acl_erp_key *key = obj;
|
|
|
|
|
struct mlxsw_sp_acl_erp_delta *delta;
|
|
|
|
|
u16 delta_start;
|
|
|
|
|
u8 delta_mask;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
if (parent_key->ctcam || key->ctcam)
|
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
|
err = mlxsw_sp_acl_erp_delta_fill(parent_key, key,
|
|
|
|
|
&delta_start, &delta_mask);
|
|
|
|
|
if (err)
|
|
|
|
|
return ERR_PTR(-EINVAL);
|
|
|
|
|
|
|
|
|
|
delta = kzalloc(sizeof(*delta), GFP_KERNEL);
|
|
|
|
|
if (!delta)
|
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
delta->start = delta_start;
|
|
|
|
|
delta->mask = delta_mask;
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_delta_inc(erp_table);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_erp_delta_inc;
|
|
|
|
|
|
|
|
|
|
memcpy(&delta->key, key, sizeof(*key));
|
|
|
|
|
err = mlxsw_sp_acl_erp_master_mask_set(erp_table, &delta->key);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_master_mask_set;
|
|
|
|
|
|
|
|
|
|
return delta;
|
|
|
|
|
|
|
|
|
|
err_master_mask_set:
|
|
|
|
|
mlxsw_sp_acl_erp_delta_dec(erp_table);
|
|
|
|
|
err_erp_delta_inc:
|
|
|
|
|
kfree(delta);
|
|
|
|
|
return ERR_PTR(err);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
}
|
|
|
|
|
|
2018-11-14 08:22:29 +00:00
|
|
|
static void mlxsw_sp_acl_erp_delta_destroy(void *priv, void *delta_priv)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
{
|
2018-11-14 08:22:35 +00:00
|
|
|
struct mlxsw_sp_acl_erp_delta *delta = delta_priv;
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion = priv;
|
|
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = aregion->erp_table;
|
|
|
|
|
|
|
|
|
|
mlxsw_sp_acl_erp_master_mask_clear(erp_table, &delta->key);
|
|
|
|
|
mlxsw_sp_acl_erp_delta_dec(erp_table);
|
|
|
|
|
kfree(delta);
|
2018-11-14 08:22:29 +00:00
|
|
|
}
|
|
|
|
|
|
2019-02-07 11:22:46 +00:00
|
|
|
static void *mlxsw_sp_acl_erp_root_create(void *priv, void *obj,
|
|
|
|
|
unsigned int root_id)
|
2018-11-14 08:22:29 +00:00
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion = priv;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = aregion->erp_table;
|
2018-11-14 08:22:29 +00:00
|
|
|
struct mlxsw_sp_acl_erp_key *key = obj;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
|
2019-02-07 11:22:46 +00:00
|
|
|
if (!key->ctcam &&
|
|
|
|
|
root_id != OBJAGG_OBJ_ROOT_ID_INVALID &&
|
|
|
|
|
root_id >= MLXSW_SP_ACL_ERP_MAX_PER_REGION)
|
|
|
|
|
return ERR_PTR(-ENOBUFS);
|
2018-11-14 08:22:29 +00:00
|
|
|
return erp_table->ops->erp_create(erp_table, key);
|
|
|
|
|
}
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
|
2018-11-14 08:22:29 +00:00
|
|
|
static void mlxsw_sp_acl_erp_root_destroy(void *priv, void *root_priv)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion = priv;
|
|
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = aregion->erp_table;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
|
2018-11-14 08:22:29 +00:00
|
|
|
erp_table->ops->erp_destroy(erp_table, root_priv);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
}
|
|
|
|
|
|
2018-11-14 08:22:29 +00:00
|
|
|
static const struct objagg_ops mlxsw_sp_acl_erp_objagg_ops = {
|
|
|
|
|
.obj_size = sizeof(struct mlxsw_sp_acl_erp_key),
|
2019-02-07 11:22:46 +00:00
|
|
|
.delta_check = mlxsw_sp_acl_erp_delta_check,
|
|
|
|
|
.hints_obj_cmp = mlxsw_sp_acl_erp_hints_obj_cmp,
|
2018-11-14 08:22:29 +00:00
|
|
|
.delta_create = mlxsw_sp_acl_erp_delta_create,
|
|
|
|
|
.delta_destroy = mlxsw_sp_acl_erp_delta_destroy,
|
|
|
|
|
.root_create = mlxsw_sp_acl_erp_root_create,
|
|
|
|
|
.root_destroy = mlxsw_sp_acl_erp_root_destroy,
|
|
|
|
|
};
|
|
|
|
|
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
static struct mlxsw_sp_acl_erp_table *
|
2019-02-07 11:22:52 +00:00
|
|
|
mlxsw_sp_acl_erp_table_create(struct mlxsw_sp_acl_atcam_region *aregion,
|
|
|
|
|
struct objagg_hints *hints)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
erp_table = kzalloc(sizeof(*erp_table), GFP_KERNEL);
|
|
|
|
|
if (!erp_table)
|
|
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
|
|
|
2018-11-14 08:22:29 +00:00
|
|
|
erp_table->objagg = objagg_create(&mlxsw_sp_acl_erp_objagg_ops,
|
2019-02-07 11:22:52 +00:00
|
|
|
hints, aregion);
|
2018-11-14 08:22:29 +00:00
|
|
|
if (IS_ERR(erp_table->objagg)) {
|
|
|
|
|
err = PTR_ERR(erp_table->objagg);
|
|
|
|
|
goto err_objagg_create;
|
|
|
|
|
}
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
|
|
|
|
|
erp_table->erp_core = aregion->atcam->erp_core;
|
|
|
|
|
erp_table->ops = &erp_no_mask_ops;
|
|
|
|
|
INIT_LIST_HEAD(&erp_table->atcam_erps_list);
|
|
|
|
|
erp_table->aregion = aregion;
|
2019-02-24 06:46:28 +00:00
|
|
|
mutex_init(&erp_table->objagg_lock);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
|
|
|
|
|
return erp_table;
|
|
|
|
|
|
2018-11-14 08:22:29 +00:00
|
|
|
err_objagg_create:
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
kfree(erp_table);
|
|
|
|
|
return ERR_PTR(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
mlxsw_sp_acl_erp_table_destroy(struct mlxsw_sp_acl_erp_table *erp_table)
|
|
|
|
|
{
|
|
|
|
|
WARN_ON(!list_empty(&erp_table->atcam_erps_list));
|
2019-02-24 06:46:28 +00:00
|
|
|
mutex_destroy(&erp_table->objagg_lock);
|
2018-11-14 08:22:29 +00:00
|
|
|
objagg_destroy(erp_table->objagg);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
kfree(erp_table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_master_mask_init(struct mlxsw_sp_acl_atcam_region *aregion)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp *mlxsw_sp = aregion->region->mlxsw_sp;
|
|
|
|
|
char percr_pl[MLXSW_REG_PERCR_LEN];
|
|
|
|
|
|
|
|
|
|
mlxsw_reg_percr_pack(percr_pl, aregion->region->id);
|
|
|
|
|
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(percr), percr_pl);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_region_param_init(struct mlxsw_sp_acl_atcam_region *aregion)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp *mlxsw_sp = aregion->region->mlxsw_sp;
|
|
|
|
|
char pererp_pl[MLXSW_REG_PERERP_LEN];
|
|
|
|
|
|
2018-07-25 09:24:06 +03:00
|
|
|
mlxsw_reg_pererp_pack(pererp_pl, aregion->region->id, false, false, 0,
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
0, 0);
|
|
|
|
|
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(pererp), pererp_pl);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-07 11:22:51 +00:00
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_hints_check(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
|
struct mlxsw_sp_acl_atcam_region *aregion,
|
|
|
|
|
struct objagg_hints *hints, bool *p_rehash_needed)
|
|
|
|
|
{
|
2019-02-24 06:46:28 +00:00
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = aregion->erp_table;
|
2019-02-07 11:22:51 +00:00
|
|
|
const struct objagg_stats *ostats;
|
|
|
|
|
const struct objagg_stats *hstats;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
*p_rehash_needed = false;
|
|
|
|
|
|
2019-02-24 06:46:28 +00:00
|
|
|
mutex_lock(&erp_table->objagg_lock);
|
|
|
|
|
ostats = objagg_stats_get(erp_table->objagg);
|
|
|
|
|
mutex_unlock(&erp_table->objagg_lock);
|
2019-02-07 11:22:51 +00:00
|
|
|
if (IS_ERR(ostats)) {
|
|
|
|
|
dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to get ERP stats\n");
|
|
|
|
|
return PTR_ERR(ostats);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
hstats = objagg_hints_stats_get(hints);
|
|
|
|
|
if (IS_ERR(hstats)) {
|
|
|
|
|
dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to get ERP hints stats\n");
|
|
|
|
|
err = PTR_ERR(hstats);
|
|
|
|
|
goto err_hints_stats_get;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Very basic criterion for now. */
|
|
|
|
|
if (hstats->root_count < ostats->root_count)
|
|
|
|
|
*p_rehash_needed = true;
|
|
|
|
|
|
|
|
|
|
err = 0;
|
|
|
|
|
|
|
|
|
|
objagg_stats_put(hstats);
|
|
|
|
|
err_hints_stats_get:
|
|
|
|
|
objagg_stats_put(ostats);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *
|
|
|
|
|
mlxsw_sp_acl_erp_rehash_hints_get(struct mlxsw_sp_acl_atcam_region *aregion)
|
|
|
|
|
{
|
2019-02-24 06:46:28 +00:00
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table = aregion->erp_table;
|
2019-02-07 11:22:51 +00:00
|
|
|
struct mlxsw_sp *mlxsw_sp = aregion->region->mlxsw_sp;
|
|
|
|
|
struct objagg_hints *hints;
|
|
|
|
|
bool rehash_needed;
|
|
|
|
|
int err;
|
|
|
|
|
|
2019-02-24 06:46:28 +00:00
|
|
|
mutex_lock(&erp_table->objagg_lock);
|
|
|
|
|
hints = objagg_hints_get(erp_table->objagg,
|
2019-02-07 11:22:51 +00:00
|
|
|
OBJAGG_OPT_ALGO_SIMPLE_GREEDY);
|
2019-02-24 06:46:28 +00:00
|
|
|
mutex_unlock(&erp_table->objagg_lock);
|
2019-02-07 11:22:51 +00:00
|
|
|
if (IS_ERR(hints)) {
|
|
|
|
|
dev_err_ratelimited(mlxsw_sp->bus_info->dev, "Failed to create ERP hints\n");
|
|
|
|
|
return ERR_CAST(hints);
|
|
|
|
|
}
|
|
|
|
|
err = mlxsw_sp_acl_erp_hints_check(mlxsw_sp, aregion, hints,
|
|
|
|
|
&rehash_needed);
|
|
|
|
|
if (err)
|
|
|
|
|
goto errout;
|
|
|
|
|
|
|
|
|
|
if (!rehash_needed) {
|
|
|
|
|
err = -EAGAIN;
|
|
|
|
|
goto errout;
|
|
|
|
|
}
|
|
|
|
|
return hints;
|
|
|
|
|
|
|
|
|
|
errout:
|
|
|
|
|
objagg_hints_put(hints);
|
|
|
|
|
return ERR_PTR(err);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mlxsw_sp_acl_erp_rehash_hints_put(void *hints_priv)
|
|
|
|
|
{
|
|
|
|
|
struct objagg_hints *hints = hints_priv;
|
|
|
|
|
|
|
|
|
|
objagg_hints_put(hints);
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-07 11:22:52 +00:00
|
|
|
int mlxsw_sp_acl_erp_region_init(struct mlxsw_sp_acl_atcam_region *aregion,
|
|
|
|
|
void *hints_priv)
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp_table *erp_table;
|
2019-02-07 11:22:52 +00:00
|
|
|
struct objagg_hints *hints = hints_priv;
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
int err;
|
|
|
|
|
|
2019-02-07 11:22:52 +00:00
|
|
|
erp_table = mlxsw_sp_acl_erp_table_create(aregion, hints);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
if (IS_ERR(erp_table))
|
|
|
|
|
return PTR_ERR(erp_table);
|
|
|
|
|
aregion->erp_table = erp_table;
|
|
|
|
|
|
2018-07-25 09:24:06 +03:00
|
|
|
/* Initialize the region's master mask to all zeroes */
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
err = mlxsw_sp_acl_erp_master_mask_init(aregion);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_erp_master_mask_init;
|
|
|
|
|
|
2018-07-25 09:24:06 +03:00
|
|
|
/* Initialize the region to not use the eRP table */
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
err = mlxsw_sp_acl_erp_region_param_init(aregion);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_erp_region_param_init;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_erp_region_param_init:
|
|
|
|
|
err_erp_master_mask_init:
|
|
|
|
|
mlxsw_sp_acl_erp_table_destroy(erp_table);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mlxsw_sp_acl_erp_region_fini(struct mlxsw_sp_acl_atcam_region *aregion)
|
|
|
|
|
{
|
|
|
|
|
mlxsw_sp_acl_erp_table_destroy(aregion->erp_table);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int
|
|
|
|
|
mlxsw_sp_acl_erp_tables_sizes_query(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
|
struct mlxsw_sp_acl_erp_core *erp_core)
|
|
|
|
|
{
|
|
|
|
|
unsigned int size;
|
|
|
|
|
|
|
|
|
|
if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, ACL_ERPT_ENTRIES_2KB) ||
|
|
|
|
|
!MLXSW_CORE_RES_VALID(mlxsw_sp->core, ACL_ERPT_ENTRIES_4KB) ||
|
|
|
|
|
!MLXSW_CORE_RES_VALID(mlxsw_sp->core, ACL_ERPT_ENTRIES_8KB) ||
|
|
|
|
|
!MLXSW_CORE_RES_VALID(mlxsw_sp->core, ACL_ERPT_ENTRIES_12KB))
|
|
|
|
|
return -EIO;
|
|
|
|
|
|
|
|
|
|
size = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_ERPT_ENTRIES_2KB);
|
|
|
|
|
erp_core->erpt_entries_size[MLXSW_SP_ACL_ATCAM_REGION_TYPE_2KB] = size;
|
|
|
|
|
|
|
|
|
|
size = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_ERPT_ENTRIES_4KB);
|
|
|
|
|
erp_core->erpt_entries_size[MLXSW_SP_ACL_ATCAM_REGION_TYPE_4KB] = size;
|
|
|
|
|
|
|
|
|
|
size = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_ERPT_ENTRIES_8KB);
|
|
|
|
|
erp_core->erpt_entries_size[MLXSW_SP_ACL_ATCAM_REGION_TYPE_8KB] = size;
|
|
|
|
|
|
|
|
|
|
size = MLXSW_CORE_RES_GET(mlxsw_sp->core, ACL_ERPT_ENTRIES_12KB);
|
|
|
|
|
erp_core->erpt_entries_size[MLXSW_SP_ACL_ATCAM_REGION_TYPE_12KB] = size;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int mlxsw_sp_acl_erp_tables_init(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
|
struct mlxsw_sp_acl_erp_core *erp_core)
|
|
|
|
|
{
|
|
|
|
|
unsigned int erpt_bank_size;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
if (!MLXSW_CORE_RES_VALID(mlxsw_sp->core, ACL_MAX_ERPT_BANK_SIZE) ||
|
|
|
|
|
!MLXSW_CORE_RES_VALID(mlxsw_sp->core, ACL_MAX_ERPT_BANKS))
|
|
|
|
|
return -EIO;
|
|
|
|
|
erpt_bank_size = MLXSW_CORE_RES_GET(mlxsw_sp->core,
|
|
|
|
|
ACL_MAX_ERPT_BANK_SIZE);
|
|
|
|
|
erp_core->num_erp_banks = MLXSW_CORE_RES_GET(mlxsw_sp->core,
|
|
|
|
|
ACL_MAX_ERPT_BANKS);
|
|
|
|
|
|
|
|
|
|
erp_core->erp_tables = gen_pool_create(0, -1);
|
|
|
|
|
if (!erp_core->erp_tables)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
gen_pool_set_algo(erp_core->erp_tables, gen_pool_best_fit, NULL);
|
|
|
|
|
|
|
|
|
|
err = gen_pool_add(erp_core->erp_tables,
|
|
|
|
|
MLXSW_SP_ACL_ERP_GENALLOC_OFFSET, erpt_bank_size,
|
|
|
|
|
-1);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_gen_pool_add;
|
|
|
|
|
|
2018-12-16 08:49:26 +00:00
|
|
|
erp_core->bf = mlxsw_sp_acl_bf_init(mlxsw_sp, erp_core->num_erp_banks);
|
|
|
|
|
if (IS_ERR(erp_core->bf)) {
|
|
|
|
|
err = PTR_ERR(erp_core->bf);
|
|
|
|
|
goto err_bf_init;
|
|
|
|
|
}
|
|
|
|
|
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
/* Different regions require masks of different sizes */
|
|
|
|
|
err = mlxsw_sp_acl_erp_tables_sizes_query(mlxsw_sp, erp_core);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_erp_tables_sizes_query;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_erp_tables_sizes_query:
|
2018-12-16 08:49:26 +00:00
|
|
|
mlxsw_sp_acl_bf_fini(erp_core->bf);
|
|
|
|
|
err_bf_init:
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
err_gen_pool_add:
|
|
|
|
|
gen_pool_destroy(erp_core->erp_tables);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void mlxsw_sp_acl_erp_tables_fini(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
|
struct mlxsw_sp_acl_erp_core *erp_core)
|
|
|
|
|
{
|
2018-12-16 08:49:26 +00:00
|
|
|
mlxsw_sp_acl_bf_fini(erp_core->bf);
|
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>
2018-07-25 09:23:55 +03:00
|
|
|
gen_pool_destroy(erp_core->erp_tables);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int mlxsw_sp_acl_erps_init(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
|
struct mlxsw_sp_acl_atcam *atcam)
|
|
|
|
|
{
|
|
|
|
|
struct mlxsw_sp_acl_erp_core *erp_core;
|
|
|
|
|
int err;
|
|
|
|
|
|
|
|
|
|
erp_core = kzalloc(sizeof(*erp_core), GFP_KERNEL);
|
|
|
|
|
if (!erp_core)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
erp_core->mlxsw_sp = mlxsw_sp;
|
|
|
|
|
atcam->erp_core = erp_core;
|
|
|
|
|
|
|
|
|
|
err = mlxsw_sp_acl_erp_tables_init(mlxsw_sp, erp_core);
|
|
|
|
|
if (err)
|
|
|
|
|
goto err_erp_tables_init;
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err_erp_tables_init:
|
|
|
|
|
kfree(erp_core);
|
|
|
|
|
return err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mlxsw_sp_acl_erps_fini(struct mlxsw_sp *mlxsw_sp,
|
|
|
|
|
struct mlxsw_sp_acl_atcam *atcam)
|
|
|
|
|
{
|
|
|
|
|
mlxsw_sp_acl_erp_tables_fini(mlxsw_sp, atcam->erp_core);
|
|
|
|
|
kfree(atcam->erp_core);
|
|
|
|
|
}
|