git: 87d86f3733a4 - stable/14 - mlx5: Add packet reformat allocation support

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Wed, 22 Nov 2023 01:51:50 UTC
The branch stable/14 has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=87d86f3733a4cdfb5777bc2b28bd11db93c7ab97

commit 87d86f3733a4cdfb5777bc2b28bd11db93c7ab97
Author:     Mark Bloch <mbloch@nvidia.com>
AuthorDate: 2023-02-19 09:36:07 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-11-22 01:40:27 +0000

    mlx5: Add packet reformat allocation support
    
    (cherry picked from commit bb4645b95b0b3976decb4e68934b2e5cc002c53d)
---
 sys/dev/mlx5/fs.h                     | 14 +++++++
 sys/dev/mlx5/mlx5_core/fs_core.h      | 12 ++++++
 sys/dev/mlx5/mlx5_core/mlx5_fs_cmd.c  | 72 +++++++++++++++++++++++++++++++
 sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c | 33 +++++++++++++++
 sys/dev/mlx5/mlx5_ifc.h               | 79 +++++++++++++++++++++++++----------
 5 files changed, 187 insertions(+), 23 deletions(-)

diff --git a/sys/dev/mlx5/fs.h b/sys/dev/mlx5/fs.h
index db5ba1964845..81384b43131d 100644
--- a/sys/dev/mlx5/fs.h
+++ b/sys/dev/mlx5/fs.h
@@ -234,4 +234,18 @@ struct mlx5_modify_hdr *mlx5_modify_header_alloc(struct mlx5_core_dev *dev,
 						 void *modify_actions);
 void mlx5_modify_header_dealloc(struct mlx5_core_dev *dev,
 				struct mlx5_modify_hdr *modify_hdr);
+
+struct mlx5_pkt_reformat_params {
+        int type;
+        u8 param_0;
+        u8 param_1;
+        size_t size;
+        void *data;
+};
+
+struct mlx5_pkt_reformat *mlx5_packet_reformat_alloc(struct mlx5_core_dev *dev,
+						     struct mlx5_pkt_reformat_params *params,
+						     enum mlx5_flow_namespace_type ns_type);
+void mlx5_packet_reformat_dealloc(struct mlx5_core_dev *dev,
+					  struct mlx5_pkt_reformat *pkt_reformat);
 #endif
diff --git a/sys/dev/mlx5/mlx5_core/fs_core.h b/sys/dev/mlx5/mlx5_core/fs_core.h
index 11b042863454..bd7aade07876 100644
--- a/sys/dev/mlx5/mlx5_core/fs_core.h
+++ b/sys/dev/mlx5/mlx5_core/fs_core.h
@@ -173,6 +173,12 @@ struct mlx5_modify_hdr {
 	u32 id;
 };
 
+struct mlx5_pkt_reformat {
+        enum mlx5_flow_namespace_type ns_type;
+        int reformat_type; /* from mlx5_ifc */
+	u32 id;
+};
+
 void _fs_remove_node(struct kref *kref);
 #define fs_get_obj(v, _base)  {v = container_of((_base), typeof(*v), base); }
 #define fs_get_parent(v, child)  {v = (child)->base.parent ?		     \
@@ -310,4 +316,10 @@ int mlx5_cmd_modify_header_alloc(struct mlx5_core_dev *dev,
 				 struct mlx5_modify_hdr *modify_hdr);
 void mlx5_cmd_modify_header_dealloc(struct mlx5_core_dev *dev,
 				    struct mlx5_modify_hdr *modify_hdr);
+int mlx5_cmd_packet_reformat_alloc(struct mlx5_core_dev *dev,
+				   struct mlx5_pkt_reformat_params *params,
+				   enum mlx5_flow_namespace_type namespace,
+				   struct mlx5_pkt_reformat *pkt_reformat);
+void mlx5_cmd_packet_reformat_dealloc(struct mlx5_core_dev *dev,
+				      struct mlx5_pkt_reformat *pkt_reformat);
 #endif
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_fs_cmd.c b/sys/dev/mlx5/mlx5_core/mlx5_fs_cmd.c
index 214b4141a973..7dcd32ed0c44 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_fs_cmd.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_fs_cmd.c
@@ -356,3 +356,75 @@ void mlx5_cmd_modify_header_dealloc(struct mlx5_core_dev *dev,
 
         mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
 }
