From patchwork Fri Nov 11 13:05:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 13040287 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B713FC433FE for ; Fri, 11 Nov 2022 13:05:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233800AbiKKNFo (ORCPT ); Fri, 11 Nov 2022 08:05:44 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35682 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233801AbiKKNFl (ORCPT ); Fri, 11 Nov 2022 08:05:41 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 455F16DCE3; Fri, 11 Nov 2022 05:05:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1668171938; x=1699707938; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=AR+nmO2jQEhSBw5v3+UnruUyhkqnIBsLZ30bfGwKdWA=; b=ZojA2esy/GsQl/ZpPl6SiQSgbK7vqetcAxG2OJgF1fYHBaWxoV26MNAG sunciPA41HVrX/gKhvRPlhVwivRwD6gXzEBjfNiRopVESI/VbFVcfGwlF Kj8qkY+Zd74/GimNxWnIt82l4WH/qz5aPTNDW1QrPj70h1XXasnVm7Wbs 0+YqiGxR10rJ2t9YlwvaS+8BTFT04NDxLmnvMeeMeraI+tf3XAuaDPyOf SCp2EWC0+PgCsWlA3S/5CbrazLNGo7ivOvybTN12FSFuA40unHr400iSa kDo/x79DxI9aaaVoFqOaXR3cTKQHCnqnMHsp7oueHJIkzgQvmbBN4EwTe g==; X-IronPort-AV: E=Sophos;i="5.96,156,1665471600"; d="scan'208";a="123000911" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 11 Nov 2022 06:05:37 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Fri, 11 Nov 2022 06:05:33 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Fri, 11 Nov 2022 06:05:29 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen , Simon Horman , Louis Peens , "Wojciech Drewek" , Baowen Zheng , Maksym Glubokiy , Pablo Neira Ayuso Subject: [PATCH net-next 1/6] net: flow_offload: add support for ARP frame matching Date: Fri, 11 Nov 2022 14:05:14 +0100 Message-ID: <20221111130519.1459549-2-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221111130519.1459549-1-steen.hegelund@microchip.com> References: <20221111130519.1459549-1-steen.hegelund@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This adds a new flow_rule_match_arp function that allows drivers to be able to dissect ARP frames. Signed-off-by: Steen Hegelund --- include/net/flow_offload.h | 6 ++++++ net/core/flow_offload.c | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/include/net/flow_offload.h b/include/net/flow_offload.h index 7a60bc6d72c9..0400a0ac8a29 100644 --- a/include/net/flow_offload.h +++ b/include/net/flow_offload.h @@ -32,6 +32,10 @@ struct flow_match_vlan { struct flow_dissector_key_vlan *key, *mask; }; +struct flow_match_arp { + struct flow_dissector_key_arp *key, *mask; +}; + struct flow_match_ipv4_addrs { struct flow_dissector_key_ipv4_addrs *key, *mask; }; @@ -98,6 +102,8 @@ void flow_rule_match_vlan(const struct flow_rule *rule, struct flow_match_vlan *out); void flow_rule_match_cvlan(const struct flow_rule *rule, struct flow_match_vlan *out); +void flow_rule_match_arp(const struct flow_rule *rule, + struct flow_match_arp *out); void flow_rule_match_ipv4_addrs(const struct flow_rule *rule, struct flow_match_ipv4_addrs *out); void flow_rule_match_ipv6_addrs(const struct flow_rule *rule, diff --git a/net/core/flow_offload.c b/net/core/flow_offload.c index abe423fd5736..acfc1f88ea79 100644 --- a/net/core/flow_offload.c +++ b/net/core/flow_offload.c @@ -97,6 +97,13 @@ void flow_rule_match_cvlan(const struct flow_rule *rule, } EXPORT_SYMBOL(flow_rule_match_cvlan); +void flow_rule_match_arp(const struct flow_rule *rule, + struct flow_match_arp *out) +{ + FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_ARP, out); +} +EXPORT_SYMBOL(flow_rule_match_arp); + void flow_rule_match_ipv4_addrs(const struct flow_rule *rule, struct flow_match_ipv4_addrs *out) { From patchwork Fri Nov 11 13:05:15 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 13040288 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4F607C4332F for ; Fri, 11 Nov 2022 13:05:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233812AbiKKNFp (ORCPT ); Fri, 11 Nov 2022 08:05:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35684 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233217AbiKKNFl (ORCPT ); Fri, 11 Nov 2022 08:05:41 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 31D267C8F1; Fri, 11 Nov 2022 05:05:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1668171939; x=1699707939; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=MwMrFBuJYmXmypJ56eKGRvFX0VICWHsAbwpGcGNvxjw=; b=ThkIGyP9k7AmriEtKJcYIoOHDXvrt/RNTkmTkbEnYQpu5wtCwDhcpS+B BT+6KWvJwIiRBhRrITRzqRY1E3gO0If3N/j5yVA8PEgG6xGP1OBZCYorE iQP7rviKAP5Z7AA+qQxVV1JemIIBwDEYWAEKX4IcdAgam3MzhgiiLszJL NPi5AwFDyxmVHPhMaRPGRe/JvC5csQ7P2bKtpj6uaBlrBNbmwAgPlY5JL U9pcmLZWt9QGC+85+8e5AikDq2zl5tZ4D/HlO9sRGhwSMqZH6x65uKWbQ c/uUAM6OPlR78VfyCEknbWnpL17yx4OwGDUyZ41OYM81pidEhMdELYZhK w==; X-IronPort-AV: E=Sophos;i="5.96,156,1665471600"; d="scan'208";a="123000930" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 11 Nov 2022 06:05:37 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Fri, 11 Nov 2022 06:05:37 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Fri, 11 Nov 2022 06:05:33 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen , Simon Horman , Louis Peens , "Wojciech Drewek" , Baowen Zheng , Maksym Glubokiy , Pablo Neira Ayuso Subject: [PATCH net-next 2/6] net: microchip: sparx5: Add support for TC flower ARP dissector Date: Fri, 11 Nov 2022 14:05:15 +0100 Message-ID: <20221111130519.1459549-3-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221111130519.1459549-1-steen.hegelund@microchip.com> References: <20221111130519.1459549-1-steen.hegelund@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This add support for Sparx5 for dissecting TC ARP flower filter keys and sets up the Sparx5 IS2 VCAP to generate the ARP keyset for ARP frames. Signed-off-by: Steen Hegelund --- .../microchip/sparx5/sparx5_tc_flower.c | 76 +++++++++++++++++++ .../microchip/sparx5/sparx5_vcap_impl.c | 2 +- 2 files changed, 77 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c index 7b364f6b4546..b76b8fc567bb 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c @@ -26,10 +26,24 @@ struct sparx5_tc_flower_parse_usage { */ static u16 sparx5_tc_known_etypes[] = { ETH_P_ALL, + ETH_P_ARP, ETH_P_IP, ETH_P_IPV6, }; +enum sparx5_is2_arp_opcode { + SPX5_IS2_ARP_REQUEST, + SPX5_IS2_ARP_REPLY, + SPX5_IS2_RARP_REQUEST, + SPX5_IS2_RARP_REPLY, +}; + +enum tc_arp_opcode { + TC_ARP_OP_RESERVED, + TC_ARP_OP_REQUEST, + TC_ARP_OP_REPLY, +}; + static bool sparx5_tc_is_known_etype(u16 etype) { int idx; @@ -404,6 +418,67 @@ sparx5_tc_flower_handler_tcp_usage(struct sparx5_tc_flower_parse_usage *st) return err; } +static int +sparx5_tc_flower_handler_arp_usage(struct sparx5_tc_flower_parse_usage *st) +{ + struct flow_match_arp mt; + u16 value, mask; + u32 ipval, ipmsk; + int err; + + flow_rule_match_arp(st->frule, &mt); + + if (mt.mask->op) { + mask = 0x3; + if (st->l3_proto == ETH_P_ARP) { + value = mt.key->op == TC_ARP_OP_REQUEST ? + SPX5_IS2_ARP_REQUEST : + SPX5_IS2_ARP_REPLY; + } else { /* RARP */ + value = mt.key->op == TC_ARP_OP_REQUEST ? + SPX5_IS2_RARP_REQUEST : + SPX5_IS2_RARP_REPLY; + } + err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_ARP_OPCODE, + value, mask); + if (err) + goto out; + } + + /* The IS2 ARP keyset does not support ARP hardware addresses */ + if (!is_zero_ether_addr(mt.mask->sha) || + !is_zero_ether_addr(mt.mask->tha)) + goto out; + + if (mt.mask->sip) { + ipval = be32_to_cpu((__force __be32)mt.key->sip); + ipmsk = be32_to_cpu((__force __be32)mt.mask->sip); + + err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L3_IP4_SIP, + ipval, ipmsk); + if (err) + goto out; + } + + if (mt.mask->tip) { + ipval = be32_to_cpu((__force __be32)mt.key->tip); + ipmsk = be32_to_cpu((__force __be32)mt.mask->tip); + + err = vcap_rule_add_key_u32(st->vrule, VCAP_KF_L3_IP4_DIP, + ipval, ipmsk); + if (err) + goto out; + } + + st->used_keys |= BIT(FLOW_DISSECTOR_KEY_ARP); + + return err; + +out: + NL_SET_ERR_MSG_MOD(st->fco->common.extack, "arp parse error"); + return err; +} + static int sparx5_tc_flower_handler_ip_usage(struct sparx5_tc_flower_parse_usage *st) { @@ -438,6 +513,7 @@ static int (*sparx5_tc_flower_usage_handlers[])(struct sparx5_tc_flower_parse_us [FLOW_DISSECTOR_KEY_BASIC] = sparx5_tc_flower_handler_basic_usage, [FLOW_DISSECTOR_KEY_VLAN] = sparx5_tc_flower_handler_vlan_usage, [FLOW_DISSECTOR_KEY_TCP] = sparx5_tc_flower_handler_tcp_usage, + [FLOW_DISSECTOR_KEY_ARP] = sparx5_tc_flower_handler_arp_usage, [FLOW_DISSECTOR_KEY_IP] = sparx5_tc_flower_handler_ip_usage, }; diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c index 10bc56cd0045..db73e2b19dc5 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c @@ -540,7 +540,7 @@ static void sparx5_vcap_port_key_selection(struct sparx5 *sparx5, VCAP_IS2_PS_IPV4_UC_IP4_TCP_UDP_OTHER, VCAP_IS2_PS_IPV6_MC_IP_7TUPLE, VCAP_IS2_PS_IPV6_UC_IP_7TUPLE, - VCAP_IS2_PS_ARP_MAC_ETYPE); + VCAP_IS2_PS_ARP_ARP); for (lookup = 0; lookup < admin->lookups; ++lookup) { for (portno = 0; portno < SPX5_PORTS; ++portno) { spx5_wr(keysel, sparx5, From patchwork Fri Nov 11 13:05:16 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 13040289 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B2FADC4332F for ; Fri, 11 Nov 2022 13:05:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233833AbiKKNFs (ORCPT ); Fri, 11 Nov 2022 08:05:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35748 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233827AbiKKNFp (ORCPT ); Fri, 11 Nov 2022 08:05:45 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.153.233]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 30346275E5; Fri, 11 Nov 2022 05:05:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1668171945; x=1699707945; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SOHnGIhnQ7MsnOmlSCy+bgSFKgeTg1oB8GLr2mkHikw=; b=mGEdJLrULSmdx3n9NN1vKTyPPMtQFV/tb2Ee4v1KHxLrGc8wFdUUVcs+ sG4Sv8yPUKGTovI+BqKC2CrF/aKoBaffvYlIAepZjPnO3mXuENdptWVPF 5lgXUHalpycrNOUO1MKNAM5+RYIcbI4tZsKx9y9+q8Yho3vNEehh+7IuT UZV+/gwbTEa+63/wos4h0eSBsZIIhjjbHVV+rxdPrCv9EWuGfR+wiF2iZ R+J4Kd9dVOvEPC6Q3rJ7TeZaRDUZP8n16Yj+z9Bl/VOkcF8fPKkT9cpaK H1VxlGKWgo9evUOiioHIjJmjhWZJpKLfNmgld5G7soXmjCqGCVqEQZA7O A==; X-IronPort-AV: E=Sophos;i="5.96,156,1665471600"; d="scan'208";a="188613198" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa5.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 11 Nov 2022 06:05:43 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Fri, 11 Nov 2022 06:05:42 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Fri, 11 Nov 2022 06:05:38 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen , Simon Horman , Louis Peens , "Wojciech Drewek" , Baowen Zheng , Maksym Glubokiy , Pablo Neira Ayuso Subject: [PATCH net-next 3/6] net: microchip: sparx5: Add/delete rules in sorted order Date: Fri, 11 Nov 2022 14:05:16 +0100 Message-ID: <20221111130519.1459549-4-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221111130519.1459549-1-steen.hegelund@microchip.com> References: <20221111130519.1459549-1-steen.hegelund@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This adds a sorting criteria to rule insertion and deletion. The criteria is (in the listed order): - Rule size (largest size first) - User (based on an enumerated user value) - Priority (highest priority first, aka lowest value) When a rule is deleted the other rules may need to be moved to fill the gap to use the available VCAP address space in the best possible way. Signed-off-by: Steen Hegelund --- .../microchip/sparx5/sparx5_vcap_impl.c | 27 +++- .../net/ethernet/microchip/vcap/vcap_api.c | 137 ++++++++++++++++-- 2 files changed, 151 insertions(+), 13 deletions(-) diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c index db73e2b19dc5..b62c48a3fc45 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c @@ -477,7 +477,32 @@ static void sparx5_vcap_update(struct net_device *ndev, static void sparx5_vcap_move(struct net_device *ndev, struct vcap_admin *admin, u32 addr, int offset, int count) { - /* this will be added later */ + struct sparx5_port *port = netdev_priv(ndev); + struct sparx5 *sparx5 = port->sparx5; + enum vcap_command cmd; + u16 mv_num_pos; + u16 mv_size; + + mv_size = count - 1; + if (offset > 0) { + mv_num_pos = offset - 1; + cmd = VCAP_CMD_MOVE_DOWN; + } else { + mv_num_pos = -offset - 1; + cmd = VCAP_CMD_MOVE_UP; + } + spx5_wr(VCAP_SUPER_CFG_MV_NUM_POS_SET(mv_num_pos) | + VCAP_SUPER_CFG_MV_SIZE_SET(mv_size), + sparx5, VCAP_SUPER_CFG); + spx5_wr(VCAP_SUPER_CTRL_UPDATE_CMD_SET(cmd) | + VCAP_SUPER_CTRL_UPDATE_ENTRY_DIS_SET(0) | + VCAP_SUPER_CTRL_UPDATE_ACTION_DIS_SET(0) | + VCAP_SUPER_CTRL_UPDATE_CNT_DIS_SET(0) | + VCAP_SUPER_CTRL_UPDATE_ADDR_SET(addr) | + VCAP_SUPER_CTRL_CLEAR_CACHE_SET(false) | + VCAP_SUPER_CTRL_UPDATE_SHOT_SET(true), + sparx5, VCAP_SUPER_CTRL); + sparx5_vcap_wait_super_update(sparx5); } /* Provide port information via a callback interface */ diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.c b/drivers/net/ethernet/microchip/vcap/vcap_api.c index b6ab6bae28c0..62b675a37a96 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api.c @@ -941,6 +941,16 @@ int vcap_val_rule(struct vcap_rule *rule, u16 l3_proto) } EXPORT_SYMBOL_GPL(vcap_val_rule); +/* Entries are sorted with increasing values of sort_key. + * I.e. Lowest numerical sort_key is first in list. + * In order to locate largest keys first in list we negate the key size with + * (max_size - size). + */ +static u32 vcap_sort_key(u32 max_size, u32 size, u8 user, u16 prio) +{ + return ((max_size - size) << 24) | (user << 16) | prio; +} + /* calculate the address of the next rule after this (lower address and prio) */ static u32 vcap_next_rule_addr(u32 addr, struct vcap_rule_internal *ri) { @@ -970,17 +980,67 @@ static u32 vcap_set_rule_id(struct vcap_rule_internal *ri) static int vcap_insert_rule(struct vcap_rule_internal *ri, struct vcap_rule_move *move) { + int sw_count = ri->vctrl->vcaps[ri->admin->vtype].sw_count; + struct vcap_rule_internal *duprule, *iter, *elem = NULL; struct vcap_admin *admin = ri->admin; - struct vcap_rule_internal *duprule; + u32 addr; + + ri->sort_key = vcap_sort_key(sw_count, ri->size, ri->data.user, + ri->data.priority); + + /* Insert the new rule in the list of rule based on the sort key + * If the rule needs to be inserted between existing rules then move + * these rules to make room for the new rule and update their start + * address. + */ + list_for_each_entry(iter, &admin->rules, list) { + if (ri->sort_key < iter->sort_key) { + elem = iter; + break; + } + } + + if (!elem) { + ri->addr = vcap_next_rule_addr(admin->last_used_addr, ri); + admin->last_used_addr = ri->addr; + + /* Add a shallow copy of the rule to the VCAP list */ + duprule = vcap_dup_rule(ri); + if (IS_ERR(duprule)) + return PTR_ERR(duprule); + + list_add_tail(&duprule->list, &admin->rules); + return 0; + } + + /* Reuse the space of the current rule */ + addr = elem->addr + elem->size; + ri->addr = vcap_next_rule_addr(addr, ri); + addr = ri->addr; - /* Only support appending rules for now */ - ri->addr = vcap_next_rule_addr(admin->last_used_addr, ri); - admin->last_used_addr = ri->addr; /* Add a shallow copy of the rule to the VCAP list */ duprule = vcap_dup_rule(ri); if (IS_ERR(duprule)) return PTR_ERR(duprule); - list_add_tail(&duprule->list, &admin->rules); + + /* Add before the current entry */ + list_add_tail(&duprule->list, &elem->list); + + /* Update the current rule */ + elem->addr = vcap_next_rule_addr(addr, elem); + addr = elem->addr; + + /* Update the address in the remaining rules in the list */ + list_for_each_entry_continue(elem, &admin->rules, list) { + elem->addr = vcap_next_rule_addr(addr, elem); + addr = elem->addr; + } + + /* Update the move info */ + move->addr = admin->last_used_addr; + move->count = ri->addr - addr; + move->offset = admin->last_used_addr - addr; + admin->last_used_addr = addr; return 0; } @@ -1032,8 +1092,11 @@ struct vcap_rule *vcap_alloc_rule(struct vcap_control *vctrl, { struct vcap_rule_internal *ri; struct vcap_admin *admin; - int maxsize; + int err, maxsize; + err = vcap_api_check(vctrl); + if (err) + return ERR_PTR(err); if (!ndev) return ERR_PTR(-ENODEV); /* Get the VCAP instance */ @@ -1098,12 +1161,57 @@ void vcap_free_rule(struct vcap_rule *rule) } EXPORT_SYMBOL_GPL(vcap_free_rule); +/* Return the alignment offset for a new rule address */ +static int vcap_valid_rule_move(struct vcap_rule_internal *el, int offset) +{ + return (el->addr + offset) % el->size; +} + +/* Update the rule address with an offset */ +static void vcap_adjust_rule_addr(struct vcap_rule_internal *el, int offset) +{ + el->addr += offset; +} + +/* Rules needs to be moved to fill the gap of the deleted rule */ +static int vcap_fill_rule_gap(struct vcap_rule_internal *ri) +{ + struct vcap_admin *admin = ri->admin; + struct vcap_rule_internal *elem; + struct vcap_rule_move move; + int gap = 0, offset = 0; + + /* If the first rule is deleted: Move other rules to the top */ + if (list_is_first(&ri->list, &admin->rules)) + offset = admin->last_valid_addr + 1 - ri->addr - ri->size; + + /* Locate gaps between odd size rules and adjust the move */ + elem = ri; + list_for_each_entry_continue(elem, &admin->rules, list) + gap += vcap_valid_rule_move(elem, ri->size); + + /* Update the address in the remaining rules in the list */ + elem = ri; + list_for_each_entry_continue(elem, &admin->rules, list) + vcap_adjust_rule_addr(elem, ri->size + gap + offset); + + /* Update the move info */ + move.addr = admin->last_used_addr; + move.count = ri->addr - admin->last_used_addr - gap; + move.offset = -(ri->size + gap + offset); + + /* Do the actual move operation */ + vcap_move_rules(ri, &move); + + return gap + offset; +} + /* Delete rule in a VCAP instance */ int vcap_del_rule(struct vcap_control *vctrl, struct net_device *ndev, u32 id) { struct vcap_rule_internal *ri, *elem; struct vcap_admin *admin; - int err; + int gap = 0, err; /* This will later also handle rule moving */ if (!ndev) @@ -1116,18 +1224,23 @@ int vcap_del_rule(struct vcap_control *vctrl, struct net_device *ndev, u32 id) if (!ri) return -EINVAL; admin = ri->admin; + + if (ri->addr > admin->last_used_addr) + gap = vcap_fill_rule_gap(ri); + + /* Delete the rule from the list of rules and the cache */ list_del(&ri->list); + vctrl->ops->init(ndev, admin, admin->last_used_addr, ri->size + gap); + kfree(ri); - /* delete the rule in the cache */ - vctrl->ops->init(ndev, admin, ri->addr, ri->size); + /* Update the last used address */ if (list_empty(&admin->rules)) { admin->last_used_addr = admin->last_valid_addr; } else { - /* update the address range end marker from the last rule in the list */ - elem = list_last_entry(&admin->rules, struct vcap_rule_internal, list); + elem = list_last_entry(&admin->rules, struct vcap_rule_internal, + list); admin->last_used_addr = elem->addr; } - kfree(ri); return 0; } EXPORT_SYMBOL_GPL(vcap_del_rule); From patchwork Fri Nov 11 13:05:17 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 13040290 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81610C433FE for ; Fri, 11 Nov 2022 13:06:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233836AbiKKNGI (ORCPT ); Fri, 11 Nov 2022 08:06:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36148 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233855AbiKKNF5 (ORCPT ); Fri, 11 Nov 2022 08:05:57 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 633687BE7C; Fri, 11 Nov 2022 05:05:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1668171949; x=1699707949; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=mYwmrTNOjBARIZVykxkW5XIgwCztK/JLX3qnOVaXM3E=; b=Fyn/7GhR5sUOlkg++9KarY6dyb+D7wbvdtcx0IjU797VRwB/LNK0wd8f SjmLqh86QZB9ikgvsM2fnC6mLMrQmOHdmNSe090mifajEEY5Zy7xcYj23 cG93Xf9nK2Q3ejFfSQa0n9CbTmqjsBhf6YPiUky6njqfkmDD8z3S3Sswb 4woi7GZag/S+Kt3sUV6s/ck32llTFxmTvLoIf5Y0EwEofNXfET7YjHoF3 GX3ZgXxVXRL19qR+jk5FQbRJG8K8HtvGRIwfc8SeNDjPhHLQA1CYtNBO2 uYoSpUjlTd9LsP6C3mSnuETE/kKQQiNLsEga8OOsnhfrC3vD2pA1n5csQ w==; X-IronPort-AV: E=Sophos;i="5.96,156,1665471600"; d="scan'208";a="183107393" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa4.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 11 Nov 2022 06:05:47 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Fri, 11 Nov 2022 06:05:46 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Fri, 11 Nov 2022 06:05:42 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen , Simon Horman , Louis Peens , "Wojciech Drewek" , Baowen Zheng , Maksym Glubokiy , Pablo Neira Ayuso Subject: [PATCH net-next 4/6] net: microchip: sparx5: Add support for IS2 VCAP rule counters Date: Fri, 11 Nov 2022 14:05:17 +0100 Message-ID: <20221111130519.1459549-5-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221111130519.1459549-1-steen.hegelund@microchip.com> References: <20221111130519.1459549-1-steen.hegelund@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This adds API methods to set and get a rule counter. A VCAP instance may contain the counter as part of the VCAP cache area, and this counter may be one or more bits in width. This type of counter automatically increments it value when the rule is hit. Other VCAP instances have a dedicated counter area outside of the VCAP and in this case the rule must contain the counter id to be able to locate the counter value. In this case there must also be a rule action that updates the counter using the rule id when the rule is hit. The Sparx5 IS2 VCAP uses a dedicated counter area. Signed-off-by: Steen Hegelund --- .../microchip/sparx5/sparx5_vcap_impl.c | 47 +++++++++++- .../net/ethernet/microchip/vcap/vcap_api.c | 71 +++++++++++++++++++ .../ethernet/microchip/vcap/vcap_api_client.h | 11 +++ 3 files changed, 127 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c index b62c48a3fc45..e8f3d030eba2 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_vcap_impl.c @@ -428,15 +428,58 @@ static void sparx5_vcap_cache_write(struct net_device *ndev, default: break; } + if (sel & VCAP_SEL_COUNTER) { + start = start & 0xfff; /* counter limit */ + if (admin->vinst == 0) + spx5_wr(admin->cache.counter, sparx5, + ANA_ACL_CNT_A(start)); + else + spx5_wr(admin->cache.counter, sparx5, + ANA_ACL_CNT_B(start)); + spx5_wr(admin->cache.sticky, sparx5, + VCAP_SUPER_VCAP_CNT_DAT(0)); + } } /* API callback used for reading from the VCAP into the VCAP cache */ static void sparx5_vcap_cache_read(struct net_device *ndev, struct vcap_admin *admin, - enum vcap_selection sel, u32 start, + enum vcap_selection sel, + u32 start, u32 count) { - /* this will be added later */ + struct sparx5_port *port = netdev_priv(ndev); + struct sparx5 *sparx5 = port->sparx5; + u32 *keystr, *mskstr, *actstr; + int idx; + + keystr = &admin->cache.keystream[start]; + mskstr = &admin->cache.maskstream[start]; + actstr = &admin->cache.actionstream[start]; + if (sel & VCAP_SEL_ENTRY) { + for (idx = 0; idx < count; ++idx) { + keystr[idx] = spx5_rd(sparx5, + VCAP_SUPER_VCAP_ENTRY_DAT(idx)); + mskstr[idx] = ~spx5_rd(sparx5, + VCAP_SUPER_VCAP_MASK_DAT(idx)); + } + } + if (sel & VCAP_SEL_ACTION) { + for (idx = 0; idx < count; ++idx) + actstr[idx] = spx5_rd(sparx5, + VCAP_SUPER_VCAP_ACTION_DAT(idx)); + } + if (sel & VCAP_SEL_COUNTER) { + start = start & 0xfff; /* counter limit */ + if (admin->vinst == 0) + admin->cache.counter = + spx5_rd(sparx5, ANA_ACL_CNT_A(start)); + else + admin->cache.counter = + spx5_rd(sparx5, ANA_ACL_CNT_B(start)); + admin->cache.sticky = + spx5_rd(sparx5, VCAP_SUPER_VCAP_CNT_DAT(0)); + } } /* API callback used for initializing a VCAP address range */ diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.c b/drivers/net/ethernet/microchip/vcap/vcap_api.c index 62b675a37a96..9c660e718526 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api.c @@ -25,6 +25,8 @@ struct vcap_rule_internal { int actionset_sw_regs; /* registers in a subword in an actionset */ int size; /* the size of the rule: max(entry, action) */ u32 addr; /* address in the VCAP at insertion */ + u32 counter_id; /* counter id (if a dedicated counter is available) */ + struct vcap_counter counter; /* last read counter value */ }; /* Moving a rule in the VCAP address space */ @@ -651,6 +653,20 @@ static int vcap_write_rule(struct vcap_rule_internal *ri) return 0; } +static int vcap_write_counter(struct vcap_rule_internal *ri, + struct vcap_counter *ctr) +{ + struct vcap_admin *admin = ri->admin; + + admin->cache.counter = ctr->value; + admin->cache.sticky = ctr->sticky; + ri->vctrl->ops->cache_write(ri->ndev, admin, VCAP_SEL_COUNTER, + ri->counter_id, 0); + ri->vctrl->ops->update(ri->ndev, admin, VCAP_CMD_WRITE, + VCAP_SEL_COUNTER, ri->addr); + return 0; +} + /* Convert a chain id to a VCAP lookup index */ int vcap_chain_id_to_lookup(struct vcap_admin *admin, int cur_cid) { @@ -1547,6 +1563,20 @@ int vcap_rule_add_action_u32(struct vcap_rule *rule, } EXPORT_SYMBOL_GPL(vcap_rule_add_action_u32); +static int vcap_read_counter(struct vcap_rule_internal *ri, + struct vcap_counter *ctr) +{ + struct vcap_admin *admin = ri->admin; + + ri->vctrl->ops->update(ri->ndev, admin, VCAP_CMD_READ, VCAP_SEL_COUNTER, + ri->addr); + ri->vctrl->ops->cache_read(ri->ndev, admin, VCAP_SEL_COUNTER, + ri->counter_id, 0); + ctr->value = admin->cache.counter; + ctr->sticky = admin->cache.sticky; + return 0; +} + /* Copy to host byte order */ void vcap_netbytes_copy(u8 *dst, u8 *src, int count) { @@ -1690,6 +1720,47 @@ int vcap_enable_lookups(struct vcap_control *vctrl, struct net_device *ndev, } EXPORT_SYMBOL_GPL(vcap_enable_lookups); +/* Set a rule counter id (for certain vcaps only) */ +void vcap_rule_set_counter_id(struct vcap_rule *rule, u32 counter_id) +{ + struct vcap_rule_internal *ri = to_intrule(rule); + + ri->counter_id = counter_id; +} +EXPORT_SYMBOL_GPL(vcap_rule_set_counter_id); + +int vcap_rule_set_counter(struct vcap_rule *rule, struct vcap_counter *ctr) +{ + struct vcap_rule_internal *ri = to_intrule(rule); + int err; + + err = vcap_api_check(ri->vctrl); + if (err) + return err; + if (!ctr) { + pr_err("%s:%d: counter is missing\n", __func__, __LINE__); + return -EINVAL; + } + return vcap_write_counter(ri, ctr); +} +EXPORT_SYMBOL_GPL(vcap_rule_set_counter); + +int vcap_rule_get_counter(struct vcap_rule *rule, struct vcap_counter *ctr) +{ + struct vcap_rule_internal *ri = to_intrule(rule); + int err; + + err = vcap_api_check(ri->vctrl); + if (err) + return err; + if (!ctr) { + pr_err("%s:%d: counter is missing\n", __func__, __LINE__); + return -EINVAL; + } + return vcap_read_counter(ri, ctr); +} +EXPORT_SYMBOL_GPL(vcap_rule_get_counter); + #ifdef CONFIG_VCAP_KUNIT_TEST #include "vcap_api_kunit.c" #endif diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h index 0ea5ec96adc8..c2655045d6d4 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h @@ -143,6 +143,11 @@ enum vcap_bit { VCAP_BIT_1 }; +struct vcap_counter { + u32 value; + bool sticky; +}; + /* Enable/Disable the VCAP instance lookups. Chain id 0 means disable */ int vcap_enable_lookups(struct vcap_control *vctrl, struct net_device *ndev, int chain_id, unsigned long cookie, bool enable); @@ -170,6 +175,8 @@ int vcap_set_rule_set_keyset(struct vcap_rule *rule, /* Update the actionset for the rule */ int vcap_set_rule_set_actionset(struct vcap_rule *rule, enum vcap_actionfield_set actionset); +/* Set a rule counter id (for certain VCAPs only) */ +void vcap_rule_set_counter_id(struct vcap_rule *rule, u32 counter_id); /* VCAP rule field operations */ int vcap_rule_add_key_bit(struct vcap_rule *rule, enum vcap_key_field key, @@ -187,6 +194,10 @@ int vcap_rule_add_action_bit(struct vcap_rule *rule, int vcap_rule_add_action_u32(struct vcap_rule *rule, enum vcap_action_field action, u32 value); +/* VCAP rule counter operations */ +int vcap_rule_set_counter(struct vcap_rule *rule, struct vcap_counter *ctr); +int vcap_rule_get_counter(struct vcap_rule *rule, struct vcap_counter *ctr); + /* VCAP lookup operations */ /* Convert a chain id to a VCAP lookup index */ int vcap_chain_id_to_lookup(struct vcap_admin *admin, int cur_cid); From patchwork Fri Nov 11 13:05:18 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 13040291 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24089C433FE for ; Fri, 11 Nov 2022 13:06:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233884AbiKKNGk (ORCPT ); Fri, 11 Nov 2022 08:06:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36900 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233925AbiKKNGd (ORCPT ); Fri, 11 Nov 2022 08:06:33 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C8130862F4; Fri, 11 Nov 2022 05:05:58 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1668171958; x=1699707958; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=8XwoBqdgKoM5V3kbMOhCihQp2eLtKE9DTDcoUojaHV4=; b=RX8MhFQdVuAkumfqNqv1sBrTpXU7jlPYgZTTuypDpdw9O6E/KJi6HrUF kztBg2qCQ9VHhJAqDv3qbkucUMXB7k4WiPKHF664ps45s4v9hvsI0qzxM rG4RDbnNyR1jVF9g8T4ne/jwSoAKAdae82pk9ed+GNaD3L/NswqXsivKx Dl8EtUEU5x8mcptjfZ7ZO86weBjaw7RLl5f2tDzrZLVhA5X6SDAUhP39d 2YmQcjvlaQ2l1qitTEESj51qNtDh+W0EUiZ+yjsKU5mLI5LaNBu+SMnx7 UCdpLMG6wcqgcwV56pBxIzQwA4StR015a7ABOlxAj31LDGtirYy4mevvT w==; X-IronPort-AV: E=Sophos;i="5.96,156,1665471600"; d="scan'208";a="123001275" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 11 Nov 2022 06:05:57 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Fri, 11 Nov 2022 06:05:51 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Fri, 11 Nov 2022 06:05:47 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen , Simon Horman , Louis Peens , "Wojciech Drewek" , Baowen Zheng , Maksym Glubokiy , Pablo Neira Ayuso Subject: [PATCH net-next 5/6] net: microchip: sparx5: Add support for TC flower filter statistics Date: Fri, 11 Nov 2022 14:05:18 +0100 Message-ID: <20221111130519.1459549-6-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221111130519.1459549-1-steen.hegelund@microchip.com> References: <20221111130519.1459549-1-steen.hegelund@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This provides flower filter packet statistics (bytes are not supported) via the dedicated IS2 counter feature. All rules having the same TC cookie will contribute to the packet statistics for the filter as they are considered to be part of the same TC flower filter. Signed-off-by: Steen Hegelund --- .../microchip/sparx5/sparx5_tc_flower.c | 68 +++++++++++++++++++ .../net/ethernet/microchip/vcap/vcap_api.c | 25 +++++++ .../ethernet/microchip/vcap/vcap_api_client.h | 3 + 3 files changed, 96 insertions(+) diff --git a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c index b76b8fc567bb..a48baeacc1d2 100644 --- a/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c +++ b/drivers/net/ethernet/microchip/sparx5/sparx5_tc_flower.c @@ -21,6 +21,11 @@ struct sparx5_tc_flower_parse_usage { unsigned int used_keys; }; +struct sparx5_tc_rule_pkt_cnt { + u64 cookie; + u32 pkts; +}; + /* These protocols have dedicated keysets in IS2 and a TC dissector * ETH_P_ARP does not have a TC dissector */ @@ -605,6 +610,20 @@ static int sparx5_tc_flower_action_check(struct vcap_control *vctrl, return 0; } +/* Add a rule counter action - only IS2 is considered for now */ +static int sparx5_tc_add_rule_counter(struct vcap_admin *admin, + struct vcap_rule *vrule) +{ + int err; + + err = vcap_rule_add_action_u32(vrule, VCAP_AF_CNT_ID, vrule->id); + if (err) + return err; + + vcap_rule_set_counter_id(vrule, vrule->id); + return err; +} + static int sparx5_tc_flower_replace(struct net_device *ndev, struct flow_cls_offload *fco, struct vcap_admin *admin) @@ -630,6 +649,11 @@ static int sparx5_tc_flower_replace(struct net_device *ndev, vrule->cookie = fco->cookie; sparx5_tc_use_dissectors(fco, admin, vrule, &l3_proto); + + err = sparx5_tc_add_rule_counter(admin, vrule); + if (err) + goto out; + frule = flow_cls_offload_flow_rule(fco); flow_action_for_each(idx, act, &frule->action) { switch (act->id) { @@ -708,6 +732,48 @@ static int sparx5_tc_flower_destroy(struct net_device *ndev, return err; } +/* Collect packet counts from all rules with the same cookie */ +static int sparx5_tc_rule_counter_cb(void *arg, struct vcap_rule *rule) +{ + struct sparx5_tc_rule_pkt_cnt *rinfo = arg; + struct vcap_counter counter; + int err = 0; + + if (rule->cookie == rinfo->cookie) { + err = vcap_rule_get_counter(rule, &counter); + if (err) + return err; + rinfo->pkts += counter.value; + /* Reset the rule counter */ + counter.value = 0; + vcap_rule_set_counter(rule, &counter); + } + return err; +} + +static int sparx5_tc_flower_stats(struct net_device *ndev, + struct flow_cls_offload *fco, + struct vcap_admin *admin) +{ + struct sparx5_port *port = netdev_priv(ndev); + struct sparx5_tc_rule_pkt_cnt rinfo = {}; + struct vcap_control *vctrl; + ulong lastused = 0; + u64 drops = 0; + u32 pkts = 0; + int err; + + rinfo.cookie = fco->cookie; + vctrl = port->sparx5->vcap_ctrl; + err = vcap_rule_iter(vctrl, sparx5_tc_rule_counter_cb, &rinfo); + if (err) + return err; + pkts = rinfo.pkts; + flow_stats_update(&fco->stats, 0x0, pkts, drops, lastused, + FLOW_ACTION_HW_STATS_IMMEDIATE); + return err; +} + int sparx5_tc_flower(struct net_device *ndev, struct flow_cls_offload *fco, bool ingress) { @@ -729,6 +795,8 @@ int sparx5_tc_flower(struct net_device *ndev, struct flow_cls_offload *fco, return sparx5_tc_flower_replace(ndev, fco, admin); case FLOW_CLS_DESTROY: return sparx5_tc_flower_destroy(ndev, fco, admin); + case FLOW_CLS_STATS: + return sparx5_tc_flower_stats(ndev, fco, admin); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api.c b/drivers/net/ethernet/microchip/vcap/vcap_api.c index 9c660e718526..d12c8ec40fe2 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api.c @@ -1729,6 +1729,31 @@ void vcap_rule_set_counter_id(struct vcap_rule *rule, u32 counter_id) } EXPORT_SYMBOL_GPL(vcap_rule_set_counter_id); +/* Provide all rules via a callback interface */ +int vcap_rule_iter(struct vcap_control *vctrl, + int (*callback)(void *, struct vcap_rule *), void *arg) +{ + struct vcap_rule_internal *ri; + struct vcap_admin *admin; + int ret; + + ret = vcap_api_check(vctrl); + if (ret) + return ret; + + /* Iterate all rules in each VCAP instance */ + list_for_each_entry(admin, &vctrl->list, list) { + list_for_each_entry(ri, &admin->rules, list) { + ret = callback(arg, &ri->data); + if (ret) + return ret; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(vcap_rule_iter); + int vcap_rule_set_counter(struct vcap_rule *rule, struct vcap_counter *ctr) { struct vcap_rule_internal *ri = to_intrule(rule); diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h index c2655045d6d4..654ef8fa6d62 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_client.h +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_client.h @@ -210,6 +210,9 @@ const struct vcap_field *vcap_lookup_keyfield(struct vcap_rule *rule, int vcap_lookup_rule_by_cookie(struct vcap_control *vctrl, u64 cookie); /* Is the next chain id in the following lookup, possible in another VCAP */ bool vcap_is_next_lookup(struct vcap_control *vctrl, int cur_cid, int next_cid); +/* Provide all rules via a callback interface */ +int vcap_rule_iter(struct vcap_control *vctrl, + int (*callback)(void *, struct vcap_rule *), void *arg); /* Copy to host byte order */ void vcap_netbytes_copy(u8 *dst, u8 *src, int count); From patchwork Fri Nov 11 13:05:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steen Hegelund X-Patchwork-Id: 13040295 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44962C433FE for ; Fri, 11 Nov 2022 13:06:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233993AbiKKNGt (ORCPT ); Fri, 11 Nov 2022 08:06:49 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36940 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233937AbiKKNGf (ORCPT ); Fri, 11 Nov 2022 08:06:35 -0500 Received: from esa.microchip.iphmx.com (esa.microchip.iphmx.com [68.232.154.123]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8972B7F540; Fri, 11 Nov 2022 05:06:02 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1668171962; x=1699707962; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=XdjhR+G7HM1WgN1AxkmCczlXrxvdXA0GR7XUV8yUGCE=; b=06eQtBOxJ5MKZr6aA5jUsLgJ1w1U4yotZNYyVn5NKy8KvC6qO8OyqW7h 9TW5uY4ygn6+Ho1puH/1rMY+V7Yc/vBrcX9X8H66tqf9UPMLDv3tm49f2 lvDaLdJRakWqLzZfoNsxcB2pTBtSYI3AuygkJrBUizVVL3wUin96arj8W banhxR6BJGs0oEgI89VpUGd/GOruYJOlOeau3ob/PC/zDSJLYocwfUKir rIVzyLnzffiC6f08Jmwnhht+yQ8ZKDk9K8F9ftKcccq3vH5RVufItEaP+ OH58Ld9WIQ0BETo3QQkR6hLms0YpFgey4mcqVzGhmZrAe+DGJJibVa6cO g==; X-IronPort-AV: E=Sophos;i="5.96,156,1665471600"; d="scan'208";a="123001319" Received: from unknown (HELO email.microchip.com) ([170.129.1.10]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 11 Nov 2022 06:06:00 -0700 Received: from chn-vm-ex04.mchp-main.com (10.10.85.152) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.12; Fri, 11 Nov 2022 06:05:55 -0700 Received: from den-dk-m31857.microchip.com (10.10.115.15) by chn-vm-ex04.mchp-main.com (10.10.85.152) with Microsoft SMTP Server id 15.1.2507.12 via Frontend Transport; Fri, 11 Nov 2022 06:05:51 -0700 From: Steen Hegelund To: "David S . Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni CC: Steen Hegelund , , Randy Dunlap , "Casper Andersson" , Russell King , Wan Jiabing , "Nathan Huckleberry" , , , , "Steen Hegelund" , Daniel Machon , Horatiu Vultur , Lars Povlsen , Simon Horman , Louis Peens , "Wojciech Drewek" , Baowen Zheng , Maksym Glubokiy , Pablo Neira Ayuso Subject: [PATCH net-next 6/6] net: microchip: sparx5: Add KUNIT test of counters and sorted rules Date: Fri, 11 Nov 2022 14:05:19 +0100 Message-ID: <20221111130519.1459549-7-steen.hegelund@microchip.com> X-Mailer: git-send-email 2.38.1 In-Reply-To: <20221111130519.1459549-1-steen.hegelund@microchip.com> References: <20221111130519.1459549-1-steen.hegelund@microchip.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This tests the insert, move and deleting of rules and checks that the unused VCAP addresses are initialized correctly. Signed-off-by: Steen Hegelund --- .../ethernet/microchip/vcap/vcap_api_kunit.c | 526 ++++++++++++++++++ 1 file changed, 526 insertions(+) diff --git a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c index b0ec51b37683..6858e44ce4a5 100644 --- a/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c +++ b/drivers/net/ethernet/microchip/vcap/vcap_api_kunit.c @@ -23,6 +23,9 @@ static u32 test_init_count; static u32 test_hw_counter_id; static struct vcap_cache_data test_hw_cache; static struct net_device test_netdev = {}; +static int test_move_addr; +static int test_move_offset; +static int test_move_count; /* Callback used by the VCAP API */ static enum vcap_keyfield_set test_val_keyset(struct net_device *ndev, @@ -195,6 +198,9 @@ static void test_cache_update(struct net_device *ndev, struct vcap_admin *admin, static void test_cache_move(struct net_device *ndev, struct vcap_admin *admin, u32 addr, int offset, int count) { + test_move_addr = addr; + test_move_offset = offset; + test_move_count = count; } /* Provide port information via a callback interface */ @@ -242,6 +248,88 @@ static void vcap_test_api_init(struct vcap_admin *admin) test_updateaddridx = 0; } +/* Helper function to create a rule of a specific size */ +static struct vcap_rule * +test_vcap_xn_rule_creator(struct kunit *test, int cid, enum vcap_user user, + u16 priority, + int id, int size, int expected_addr) +{ + struct vcap_rule *rule = 0; + struct vcap_rule_internal *ri = 0; + enum vcap_keyfield_set keyset = VCAP_KFS_NO_VALUE; + enum vcap_actionfield_set actionset = VCAP_AFS_NO_VALUE; + int ret; + + /* init before testing */ + memset(test_updateaddr, 0, sizeof(test_updateaddr)); + test_updateaddridx = 0; + test_move_addr = 0; + test_move_offset = 0; + test_move_count = 0; + + switch (size) { + case 2: + keyset = VCAP_KFS_ETAG; + actionset = VCAP_AFS_CLASS_REDUCED; + break; + case 3: + keyset = VCAP_KFS_PURE_5TUPLE_IP4; + actionset = VCAP_AFS_CLASSIFICATION; + break; + case 6: + keyset = VCAP_KFS_NORMAL_5TUPLE_IP4; + actionset = VCAP_AFS_CLASSIFICATION; + break; + case 12: + keyset = VCAP_KFS_NORMAL_7TUPLE; + actionset = VCAP_AFS_FULL; + break; + default: + break; + } + + /* Check that a valid size was used */ + KUNIT_ASSERT_NE(test, VCAP_KFS_NO_VALUE, keyset); + + /* Allocate the rule */ + rule = vcap_alloc_rule(&test_vctrl, &test_netdev, cid, user, priority, + id); + KUNIT_EXPECT_PTR_NE(test, NULL, rule); + + ri = (struct vcap_rule_internal *)rule; + + /* Override rule keyset */ + ret = vcap_set_rule_set_keyset(rule, keyset); + + /* Add rule actions : there must be at least one action */ + ret = vcap_rule_add_action_u32(rule, VCAP_AF_COSID_VAL, 0); + + /* Override rule actionset */ + ret = vcap_set_rule_set_actionset(rule, actionset); + + ret = vcap_val_rule(rule, ETH_P_ALL); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, keyset, rule->keyset); + KUNIT_EXPECT_EQ(test, actionset, rule->actionset); + KUNIT_EXPECT_EQ(test, size, ri->size); + + /* Add rule with write callback */ + ret = vcap_add_rule(rule); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, expected_addr, ri->addr); + return rule; +} + +/* Prepare testing rule deletion */ +static void test_init_rule_deletion(void) +{ + test_move_addr = 0; + test_move_offset = 0; + test_move_count = 0; + test_init_start = 0; + test_init_count = 0; +} + /* Define the test cases. */ static void vcap_api_set_bit_1_test(struct kunit *test) @@ -1333,6 +1421,414 @@ static void vcap_api_encode_rule_test(struct kunit *test) KUNIT_EXPECT_EQ(test, true, ret); } +static void vcap_api_set_rule_counter_test(struct kunit *test) +{ + struct vcap_admin is2_admin = { + .cache = { + .counter = 100, + .sticky = true, + }, + }; + struct vcap_rule_internal ri = { + .data = { + .id = 1001, + }, + .addr = 600, + .admin = &is2_admin, + .counter_id = 1002, + .vctrl = &test_vctrl, + }; + struct vcap_rule_internal ri2 = { + .data = { + .id = 2001, + }, + .addr = 700, + .admin = &is2_admin, + .counter_id = 2002, + .vctrl = &test_vctrl, + }; + struct vcap_counter ctr = { .value = 0, .sticky = false}; + struct vcap_counter ctr2 = { .value = 101, .sticky = true}; + int ret; + + vcap_test_api_init(&is2_admin); + list_add_tail(&ri.list, &is2_admin.rules); + list_add_tail(&ri2.list, &is2_admin.rules); + + pr_info("%s:%d\n", __func__, __LINE__); + ret = vcap_rule_set_counter(&ri.data, &ctr); + pr_info("%s:%d\n", __func__, __LINE__); + KUNIT_EXPECT_EQ(test, 0, ret); + + KUNIT_EXPECT_EQ(test, 1002, test_hw_counter_id); + KUNIT_EXPECT_EQ(test, 0, test_hw_cache.counter); + KUNIT_EXPECT_EQ(test, false, test_hw_cache.sticky); + KUNIT_EXPECT_EQ(test, 600, test_updateaddr[0]); + + ret = vcap_rule_set_counter(&ri2.data, &ctr2); + KUNIT_EXPECT_EQ(test, 0, ret); + + KUNIT_EXPECT_EQ(test, 2002, test_hw_counter_id); + KUNIT_EXPECT_EQ(test, 101, test_hw_cache.counter); + KUNIT_EXPECT_EQ(test, true, test_hw_cache.sticky); + KUNIT_EXPECT_EQ(test, 700, test_updateaddr[1]); +} + +static void vcap_api_get_rule_counter_test(struct kunit *test) +{ + struct vcap_admin is2_admin = { + .cache = { + .counter = 100, + .sticky = true, + }, + }; + struct vcap_rule_internal ri = { + .data = { + .id = 1010, + }, + .addr = 400, + .admin = &is2_admin, + .counter_id = 1011, + .vctrl = &test_vctrl, + }; + struct vcap_rule_internal ri2 = { + .data = { + .id = 2011, + }, + .addr = 300, + .admin = &is2_admin, + .counter_id = 2012, + .vctrl = &test_vctrl, + }; + struct vcap_counter ctr = {}; + struct vcap_counter ctr2 = {}; + int ret; + + vcap_test_api_init(&is2_admin); + test_hw_cache.counter = 55; + test_hw_cache.sticky = true; + + list_add_tail(&ri.list, &is2_admin.rules); + list_add_tail(&ri2.list, &is2_admin.rules); + + ret = vcap_rule_get_counter(&ri.data, &ctr); + KUNIT_EXPECT_EQ(test, 0, ret); + + KUNIT_EXPECT_EQ(test, 1011, test_hw_counter_id); + KUNIT_EXPECT_EQ(test, 55, ctr.value); + KUNIT_EXPECT_EQ(test, true, ctr.sticky); + KUNIT_EXPECT_EQ(test, 400, test_updateaddr[0]); + + test_hw_cache.counter = 22; + test_hw_cache.sticky = false; + + ret = vcap_rule_get_counter(&ri2.data, &ctr2); + KUNIT_EXPECT_EQ(test, 0, ret); + + KUNIT_EXPECT_EQ(test, 2012, test_hw_counter_id); + KUNIT_EXPECT_EQ(test, 22, ctr2.value); + KUNIT_EXPECT_EQ(test, false, ctr2.sticky); + KUNIT_EXPECT_EQ(test, 300, test_updateaddr[1]); +} + +static void vcap_api_rule_insert_in_order_test(struct kunit *test) +{ + /* Data used by VCAP Library callback */ + static u32 keydata[32] = {}; + static u32 mskdata[32] = {}; + static u32 actdata[32] = {}; + + struct vcap_admin admin = { + .vtype = VCAP_TYPE_IS0, + .first_cid = 10000, + .last_cid = 19999, + .lookups = 4, + .last_valid_addr = 3071, + .first_valid_addr = 0, + .last_used_addr = 800, + .cache = { + .keystream = keydata, + .maskstream = mskdata, + .actionstream = actdata, + }, + }; + + vcap_test_api_init(&admin); + + /* Create rules with different sizes and check that they are placed + * at the correct address in the VCAP according to size + */ + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768); +} + +static void vcap_api_rule_insert_reverse_order_test(struct kunit *test) +{ + /* Data used by VCAP Library callback */ + static u32 keydata[32] = {}; + static u32 mskdata[32] = {}; + static u32 actdata[32] = {}; + + struct vcap_admin admin = { + .vtype = VCAP_TYPE_IS0, + .first_cid = 10000, + .last_cid = 19999, + .lookups = 4, + .last_valid_addr = 3071, + .first_valid_addr = 0, + .last_used_addr = 800, + .cache = { + .keystream = keydata, + .maskstream = mskdata, + .actionstream = actdata, + }, + }; + struct vcap_rule_internal *elem; + u32 exp_addr[] = {780, 774, 771, 768, 767}; + int idx; + + vcap_test_api_init(&admin); + + /* Create rules with different sizes and check that they are placed + * at the correct address in the VCAP according to size + */ + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 200, 2, 798); + KUNIT_EXPECT_EQ(test, 0, test_move_offset); + KUNIT_EXPECT_EQ(test, 0, test_move_count); + KUNIT_EXPECT_EQ(test, 0, test_move_addr); + + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 795); + KUNIT_EXPECT_EQ(test, 6, test_move_offset); + KUNIT_EXPECT_EQ(test, 3, test_move_count); + KUNIT_EXPECT_EQ(test, 798, test_move_addr); + + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 400, 6, 792); + KUNIT_EXPECT_EQ(test, 6, test_move_offset); + KUNIT_EXPECT_EQ(test, 6, test_move_count); + KUNIT_EXPECT_EQ(test, 792, test_move_addr); + + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 50, 500, 12, 780); + KUNIT_EXPECT_EQ(test, 18, test_move_offset); + KUNIT_EXPECT_EQ(test, 12, test_move_count); + KUNIT_EXPECT_EQ(test, 786, test_move_addr); + + idx = 0; + list_for_each_entry(elem, &admin.rules, list) { + KUNIT_EXPECT_EQ(test, exp_addr[idx], elem->addr); + ++idx; + } + KUNIT_EXPECT_EQ(test, 768, admin.last_used_addr); +} + +static void vcap_api_rule_remove_at_end_test(struct kunit *test) +{ + /* Data used by VCAP Library callback */ + static u32 keydata[32] = {}; + static u32 mskdata[32] = {}; + static u32 actdata[32] = {}; + + struct vcap_admin admin = { + .vtype = VCAP_TYPE_IS0, + .first_cid = 10000, + .last_cid = 19999, + .lookups = 4, + .last_valid_addr = 3071, + .first_valid_addr = 0, + .last_used_addr = 800, + .cache = { + .keystream = keydata, + .maskstream = mskdata, + .actionstream = actdata, + }, + }; + int ret; + + vcap_test_api_init(&admin); + test_init_rule_deletion(); + + /* Create rules with different sizes and check that they are placed + * at the correct address in the VCAP according to size + */ + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768); + + /* Remove rules again from the end */ + ret = vcap_del_rule(&test_vctrl, &test_netdev, 200); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, 0, test_move_addr); + KUNIT_EXPECT_EQ(test, 0, test_move_offset); + KUNIT_EXPECT_EQ(test, 0, test_move_count); + KUNIT_EXPECT_EQ(test, 768, test_init_start); + KUNIT_EXPECT_EQ(test, 2, test_init_count); + KUNIT_EXPECT_EQ(test, 771, admin.last_used_addr); + + ret = vcap_del_rule(&test_vctrl, &test_netdev, 300); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, 0, test_move_addr); + KUNIT_EXPECT_EQ(test, 0, test_move_offset); + KUNIT_EXPECT_EQ(test, 0, test_move_count); + KUNIT_EXPECT_EQ(test, 771, test_init_start); + KUNIT_EXPECT_EQ(test, 3, test_init_count); + KUNIT_EXPECT_EQ(test, 774, admin.last_used_addr); + + ret = vcap_del_rule(&test_vctrl, &test_netdev, 400); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, 0, test_move_addr); + KUNIT_EXPECT_EQ(test, 0, test_move_offset); + KUNIT_EXPECT_EQ(test, 0, test_move_count); + KUNIT_EXPECT_EQ(test, 774, test_init_start); + KUNIT_EXPECT_EQ(test, 6, test_init_count); + KUNIT_EXPECT_EQ(test, 780, admin.last_used_addr); + + ret = vcap_del_rule(&test_vctrl, &test_netdev, 500); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, 0, test_move_addr); + KUNIT_EXPECT_EQ(test, 0, test_move_offset); + KUNIT_EXPECT_EQ(test, 0, test_move_count); + KUNIT_EXPECT_EQ(test, 780, test_init_start); + KUNIT_EXPECT_EQ(test, 12, test_init_count); + KUNIT_EXPECT_EQ(test, 3071, admin.last_used_addr); +} + +static void vcap_api_rule_remove_in_middle_test(struct kunit *test) +{ + /* Data used by VCAP Library callback */ + static u32 keydata[32] = {}; + static u32 mskdata[32] = {}; + static u32 actdata[32] = {}; + + struct vcap_admin admin = { + .vtype = VCAP_TYPE_IS0, + .first_cid = 10000, + .last_cid = 19999, + .lookups = 4, + .first_valid_addr = 0, + .last_used_addr = 800, + .last_valid_addr = 800 - 1, + .cache = { + .keystream = keydata, + .maskstream = mskdata, + .actionstream = actdata, + }, + }; + int ret; + + vcap_test_api_init(&admin); + + /* Create rules with different sizes and check that they are placed + * at the correct address in the VCAP according to size + */ + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 774); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 771); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 768); + + /* Remove rules in the middle */ + test_init_rule_deletion(); + ret = vcap_del_rule(&test_vctrl, &test_netdev, 400); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, 768, test_move_addr); + KUNIT_EXPECT_EQ(test, -6, test_move_offset); + KUNIT_EXPECT_EQ(test, 6, test_move_count); + KUNIT_EXPECT_EQ(test, 768, test_init_start); + KUNIT_EXPECT_EQ(test, 6, test_init_count); + KUNIT_EXPECT_EQ(test, 774, admin.last_used_addr); + + test_init_rule_deletion(); + ret = vcap_del_rule(&test_vctrl, &test_netdev, 300); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, 774, test_move_addr); + KUNIT_EXPECT_EQ(test, -4, test_move_offset); + KUNIT_EXPECT_EQ(test, 2, test_move_count); + KUNIT_EXPECT_EQ(test, 774, test_init_start); + KUNIT_EXPECT_EQ(test, 4, test_init_count); + KUNIT_EXPECT_EQ(test, 778, admin.last_used_addr); + + test_init_rule_deletion(); + ret = vcap_del_rule(&test_vctrl, &test_netdev, 500); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, 778, test_move_addr); + KUNIT_EXPECT_EQ(test, -20, test_move_offset); + KUNIT_EXPECT_EQ(test, 2, test_move_count); + KUNIT_EXPECT_EQ(test, 778, test_init_start); + KUNIT_EXPECT_EQ(test, 20, test_init_count); + KUNIT_EXPECT_EQ(test, 798, admin.last_used_addr); + + test_init_rule_deletion(); + ret = vcap_del_rule(&test_vctrl, &test_netdev, 200); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, 0, test_move_addr); + KUNIT_EXPECT_EQ(test, 0, test_move_offset); + KUNIT_EXPECT_EQ(test, 0, test_move_count); + KUNIT_EXPECT_EQ(test, 798, test_init_start); + KUNIT_EXPECT_EQ(test, 2, test_init_count); + KUNIT_EXPECT_EQ(test, 799, admin.last_used_addr); +} + +static void vcap_api_rule_remove_in_front_test(struct kunit *test) +{ + /* Data used by VCAP Library callback */ + static u32 keydata[32] = {}; + static u32 mskdata[32] = {}; + static u32 actdata[32] = {}; + + struct vcap_admin admin = { + .vtype = VCAP_TYPE_IS0, + .first_cid = 10000, + .last_cid = 19999, + .lookups = 4, + .first_valid_addr = 0, + .last_used_addr = 800, + .last_valid_addr = 800 - 1, + .cache = { + .keystream = keydata, + .maskstream = mskdata, + .actionstream = actdata, + }, + }; + int ret; + + vcap_test_api_init(&admin); + + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 10, 500, 12, 780); + KUNIT_EXPECT_EQ(test, 780, admin.last_used_addr); + + test_init_rule_deletion(); + ret = vcap_del_rule(&test_vctrl, &test_netdev, 500); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, 0, test_move_addr); + KUNIT_EXPECT_EQ(test, 0, test_move_offset); + KUNIT_EXPECT_EQ(test, 0, test_move_count); + KUNIT_EXPECT_EQ(test, 780, test_init_start); + KUNIT_EXPECT_EQ(test, 12, test_init_count); + KUNIT_EXPECT_EQ(test, 799, admin.last_used_addr); + + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 20, 400, 6, 792); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 30, 300, 3, 789); + test_vcap_xn_rule_creator(test, 10000, VCAP_USER_QOS, 40, 200, 2, 786); + + test_init_rule_deletion(); + ret = vcap_del_rule(&test_vctrl, &test_netdev, 400); + KUNIT_EXPECT_EQ(test, 0, ret); + KUNIT_EXPECT_EQ(test, 786, test_move_addr); + KUNIT_EXPECT_EQ(test, -8, test_move_offset); + KUNIT_EXPECT_EQ(test, 6, test_move_count); + KUNIT_EXPECT_EQ(test, 786, test_init_start); + KUNIT_EXPECT_EQ(test, 8, test_init_count); + KUNIT_EXPECT_EQ(test, 794, admin.last_used_addr); +} + +static struct kunit_case vcap_api_rule_remove_test_cases[] = { + KUNIT_CASE(vcap_api_rule_remove_at_end_test), + KUNIT_CASE(vcap_api_rule_remove_in_middle_test), + KUNIT_CASE(vcap_api_rule_remove_in_front_test), + {} +}; + static void vcap_api_next_lookup_basic_test(struct kunit *test) { struct vcap_admin admin1 = { @@ -1458,6 +1954,33 @@ static void vcap_api_next_lookup_advanced_test(struct kunit *test) KUNIT_EXPECT_EQ(test, true, ret); } +static struct kunit_suite vcap_api_rule_remove_test_suite = { + .name = "VCAP_API_Rule_Remove_Testsuite", + .test_cases = vcap_api_rule_remove_test_cases, +}; + +static struct kunit_case vcap_api_rule_insert_test_cases[] = { + KUNIT_CASE(vcap_api_rule_insert_in_order_test), + KUNIT_CASE(vcap_api_rule_insert_reverse_order_test), + {} +}; + +static struct kunit_suite vcap_api_rule_insert_test_suite = { + .name = "VCAP_API_Rule_Insert_Testsuite", + .test_cases = vcap_api_rule_insert_test_cases, +}; + +static struct kunit_case vcap_api_rule_counter_test_cases[] = { + KUNIT_CASE(vcap_api_set_rule_counter_test), + KUNIT_CASE(vcap_api_get_rule_counter_test), + {} +}; + +static struct kunit_suite vcap_api_rule_counter_test_suite = { + .name = "VCAP_API_Rule_Counter_Testsuite", + .test_cases = vcap_api_rule_counter_test_cases, +}; + static struct kunit_case vcap_api_support_test_cases[] = { KUNIT_CASE(vcap_api_next_lookup_basic_test), KUNIT_CASE(vcap_api_next_lookup_advanced_test), @@ -1519,6 +2042,9 @@ static struct kunit_suite vcap_api_encoding_test_suite = { .test_cases = vcap_api_encoding_test_cases, }; +kunit_test_suite(vcap_api_rule_remove_test_suite); +kunit_test_suite(vcap_api_rule_insert_test_suite); +kunit_test_suite(vcap_api_rule_counter_test_suite); kunit_test_suite(vcap_api_support_test_suite); kunit_test_suite(vcap_api_full_rule_test_suite); kunit_test_suite(vcap_api_rule_value_test_suite);