Skip to content

Commit

Permalink
Merge tag 'mlx5-dr-2021-01-29' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5-dr-2021-01-29

Add support for Connect-X6DX Software steering

This series adds SW Steering support for Connect-X6DX.

Since the STE and actions formats are different on this new HW,
we implemented the HW specific STEv1 layer on the infrastructure
implemented in previous mlx5 DR patchset to support all the
functionalities as previous devices.

Most of the code in this series very is low level HW specific, we
implement the function pointers for the generic SW steering layer.

* tag 'mlx5-dr-2021-01-29' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux:
  net/mlx5: DR, Allow SW steering for sw_owner_v2 devices
  net/mlx5: DR, Copy all 64B whenever replacing STE in the head of miss-list
  net/mlx5: DR, Use HW specific logic API when writing STE
  net/mlx5: DR, Use the right size when writing partial STE into HW
  net/mlx5: DR, Add STEv1 modify header logic
  net/mlx5: DR, Add STEv1 action apply logic
  net/mlx5: DR, Add STEv1 setters and getters
  net/mlx5: DR, Allow native protocol support for HW STEv1
  net/mlx5: DR, Add HW STEv1 match logic
  net/mlx5: DR, Add match STEv1 structs to ifc
  net/mlx5: DR, Fix potential shift wrapping of 32-bit value
====================

Link: https://lore.kernel.org/r/20210130022618.317351-1-saeed@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Feb 2, 2021
2 parents f222a99 + 64f45c0 commit 1a2b60f
Show file tree
Hide file tree
Showing 13 changed files with 2,169 additions and 44 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/mellanox/mlx5/core/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ mlx5_core-$(CONFIG_MLX5_SW_STEERING) += steering/dr_domain.o steering/dr_table.o
steering/dr_matcher.o steering/dr_rule.o \
steering/dr_icm_pool.o steering/dr_buddy.o \
steering/dr_ste.o steering/dr_send.o \
steering/dr_ste_v0.o \
steering/dr_ste_v0.o steering/dr_ste_v1.o \
steering/dr_cmd.o steering/dr_fw.o \
steering/dr_action.o steering/fs_dr.o
#
Expand Down
17 changes: 11 additions & 6 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ int mlx5dr_cmd_query_esw_caps(struct mlx5_core_dev *mdev,
caps->uplink_icm_address_tx =
MLX5_CAP64_ESW_FLOWTABLE(mdev,
sw_steering_uplink_icm_address_tx);
caps->sw_owner =
MLX5_CAP_ESW_FLOWTABLE_FDB(mdev,
sw_owner);
caps->sw_owner_v2 = MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, sw_owner_v2);
if (!caps->sw_owner_v2)
caps->sw_owner = MLX5_CAP_ESW_FLOWTABLE_FDB(mdev, sw_owner);

return 0;
}
Expand Down Expand Up @@ -113,10 +113,15 @@ int mlx5dr_cmd_query_device(struct mlx5_core_dev *mdev,
caps->nic_tx_allow_address =
MLX5_CAP64_FLOWTABLE(mdev, sw_steering_nic_tx_action_allow_icm_address);

caps->rx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner);
caps->max_ft_level = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_ft_level);
caps->rx_sw_owner_v2 = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner_v2);
caps->tx_sw_owner_v2 = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner_v2);

if (!caps->rx_sw_owner_v2)
caps->rx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, sw_owner);
if (!caps->tx_sw_owner_v2)
caps->tx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner);

caps->tx_sw_owner = MLX5_CAP_FLOWTABLE_NIC_TX(mdev, sw_owner);
caps->max_ft_level = MLX5_CAP_FLOWTABLE_NIC_RX(mdev, max_ft_level);

caps->log_icm_size = MLX5_CAP_DEV_MEM(mdev, log_steering_sw_icm_size);
caps->hdr_modify_icm_addr =
Expand Down
17 changes: 9 additions & 8 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
#include <linux/mlx5/eswitch.h>
#include "dr_types.h"

