net/mlx5: DR, Use HW specific logic API when writing STE
authorYevgeny Kliteynik <kliteyn@nvidia.com>
Sun, 6 Dec 2020 16:13:01 +0000 (18:13 +0200)
committerSaeed Mahameed <saeedm@nvidia.com>
Sat, 30 Jan 2021 02:12:55 +0000 (18:12 -0800)
STEv0 format and STEv1 HW format are different, each has a
different order:
STEv0: CTRL 32B, TAG 16B, BITMASK 16B
STEv1: CTRL 32B, BITMASK 16B, TAG 16B

To make this transparent to upper layers we introduce a
new ste_ctx function to format the STE prior to writing it.

Signed-off-by: Erez Shitrit <erezsh@nvidia.com>
Signed-off-by: Alex Vesker <valex@nvidia.com>
Signed-off-by: Yevgeny Kliteynik <kliteyn@nvidia.com>
Signed-off-by: Saeed Mahameed <saeedm@nvidia.com>
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_rule.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_send.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste.h
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_ste_v1.c
drivers/net/ethernet/mellanox/mlx5/core/steering/dr_types.h

index fcea2a21abe9cbcfe04de342f9d5a9e21688f18d..b337d6626bffcd498c6c165c77f1bea1680c91cc 100644 (file)
@@ -106,10 +106,6 @@ dr_rule_handle_one_ste_in_update_list(struct mlx5dr_ste_send_info *ste_info,
        int ret;
 
        list_del(&ste_info->send_list);
-       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 or control, the last 16B (mask)
         * is already written to the hw.
@@ -119,6 +115,11 @@ dr_rule_handle_one_ste_in_update_list(struct mlx5dr_ste_send_info *ste_info,
        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;
+
 out:
        kfree(ste_info);
        return ret;
index 24dede1b0a2096b68f0de71f8601af5543cc130d..83c4c877d558c02673fdcb27cddee60f5cea27e0 100644 (file)
@@ -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;
@@ -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);
@@ -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);
                        }
                }
 
@@ -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;
@@ -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);
index e21b61030e3524a0931fa36a212e52999dc69134..8ac3ccdda84c67284842b978ac2c9b2154c156ea 100644 (file)
@@ -356,6 +356,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,
index 0dc08fe1a9dbae2dd5ecbd9bc34139b89c7fd0d7..06bcb0ee8f96578a78d839912da3fc585bc7d792 100644 (file)
@@ -160,6 +160,9 @@ 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;
index 42b853fa3465442aafcf313b448f1965591fe7fc..4088d6e515082f729bcde3e2c7b2f378eb337ff3 100644 (file)
@@ -324,6 +324,26 @@ static void dr_ste_v1_init(u8 *hw_ste_p, u16 lu_type,
        MLX5_SET(ste_match_bwc_v1, hw_ste_p, miss_address_63_48, gvmi);
 }
 
+static void dr_ste_v1_prepare_for_postsend(u8 *hw_ste_p,
+                                          u32 ste_size)
+{
+       u8 *tag = hw_ste_p + DR_STE_SIZE_CTRL;
+       u8 *mask = tag + DR_STE_SIZE_TAG;
+       u8 tmp_tag[DR_STE_SIZE_TAG] = {};
+
+       if (ste_size == DR_STE_SIZE_CTRL)
+               return;
+
+       WARN_ON(ste_size != DR_STE_SIZE);
+
+       /* Backup tag */
+       memcpy(tmp_tag, tag, DR_STE_SIZE_TAG);
+
+       /* Swap mask and tag  both are the same size */
+       memcpy(tag, mask, DR_STE_SIZE_MASK);
+       memcpy(mask, tmp_tag, DR_STE_SIZE_TAG);
+}
+
 static void dr_ste_v1_set_rx_flow_tag(u8 *s_action, u32 flow_tag)
 {
        MLX5_SET(ste_single_action_flow_tag_v1, s_action, action_id,
@@ -1608,4 +1628,6 @@ struct mlx5dr_ste_ctx ste_ctx_v1 = {
        .set_action_add                 = &dr_ste_v1_set_action_add,
        .set_action_copy                = &dr_ste_v1_set_action_copy,
        .set_action_decap_l3_list       = &dr_ste_v1_set_action_decap_l3_list,
+       /* Send */
+       .prepare_for_postsend           = &dr_ste_v1_prepare_for_postsend,
 };
index 8d2c3b6e2755241f6d0099677ba294ef3bec9f24..3b76142218d157de349ec058f6b20a752389a220 100644 (file)
@@ -1072,6 +1072,9 @@ struct mlx5dr_icm_chunk *
 mlx5dr_icm_alloc_chunk(struct mlx5dr_icm_pool *pool,
                       enum mlx5dr_icm_chunk_size chunk_size);
 void mlx5dr_icm_free_chunk(struct mlx5dr_icm_chunk *chunk);
+
+void mlx5dr_ste_prepare_for_postsend(struct mlx5dr_ste_ctx *ste_ctx,
+                                    u8 *hw_ste_p, u32 ste_size);
 int mlx5dr_ste_htbl_init_and_postsend(struct mlx5dr_domain *dmn,
                                      struct mlx5dr_domain_rx_tx *nic_dmn,
                                      struct mlx5dr_ste_htbl *htbl,