+
+int mlx5_cmd_packet_reformat_alloc(struct mlx5_core_dev *dev,
+				   struct mlx5_pkt_reformat_params *params,
+				   enum mlx5_flow_namespace_type namespace,
+				   struct mlx5_pkt_reformat *pkt_reformat)
+{
+        u32 out[MLX5_ST_SZ_DW(alloc_packet_reformat_context_out)] = {};
+        void *packet_reformat_context_in;
+        int max_encap_size;
+        void *reformat;
+        int inlen;
+        int err;
+        u32 *in;
+
+        if (namespace == MLX5_FLOW_NAMESPACE_FDB)
+                max_encap_size = MLX5_CAP_ESW(dev, max_encap_header_size);
+        else
+                max_encap_size = MLX5_CAP_FLOWTABLE(dev, max_encap_header_size);
+
+        if (params->size > max_encap_size) {
+                mlx5_core_warn(dev, "encap size %zd too big, max supported is %d\n",
+                               params->size, max_encap_size);
+                return -EINVAL;
+        }
+
+        in = kzalloc(MLX5_ST_SZ_BYTES(alloc_packet_reformat_context_in) +
+                     params->size, GFP_KERNEL);
+        if (!in)
+                return -ENOMEM;
+
+        packet_reformat_context_in = MLX5_ADDR_OF(alloc_packet_reformat_context_in,
+                                                  in, packet_reformat_context);
+        reformat = MLX5_ADDR_OF(packet_reformat_context_in,
+                                packet_reformat_context_in,
+                                reformat_data);
+        inlen = reformat - (void *)in + params->size;
+
+        MLX5_SET(alloc_packet_reformat_context_in, in, opcode,
+                 MLX5_CMD_OP_ALLOC_PACKET_REFORMAT_CONTEXT);
+        MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
+                 reformat_data_size, params->size);
+        MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
+                 reformat_type, params->type);
+        MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
+                 reformat_param_0, params->param_0);
+        MLX5_SET(packet_reformat_context_in, packet_reformat_context_in,
+                 reformat_param_1, params->param_1);
+        if (params->data && params->size)
+                memcpy(reformat, params->data, params->size);
+
+        err = mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
+
+        pkt_reformat->id = MLX5_GET(alloc_packet_reformat_context_out,
+                                    out, packet_reformat_id);
+        kfree(in);
+
+        return err;
+}
+
+void mlx5_cmd_packet_reformat_dealloc(struct mlx5_core_dev *dev,
+				      struct mlx5_pkt_reformat *pkt_reformat)
+{
+        u32 out[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_out)] = {};
+	u32 in[MLX5_ST_SZ_DW(dealloc_packet_reformat_context_in)] = {};
+
+        MLX5_SET(dealloc_packet_reformat_context_in, in, opcode,
+                 MLX5_CMD_OP_DEALLOC_PACKET_REFORMAT_CONTEXT);
+        MLX5_SET(dealloc_packet_reformat_context_in, in, packet_reformat_id,
+                 pkt_reformat->id);
+
+        mlx5_cmd_exec(dev, in, sizeof(in), out, sizeof(out));
+}
diff --git a/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c b/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c
index 9e9febfe902e..358eb671de5a 100644
--- a/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c
+++ b/sys/dev/mlx5/mlx5_core/mlx5_fs_tree.c
@@ -2771,3 +2771,36 @@ void mlx5_modify_header_dealloc(struct mlx5_core_dev *dev,
         kfree(modify_hdr);
 }
 EXPORT_SYMBOL(mlx5_modify_header_dealloc);