#define DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, dmn_type) \
((dmn)->info.caps.dmn_type##_sw_owner || \
((dmn)->info.caps.dmn_type##_sw_owner_v2 && \
(dmn)->info.caps.sw_format_ver <= MLX5_STEERING_FORMAT_CONNECTX_6DX))

static int dr_domain_init_cache(struct mlx5dr_domain *dmn)
{
/* Per vport cached FW FT for checksum recalculation, this
Expand Down Expand Up @@ -187,6 +192,7 @@ static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev,
return ret;

dmn->info.caps.fdb_sw_owner = dmn->info.caps.esw_caps.sw_owner;
dmn->info.caps.fdb_sw_owner_v2 = dmn->info.caps.esw_caps.sw_owner_v2;
dmn->info.caps.esw_rx_drop_address = dmn->info.caps.esw_caps.drop_icm_address_rx;
dmn->info.caps.esw_tx_drop_address = dmn->info.caps.esw_caps.drop_icm_address_tx;

Expand Down Expand Up @@ -229,18 +235,13 @@ static int dr_domain_caps_init(struct mlx5_core_dev *mdev,
if (ret)
return ret;

if (dmn->info.caps.sw_format_ver != MLX5_STEERING_FORMAT_CONNECTX_5) {
mlx5dr_err(dmn, "SW steering is not supported on this device\n");
return -EOPNOTSUPP;
}

ret = dr_domain_query_fdb_caps(mdev, dmn);
if (ret)
return ret;

switch (dmn->type) {
case MLX5DR_DOMAIN_TYPE_NIC_RX:
if (!dmn->info.caps.rx_sw_owner)
if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, rx))
return -ENOTSUPP;

dmn->info.supp_sw_steering = true;
Expand All @@ -249,7 +250,7 @@ static int dr_domain_caps_init(struct mlx5_core_dev *mdev,
dmn->info.rx.drop_icm_addr = dmn->info.caps.nic_rx_drop_address;
break;
case MLX5DR_DOMAIN_TYPE_NIC_TX:
if (!dmn->info.caps.tx_sw_owner)
if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, tx))
return -ENOTSUPP;

dmn->info.supp_sw_steering = true;
Expand All @@ -261,7 +262,7 @@ static int dr_domain_caps_init(struct mlx5_core_dev *mdev,
if (!dmn->info.caps.eswitch_manager)
return -ENOTSUPP;

if (!dmn->info.caps.fdb_sw_owner)
if (!DR_DOMAIN_SW_STEERING_SUPPORTED(dmn, fdb))
return -ENOTSUPP;

dmn->info.rx.ste_type = MLX5DR_STE_TYPE_RX;
Expand Down
12 changes: 8 additions & 4 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_matcher.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ dr_mask_is_vxlan_gpe_set(struct mlx5dr_match_misc3 *misc3)
static bool
dr_matcher_supp_vxlan_gpe(struct mlx5dr_cmd_caps *caps)
{
return caps->flex_protocols & MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED;
return (caps->sw_format_ver == MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
(caps->flex_protocols & MLX5_FLEX_PARSER_VXLAN_GPE_ENABLED);
}

static bool
Expand All @@ -135,7 +136,8 @@ static bool dr_mask_is_tnl_geneve_set(struct mlx5dr_match_misc *misc)
static bool
dr_matcher_supp_tnl_geneve(struct mlx5dr_cmd_caps *caps)
{
return caps->flex_protocols & MLX5_FLEX_PARSER_GENEVE_ENABLED;
return (caps->sw_format_ver == MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
(caps->flex_protocols & MLX5_FLEX_PARSER_GENEVE_ENABLED);
}

static bool
Expand All @@ -148,12 +150,14 @@ dr_mask_is_tnl_geneve(struct mlx5dr_match_param *mask,

static int dr_matcher_supp_icmp_v4(struct mlx5dr_cmd_caps *caps)
{
return caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V4_ENABLED;
return (caps->sw_format_ver == MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
(caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V4_ENABLED);
}

static int dr_matcher_supp_icmp_v6(struct mlx5dr_cmd_caps *caps)
{
return caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V6_ENABLED;
return (caps->sw_format_ver == MLX5_STEERING_FORMAT_CONNECTX_6DX) ||
(caps->flex_protocols & MLX5_FLEX_PARSER_ICMP_V6_ENABLED);
}

static bool dr_mask_is_icmpv6_set(struct mlx5dr_match_misc3 *misc3)
Expand Down
17 changes: 11 additions & 6 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ static int dr_rule_append_to_miss_list(struct mlx5dr_ste_ctx *ste_ctx,
mlx5dr_ste_get_icm_addr(new_last_ste));
list_add_tail(&new_last_ste->miss_list_node, miss_list);

mlx5dr_send_fill_and_append_ste_send_info(last_ste, DR_STE_SIZE_REDUCED,
mlx5dr_send_fill_and_append_ste_send_info(last_ste, DR_STE_SIZE_CTRL,
0, last_ste->hw_ste,
ste_info_last, send_list, true);

Expand Down Expand Up @@ -106,14 +106,19 @@ dr_rule_handle_one_ste_in_update_list(struct mlx5dr_ste_send_info *ste_info,
int ret;

list_del(&ste_info->send_list);

/* Copy data to ste, only reduced size or control, the last 16B (mask)
* is already written to the hw.
*/
if (ste_info->size == DR_STE_SIZE_CTRL)
memcpy(ste_info->ste->hw_ste, ste_info->data, DR_STE_SIZE_CTRL);
else
memcpy(ste_info->ste->hw_ste, ste_info->data, DR_STE_SIZE_REDUCED);

ret = mlx5dr_send_postsend_ste(dmn, ste_info->ste, ste_info->data,
ste_info->size, ste_info->offset);
if (ret)
goto out;
/* Copy data to ste, only reduced size, the last 16B (mask)
* is already written to the hw.
*/
memcpy(ste_info->ste->hw_ste, ste_info->data, DR_STE_SIZE_REDUCED);

out:
kfree(ste_info);
Expand Down Expand Up @@ -456,7 +461,7 @@ dr_rule_rehash_htbl(struct mlx5dr_rule *rule,
ste_to_update = cur_htbl->pointing_ste;
}

mlx5dr_send_fill_and_append_ste_send_info(ste_to_update, DR_STE_SIZE_REDUCED,
mlx5dr_send_fill_and_append_ste_send_info(ste_to_update, DR_STE_SIZE_CTRL,
0, ste_to_update->hw_ste, ste_info,
update_list, false);

Expand Down
29 changes: 20 additions & 9 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,8 @@ int mlx5dr_send_postsend_ste(struct mlx5dr_domain *dmn, struct mlx5dr_ste *ste,
{
struct postsend_info send_info = {};

mlx5dr_ste_prepare_for_postsend(dmn->ste_ctx, data, size);

send_info.write.addr = (uintptr_t)data;
send_info.write.length = size;
send_info.write.lkey = 0;
Expand All @@ -457,6 +459,8 @@ int mlx5dr_send_postsend_htbl(struct mlx5dr_domain *dmn,
if (ret)
return ret;

mlx5dr_ste_prepare_for_postsend(dmn->ste_ctx, formatted_ste, DR_STE_SIZE);

/* Send the data iteration times */
for (i = 0; i < iterations; i++) {
u32 ste_index = i * (byte_size / DR_STE_SIZE);
Expand All @@ -480,6 +484,10 @@ int mlx5dr_send_postsend_htbl(struct mlx5dr_domain *dmn,
/* Copy bit_mask */
memcpy(data + ste_off + DR_STE_SIZE_REDUCED,
mask, DR_STE_SIZE_MASK);
/* Only when we have mask we need to re-arrange the STE */
mlx5dr_ste_prepare_for_postsend(dmn->ste_ctx,
data + (j * DR_STE_SIZE),
DR_STE_SIZE);
}
}

Expand Down Expand Up @@ -509,6 +517,7 @@ int mlx5dr_send_postsend_formatted_htbl(struct mlx5dr_domain *dmn,
u32 byte_size = htbl->chunk->byte_size;
int iterations;
int num_stes;
u8 *copy_dst;
u8 *data;
int ret;
int i;
Expand All @@ -518,20 +527,22 @@ int mlx5dr_send_postsend_formatted_htbl(struct mlx5dr_domain *dmn,
if (ret)
return ret;

for (i = 0; i < num_stes; i++) {
u8 *copy_dst;

/* Copy the same ste on the data buffer */
copy_dst = data + i * DR_STE_SIZE;
memcpy(copy_dst, ste_init_data, DR_STE_SIZE);

if (update_hw_ste) {
/* Copy the reduced ste to hash table ste_arr */
if (update_hw_ste) {
/* Copy the reduced STE to hash table ste_arr */
for (i = 0; i < num_stes; i++) {
copy_dst = htbl->hw_ste_arr + i * DR_STE_SIZE_REDUCED;
memcpy(copy_dst, ste_init_data, DR_STE_SIZE_REDUCED);
}
}

mlx5dr_ste_prepare_for_postsend(dmn->ste_ctx, ste_init_data, DR_STE_SIZE);

/* Copy the same STE on the data buffer */
for (i = 0; i < num_stes; i++) {
copy_dst = data + i * DR_STE_SIZE;
memcpy(copy_dst, ste_init_data, DR_STE_SIZE);
}

/* Send the data iteration times */
for (i = 0; i < iterations; i++) {
u8 ste_index = i * (byte_size / DR_STE_SIZE);
Expand Down
30 changes: 24 additions & 6 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,13 +211,17 @@ dr_ste_remove_head_ste(struct mlx5dr_ste_ctx *ste_ctx,
* |_ste_| --> |_next_ste_| -->|__| -->|__| -->/0
*/
static void
dr_ste_replace_head_ste(struct mlx5dr_ste *ste, struct mlx5dr_ste *next_ste,
dr_ste_replace_head_ste(struct mlx5dr_matcher_rx_tx *nic_matcher,
struct mlx5dr_ste *ste,
struct mlx5dr_ste *next_ste,
struct mlx5dr_ste_send_info *ste_info_head,
struct list_head *send_ste_list,
struct mlx5dr_ste_htbl *stats_tbl)

{
struct mlx5dr_ste_htbl *next_miss_htbl;
u8 hw_ste[DR_STE_SIZE] = {};
int sb_idx;

next_miss_htbl = next_ste->htbl;

Expand All @@ -230,13 +234,19 @@ dr_ste_replace_head_ste(struct mlx5dr_ste *ste, struct mlx5dr_ste *next_ste,
/* Move data from next into ste */
dr_ste_replace(ste, next_ste);

/* Copy all 64 hw_ste bytes */
memcpy(hw_ste, ste->hw_ste, DR_STE_SIZE_REDUCED);
sb_idx = ste->ste_chain_location - 1;
mlx5dr_ste_set_bit_mask(hw_ste,
nic_matcher->ste_builder[sb_idx].bit_mask);

/* Del the htbl that contains the next_ste.
* The origin htbl stay with the same number of entries.
*/
mlx5dr_htbl_put(next_miss_htbl);

mlx5dr_send_fill_and_append_ste_send_info(ste, DR_STE_SIZE_REDUCED,
0, ste->hw_ste,
mlx5dr_send_fill_and_append_ste_send_info(ste, DR_STE_SIZE,
0, hw_ste,
ste_info_head,
send_ste_list,
true /* Copy data */);
Expand Down Expand Up @@ -264,7 +274,7 @@ static void dr_ste_remove_middle_ste(struct mlx5dr_ste_ctx *ste_ctx,
miss_addr = ste_ctx->get_miss_addr(ste->hw_ste);
ste_ctx->set_miss_addr(prev_ste->hw_ste, miss_addr);

mlx5dr_send_fill_and_append_ste_send_info(prev_ste, DR_STE_SIZE_REDUCED, 0,
mlx5dr_send_fill_and_append_ste_send_info(prev_ste, DR_STE_SIZE_CTRL, 0,
prev_ste->hw_ste, ste_info,
send_ste_list, true /* Copy data*/);

Expand Down Expand Up @@ -316,7 +326,8 @@ void mlx5dr_ste_free(struct mlx5dr_ste *ste,
stats_tbl);
} else {
/* First but not only entry in the list */
dr_ste_replace_head_ste(ste, next_ste, &ste_info_head,
dr_ste_replace_head_ste(nic_matcher, ste,
next_ste, &ste_info_head,
&send_ste_list, stats_tbl);
put_on_origin_table = false;
}
Expand Down Expand Up @@ -356,6 +367,13 @@ void mlx5dr_ste_set_hit_addr_by_next_htbl(struct mlx5dr_ste_ctx *ste_ctx,
ste_ctx->set_hit_addr(hw_ste, chunk->icm_addr, chunk->num_of_entries);
}

void mlx5dr_ste_prepare_for_postsend(struct mlx5dr_ste_ctx *ste_ctx,
u8 *hw_ste_p, u32 ste_size)
{
if (ste_ctx->prepare_for_postsend)
ste_ctx->prepare_for_postsend(hw_ste_p, ste_size);
}

/* Init one ste as a pattern for ste data array */
void mlx5dr_ste_set_formatted_ste(struct mlx5dr_ste_ctx *ste_ctx,
u16 gvmi,
Expand Down Expand Up @@ -1127,7 +1145,7 @@ void mlx5dr_ste_build_src_gvmi_qpn(struct mlx5dr_ste_ctx *ste_ctx,

static struct mlx5dr_ste_ctx *mlx5dr_ste_ctx_arr[] = {
[MLX5_STEERING_FORMAT_CONNECTX_5] = &ste_ctx_v0,
[MLX5_STEERING_FORMAT_CONNECTX_6DX] = NULL,
[MLX5_STEERING_FORMAT_CONNECTX_6DX] = &ste_ctx_v1,
};

struct mlx5dr_ste_ctx *mlx5dr_ste_get_ctx(u8 version)
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,12 @@ struct mlx5dr_ste_ctx {
u8 *hw_action,
u32 hw_action_sz,
u16 *used_hw_action_num);

/* Send */
void (*prepare_for_postsend)(u8 *hw_ste_p, u32 ste_size);
};

extern struct mlx5dr_ste_ctx ste_ctx_v0;
extern struct mlx5dr_ste_ctx ste_ctx_v1;

#endif /* _DR_STE_ */
4 changes: 2 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v0.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,8 +248,8 @@ static void dr_ste_v0_set_miss_addr(u8 *hw_ste_p, u64 miss_addr)
static u64 dr_ste_v0_get_miss_addr(u8 *hw_ste_p)
{
u64 index =
(MLX5_GET(ste_rx_steering_mult, hw_ste_p, miss_address_31_6) |
MLX5_GET(ste_rx_steering_mult, hw_ste_p, miss_address_39_32) << 26);
((u64)MLX5_GET(ste_rx_steering_mult, hw_ste_p, miss_address_31_6) |
((u64)MLX5_GET(ste_rx_steering_mult, hw_ste_p, miss_address_39_32)) << 26);

return index << 6;
}
Expand Down
Loading

0 comments on commit 1a2b60f

Please sign in to comment.