Skip to content

Commit

Permalink
Merge branch 'mlxsw-add-port-range-matching-support'
Browse files Browse the repository at this point in the history
Petr Machata says:

====================
mlxsw: Add port range matching support

Ido Schimmel writes:

Add port range matching support in mlxsw as part of tc-flower offload.

Patches #1-#7 gradually add port range matching support in mlxsw. See
patch #3 to understand how port range matching is implemented in the
device.

Patches #8-#10 add selftests.
====================

Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>
  • Loading branch information
kuba-moo committed Jul 12, 2023
2 parents 9f4a7c9 + 209218e commit fa3530b
Show file tree
Hide file tree
Showing 20 changed files with 876 additions and 7 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlxsw/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ mlxsw_spectrum-objs := spectrum.o spectrum_buffers.o \
spectrum_nve.o spectrum_nve_vxlan.o \
spectrum_dpipe.o spectrum_trap.o \
spectrum_ethtool.o spectrum_policer.o \
spectrum_pgt.o
spectrum_pgt.o spectrum_port_range.o
mlxsw_spectrum-$(CONFIG_MLXSW_SPECTRUM_DCB) += spectrum_dcb.o
mlxsw_spectrum-$(CONFIG_PTP_1588_CLOCK) += spectrum_ptp.o
obj-$(CONFIG_MLXSW_MINIMAL) += mlxsw_minimal.o
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ static const struct mlxsw_afk_element_info mlxsw_afk_element_infos[] = {
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_32_63, 0x38, 4),
MLXSW_AFK_ELEMENT_INFO_BUF(DST_IP_0_31, 0x3C, 4),
MLXSW_AFK_ELEMENT_INFO_U32(FDB_MISS, 0x40, 0, 1),
MLXSW_AFK_ELEMENT_INFO_U32(L4_PORT_RANGE, 0x40, 1, 16),
};

struct mlxsw_afk {
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/mellanox/mlxsw/core_acl_flex_keys.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ enum mlxsw_afk_element {
MLXSW_AFK_ELEMENT_VIRT_ROUTER_MSB,
MLXSW_AFK_ELEMENT_VIRT_ROUTER_LSB,
MLXSW_AFK_ELEMENT_FDB_MISS,
MLXSW_AFK_ELEMENT_L4_PORT_RANGE,
MLXSW_AFK_ELEMENT_MAX,
};

Expand Down
73 changes: 73 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -2799,6 +2799,78 @@ static inline void mlxsw_reg_ptar_unpack(char *payload, char *tcam_region_info)
mlxsw_reg_ptar_tcam_region_info_memcpy_from(payload, tcam_region_info);
}

/* PPRR - Policy-Engine Port Range Register
* ----------------------------------------
* This register is used for configuring port range identification.
*/
#define MLXSW_REG_PPRR_ID 0x3008
#define MLXSW_REG_PPRR_LEN 0x14

MLXSW_REG_DEFINE(pprr, MLXSW_REG_PPRR_ID, MLXSW_REG_PPRR_LEN);

/* reg_pprr_ipv4
* Apply port range register to IPv4 packets.
* Access: RW
*/
MLXSW_ITEM32(reg, pprr, ipv4, 0x00, 31, 1);

/* reg_pprr_ipv6
* Apply port range register to IPv6 packets.
* Access: RW
*/
MLXSW_ITEM32(reg, pprr, ipv6, 0x00, 30, 1);

/* reg_pprr_src
* Apply port range register to source L4 ports.
* Access: RW
*/
MLXSW_ITEM32(reg, pprr, src, 0x00, 29, 1);

/* reg_pprr_dst
* Apply port range register to destination L4 ports.
* Access: RW
*/
MLXSW_ITEM32(reg, pprr, dst, 0x00, 28, 1);

/* reg_pprr_tcp
* Apply port range register to TCP packets.
* Access: RW
*/
MLXSW_ITEM32(reg, pprr, tcp, 0x00, 27, 1);

/* reg_pprr_udp
* Apply port range register to UDP packets.
* Access: RW
*/
MLXSW_ITEM32(reg, pprr, udp, 0x00, 26, 1);