+
+struct mlx5_pkt_reformat *mlx5_packet_reformat_alloc(struct mlx5_core_dev *dev,
+                                                     struct mlx5_pkt_reformat_params *params,
+                                                     enum mlx5_flow_namespace_type ns_type)
+{
+        struct mlx5_pkt_reformat *pkt_reformat;
+        int err;
+
+        pkt_reformat = kzalloc(sizeof(*pkt_reformat), GFP_KERNEL);
+        if (!pkt_reformat)
+                return ERR_PTR(-ENOMEM);
+
+        pkt_reformat->ns_type = ns_type;
+        pkt_reformat->reformat_type = params->type;
+	err = mlx5_cmd_packet_reformat_alloc(dev, params, ns_type,
+					     pkt_reformat);
+        if (err) {
+                kfree(pkt_reformat);
+                return ERR_PTR(err);
+        }
+
+        return pkt_reformat;
+}
+EXPORT_SYMBOL(mlx5_packet_reformat_alloc);
+
+void mlx5_packet_reformat_dealloc(struct mlx5_core_dev *dev,
+                                  struct mlx5_pkt_reformat *pkt_reformat)
+{
+        mlx5_cmd_packet_reformat_dealloc(dev, pkt_reformat);
+        kfree(pkt_reformat);
+}
+EXPORT_SYMBOL(mlx5_packet_reformat_dealloc);
+
diff --git a/sys/dev/mlx5/mlx5_ifc.h b/sys/dev/mlx5/mlx5_ifc.h
index fcea7342532b..340e3b2e2d03 100644
--- a/sys/dev/mlx5/mlx5_ifc.h
+++ b/sys/dev/mlx5/mlx5_ifc.h
@@ -778,18 +778,40 @@ struct mlx5_ifc_snapshot_cap_bits {
 };
 
 struct mlx5_ifc_e_switch_cap_bits {
-	u8         vport_svlan_strip[0x1];
-	u8         vport_cvlan_strip[0x1];
-	u8         vport_svlan_insert[0x1];
-	u8         vport_cvlan_insert_if_not_exist[0x1];
-	u8         vport_cvlan_insert_overwrite[0x1];
-
-	u8         reserved_0[0x19];
-
-	u8         nic_vport_node_guid_modify[0x1];
-	u8         nic_vport_port_guid_modify[0x1];
+        u8         vport_svlan_strip[0x1];
+        u8         vport_cvlan_strip[0x1];
+        u8         vport_svlan_insert[0x1];
+        u8         vport_cvlan_insert_if_not_exist[0x1];
+        u8         vport_cvlan_insert_overwrite[0x1];
+        u8         reserved_at_5[0x1];
+        u8         vport_cvlan_insert_always[0x1];
+        u8         esw_shared_ingress_acl[0x1];
+        u8         esw_uplink_ingress_acl[0x1];
+        u8         root_ft_on_other_esw[0x1];
+        u8         reserved_at_a[0xf];
+        u8         esw_functions_changed[0x1];
+        u8         reserved_at_1a[0x1];
+        u8         ecpf_vport_exists[0x1];
+        u8         counter_eswitch_affinity[0x1];
+        u8         merged_eswitch[0x1];
+        u8         nic_vport_node_guid_modify[0x1];
+        u8         nic_vport_port_guid_modify[0x1];
+
+        u8         vxlan_encap_decap[0x1];
+        u8         nvgre_encap_decap[0x1];
+        u8         reserved_at_22[0x1];
+        u8         log_max_fdb_encap_uplink[0x5];
+        u8         reserved_at_21[0x3];
+        u8         log_max_packet_reformat_context[0x5];
+        u8         reserved_2b[0x6];
+        u8         max_encap_header_size[0xa];
+
+        u8         reserved_at_40[0xb];
+        u8         log_max_esw_sf[0x5];
+        u8         esw_sf_base_id[0x10];
+
+        u8         reserved_at_60[0x7a0];
 
-	u8         reserved_1[0x7e0];
 };
 
 struct mlx5_ifc_flow_table_eswitch_cap_bits {
@@ -806,9 +828,18 @@ struct mlx5_ifc_flow_table_eswitch_cap_bits {
 
 struct mlx5_ifc_flow_table_nic_cap_bits {
 	u8         nic_rx_multi_path_tirs[0x1];
-	u8         nic_rx_multi_path_tirs_fts[0x1];
-	u8         allow_sniffer_and_nic_rx_shared_tir[0x1];
-	u8         reserved_at_3[0x1fd];
+        u8         nic_rx_multi_path_tirs_fts[0x1];
+        u8         allow_sniffer_and_nic_rx_shared_tir[0x1];
+        u8         reserved_at_3[0x4];
+        u8         sw_owner_reformat_supported[0x1];
+        u8         reserved_at_8[0x18];
+
+        u8         encap_general_header[0x1];
+        u8         reserved_at_21[0xa];
+        u8         log_max_packet_reformat_context[0x5];
+        u8         reserved_at_30[0x6];
+        u8         max_encap_header_size[0xa];
+        u8         reserved_at_40[0x1c0];
 
 	struct mlx5_ifc_flow_table_prop_layout_bits flow_table_properties_nic_receive;
 
@@ -2252,7 +2283,7 @@ struct mlx5_ifc_flow_context_bits {
 	u8         reserved_4[0x8];
 	u8         flow_counter_list_size[0x18];
 
-	u8         reserved_5[0x20];
+	u8         packet_reformat_id[0x20];
 
 	u8	   modify_header_id[0x20];
 
@@ -2923,7 +2954,7 @@ enum {
 };
 
 struct mlx5_ifc_flow_table_context_bits {
-	u8         encap_en[0x1];
+	u8         reformat_en[0x1];
 	u8         decap_en[0x1];
 	u8         reserved_at_2[0x2];
 	u8         table_miss_action[0x4];
@@ -5404,15 +5435,17 @@ struct mlx5_ifc_query_dc_cnak_trace_in_bits {
 };
 
 struct mlx5_ifc_packet_reformat_context_in_bits {
-	u8         reserved_at_0[0x5];
-	u8         reformat_type[0x3];
-	u8         reserved_at_8[0xe];
-	u8         reformat_data_size[0xa];
+        u8         reformat_type[0x8];
+        u8         reserved_at_8[0x4];
+        u8         reformat_param_0[0x4];
+        u8         reserved_at_10[0x6];
+        u8         reformat_data_size[0xa];
 
-	u8         reserved_at_20[0x10];
-	u8         reformat_data[2][0x8];
+        u8         reformat_param_1[0x8];
+        u8         reserved_at_28[0x8];
+        u8         reformat_data[2][0x8];
 
-	u8         more_reformat_data[0][0x8];
+        u8         more_reformat_data[][0x8];
 };
 
 struct mlx5_ifc_query_packet_reformat_context_out_bits {