From nobody Tue Feb 01 15:24:31 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 8045A1916D19; Tue, 1 Feb 2022 15:24:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Jp7yR4lkYz3Fl7; Tue, 1 Feb 2022 15:24:31 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1643729073; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=fJpsgBBL1CznhnKA6v4f4o0/mCgu7pklZvLGOUIPrB8=; b=WP8yZCsTyuzAywnthI9EGT2lWxf0U+RaM5po7R/wu3U+YZJNjbzl1mgJxQK6FZUW2ZBWJc WC/Hrvt9KA82IFynRN7NQACXWUisED1h52aAf8cqzgx0Xt+WrXv6reEKTZdxZHU9t3pUA5 b5k9kwxv0GHVRsxQfL06wxLQn5xMNbvT9ztivKvIK0ouxppIVjH1J9RRuuTKicm7uLQp1j QABXkmTFfj1Ck3c9QDHi99vqXS+EIvbckodBh347loJhpjXjdAV/8CM1lvLuigEkm1LiUK W2tCZ3tir1veRX95StA2hX5XDh1EDNZ+0u78raPpyAYBgRREDoJi1MRtHhicmQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 6C1F513424; Tue, 1 Feb 2022 15:24:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 211FOVWP051248; Tue, 1 Feb 2022 15:24:31 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 211FOVXw051247; Tue, 1 Feb 2022 15:24:31 GMT (envelope-from git) Date: Tue, 1 Feb 2022 15:24:31 GMT Message-Id: <202202011524.211FOVXw051247@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Hans Petter Selasky Subject: git: 2c0ade806aa7 - main - mlx5: Implement flow steering helper functions for TCP sockets. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: hselasky X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2c0ade806aa7b450dc4f4c53b5345050eb6dcb4b Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1643729073; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=fJpsgBBL1CznhnKA6v4f4o0/mCgu7pklZvLGOUIPrB8=; b=pKMlk79aDCbrMudXBcz7htZsTKpSLKuL0hDcr3Q9BZCrTfxup+hqoVQTHh5zN2uQAcS2dh WLFuYbo1zKy/OKrViA4w1l73Hn/LhuUgC1Dz/O56l7Y4Gkmkv9atXYZlGtZapehWgJWhSL eaHJgpSqdS8veeJAosRRPzkuq+MBPm6rZ4ncbTTxLBoSzEPh9IGdp5gt5CpZIjqGsklIYr uQuXEaEb8UCj4u7FcWpkg0fKRydGPRhNkzq+DUZSiXS/6ryJMy1Y5kpcZOhT42RKzMI9kZ MCPKDG1OfA8yZBhAprxdnWz7YKeBWgaRbDecZHk4wwATypASy4RhysvsSfKwMQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1643729073; a=rsa-sha256; cv=none; b=FlK4aKLorFUSOvv1GYitjDNV1DW3fn9XXh1Ya98MnEp6lYB/tr6vcPtQkCXgao/A0Xulyr Vx3rVI+hXCRxB+iuNP+b6G1xJKkrtil5H5vhoMpYoI+B2H3sBgxiT0YBeot03aE/ly5Kz6 dT212ovunQshmUOJydeGQvgWbL+2bW/m0QoEn/1OXD0hz5f8V6ZXiaGfpcRZ6aNZsXkG8f TIr1G3Cm7hLXA/mFoYxzVKH9E5QwkNx+N+0oDDDqOuHabri01gLIpxmFtJhoSHX6f3Ib3T NHaKyPP48/Ps94b0Teg3CRC5kf8+4PfEglHfWr3rrLpspJYBI01rnoP6Ras6fQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by hselasky: URL: https://cgit.FreeBSD.org/src/commit/?id=2c0ade806aa7b450dc4f4c53b5345050eb6dcb4b commit 2c0ade806aa7b450dc4f4c53b5345050eb6dcb4b Author: Hans Petter Selasky AuthorDate: 2022-02-01 15:20:13 +0000 Commit: Hans Petter Selasky CommitDate: 2022-02-01 15:21:16 +0000 mlx5: Implement flow steering helper functions for TCP sockets. This change adds convenience functions to setup a flow steering rule based on a TCP socket. The helper function gets all the address information from the socket and returns a steering rule, to be used with HW TLS RX offload. MFC after: 1 week Sponsored by: NVIDIA Networking --- sys/conf/files | 2 + sys/dev/mlx5/device.h | 6 + sys/dev/mlx5/mlx5_core/fs_tcp.h | 41 +++ sys/dev/mlx5/mlx5_core/mlx5_fs_tcp.c | 404 ++++++++++++++++++++++++++++++ sys/dev/mlx5/mlx5_en/en.h | 15 ++ sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c | 57 +++-- sys/dev/mlx5/mlx5_ifc.h | 6 +- sys/modules/mlx5/Makefile | 1 + 8 files changed, 512 insertions(+), 20 deletions(-) diff --git a/sys/conf/files b/sys/conf/files index 48ec9511b32f..5f452f851ea6 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -4870,6 +4870,8 @@ dev/mlx5/mlx5_core/mlx5_eswitch.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_cmd.c optional mlx5 pci \ compile-with "${OFED_C}" +dev/mlx5/mlx5_core/mlx5_fs_tcp.c optional mlx5 pci \ + compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fs_tree.c optional mlx5 pci \ compile-with "${OFED_C}" dev/mlx5/mlx5_core/mlx5_fw.c optional mlx5 pci \ diff --git a/sys/dev/mlx5/device.h b/sys/dev/mlx5/device.h index bd52d04244af..f183ca74c2d7 100644 --- a/sys/dev/mlx5/device.h +++ b/sys/dev/mlx5/device.h @@ -1039,6 +1039,12 @@ enum mlx5_mcam_feature_groups { #define MLX5_CAP_FLOWTABLE_MAX(mdev, cap) \ MLX5_GET(flow_table_nic_cap, mdev->hca_caps_max[MLX5_CAP_FLOW_TABLE], cap) +#define MLX5_CAP_FLOWTABLE_NIC_RX(mdev, cap) \ + MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.cap) + +#define MLX5_CAP_FLOWTABLE_NIC_RX_MAX(mdev, cap) \ + MLX5_CAP_FLOWTABLE_MAX(mdev, flow_table_properties_nic_receive.cap) + #define MLX5_CAP_ESW_FLOWTABLE(mdev, cap) \ MLX5_GET(flow_table_eswitch_cap, \ mdev->hca_caps_cur[MLX5_CAP_ESWITCH_FLOW_TABLE], cap) diff --git a/sys/dev/mlx5/mlx5_core/fs_tcp.h b/sys/dev/mlx5/mlx5_core/fs_tcp.h new file mode 100644 index 000000000000..fa11ad9c4cb5 --- /dev/null +++ b/sys/dev/mlx5/mlx5_core/fs_tcp.h @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2020-2021, Mellanox Technologies, Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __MLX5E_ACCEL_FS_TCP_H__ +#define __MLX5E_ACCEL_FS_TCP_H__ + +struct inpcb; +struct mlx5_flow_rule; +struct mlx5e_priv; + +int mlx5e_accel_fs_tcp_create(struct mlx5e_priv *); +void mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *); +struct mlx5_flow_rule * +mlx5e_accel_fs_add_inpcb(struct mlx5e_priv *, + struct inpcb *, uint32_t tirn, uint32_t flow_tag, uint16_t vlan_id); +#define MLX5E_ACCEL_FS_ADD_INPCB_NO_VLAN 0xFFFF +void mlx5e_accel_fs_del_inpcb(struct mlx5_flow_rule *); + +#endif /* __MLX5E_ACCEL_FS_TCP_H__ */ diff --git a/sys/dev/mlx5/mlx5_core/mlx5_fs_tcp.c b/sys/dev/mlx5/mlx5_core/mlx5_fs_tcp.c new file mode 100644 index 000000000000..543c7a4ef502 --- /dev/null +++ b/sys/dev/mlx5/mlx5_core/mlx5_fs_tcp.c @@ -0,0 +1,404 @@ +/*- + * Copyright (c) 2020-2021, Mellanox Technologies, Ltd. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "opt_inet.h" +#include "opt_inet6.h" + +#include + +#include +#include +#include + +#include + +#include + +#if defined(INET) || defined(INET6) +static void +accel_fs_tcp_set_ipv4_flow(struct mlx5_flow_spec *spec, struct inpcb *inp) +{ + MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol); + MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, IPPROTO_TCP); + MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_version); + MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_version, 4); + memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value, + outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4), + &inp->inp_faddr, 4); + memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value, + outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4), + &inp->inp_laddr, 4); + MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, + outer_headers.src_ipv4_src_ipv6.ipv4_layout.ipv4); + MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, + outer_headers.dst_ipv4_dst_ipv6.ipv4_layout.ipv4); +} +#endif + +#ifdef INET6 +static void +accel_fs_tcp_set_ipv6_flow(struct mlx5_flow_spec *spec, struct inpcb *inp) +{ + MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_protocol); + MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_protocol, IPPROTO_TCP); + MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.ip_version); + MLX5_SET(fte_match_param, spec->match_value, outer_headers.ip_version, 6); + memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value, + outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6), + &inp->in6p_faddr, 16); + memcpy(MLX5_ADDR_OF(fte_match_param, spec->match_value, + outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6), + &inp->in6p_laddr, 16); + memset(MLX5_ADDR_OF(fte_match_param, spec->match_criteria, + outer_headers.src_ipv4_src_ipv6.ipv6_layout.ipv6), + 0xff, 16); + memset(MLX5_ADDR_OF(fte_match_param, spec->match_criteria, + outer_headers.dst_ipv4_dst_ipv6.ipv6_layout.ipv6), + 0xff, 16); +} +#endif + +void +mlx5e_accel_fs_del_inpcb(struct mlx5_flow_rule *rule) +{ + mlx5_del_flow_rule(rule); +} + +struct mlx5_flow_rule * +mlx5e_accel_fs_add_inpcb(struct mlx5e_priv *priv, + struct inpcb *inp, uint32_t tirn, uint32_t flow_tag, + uint16_t vlan_id) +{ + struct mlx5_flow_destination dest = {}; + struct mlx5e_flow_table *ft = NULL; + struct mlx5e_accel_fs_tcp *fs_tcp; + struct mlx5_flow_rule *flow; + struct mlx5_flow_spec *spec; + + spec = kvzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return (ERR_PTR(-ENOMEM)); + + fs_tcp = &priv->fts.accel_tcp; + + spec->match_criteria_enable = MLX5_MATCH_OUTER_HEADERS; + + INP_RLOCK(inp); + /* Set VLAN ID to match, if any. */ + MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.cvlan_tag); + MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, outer_headers.first_vid); + if (vlan_id != MLX5E_ACCEL_FS_ADD_INPCB_NO_VLAN) { + MLX5_SET_TO_ONES(fte_match_param, spec->match_value, outer_headers.cvlan_tag); + MLX5_SET(fte_match_param, spec->match_value, outer_headers.first_vid, vlan_id); + } + + /* Set TCP port numbers. */ + MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, + outer_headers.tcp_dport); + MLX5_SET_TO_ONES(fte_match_param, spec->match_criteria, + outer_headers.tcp_sport); + MLX5_SET(fte_match_param, spec->match_value, outer_headers.tcp_dport, + ntohs(inp->inp_lport)); + MLX5_SET(fte_match_param, spec->match_value, outer_headers.tcp_sport, + ntohs(inp->inp_fport)); + + /* Set IP addresses. */ + switch (INP_SOCKAF(inp->inp_socket)) { +#ifdef INET + case AF_INET: + accel_fs_tcp_set_ipv4_flow(spec, inp); + ft = &fs_tcp->tables[MLX5E_ACCEL_FS_IPV4_TCP]; + break; +#endif +#ifdef INET6 + case AF_INET6: + if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0 && + IN6_IS_ADDR_V4MAPPED(&inp->in6p_faddr)) { + accel_fs_tcp_set_ipv4_flow(spec, inp); + ft = &fs_tcp->tables[MLX5E_ACCEL_FS_IPV4_TCP]; + } else { + accel_fs_tcp_set_ipv6_flow(spec, inp); + ft = &fs_tcp->tables[MLX5E_ACCEL_FS_IPV6_TCP]; + } + break; +#endif + default: + break; + } + INP_RUNLOCK(inp); + + if (!ft) { + flow = ERR_PTR(-EINVAL); + goto out; + } + + dest.type = MLX5_FLOW_DESTINATION_TYPE_TIR; + dest.tir_num = tirn; + + flow = mlx5_add_flow_rule(ft->t, spec->match_criteria_enable, + spec->match_criteria, + spec->match_value, + MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, + flow_tag, + &dest); +out: + kvfree(spec); + return (flow); +} + +static int +accel_fs_tcp_add_default_rule(struct mlx5e_priv *priv, int type) +{ + static u32 match_criteria[MLX5_ST_SZ_DW(fte_match_param)]; + static u32 match_value[MLX5_ST_SZ_DW(fte_match_param)]; + struct mlx5_flow_destination dest = {}; + struct mlx5e_accel_fs_tcp *fs_tcp; + struct mlx5_flow_rule *rule; + + fs_tcp = &priv->fts.accel_tcp; + + dest.type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; + + /* + * Traffic not matched by flow table rules should be forwarded + * to the next flow table in order to not be dropped by the + * default action. Refer to the diagram in + * mlx5_en_flow_table.c for more information about the order + * of flow tables. + */ + dest.ft = (type == MLX5E_ACCEL_FS_TCP_NUM_TYPES - 1) ? + priv->fts.vlan.t : fs_tcp->tables[type + 1].t; + + rule = mlx5_add_flow_rule(fs_tcp->tables[type].t, 0, match_criteria, match_value, + MLX5_FLOW_CONTEXT_ACTION_FWD_DEST, MLX5_FS_DEFAULT_FLOW_TAG, &dest); + if (IS_ERR(rule)) + return (PTR_ERR(rule)); + + fs_tcp->default_rules[type] = rule; + return (0); +} + +#define MLX5E_ACCEL_FS_TCP_NUM_GROUPS (2) +#define MLX5E_ACCEL_FS_TCP_GROUP1_SIZE (BIT(16) - 1) +#define MLX5E_ACCEL_FS_TCP_GROUP2_SIZE (BIT(0)) +#define MLX5E_ACCEL_FS_TCP_TABLE_SIZE (MLX5E_ACCEL_FS_TCP_GROUP1_SIZE +\ + MLX5E_ACCEL_FS_TCP_GROUP2_SIZE) +static int +accel_fs_tcp_create_groups(struct mlx5e_flow_table *ft, int type) +{ + int inlen = MLX5_ST_SZ_BYTES(create_flow_group_in); + void *outer_headers_c; + int ix = 0; + u32 *in; + int err; + u8 *mc; + + ft->g = kcalloc(MLX5E_ACCEL_FS_TCP_NUM_GROUPS, sizeof(*ft->g), GFP_KERNEL); + in = kvzalloc(inlen, GFP_KERNEL); + if (!in || !ft->g) { + kfree(ft->g); + kvfree(in); + return (-ENOMEM); + } + + mc = MLX5_ADDR_OF(create_flow_group_in, in, match_criteria); + outer_headers_c = MLX5_ADDR_OF(fte_match_param, mc, outer_headers); + MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, ip_protocol); + MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, ip_version); + MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, cvlan_tag); + MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, first_vid); + + switch (type) { + case MLX5E_ACCEL_FS_IPV4_TCP: + case MLX5E_ACCEL_FS_IPV6_TCP: + MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, tcp_dport); + MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, tcp_sport); + break; + default: + err = -EINVAL; + goto out; + } + + switch (type) { + case MLX5E_ACCEL_FS_IPV4_TCP: + MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, + src_ipv4_src_ipv6.ipv4_layout.ipv4); + MLX5_SET_TO_ONES(fte_match_set_lyr_2_4, outer_headers_c, + dst_ipv4_dst_ipv6.ipv4_layout.ipv4); + break; + case MLX5E_ACCEL_FS_IPV6_TCP: + memset(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, + src_ipv4_src_ipv6.ipv6_layout.ipv6), + 0xff, 16); + memset(MLX5_ADDR_OF(fte_match_set_lyr_2_4, outer_headers_c, + dst_ipv4_dst_ipv6.ipv6_layout.ipv6), + 0xff, 16); + break; + default: + err = -EINVAL; + goto out; + } + + MLX5_SET_CFG(in, match_criteria_enable, MLX5_MATCH_OUTER_HEADERS); + MLX5_SET_CFG(in, start_flow_index, ix); + ix += MLX5E_ACCEL_FS_TCP_GROUP1_SIZE; + MLX5_SET_CFG(in, end_flow_index, ix - 1); + ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); + if (IS_ERR(ft->g[ft->num_groups])) + goto err; + ft->num_groups++; + + /* Default Flow Group */ + memset(in, 0, inlen); + MLX5_SET_CFG(in, start_flow_index, ix); + ix += MLX5E_ACCEL_FS_TCP_GROUP2_SIZE; + MLX5_SET_CFG(in, end_flow_index, ix - 1); + ft->g[ft->num_groups] = mlx5_create_flow_group(ft->t, in); + if (IS_ERR(ft->g[ft->num_groups])) + goto err; + ft->num_groups++; + + kvfree(in); + return (0); + +err: + err = PTR_ERR(ft->g[ft->num_groups]); + ft->g[ft->num_groups] = NULL; +out: + kvfree(in); + + return (err); +} + +static void +accel_fs_tcp_destroy_groups(struct mlx5e_flow_table *ft) +{ + int i; + + for (i = ft->num_groups - 1; i >= 0; i--) { + if (!IS_ERR_OR_NULL(ft->g[i])) + mlx5_destroy_flow_group(ft->g[i]); + ft->g[i] = NULL; + } + ft->num_groups = 0; +} + +static int +accel_fs_tcp_create_table(struct mlx5e_priv *priv, int type) +{ + struct mlx5e_flow_table *ft = &priv->fts.accel_tcp.tables[type]; + int err; + + ft->num_groups = 0; + ft->t = mlx5_create_flow_table(priv->fts.accel_tcp.ns, 0, "tcp", + MLX5E_ACCEL_FS_TCP_TABLE_SIZE); + if (IS_ERR(ft->t)) { + err = PTR_ERR(ft->t); + ft->t = NULL; + return (err); + } + + err = accel_fs_tcp_create_groups(ft, type); + if (err) + goto err_destroy_flow_table; + + return (0); + +err_destroy_flow_table: + mlx5_destroy_flow_table(ft->t); + ft->t = NULL; + return (err); +} + +static void +accel_fs_tcp_destroy_table(struct mlx5e_priv *priv, int i) +{ + struct mlx5e_accel_fs_tcp *fs_tcp; + struct mlx5e_flow_table *ft; + + fs_tcp = &priv->fts.accel_tcp; + ft = fs_tcp->tables + i; + + mlx5_del_flow_rule(fs_tcp->default_rules[i]); + + accel_fs_tcp_destroy_groups(ft); + kfree(ft->g); + ft->g = NULL; + mlx5_destroy_flow_table(ft->t); + ft->t = NULL; +} + +void +mlx5e_accel_fs_tcp_destroy(struct mlx5e_priv *priv) +{ + int i; + + if (!MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version)) + return; + + for (i = 0; i < MLX5E_ACCEL_FS_TCP_NUM_TYPES; i++) + accel_fs_tcp_destroy_table(priv, i); +} + +int +mlx5e_accel_fs_tcp_create(struct mlx5e_priv *priv) +{ + int i, err; + + if (!MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ft_field_support.outer_ip_version)) + return (0); + + /* Setup namespace pointer. */ + priv->fts.accel_tcp.ns = mlx5_get_flow_namespace( + priv->mdev, MLX5_FLOW_NAMESPACE_OFFLOADS); + + /* + * Create flow tables first, because the priority level is + * assigned at allocation time. + */ + for (i = 0; i != MLX5E_ACCEL_FS_TCP_NUM_TYPES; i++) { + err = accel_fs_tcp_create_table(priv, i); + if (err) + goto err_destroy_tables; + } + + /* Create default rules last. */ + for (i = 0; i != MLX5E_ACCEL_FS_TCP_NUM_TYPES; i++) { + err = accel_fs_tcp_add_default_rule(priv, i); + if (err) + goto err_destroy_rules; + } + return (0); + +err_destroy_rules: + while (i--) + mlx5_del_flow_rule(priv->fts.accel_tcp.default_rules[i]); + i = MLX5E_ACCEL_FS_TCP_NUM_TYPES; + +err_destroy_tables: + while (i--) + accel_fs_tcp_destroy_table(priv, i); + return (err); +} diff --git a/sys/dev/mlx5/mlx5_en/en.h b/sys/dev/mlx5/mlx5_en/en.h index 29898a626b38..c7e15b8968ba 100644 --- a/sys/dev/mlx5/mlx5_en/en.h +++ b/sys/dev/mlx5/mlx5_en/en.h @@ -72,6 +72,8 @@ #include #include +#define MLX5_SET_CFG(p, f, v) MLX5_SET(create_flow_group_in, p, f, v) + #define MLX5E_MAX_PRIORITY 8 #define MLX5E_MAX_FEC_10X_25X 4 @@ -1015,6 +1017,18 @@ struct mlx5e_flow_table { struct mlx5_flow_group **g; }; +enum accel_fs_tcp_type { + MLX5E_ACCEL_FS_IPV4_TCP, + MLX5E_ACCEL_FS_IPV6_TCP, + MLX5E_ACCEL_FS_TCP_NUM_TYPES, +}; + +struct mlx5e_accel_fs_tcp { + struct mlx5_flow_namespace *ns; + struct mlx5e_flow_table tables[MLX5E_ACCEL_FS_TCP_NUM_TYPES]; + struct mlx5_flow_rule *default_rules[MLX5E_ACCEL_FS_TCP_NUM_TYPES]; +}; + struct mlx5e_flow_tables { struct mlx5_flow_namespace *ns; struct mlx5e_flow_table vlan; @@ -1024,6 +1038,7 @@ struct mlx5e_flow_tables { struct mlx5e_flow_table main_vxlan; struct mlx5_flow_rule *main_vxlan_rule[MLX5E_NUM_TT]; struct mlx5e_flow_table inner_rss; + struct mlx5e_accel_fs_tcp accel_tcp; }; struct mlx5e_xmit_args { diff --git a/sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c b/sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c index 10ff5a3e7417..5d52415381aa 100644 --- a/sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c +++ b/sys/dev/mlx5/mlx5_en/mlx5_en_flow_table.c @@ -33,28 +33,44 @@ #include #include #include +#include /* * The flow tables with rules define the packet processing on receive. - * Currently, the following structure is set up to handle different offloads - * like VLAN decapsulation, packet classification, RSS hashing, VxLAN checksum - * offloading: + * Currently the following structure is set up to handle different + * offloads like TLS RX offload, VLAN decapsulation, packet + * classification, RSS hashing, VxLAN checksum offloading: * - * - * +=========+ +=========+ +=================+ - * |VLAN ft: | |VxLAN | |VxLAN Main | + * +=========+ +=========+ +=================+ + * |TCP/IPv4 | |TCP/IPv4 | |TCP/IPv4 Match | + * |Flowtable|------>| |----->|Outer Proto Match|=====> TLS TIR n + * | | |Catch-all|\ | | + * +=========+ +=========+| +=================+ + * | + * +------------------------+ + * V + * +=========+ +=========+ +=================+ + * |TCP/IPv6 | |TCP/IPv6 | |TCP/IPv6 Match | + * |Flowtable|------>| |----->|Outer Proto Match|=====> TLS TIR n + * | | |Catch-all|\ | | + * +=========+ +=========+| +=================+ + * | + * +------------------------+ + * V + * +=========+ +=========+ +=================+ + * |VLAN ft: | |VxLAN | |VxLAN Main | * |CTAG/STAG|------>| VNI|----->|Inner Proto Match|=====> Inner TIR n - * |VID/noVID|/ |Catch-all|\ | | - * +=========+ +=========+| +=================+ - * | - * | - * | - * v - * +=================+ - * |Main | - * |Outer Proto Match|=====> TIR n - * | | - * +=================+ + * |VID/noVID|/ |Catch-all|\ | | + * +=========+ +=========+| +=================+ + * | + * | + * | + * v + * +=================+ + * |Main | + * |Outer Proto Match|=====> TIR n + * | | + * +=================+ * * The path through flow rules directs each packet into an appropriate TIR, * according to the: @@ -2292,8 +2308,14 @@ mlx5e_open_flow_tables(struct mlx5e_priv *priv) if (err) goto err_destroy_inner_rss_flow_table; + err = mlx5e_accel_fs_tcp_create(priv); + if (err) + goto err_del_vxlan_catchall_rule; + return (0); +err_del_vxlan_catchall_rule: + mlx5e_del_vxlan_catchall_rule(priv); err_destroy_inner_rss_flow_table: mlx5e_destroy_inner_rss_flow_table(priv); err_destroy_main_vxlan_flow_table: @@ -2311,6 +2333,7 @@ err_destroy_vlan_flow_table: void mlx5e_close_flow_tables(struct mlx5e_priv *priv) { + mlx5e_accel_fs_tcp_destroy(priv); mlx5e_del_vxlan_catchall_rule(priv); mlx5e_destroy_inner_rss_flow_table(priv); mlx5e_destroy_main_vxlan_flow_table(priv); diff --git a/sys/dev/mlx5/mlx5_ifc.h b/sys/dev/mlx5/mlx5_ifc.h index 04aea2d0be3f..d128c9cb45cd 100644 --- a/sys/dev/mlx5/mlx5_ifc.h +++ b/sys/dev/mlx5/mlx5_ifc.h @@ -339,7 +339,7 @@ struct mlx5_ifc_flow_table_fields_supported_bits { u8 outer_dmac[0x1]; u8 outer_smac[0x1]; u8 outer_ether_type[0x1]; - u8 reserved_0[0x1]; + u8 outer_ip_version[0x1]; u8 outer_first_prio[0x1]; u8 outer_first_cfi[0x1]; u8 outer_first_vid[0x1]; @@ -372,7 +372,7 @@ struct mlx5_ifc_flow_table_fields_supported_bits { u8 inner_dmac[0x1]; u8 inner_smac[0x1]; u8 inner_ether_type[0x1]; - u8 reserved_3[0x1]; + u8 inner_ip_version[0x1]; u8 inner_first_prio[0x1]; u8 inner_first_cfi[0x1]; u8 inner_first_vid[0x1]; @@ -562,7 +562,7 @@ struct mlx5_ifc_fte_match_set_lyr_2_4_bits { u8 cvlan_tag[0x1]; u8 svlan_tag[0x1]; u8 frag[0x1]; - u8 reserved_1[0x4]; + u8 ip_version[0x4]; u8 tcp_flags[0x9]; u8 tcp_sport[0x10]; diff --git a/sys/modules/mlx5/Makefile b/sys/modules/mlx5/Makefile index c9eccde7d610..f9e282789d1c 100644 --- a/sys/modules/mlx5/Makefile +++ b/sys/modules/mlx5/Makefile @@ -12,6 +12,7 @@ mlx5_diagnostics.c \ mlx5_eq.c \ mlx5_eswitch.c \ mlx5_fs_cmd.c \ +mlx5_fs_tcp.c \ mlx5_fs_tree.c \ mlx5_fw.c \ mlx5_fwdump.c \