Commit 3d907eaf authored by David S. Miller's avatar David S. Miller

Merge branch 'mlxsw-Spectrum2-acl-prep'

Ido Schimmel says:

====================
mlxsw: Spectrum-2 small ACL preparations

This is the first set of changes towards Spectrum-2 support in the mlxsw
driver. It contains small changes that prepare the code for the later
introduction of Spectrum-2 support.

The Spectrum-2 ASIC uses an algorithmic TCAM (A-TCAM) instead of a
circuit TCAM (C-TCAM) as Spectrum, and thus most of the changes are
around the ACL code.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 0dbc81ea 0317a6f4
...@@ -351,9 +351,24 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa) ...@@ -351,9 +351,24 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa)
block->first_set = mlxsw_afa_set_create(true); block->first_set = mlxsw_afa_set_create(true);
if (!block->first_set) if (!block->first_set)
goto err_first_set_create; goto err_first_set_create;
block->cur_set = block->first_set;
/* In case user instructs to have dummy first set, we leave it
* empty here and create another, real, set right away.
*/
if (mlxsw_afa->ops->dummy_first_set) {
block->cur_set = mlxsw_afa_set_create(false);
if (!block->cur_set)
goto err_second_set_create;
block->cur_set->prev = block->first_set;
block->first_set->next = block->cur_set;
} else {
block->cur_set = block->first_set;
}
return block; return block;
err_second_set_create:
mlxsw_afa_set_destroy(block->first_set);
err_first_set_create: err_first_set_create:
kfree(block); kfree(block);
return NULL; return NULL;
...@@ -415,11 +430,16 @@ char *mlxsw_afa_block_first_set(struct mlxsw_afa_block *block) ...@@ -415,11 +430,16 @@ char *mlxsw_afa_block_first_set(struct mlxsw_afa_block *block)
} }
EXPORT_SYMBOL(mlxsw_afa_block_first_set); EXPORT_SYMBOL(mlxsw_afa_block_first_set);
u32 mlxsw_afa_block_first_set_kvdl_index(struct mlxsw_afa_block *block) u32 mlxsw_afa_block_first_kvdl_index(struct mlxsw_afa_block *block)
{ {
return block->first_set->kvdl_index; /* First set is never in KVD linear. So the first set
* with valid KVD linear index is always the second one.
*/
if (WARN_ON(!block->first_set->next))
return 0;
return block->first_set->next->kvdl_index;
} }
EXPORT_SYMBOL(mlxsw_afa_block_first_set_kvdl_index); EXPORT_SYMBOL(mlxsw_afa_block_first_kvdl_index);
int mlxsw_afa_block_continue(struct mlxsw_afa_block *block) int mlxsw_afa_block_continue(struct mlxsw_afa_block *block)
{ {
......
...@@ -54,6 +54,7 @@ struct mlxsw_afa_ops { ...@@ -54,6 +54,7 @@ struct mlxsw_afa_ops {
bool ingress, int *p_span_id); bool ingress, int *p_span_id);
void (*mirror_del)(void *priv, u8 local_in_port, int span_id, void (*mirror_del)(void *priv, u8 local_in_port, int span_id,
bool ingress); bool ingress);
bool dummy_first_set;
}; };
struct mlxsw_afa *mlxsw_afa_create(unsigned int max_acts_per_set, struct mlxsw_afa *mlxsw_afa_create(unsigned int max_acts_per_set,
...@@ -64,7 +65,7 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa); ...@@ -64,7 +65,7 @@ struct mlxsw_afa_block *mlxsw_afa_block_create(struct mlxsw_afa *mlxsw_afa);
void mlxsw_afa_block_destroy(struct mlxsw_afa_block *block); void mlxsw_afa_block_destroy(struct mlxsw_afa_block *block);
int mlxsw_afa_block_commit(struct mlxsw_afa_block *block); int mlxsw_afa_block_commit(struct mlxsw_afa_block *block);
char *mlxsw_afa_block_first_set(struct mlxsw_afa_block *block); char *mlxsw_afa_block_first_set(struct mlxsw_afa_block *block);
u32 mlxsw_afa_block_first_set_kvdl_index(struct mlxsw_afa_block *block); u32 mlxsw_afa_block_first_kvdl_index(struct mlxsw_afa_block *block);
int mlxsw_afa_block_continue(struct mlxsw_afa_block *block); int mlxsw_afa_block_continue(struct mlxsw_afa_block *block);
int mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id); int mlxsw_afa_block_jump(struct mlxsw_afa_block *block, u16 group_id);
int mlxsw_afa_block_terminate(struct mlxsw_afa_block *block); int mlxsw_afa_block_terminate(struct mlxsw_afa_block *block);
......
...@@ -42,16 +42,20 @@ ...@@ -42,16 +42,20 @@
enum mlxsw_afk_element { enum mlxsw_afk_element {
MLXSW_AFK_ELEMENT_SRC_SYS_PORT, MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
MLXSW_AFK_ELEMENT_DMAC, MLXSW_AFK_ELEMENT_DMAC_32_47,
MLXSW_AFK_ELEMENT_SMAC, MLXSW_AFK_ELEMENT_DMAC_0_31,
MLXSW_AFK_ELEMENT_SMAC_32_47,
MLXSW_AFK_ELEMENT_SMAC_0_31,
MLXSW_AFK_ELEMENT_ETHERTYPE, MLXSW_AFK_ELEMENT_ETHERTYPE,
MLXSW_AFK_ELEMENT_IP_PROTO, MLXSW_AFK_ELEMENT_IP_PROTO,
MLXSW_AFK_ELEMENT_SRC_IP4, MLXSW_AFK_ELEMENT_SRC_IP_96_127,
MLXSW_AFK_ELEMENT_DST_IP4, MLXSW_AFK_ELEMENT_SRC_IP_64_95,
MLXSW_AFK_ELEMENT_SRC_IP6_HI, MLXSW_AFK_ELEMENT_SRC_IP_32_63,
MLXSW_AFK_ELEMENT_SRC_IP6_LO, MLXSW_AFK_ELEMENT_SRC_IP_0_31,
MLXSW_AFK_ELEMENT_DST_IP6_HI, MLXSW_AFK_ELEMENT_DST_IP_96_127,
MLXSW_AFK_ELEMENT_DST_IP6_LO, MLXSW_AFK_ELEMENT_DST_IP_64_95,
MLXSW_AFK_ELEMENT_DST_IP_32_63,
MLXSW_AFK_ELEMENT_DST_IP_0_31,
MLXSW_AFK_ELEMENT_DST_L4_PORT, MLXSW_AFK_ELEMENT_DST_L4_PORT,
MLXSW_AFK_ELEMENT_SRC_L4_PORT, MLXSW_AFK_ELEMENT_SRC_L4_PORT,
MLXSW_AFK_ELEMENT_VID, MLXSW_AFK_ELEMENT_VID,
...@@ -99,9 +103,11 @@ struct mlxsw_afk_element_info { ...@@ -99,9 +103,11 @@ struct mlxsw_afk_element_info {
* define an internal storage geometry. * define an internal storage geometry.
*/ */
static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = { static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 16), MLXSW_AFK_ELEMENT_INFO_U32(SRC_SYS_PORT, 0x00, 16, 8),
MLXSW_AFK_ELEMENT_INFO_BUF(DMAC, 0x04, 6), MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_32_47, 0x04, 2),
MLXSW_AFK_ELEMENT_INFO_BUF(SMAC, 0x0A, 6), MLXSW_AFK_ELEMENT_INFO_BUF(DMAC_0_31, 0x06, 4),
MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_32_47, 0x0A, 2),
MLXSW_AFK_ELEMENT_INFO_BUF(SMAC_0_31, 0x0C, 4),
MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16), MLXSW_AFK_ELEMENT_INFO_U32(ETHERTYPE, 0x00, 0, 16),
MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8), MLXSW_AFK_ELEMENT_INFO_U32(IP_PROTO, 0x10, 0, 8),
MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12), MLXSW_AFK_ELEMENT_INFO_U32(VID, 0x10, 8, 12),
...@@ -112,12 +118,14 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = { ...@@ -112,12 +118,14 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8), MLXSW_AFK_ELEMENT_INFO_U32(IP_TTL_, 0x18, 0, 8),
MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2), MLXSW_AFK_ELEMENT_INFO_U32(IP_ECN, 0x18, 9, 2),
MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6), MLXSW_AFK_ELEMENT_INFO_U32(IP_DSCP, 0x18, 11, 6),
MLXSW_AFK_ELEMENT_INFO_U32(SRC_IP4, 0x20, 0, 32), MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_96_127, 0x20, 4),
MLXSW_AFK_ELEMENT_INFO_U32(DST_IP4, 0x24, 0, 32), MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_64_95, 0x24, 4),
MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_HI, 0x20, 8), MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_32_63, 0x28, 4),
MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP6_LO, 0x28, 8), MLXSW_AFK_ELEMENT_INFO_BUF(SRC_IP_0_31, 0x2C, 4),
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_HI, 0x30, 8), MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_96_127, 0x30, 4),
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP6_LO, 0x38, 8), MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_64_95, 0x34, 4),
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_32_63, 0x38, 4),
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4),
}; };
#define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40 #define MLXSW_AFK_ELEMENT_STORAGE_SIZE 0x40
......
...@@ -2132,14 +2132,18 @@ MLXSW_ITEM32(reg, ptar, op, 0x00, 28, 4); ...@@ -2132,14 +2132,18 @@ MLXSW_ITEM32(reg, ptar, op, 0x00, 28, 4);
/* reg_ptar_action_set_type /* reg_ptar_action_set_type
* Type of action set to be used on this region. * Type of action set to be used on this region.
* For Spectrum, this is always type 2 - "flexible" * For Spectrum and Spectrum-2, this is always type 2 - "flexible"
* Access: WO * Access: WO
*/ */
MLXSW_ITEM32(reg, ptar, action_set_type, 0x00, 16, 8); MLXSW_ITEM32(reg, ptar, action_set_type, 0x00, 16, 8);
enum mlxsw_reg_ptar_key_type {
MLXSW_REG_PTAR_KEY_TYPE_FLEX = 0x50, /* Spetrum */
MLXSW_REG_PTAR_KEY_TYPE_FLEX2 = 0x51, /* Spectrum-2 */
};
/* reg_ptar_key_type /* reg_ptar_key_type
* TCAM key type for the region. * TCAM key type for the region.
* For Spectrum, this is always type 0x50 - "FLEX_KEY"
* Access: WO * Access: WO
*/ */
MLXSW_ITEM32(reg, ptar, key_type, 0x00, 0, 8); MLXSW_ITEM32(reg, ptar, key_type, 0x00, 0, 8);
...@@ -2182,13 +2186,14 @@ MLXSW_ITEM8_INDEXED(reg, ptar, flexible_key_id, 0x20, 0, 8, ...@@ -2182,13 +2186,14 @@ MLXSW_ITEM8_INDEXED(reg, ptar, flexible_key_id, 0x20, 0, 8,
MLXSW_REG_PTAR_KEY_ID_LEN, 0x00, false); MLXSW_REG_PTAR_KEY_ID_LEN, 0x00, false);
static inline void mlxsw_reg_ptar_pack(char *payload, enum mlxsw_reg_ptar_op op, static inline void mlxsw_reg_ptar_pack(char *payload, enum mlxsw_reg_ptar_op op,
enum mlxsw_reg_ptar_key_type key_type,
u16 region_size, u16 region_id, u16 region_size, u16 region_id,
const char *tcam_region_info) const char *tcam_region_info)
{ {
MLXSW_REG_ZERO(ptar, payload); MLXSW_REG_ZERO(ptar, payload);
mlxsw_reg_ptar_op_set(payload, op); mlxsw_reg_ptar_op_set(payload, op);
mlxsw_reg_ptar_action_set_type_set(payload, 2); /* "flexible" */ mlxsw_reg_ptar_action_set_type_set(payload, 2); /* "flexible" */
mlxsw_reg_ptar_key_type_set(payload, 0x50); /* "FLEX_KEY" */ mlxsw_reg_ptar_key_type_set(payload, key_type);
mlxsw_reg_ptar_region_size_set(payload, region_size); mlxsw_reg_ptar_region_size_set(payload, region_size);
mlxsw_reg_ptar_region_id_set(payload, region_id); mlxsw_reg_ptar_region_id_set(payload, region_id);
mlxsw_reg_ptar_tcam_region_info_memcpy_to(payload, tcam_region_info); mlxsw_reg_ptar_tcam_region_info_memcpy_to(payload, tcam_region_info);
......
...@@ -3621,6 +3621,8 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core, ...@@ -3621,6 +3621,8 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core); struct mlxsw_sp *mlxsw_sp = mlxsw_core_driver_priv(mlxsw_core);
int err; int err;
mlxsw_sp->afa_ops = &mlxsw_sp1_act_afa_ops;
mlxsw_sp->core = mlxsw_core; mlxsw_sp->core = mlxsw_core;
mlxsw_sp->bus_info = mlxsw_bus_info; mlxsw_sp->bus_info = mlxsw_bus_info;
......
...@@ -168,6 +168,7 @@ struct mlxsw_sp { ...@@ -168,6 +168,7 @@ struct mlxsw_sp {
struct mlxsw_sp_span_entry *entries; struct mlxsw_sp_span_entry *entries;
int entries_count; int entries_count;
} span; } span;
const struct mlxsw_afa_ops *afa_ops;
}; };
static inline struct mlxsw_sp_upper * static inline struct mlxsw_sp_upper *
...@@ -584,6 +585,9 @@ void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp); ...@@ -584,6 +585,9 @@ void mlxsw_sp_acl_fini(struct mlxsw_sp *mlxsw_sp);
/* spectrum_acl_tcam.c */ /* spectrum_acl_tcam.c */
extern const struct mlxsw_sp_acl_ops mlxsw_sp_acl_tcam_ops; extern const struct mlxsw_sp_acl_ops mlxsw_sp_acl_tcam_ops;
/* spectrum_acl_flex_actions.c */
extern const struct mlxsw_afa_ops mlxsw_sp1_act_afa_ops;
/* spectrum_flower.c */ /* spectrum_flower.c */
int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp, int mlxsw_sp_flower_replace(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_block *block, struct mlxsw_sp_acl_block *block,
......
...@@ -487,7 +487,7 @@ int mlxsw_sp_acl_rulei_commit(struct mlxsw_sp_acl_rule_info *rulei) ...@@ -487,7 +487,7 @@ int mlxsw_sp_acl_rulei_commit(struct mlxsw_sp_acl_rule_info *rulei)
void mlxsw_sp_acl_rulei_priority(struct mlxsw_sp_acl_rule_info *rulei, void mlxsw_sp_acl_rulei_priority(struct mlxsw_sp_acl_rule_info *rulei,
unsigned int priority) unsigned int priority)
{ {
rulei->priority = priority; rulei->priority = priority >> 16;
} }
void mlxsw_sp_acl_rulei_keymask_u32(struct mlxsw_sp_acl_rule_info *rulei, void mlxsw_sp_acl_rulei_keymask_u32(struct mlxsw_sp_acl_rule_info *rulei,
...@@ -837,8 +837,8 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp) ...@@ -837,8 +837,8 @@ int mlxsw_sp_acl_init(struct mlxsw_sp *mlxsw_sp)
acl->mlxsw_sp = mlxsw_sp; acl->mlxsw_sp = mlxsw_sp;
acl->afk = mlxsw_afk_create(MLXSW_CORE_RES_GET(mlxsw_sp->core, acl->afk = mlxsw_afk_create(MLXSW_CORE_RES_GET(mlxsw_sp->core,
ACL_FLEX_KEYS), ACL_FLEX_KEYS),
mlxsw_sp_afk_blocks, mlxsw_sp1_afk_blocks,
MLXSW_SP_AFK_BLOCKS_COUNT); MLXSW_SP1_AFK_BLOCKS_COUNT);
if (!acl->afk) { if (!acl->afk) {
err = -ENOMEM; err = -ENOMEM;
goto err_afk_create; goto err_afk_create;
......
...@@ -154,7 +154,7 @@ mlxsw_sp_act_mirror_del(void *priv, u8 local_in_port, int span_id, bool ingress) ...@@ -154,7 +154,7 @@ mlxsw_sp_act_mirror_del(void *priv, u8 local_in_port, int span_id, bool ingress)
mlxsw_sp_span_mirror_del(in_port, span_id, type, false); mlxsw_sp_span_mirror_del(in_port, span_id, type, false);
} }
static const struct mlxsw_afa_ops mlxsw_sp_act_afa_ops = { const struct mlxsw_afa_ops mlxsw_sp1_act_afa_ops = {
.kvdl_set_add = mlxsw_sp_act_kvdl_set_add, .kvdl_set_add = mlxsw_sp_act_kvdl_set_add,
.kvdl_set_del = mlxsw_sp_act_kvdl_set_del, .kvdl_set_del = mlxsw_sp_act_kvdl_set_del,
.kvdl_fwd_entry_add = mlxsw_sp_act_kvdl_fwd_entry_add, .kvdl_fwd_entry_add = mlxsw_sp_act_kvdl_fwd_entry_add,
...@@ -169,7 +169,7 @@ int mlxsw_sp_afa_init(struct mlxsw_sp *mlxsw_sp) ...@@ -169,7 +169,7 @@ int mlxsw_sp_afa_init(struct mlxsw_sp *mlxsw_sp)
{ {
mlxsw_sp->afa = mlxsw_afa_create(MLXSW_CORE_RES_GET(mlxsw_sp->core, mlxsw_sp->afa = mlxsw_afa_create(MLXSW_CORE_RES_GET(mlxsw_sp->core,
ACL_ACTIONS_PER_SET), ACL_ACTIONS_PER_SET),
&mlxsw_sp_act_afa_ops, mlxsw_sp); mlxsw_sp->afa_ops, mlxsw_sp);
return PTR_ERR_OR_ZERO(mlxsw_sp->afa); return PTR_ERR_OR_ZERO(mlxsw_sp->afa);
} }
......
...@@ -38,38 +38,41 @@ ...@@ -38,38 +38,41 @@
#include "core_acl_flex_keys.h" #include "core_acl_flex_keys.h"
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_dmac[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_dmac[] = {
MLXSW_AFK_ELEMENT_INST_BUF(DMAC, 0x00, 6), MLXSW_AFK_ELEMENT_INST_BUF(DMAC_32_47, 0x00, 2),
MLXSW_AFK_ELEMENT_INST_BUF(DMAC_0_31, 0x02, 4),
MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3), MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3),
MLXSW_AFK_ELEMENT_INST_U32(VID, 0x08, 0, 12), MLXSW_AFK_ELEMENT_INST_U32(VID, 0x08, 0, 12),
MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16), MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 8),
}; };
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac[] = {
MLXSW_AFK_ELEMENT_INST_BUF(SMAC, 0x00, 6), MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x00, 2),
MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x02, 4),
MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3), MLXSW_AFK_ELEMENT_INST_U32(PCP, 0x08, 13, 3),
MLXSW_AFK_ELEMENT_INST_U32(VID, 0x08, 0, 12), MLXSW_AFK_ELEMENT_INST_U32(VID, 0x08, 0, 12),
MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16), MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 8),
}; };
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac_ex[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l2_smac_ex[] = {
MLXSW_AFK_ELEMENT_INST_BUF(SMAC, 0x02, 6), MLXSW_AFK_ELEMENT_INST_BUF(SMAC_32_47, 0x02, 2),
MLXSW_AFK_ELEMENT_INST_BUF(SMAC_0_31, 0x04, 4),
MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x0C, 0, 16), MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x0C, 0, 16),
}; };
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_sip[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_sip[] = {
MLXSW_AFK_ELEMENT_INST_U32(SRC_IP4, 0x00, 0, 32), MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),
MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8), MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16), MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 8),
}; };
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip[] = {
MLXSW_AFK_ELEMENT_INST_U32(DST_IP4, 0x00, 0, 32), MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x00, 4),
MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8), MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16), MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 8),
}; };
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4[] = {
MLXSW_AFK_ELEMENT_INST_U32(SRC_IP4, 0x00, 0, 32), MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),
MLXSW_AFK_ELEMENT_INST_U32(IP_ECN, 0x04, 4, 2), MLXSW_AFK_ELEMENT_INST_U32(IP_ECN, 0x04, 4, 2),
MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_, 0x04, 24, 8), MLXSW_AFK_ELEMENT_INST_U32(IP_TTL_, 0x04, 24, 8),
MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP, 0x08, 0, 6), MLXSW_AFK_ELEMENT_INST_U32(IP_DSCP, 0x08, 0, 6),
...@@ -84,27 +87,31 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_ex[] = { ...@@ -84,27 +87,31 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_ex[] = {
}; };
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_dip[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_dip[] = {
MLXSW_AFK_ELEMENT_INST_BUF(DST_IP6_LO, 0x00, 8), MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_32_63, 0x00, 4),
MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x04, 4),
}; };
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_ex1[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_ex1[] = {
MLXSW_AFK_ELEMENT_INST_BUF(DST_IP6_HI, 0x00, 8), MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_96_127, 0x00, 4),
MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_64_95, 0x04, 4),
MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8), MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
}; };
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip[] = {
MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP6_LO, 0x00, 8), MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_32_63, 0x00, 4),
MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x04, 4),
}; };
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip_ex[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv6_sip_ex[] = {
MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP6_HI, 0x00, 8), MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_96_127, 0x00, 4),
MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_64_95, 0x04, 4),
}; };
static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_packet_type[] = { static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_packet_type[] = {
MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x00, 0, 16), MLXSW_AFK_ELEMENT_INST_U32(ETHERTYPE, 0x00, 0, 16),
}; };
static const struct mlxsw_afk_block mlxsw_sp_afk_blocks[] = { static const struct mlxsw_afk_block mlxsw_sp1_afk_blocks[] = {
MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_l2_dmac), MLXSW_AFK_BLOCK(0x10, mlxsw_sp_afk_element_info_l2_dmac),
MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_l2_smac), MLXSW_AFK_BLOCK(0x11, mlxsw_sp_afk_element_info_l2_smac),
MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_l2_smac_ex), MLXSW_AFK_BLOCK(0x12, mlxsw_sp_afk_element_info_l2_smac_ex),
...@@ -119,6 +126,6 @@ static const struct mlxsw_afk_block mlxsw_sp_afk_blocks[] = { ...@@ -119,6 +126,6 @@ static const struct mlxsw_afk_block mlxsw_sp_afk_blocks[] = {
MLXSW_AFK_BLOCK(0xB0, mlxsw_sp_afk_element_info_packet_type), MLXSW_AFK_BLOCK(0xB0, mlxsw_sp_afk_element_info_packet_type),
}; };
#define MLXSW_SP_AFK_BLOCKS_COUNT ARRAY_SIZE(mlxsw_sp_afk_blocks) #define MLXSW_SP1_AFK_BLOCKS_COUNT ARRAY_SIZE(mlxsw_sp1_afk_blocks)
#endif #endif
...@@ -165,6 +165,7 @@ struct mlxsw_sp_acl_tcam_region { ...@@ -165,6 +165,7 @@ struct mlxsw_sp_acl_tcam_region {
struct parman *parman; struct parman *parman;
struct mlxsw_sp *mlxsw_sp; struct mlxsw_sp *mlxsw_sp;
struct mlxsw_sp_acl_tcam_group *group; struct mlxsw_sp_acl_tcam_group *group;
enum mlxsw_reg_ptar_key_type key_type;
u16 id; /* ACL ID and region ID - they are same */ u16 id; /* ACL ID and region ID - they are same */
char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN]; char tcam_region_info[MLXSW_REG_PXXX_TCAM_REGION_INFO_LEN];
struct mlxsw_afk_key_info *key_info; struct mlxsw_afk_key_info *key_info;
...@@ -455,6 +456,7 @@ mlxsw_sp_acl_tcam_region_alloc(struct mlxsw_sp *mlxsw_sp, ...@@ -455,6 +456,7 @@ mlxsw_sp_acl_tcam_region_alloc(struct mlxsw_sp *mlxsw_sp,
int err; int err;
mlxsw_reg_ptar_pack(ptar_pl, MLXSW_REG_PTAR_OP_ALLOC, mlxsw_reg_ptar_pack(ptar_pl, MLXSW_REG_PTAR_OP_ALLOC,
region->key_type,
MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT, MLXSW_SP_ACL_TCAM_REGION_BASE_COUNT,
region->id, region->tcam_region_info); region->id, region->tcam_region_info);
encodings_count = mlxsw_afk_key_info_blocks_count_get(key_info); encodings_count = mlxsw_afk_key_info_blocks_count_get(key_info);
...@@ -477,7 +479,8 @@ mlxsw_sp_acl_tcam_region_free(struct mlxsw_sp *mlxsw_sp, ...@@ -477,7 +479,8 @@ mlxsw_sp_acl_tcam_region_free(struct mlxsw_sp *mlxsw_sp,
{ {
char ptar_pl[MLXSW_REG_PTAR_LEN]; char ptar_pl[MLXSW_REG_PTAR_LEN];
mlxsw_reg_ptar_pack(ptar_pl, MLXSW_REG_PTAR_OP_FREE, 0, region->id, mlxsw_reg_ptar_pack(ptar_pl, MLXSW_REG_PTAR_OP_FREE,
region->key_type, 0, region->id,
region->tcam_region_info); region->tcam_region_info);
mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptar), ptar_pl); mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptar), ptar_pl);
} }
...@@ -490,7 +493,8 @@ mlxsw_sp_acl_tcam_region_resize(struct mlxsw_sp *mlxsw_sp, ...@@ -490,7 +493,8 @@ mlxsw_sp_acl_tcam_region_resize(struct mlxsw_sp *mlxsw_sp,
char ptar_pl[MLXSW_REG_PTAR_LEN]; char ptar_pl[MLXSW_REG_PTAR_LEN];
mlxsw_reg_ptar_pack(ptar_pl, MLXSW_REG_PTAR_OP_RESIZE, mlxsw_reg_ptar_pack(ptar_pl, MLXSW_REG_PTAR_OP_RESIZE,
new_size, region->id, region->tcam_region_info); region->key_type, new_size, region->id,
region->tcam_region_info);
return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptar), ptar_pl); return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(ptar), ptar_pl);
} }
...@@ -713,6 +717,7 @@ mlxsw_sp_acl_tcam_region_create(struct mlxsw_sp *mlxsw_sp, ...@@ -713,6 +717,7 @@ mlxsw_sp_acl_tcam_region_create(struct mlxsw_sp *mlxsw_sp,
if (err) if (err)
goto err_region_id_get; goto err_region_id_get;
region->key_type = MLXSW_REG_PTAR_KEY_TYPE_FLEX;
err = mlxsw_sp_acl_tcam_region_alloc(mlxsw_sp, region); err = mlxsw_sp_acl_tcam_region_alloc(mlxsw_sp, region);
if (err) if (err)
goto err_tcam_region_alloc; goto err_tcam_region_alloc;
...@@ -968,12 +973,14 @@ mlxsw_sp_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp, ...@@ -968,12 +973,14 @@ mlxsw_sp_acl_tcam_entry_activity_get(struct mlxsw_sp *mlxsw_sp,
static const enum mlxsw_afk_element mlxsw_sp_acl_tcam_pattern_ipv4[] = { static const enum mlxsw_afk_element mlxsw_sp_acl_tcam_pattern_ipv4[] = {
MLXSW_AFK_ELEMENT_SRC_SYS_PORT, MLXSW_AFK_ELEMENT_SRC_SYS_PORT,
MLXSW_AFK_ELEMENT_DMAC, MLXSW_AFK_ELEMENT_DMAC_32_47,
MLXSW_AFK_ELEMENT_SMAC, MLXSW_AFK_ELEMENT_DMAC_0_31,
MLXSW_AFK_ELEMENT_SMAC_32_47,
MLXSW_AFK_ELEMENT_SMAC_0_31,
MLXSW_AFK_ELEMENT_ETHERTYPE, MLXSW_AFK_ELEMENT_ETHERTYPE,
MLXSW_AFK_ELEMENT_IP_PROTO, MLXSW_AFK_ELEMENT_IP_PROTO,
MLXSW_AFK_ELEMENT_SRC_IP4, MLXSW_AFK_ELEMENT_SRC_IP_0_31,
MLXSW_AFK_ELEMENT_DST_IP4, MLXSW_AFK_ELEMENT_DST_IP_0_31,
MLXSW_AFK_ELEMENT_DST_L4_PORT, MLXSW_AFK_ELEMENT_DST_L4_PORT,
MLXSW_AFK_ELEMENT_SRC_L4_PORT, MLXSW_AFK_ELEMENT_SRC_L4_PORT,
MLXSW_AFK_ELEMENT_VID, MLXSW_AFK_ELEMENT_VID,
...@@ -987,10 +994,14 @@ static const enum mlxsw_afk_element mlxsw_sp_acl_tcam_pattern_ipv4[] = { ...@@ -987,10 +994,14 @@ static const enum mlxsw_afk_element mlxsw_sp_acl_tcam_pattern_ipv4[] = {
static const enum mlxsw_afk_element mlxsw_sp_acl_tcam_pattern_ipv6[] = { static const enum mlxsw_afk_element mlxsw_sp_acl_tcam_pattern_ipv6[] = {
MLXSW_AFK_ELEMENT_ETHERTYPE, MLXSW_AFK_ELEMENT_ETHERTYPE,
MLXSW_AFK_ELEMENT_IP_PROTO, MLXSW_AFK_ELEMENT_IP_PROTO,
MLXSW_AFK_ELEMENT_SRC_IP6_HI, MLXSW_AFK_ELEMENT_SRC_IP_96_127,
MLXSW_AFK_ELEMENT_SRC_IP6_LO, MLXSW_AFK_ELEMENT_SRC_IP_64_95,
MLXSW_AFK_ELEMENT_DST_IP6_HI, MLXSW_AFK_ELEMENT_SRC_IP_32_63,
MLXSW_AFK_ELEMENT_DST_IP6_LO, MLXSW_AFK_ELEMENT_SRC_IP_0_31,
MLXSW_AFK_ELEMENT_DST_IP_96_127,
MLXSW_AFK_ELEMENT_DST_IP_64_95,
MLXSW_AFK_ELEMENT_DST_IP_32_63,
MLXSW_AFK_ELEMENT_DST_IP_0_31,
MLXSW_AFK_ELEMENT_DST_L4_PORT, MLXSW_AFK_ELEMENT_DST_L4_PORT,
MLXSW_AFK_ELEMENT_SRC_L4_PORT, MLXSW_AFK_ELEMENT_SRC_L4_PORT,
}; };
......
...@@ -144,10 +144,12 @@ static void mlxsw_sp_flower_parse_ipv4(struct mlxsw_sp_acl_rule_info *rulei, ...@@ -144,10 +144,12 @@ static void mlxsw_sp_flower_parse_ipv4(struct mlxsw_sp_acl_rule_info *rulei,
FLOW_DISSECTOR_KEY_IPV4_ADDRS, FLOW_DISSECTOR_KEY_IPV4_ADDRS,
f->mask); f->mask);
mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_SRC_IP4, mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP_0_31,
ntohl(key->src), ntohl(mask->src)); (char *) &key->src,
mlxsw_sp_acl_rulei_keymask_u32(rulei, MLXSW_AFK_ELEMENT_DST_IP4, (char *) &mask->src, 4);
ntohl(key->dst), ntohl(mask->dst)); mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP_0_31,
(char *) &key->dst,
(char *) &mask->dst, 4);
} }
static void mlxsw_sp_flower_parse_ipv6(struct mlxsw_sp_acl_rule_info *rulei, static void mlxsw_sp_flower_parse_ipv6(struct mlxsw_sp_acl_rule_info *rulei,
...@@ -161,24 +163,31 @@ static void mlxsw_sp_flower_parse_ipv6(struct mlxsw_sp_acl_rule_info *rulei, ...@@ -161,24 +163,31 @@ static void mlxsw_sp_flower_parse_ipv6(struct mlxsw_sp_acl_rule_info *rulei,
skb_flow_dissector_target(f->dissector, skb_flow_dissector_target(f->dissector,
FLOW_DISSECTOR_KEY_IPV6_ADDRS, FLOW_DISSECTOR_KEY_IPV6_ADDRS,
f->mask); f->mask);
size_t addr_half_size = sizeof(key->src) / 2;
mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP_96_127,
mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP6_HI, &key->src.s6_addr[0x0],
&key->src.s6_addr[0], &mask->src.s6_addr[0x0], 4);
&mask->src.s6_addr[0], mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP_64_95,
addr_half_size); &key->src.s6_addr[0x4],
mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP6_LO, &mask->src.s6_addr[0x4], 4);
&key->src.s6_addr[addr_half_size], mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP_32_63,
&mask->src.s6_addr[addr_half_size], &key->src.s6_addr[0x8],
addr_half_size); &mask->src.s6_addr[0x8], 4);
mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP6_HI, mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_SRC_IP_0_31,
&key->dst.s6_addr[0], &key->src.s6_addr[0xC],
&mask->dst.s6_addr[0], &mask->src.s6_addr[0xC], 4);
addr_half_size); mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP_96_127,
mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP6_LO, &key->dst.s6_addr[0x0],
&key->dst.s6_addr[addr_half_size], &mask->dst.s6_addr[0x0], 4);
&mask->dst.s6_addr[addr_half_size], mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP_64_95,
addr_half_size); &key->dst.s6_addr[0x4],
&mask->dst.s6_addr[0x4], 4);
mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP_32_63,
&key->dst.s6_addr[0x8],
&mask->dst.s6_addr[0x8], 4);
mlxsw_sp_acl_rulei_keymask_buf(rulei, MLXSW_AFK_ELEMENT_DST_IP_0_31,
&key->dst.s6_addr[0xC],
&mask->dst.s6_addr[0xC], 4);
} }
static int mlxsw_sp_flower_parse_ports(struct mlxsw_sp *mlxsw_sp, static int mlxsw_sp_flower_parse_ports(struct mlxsw_sp *mlxsw_sp,
...@@ -340,13 +349,17 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp, ...@@ -340,13 +349,17 @@ static int mlxsw_sp_flower_parse(struct mlxsw_sp *mlxsw_sp,
f->mask); f->mask);
mlxsw_sp_acl_rulei_keymask_buf(rulei, mlxsw_sp_acl_rulei_keymask_buf(rulei,
MLXSW_AFK_ELEMENT_DMAC, MLXSW_AFK_ELEMENT_DMAC_32_47,
key->dst, mask->dst, key->dst, mask->dst, 2);
sizeof(key->dst)); mlxsw_sp_acl_rulei_keymask_buf(rulei,
MLXSW_AFK_ELEMENT_DMAC_0_31,
key->dst + 2, mask->dst + 2, 4);
mlxsw_sp_acl_rulei_keymask_buf(rulei,
MLXSW_AFK_ELEMENT_SMAC_32_47,
key->src, mask->src, 2);
mlxsw_sp_acl_rulei_keymask_buf(rulei, mlxsw_sp_acl_rulei_keymask_buf(rulei,
MLXSW_AFK_ELEMENT_SMAC, MLXSW_AFK_ELEMENT_SMAC_0_31,
key->src, mask->src, key->src + 2, mask->src + 2, 4);
sizeof(key->src));
} }
if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) { if (dissector_uses_key(f->dissector, FLOW_DISSECTOR_KEY_VLAN)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment