Skip to content

Commit

Permalink
mlx5: DR, Add support for ConnectX-8 steering
Browse files Browse the repository at this point in the history
Add support for a new SW format version that is implemented by
ConnectX-8.
Except for several differences, the STEv3 is identical to STEv2, so for
most callbacks the STEv3 context struct will call STEv2 functions.

Signed-off-by: Itamar Gozlan <igozlan@nvidia.com>
Reviewed-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
Signed-off-by: Yishai Hadas <yishaih@nvidia.com>
  • Loading branch information
Itamar-Gozlan authored and Yishai Hadas committed Oct 28, 2024
1 parent f936e36 commit 1bce194
Show file tree
Hide file tree
Showing 6 changed files with 246 additions and 1 deletion.
1 change: 1 addition & 0 deletions providers/mlx5/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ rdma_shared_provider(mlx5 libmlx5.map
dr_ste_v0.c
dr_ste_v1.c
dr_ste_v2.c
dr_ste_v3.c
dr_table.c
dr_send.c
dr_vports.c
Expand Down
2 changes: 1 addition & 1 deletion providers/mlx5/dr_domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ static bool dr_domain_caps_is_sw_owner_supported(bool sw_owner,
uint8_t sw_format_ver)
{
return sw_owner ||
(sw_owner_v2 && sw_format_ver <= MLX5_HW_CONNECTX_7);
(sw_owner_v2 && sw_format_ver <= MLX5_HW_CONNECTX_8);
}

static int dr_domain_caps_init(struct ibv_context *ctx,
Expand Down
2 changes: 2 additions & 0 deletions providers/mlx5/dr_ste.c
Original file line number Diff line number Diff line change
Expand Up @@ -1765,6 +1765,8 @@ struct dr_ste_ctx *dr_ste_get_ctx(uint8_t version)
return dr_ste_get_ctx_v1();
else if (version == MLX5_HW_CONNECTX_7)
return dr_ste_get_ctx_v2();
else if (version == MLX5_HW_CONNECTX_8)
return dr_ste_get_ctx_v3();

errno = EOPNOTSUPP;

Expand Down
1 change: 1 addition & 0 deletions providers/mlx5/dr_ste.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,5 +282,6 @@ struct dr_ste_ctx {
struct dr_ste_ctx *dr_ste_get_ctx_v0(void);
struct dr_ste_ctx *dr_ste_get_ctx_v1(void);
struct dr_ste_ctx *dr_ste_get_ctx_v2(void);
struct dr_ste_ctx *dr_ste_get_ctx_v3(void);

#endif
200 changes: 200 additions & 0 deletions providers/mlx5/dr_ste_v3.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
/*
* Copyright (c) 2024, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
*
* This software is available to you under a choice of one of two
* licenses. You may choose to be licensed under the terms of the GNU
* General Public License (GPL) Version 2, available from the file
* COPYING in the main directory of this source tree, or the
* OpenIB.org BSD license below:
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
* - Redistributions of source code must retain the above
* copyright notice, this list of conditions and the following
* disclaimer.
*
* - Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

#include "dr_ste_v1.h"

static void dr_ste_v3_set_encap(uint8_t *hw_ste_p, uint8_t *d_action,
uint32_t reformat_id, int size)
{
DR_STE_SET(double_action_insert_with_ptr_v3, d_action, action_id,
DR_STE_V1_ACTION_ID_INSERT_POINTER);
/* The hardware expects here size in words (2 bytes) */
DR_STE_SET(double_action_insert_with_ptr_v3, d_action, size, size / 2);
DR_STE_SET(double_action_insert_with_ptr_v3, d_action, pointer, reformat_id);
DR_STE_SET(double_action_insert_with_ptr_v3, d_action, attributes,
DR_STE_V1_ACTION_INSERT_PTR_ATTR_ENCAP);

dr_ste_v1_set_reparse(hw_ste_p);
}

static void dr_ste_v3_set_push_vlan(uint8_t *ste, uint8_t *d_action,
uint32_t vlan_hdr)
{
DR_STE_SET(double_action_insert_with_inline_v3, d_action, action_id,
DR_STE_V1_ACTION_ID_INSERT_INLINE);
/* The hardware expects here offset to vlan header in words (2 byte) */
DR_STE_SET(double_action_insert_with_inline_v3, d_action, start_offset,
HDR_LEN_L2_MACS >> 1);
DR_STE_SET(double_action_insert_with_inline_v3, d_action, inline_data, vlan_hdr);
dr_ste_v1_set_reparse(ste);
}

static void dr_ste_v3_set_pop_vlan(uint8_t *hw_ste_p, uint8_t *s_action,
uint8_t vlans_num)
{
DR_STE_SET(single_action_remove_header_size_v3, s_action, action_id,
DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE);
DR_STE_SET(single_action_remove_header_size_v3, s_action, start_anchor,
DR_STE_HEADER_ANCHOR_1ST_VLAN);
/* The hardware expects here size in words (2 byte) */
DR_STE_SET(single_action_remove_header_size_v3, s_action, remove_size,
(HDR_LEN_L2_VLAN >> 1) * vlans_num);

dr_ste_v1_set_reparse(hw_ste_p);
}

static void dr_ste_v3_set_encap_l3(uint8_t *hw_ste_p,
uint8_t *frst_s_action,
uint8_t *scnd_d_action,
uint32_t reformat_id,
int size)
{
/* Remove L2 headers */
DR_STE_SET(single_action_remove_header_v3, frst_s_action, action_id,
DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER);
DR_STE_SET(single_action_remove_header_v3, frst_s_action, end_anchor,
DR_STE_HEADER_ANCHOR_IPV6_IPV4);

/* Encapsulate with given reformat ID */
DR_STE_SET(double_action_insert_with_ptr_v3, scnd_d_action, action_id,
DR_STE_V1_ACTION_ID_INSERT_POINTER);
/* The hardware expects here size in words (2 bytes) */
DR_STE_SET(double_action_insert_with_ptr_v3, scnd_d_action, size, size / 2);
DR_STE_SET(double_action_insert_with_ptr_v3, scnd_d_action, pointer, reformat_id);
DR_STE_SET(double_action_insert_with_ptr_v3, scnd_d_action, attributes,
DR_STE_V1_ACTION_INSERT_PTR_ATTR_ENCAP);

dr_ste_v1_set_reparse(hw_ste_p);
}

static void dr_ste_v3_set_rx_decap(uint8_t *hw_ste_p, uint8_t *s_action)
{
DR_STE_SET(single_action_remove_header_v3, s_action, action_id,
DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER);
DR_STE_SET(single_action_remove_header_v3, s_action, decap, 1);
DR_STE_SET(single_action_remove_header_v3, s_action, vni_to_cqe, 1);
DR_STE_SET(single_action_remove_header_v3, s_action, end_anchor,
DR_STE_HEADER_ANCHOR_INNER_MAC);

dr_ste_v1_set_reparse(hw_ste_p);
}

static int
dr_ste_v3_set_action_decap_l3_list(void *data, uint32_t data_sz,
uint8_t *hw_action, uint32_t hw_action_sz,
uint16_t *used_hw_action_num)
{
uint8_t padded_data[DR_STE_L2_HDR_MAX_SZ] = {};
void *data_ptr = padded_data;
uint16_t used_actions = 0;
uint32_t inline_data_sz;
uint32_t i;

if (hw_action_sz / DR_STE_ACTION_DOUBLE_SZ < DR_STE_DECAP_L3_ACTION_NUM) {
errno = EINVAL;
return errno;
}

inline_data_sz =
DEVX_FLD_SZ_BYTES(ste_double_action_insert_with_inline_v3, inline_data);

/* Add an alignment padding */
memcpy(padded_data + data_sz % inline_data_sz, data, data_sz);

/* Remove L2L3 outer headers */
DR_STE_SET(single_action_remove_header_v3, hw_action, action_id,
DR_STE_V1_ACTION_ID_REMOVE_HEADER_TO_HEADER);
DR_STE_SET(single_action_remove_header_v3, hw_action, decap, 1);
DR_STE_SET(single_action_remove_header_v3, hw_action, vni_to_cqe, 1);
DR_STE_SET(single_action_remove_header_v3, hw_action, end_anchor,
DR_STE_HEADER_ANCHOR_INNER_IPV6_IPV4);
hw_action += DR_STE_ACTION_DOUBLE_SZ;
used_actions++;

/* Point to the last dword of the header */
data_ptr += (data_sz / inline_data_sz) * inline_data_sz;

/* Add the new header using inline action 4Byte at a time, the header
* is added in reversed order to the beginning of the packet to avoid
* incorrect parsing by the HW. Since header is 14B or 18B an extra
* two bytes are padded and later removed.
*/
for (i = 0; i < data_sz / inline_data_sz + 1; i++) {
void *addr_inline;

DR_STE_SET(double_action_insert_with_inline_v3, hw_action, action_id,
DR_STE_V1_ACTION_ID_INSERT_INLINE);
/* The hardware expects here offset to words (2 bytes) */
DR_STE_SET(double_action_insert_with_inline_v3, hw_action, start_offset, 0);

/* Copy byte in order to skip endianness problem */
addr_inline = DEVX_ADDR_OF(ste_double_action_insert_with_inline_v3,
hw_action, inline_data);
memcpy(addr_inline, data_ptr - inline_data_sz * i, inline_data_sz);
hw_action += DR_STE_ACTION_DOUBLE_SZ;
used_actions++;
}

/* Remove first 2 extra bytes */
DR_STE_SET(single_action_remove_header_size_v3, hw_action, action_id,
DR_STE_V1_ACTION_ID_REMOVE_BY_SIZE);
DR_STE_SET(single_action_remove_header_size_v3, hw_action, start_offset, 0);
/* The hardware expects here size in words (2 bytes) */
DR_STE_SET(single_action_remove_header_size_v3, hw_action, remove_size, 1);
used_actions++;

*used_hw_action_num = used_actions;

return 0;
}

static struct dr_ste_ctx ste_ctx_v3;
static pthread_mutex_t ctx_mutex = PTHREAD_MUTEX_INITIALIZER;

struct dr_ste_ctx *dr_ste_get_ctx_v3(void)
{
pthread_mutex_lock(&ctx_mutex);

if (!ste_ctx_v3.actions_caps) {
ste_ctx_v3 = *dr_ste_get_ctx_v2();
ste_ctx_v3.set_encap = &dr_ste_v3_set_encap;
ste_ctx_v3.set_push_vlan = &dr_ste_v3_set_push_vlan;
ste_ctx_v3.set_pop_vlan = &dr_ste_v3_set_pop_vlan;
ste_ctx_v3.set_rx_decap = &dr_ste_v3_set_rx_decap;
ste_ctx_v3.set_encap_l3 = &dr_ste_v3_set_encap_l3;
ste_ctx_v3.set_action_decap_l3_list = &dr_ste_v3_set_action_decap_l3_list;
}

pthread_mutex_unlock(&ctx_mutex);

return &ste_ctx_v3;
}
41 changes: 41 additions & 0 deletions providers/mlx5/mlx5_ifc.h
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,7 @@ enum mlx5_ifc_steering_format_version {
MLX5_HW_CONNECTX_5 = 0x0,
MLX5_HW_CONNECTX_6DX = 0x1,
MLX5_HW_CONNECTX_7 = 0x2,
MLX5_HW_CONNECTX_8 = 0x3,
};

enum mlx5_ifc_ste_v1_modify_hdr_offset {
Expand Down Expand Up @@ -3096,6 +3097,46 @@ struct mlx5_ifc_ste_def33_v1_bits {
u8 outer_ip_protocol[0x8];
};

struct mlx5_ifc_ste_single_action_remove_header_v3_bits {
u8 action_id[0x8];
u8 start_anchor[0x7];
u8 end_anchor[0x7];
u8 reserved_at_16[0x1];
u8 outer_l4_remove[0x1];
u8 reserved_at_18[0x4];
u8 decap[0x1];
u8 vni_to_cqe[0x1];
u8 qos_profile[0x2];
};

struct mlx5_ifc_ste_single_action_remove_header_size_v3_bits {
u8 action_id[0x8];
u8 start_anchor[0x7];
u8 start_offset[0x8];
u8 outer_l4_remove[0x1];
u8 reserved_at_18[0x2];
u8 remove_size[0x6];
};

struct mlx5_ifc_ste_double_action_insert_with_inline_v3_bits {
u8 action_id[0x8];
u8 start_anchor[0x7];
u8 start_offset[0x8];
u8 reserved_at_17[0x9];

u8 inline_data[0x20];
};

struct mlx5_ifc_ste_double_action_insert_with_ptr_v3_bits {
u8 action_id[0x8];
u8 start_anchor[0x7];
u8 start_offset[0x8];
u8 size[0x6];
u8 attributes[0x3];

u8 pointer[0x20];
};

struct mlx5_ifc_set_action_in_bits {
u8 action_type[0x4];
u8 field[0xc];
Expand Down

0 comments on commit 1bce194

Please sign in to comment.