/* reg_pprr_register_index
* Index of Port Range Register being accessed.
* Range is 0..cap_max_acl_l4_port_range-1.
* Access: Index
*/
MLXSW_ITEM32(reg, pprr, register_index, 0x00, 0, 8);

/* reg_prrr_port_range_min
* Minimum port range for comparison.
* Match is defined as:
* port_range_min <= packet_port <= port_range_max.
* Access: RW
*/
MLXSW_ITEM32(reg, pprr, port_range_min, 0x04, 16, 16);

/* reg_prrr_port_range_max
* Maximum port range for comparison.
* Access: RW
*/
MLXSW_ITEM32(reg, pprr, port_range_max, 0x04, 0, 16);

static inline void mlxsw_reg_pprr_pack(char *payload, u8 register_index)
{
MLXSW_REG_ZERO(pprr, payload);
mlxsw_reg_pprr_register_index_set(payload, register_index);
}

/* PPBS - Policy-Engine Policy Based Switching Register
* ----------------------------------------------------
* This register retrieves and sets Policy Based Switching Table entries.
Expand Down Expand Up @@ -12819,6 +12891,7 @@ static const struct mlxsw_reg_info *mlxsw_reg_infos[] = {
MLXSW_REG(pacl),
MLXSW_REG(pagt),
MLXSW_REG(ptar),
MLXSW_REG(pprr),
MLXSW_REG(ppbs),
MLXSW_REG(prcr),
MLXSW_REG(pefa),
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ enum mlxsw_res_id {
MLXSW_RES_ID_ACL_FLEX_KEYS,
MLXSW_RES_ID_ACL_MAX_ACTION_PER_RULE,
MLXSW_RES_ID_ACL_ACTIONS_PER_SET,
MLXSW_RES_ID_ACL_MAX_L4_PORT_RANGE,
MLXSW_RES_ID_ACL_MAX_ERPT_BANKS,
MLXSW_RES_ID_ACL_MAX_ERPT_BANK_SIZE,
MLXSW_RES_ID_ACL_MAX_LARGE_KEY_ID,
Expand Down Expand Up @@ -99,6 +100,7 @@ static u16 mlxsw_res_ids[] = {
[MLXSW_RES_ID_ACL_FLEX_KEYS] = 0x2910,
[MLXSW_RES_ID_ACL_MAX_ACTION_PER_RULE] = 0x2911,
[MLXSW_RES_ID_ACL_ACTIONS_PER_SET] = 0x2912,
[MLXSW_RES_ID_ACL_MAX_L4_PORT_RANGE] = 0x2920,
[MLXSW_RES_ID_ACL_MAX_ERPT_BANKS] = 0x2940,
[MLXSW_RES_ID_ACL_MAX_ERPT_BANK_SIZE] = 0x2941,
[MLXSW_RES_ID_ACL_MAX_LARGE_KEY_ID] = 0x2942,
Expand Down
39 changes: 39 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.c
Original file line number Diff line number Diff line change
Expand Up @@ -3188,6 +3188,12 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
goto err_nve_init;
}

err = mlxsw_sp_port_range_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize port ranges\n");
goto err_port_range_init;
}

err = mlxsw_sp_acl_init(mlxsw_sp);
if (err) {
dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize ACL\n");
Expand Down Expand Up @@ -3280,6 +3286,8 @@ static int mlxsw_sp_init(struct mlxsw_core *mlxsw_core,
err_router_init:
mlxsw_sp_acl_fini(mlxsw_sp);
err_acl_init:
mlxsw_sp_port_range_fini(mlxsw_sp);
err_port_range_init:
mlxsw_sp_nve_fini(mlxsw_sp);
err_nve_init:
mlxsw_sp_ipv6_addr_ht_fini(mlxsw_sp);
Expand Down Expand Up @@ -3462,6 +3470,7 @@ static void mlxsw_sp_fini(struct mlxsw_core *mlxsw_core)
}
mlxsw_sp_router_fini(mlxsw_sp);
mlxsw_sp_acl_fini(mlxsw_sp);
mlxsw_sp_port_range_fini(mlxsw_sp);
mlxsw_sp_nve_fini(mlxsw_sp);
mlxsw_sp_ipv6_addr_ht_fini(mlxsw_sp);
mlxsw_sp_afa_fini(mlxsw_sp);
Expand Down Expand Up @@ -3730,6 +3739,26 @@ static int mlxsw_sp_resources_rifs_register(struct mlxsw_core *mlxsw_core)
&size_params);
}

static int
mlxsw_sp_resources_port_range_register(struct mlxsw_core *mlxsw_core)
{
struct devlink *devlink = priv_to_devlink(mlxsw_core);
struct devlink_resource_size_params size_params;
u64 max;

if (!MLXSW_CORE_RES_VALID(mlxsw_core, ACL_MAX_L4_PORT_RANGE))
return -EIO;

max = MLXSW_CORE_RES_GET(mlxsw_core, ACL_MAX_L4_PORT_RANGE);
devlink_resource_size_params_init(&size_params, max, max, 1,
DEVLINK_RESOURCE_UNIT_ENTRY);

return devl_resource_register(devlink, "port_range_registers", max,
MLXSW_SP_RESOURCE_PORT_RANGE_REGISTERS,
DEVLINK_RESOURCE_ID_PARENT_TOP,
&size_params);
}

static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
{
int err;
Expand Down Expand Up @@ -3758,8 +3787,13 @@ static int mlxsw_sp1_resources_register(struct mlxsw_core *mlxsw_core)
if (err)
goto err_resources_rifs_register;

err = mlxsw_sp_resources_port_range_register(mlxsw_core);
if (err)
goto err_resources_port_range_register;

return 0;

err_resources_port_range_register:
err_resources_rifs_register:
err_resources_rif_mac_profile_register:
err_policer_resources_register:
Expand Down Expand Up @@ -3797,8 +3831,13 @@ static int mlxsw_sp2_resources_register(struct mlxsw_core *mlxsw_core)
if (err)
goto err_resources_rifs_register;

err = mlxsw_sp_resources_port_range_register(mlxsw_core);
if (err)
goto err_resources_port_range_register;

return 0;

err_resources_port_range_register:
err_resources_rifs_register:
err_resources_rif_mac_profile_register:
err_policer_resources_register:
Expand Down
25 changes: 23 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ enum mlxsw_sp_resource_id {
MLXSW_SP_RESOURCE_SINGLE_RATE_POLICERS,
MLXSW_SP_RESOURCE_RIF_MAC_PROFILES,
MLXSW_SP_RESOURCE_RIFS,
MLXSW_SP_RESOURCE_PORT_RANGE_REGISTERS,
};

struct mlxsw_sp_port;
Expand Down Expand Up @@ -175,6 +176,7 @@ struct mlxsw_sp {
struct mlxsw_sp_acl *acl;
struct mlxsw_sp_fid_core *fid_core;
struct mlxsw_sp_policer_core *policer_core;
struct mlxsw_sp_port_range_core *pr_core;
struct mlxsw_sp_kvdl *kvdl;
struct mlxsw_sp_nve *nve;
struct notifier_block netdevice_nb;
Expand Down Expand Up @@ -865,9 +867,13 @@ struct mlxsw_sp_acl_rule_info {
egress_bind_blocker:1,
counter_valid:1,
policer_index_valid:1,
ipv6_valid:1;
ipv6_valid:1,
src_port_range_reg_valid:1,
dst_port_range_reg_valid:1;
unsigned int counter_index;
u16 policer_index;
u8 src_port_range_reg_index;
u8 dst_port_range_reg_index;
struct {
u32 prev_val;
enum mlxsw_sp_acl_mangle_field prev_field;
Expand Down Expand Up @@ -992,7 +998,8 @@ void mlxsw_sp_acl_ruleset_prio_get(struct mlxsw_sp_acl_ruleset *ruleset,
struct mlxsw_sp_acl_rule_info *
mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
struct mlxsw_afa_block *afa_block);
void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp_acl_rule_info *rulei);
void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_rule_info *rulei);
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,
unsigned int priority);
Expand Down Expand Up @@ -1484,4 +1491,18 @@ int mlxsw_sp_pgt_entry_port_set(struct mlxsw_sp *mlxsw_sp, u16 mid,
int mlxsw_sp_pgt_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_pgt_fini(struct mlxsw_sp *mlxsw_sp);

/* spectrum_port_range.c */
struct mlxsw_sp_port_range {
u16 min;
u16 max;
u8 source:1; /* Source or destination */
};

int mlxsw_sp_port_range_reg_get(struct mlxsw_sp *mlxsw_sp,
const struct mlxsw_sp_port_range *range,
struct netlink_ext_ack *extack,
u8 *p_prr_index);
void mlxsw_sp_port_range_reg_put(struct mlxsw_sp *mlxsw_sp, u8 prr_index);
int mlxsw_sp_port_range_init(struct mlxsw_sp *mlxsw_sp);
void mlxsw_sp_port_range_fini(struct mlxsw_sp *mlxsw_sp);
#endif
4 changes: 2 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum1_acl_tcam.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ mlxsw_sp1_acl_ctcam_region_catchall_add(struct mlxsw_sp *mlxsw_sp,
err_entry_add:
err_rulei_commit:
err_rulei_act_continue:
mlxsw_sp_acl_rulei_destroy(rulei);
mlxsw_sp_acl_rulei_destroy(mlxsw_sp, rulei);
err_rulei_create:
mlxsw_sp_acl_ctcam_chunk_fini(&region->catchall.cchunk);
return err;
Expand All @@ -105,7 +105,7 @@ mlxsw_sp1_acl_ctcam_region_catchall_del(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp_acl_ctcam_entry_del(mlxsw_sp, &region->cregion,
&region->catchall.cchunk,
&region->catchall.centry);
mlxsw_sp_acl_rulei_destroy(rulei);
mlxsw_sp_acl_rulei_destroy(mlxsw_sp, rulei);
mlxsw_sp_acl_ctcam_chunk_fini(&region->catchall.cchunk);
}

Expand Down
11 changes: 9 additions & 2 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,17 @@ mlxsw_sp_acl_rulei_create(struct mlxsw_sp_acl *acl,
return ERR_PTR(err);
}

void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp_acl_rule_info *rulei)
void mlxsw_sp_acl_rulei_destroy(struct mlxsw_sp *mlxsw_sp,
struct mlxsw_sp_acl_rule_info *rulei)
{
if (rulei->action_created)
mlxsw_afa_block_destroy(rulei->act_block);
if (rulei->src_port_range_reg_valid)
mlxsw_sp_port_range_reg_put(mlxsw_sp,
rulei->src_port_range_reg_index);
if (rulei->dst_port_range_reg_valid)
mlxsw_sp_port_range_reg_put(mlxsw_sp,
rulei->dst_port_range_reg_index);
kfree(rulei);
}

Expand Down Expand Up @@ -834,7 +841,7 @@ void mlxsw_sp_acl_rule_destroy(struct mlxsw_sp *mlxsw_sp,
{
struct mlxsw_sp_acl_ruleset *ruleset = rule->ruleset;

mlxsw_sp_acl_rulei_destroy(rule->rulei);
mlxsw_sp_acl_rulei_destroy(mlxsw_sp, rule->rulei);
kfree(rule);
mlxsw_sp_acl_ruleset_ref_dec(mlxsw_sp, ruleset);
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_flex_keys.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ 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_ipv4_sip[] = {
MLXSW_AFK_ELEMENT_INST_BUF(SRC_IP_0_31, 0x00, 4),
MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 16, 16),
MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
};

static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_ipv4_dip[] = {
MLXSW_AFK_ELEMENT_INST_BUF(DST_IP_0_31, 0x00, 4),
MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 16, 16),
MLXSW_AFK_ELEMENT_INST_U32(IP_PROTO, 0x08, 0, 8),
MLXSW_AFK_ELEMENT_INST_U32(SRC_SYS_PORT, 0x0C, 0, 16),
};
Expand Down Expand Up @@ -205,6 +207,7 @@ static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_0[] = {

static struct mlxsw_afk_element_inst mlxsw_sp_afk_element_info_l4_2[] = {
MLXSW_AFK_ELEMENT_INST_U32(TCP_FLAGS, 0x04, 16, 9), /* TCP_CONTROL + TCP_ECN */
MLXSW_AFK_ELEMENT_INST_U32(L4_PORT_RANGE, 0x04, 0, 16),
};

static const struct mlxsw_afk_block mlxsw_sp2_afk_blocks[] = {
Expand Down
Loading

0 comments on commit fa3530b

Please sign in to comment.