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: 13040293 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6D8B9C4332F for ; Fri, 11 Nov 2022 13:06:56 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=5muzTppJECIeMhQ3cmyf5YZ8SNUlH+qoASWkhdtRjNY=; b=pkj4MkQb66dG1b yin9jenqFkmwXGxDL5dZx5BHIwGM/7Mwqek5RPm/USjvqz7s0XHQ/h4jSsk+nIE+OrXBZAV/Y/OmY ZbQLn7iSdy6eBCU+ryojGc0CpKETAGH1j4lCDpRxBD7HkcCrkVLQk3coG+uXcCzb/vZIsXARYD0cG NMfx4VWI44bKf3jkWlLPdkSivFtk0J4+utWMD7rc8ccLvnzIBWnSrL6ZYHq/Saz4nbpHWvuY7oUb1 Nnn65PeX+j7iJ/2grLH8masshDaEPaEooP1LzKZz4acEE/ZNV1JTDAiueOKbh/hjGScoWcdzEjdaZ 6qhOzRT5a+Wy/EfoCTTA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTjB-00FlfQ-AL; Fri, 11 Nov 2022 13:05:49 +0000 Received: from esa.microchip.iphmx.com ([68.232.154.123]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTj0-00FlVp-47 for linux-arm-kernel@lists.infradead.org; Fri, 11 Nov 2022 13:05:39 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1668171937; x=1699707937; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=AR+nmO2jQEhSBw5v3+UnruUyhkqnIBsLZ30bfGwKdWA=; b=Vs/Hq71CmWMo1LJJtrHLLc9SHsNFO0ZW6qyQxd2EW1Xf/nOfECeAcd2E 31zPR42T0Nt9lAj2xHoIDimvnbEJLn0yT079/Ib9LsQfTYcWRYmjF0Ond WgpEp54yEJJRcKtPevYcsRH01VFB4k2TdchFNaPxl37vsbkXcotm59JUR FTvvq8oihghasC/wsQViOcBLnpb/V4ROH+QGRUBhuSAtn+T0PBtSvTN0/ +SdUZFSHYSoVRbTYFT20eth06IgwQEnc6Ngv+dumsjrVRII3UnztK8CXS 5AKtoPnKLCV+X4bNzEL0TQTnj2dOXUBViMJNacSyarsl03Ofms3OBt0V/ 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221111_050538_261905_3FA1634A X-CRM114-Status: UNSURE ( 8.95 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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: 13040304 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 87FA0C4332F for ; Fri, 11 Nov 2022 13:07:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=B2nf3pjjtD0ySdes2VKxUvD2fk0hA7kg+hOJQMbpABU=; b=KTW7MptEXYDKkT g5X/Op1yfa7VGjQtNrERfJit0xxY2GNtLKk6hd4AAK6eAs0BljEHjJ27Om4h5pSVrbmbl0GVGAmGY JJFjQtClgbDcqG1zp+mPG09hlSr1GxQ+Q0ixMcRVwyH+U59YNGAv3oQ1phPEFxdDxyz5JbenPdSIH Zgpn3bb65R1nDHekf1HteAJ/DC/7V5pVbh+SkA7DBz4usJuWWU3iHJgplBjvxCuc76sT54ljmwQL5 Mz7vqAMpE7aZxh+7bProlh1NUMA9GHXUE1YgwkL1N4xh28/V7aJNLX+akR85YyBMA5a8BqB+5d1NW WiyG65nxdJsZqEnYbVUA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTjM-00FlmH-Eh; Fri, 11 Nov 2022 13:06:00 +0000 Received: from esa.microchip.iphmx.com ([68.232.154.123]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTj0-00FlZB-Mt for linux-arm-kernel@lists.infradead.org; Fri, 11 Nov 2022 13:05:41 +0000 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=MwMrFBuJYmXmypJ56eKGRvFX0VICWHsAbwpGcGNvxjw=; b=hqfT6YVSzbEud2z88KPJtw+TWGT3ViWdHma70fIxEar2R50Zv4GO7La1 sy5D3oGGI5e6V6VaFa0m1XY+1ypLqSqVjg2y+idj63Cb2unOO0b6SnyBz /He68ABfZqjqW5YBAl+4tBpoMvoXTdCZUEgyMd/DmA6Kapglieb9jjgdC Qs5juL7UIk9Z/i0UTocxDw64+SKbBQ7Nvc54B6EFh5dWwnUzCl3S3lpYS bVWEMKZJ/O7qmj3SAj+frPLjXGNb1uUUZkOKizaaRk0u3SfdbgQoAkWng sXlkTmzminV2hHQ6ROMIxha5PQlvlNAhDQrfkvkWexsyRfj/85NY/lRwC 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221111_050538_872743_5010E6B5 X-CRM114-Status: GOOD ( 14.19 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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: 13040305 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 3CC55C4332F for ; Fri, 11 Nov 2022 13:07:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=WQshaMiHWvqM0bfAtTHAqNuKinWwYY8PeHv84+UvAPo=; b=cGuwwLBS692cXM 6NlyWwcMGg8Gylb3y6XmaMSREt58mCHiY7aSKjsVYQo2k+vAmPN/R1NR4a6/lcY8RSA3Y97ddVx5U rWNGQ13Uqf/NhDbIDinmYT+QHI9j9JXVVIFb+0m2EfScD4jGsCZK40PbOodu9RZUepwuPXZ6/bMh3 6czQBERZLGnZnLx+ia6iuQC4NUqtC7rS8+k2YsVd0YLOHteAdVjMvuB+orxFN1KyWbO/MmUiv7L56 N8ViSAqJ0dt5j3hd2V2VBRL5bM/UIC3V1/5YRhKNjFqnTPoNuNx/JOcJWQMozlk79TO8ll9+Ge32i 3QWVu9KuYTazm8LQgheg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTjZ-00FlwQ-Ep; Fri, 11 Nov 2022 13:06:13 +0000 Received: from esa.microchip.iphmx.com ([68.232.153.233]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTj9-00Flco-7h for linux-arm-kernel@lists.infradead.org; Fri, 11 Nov 2022 13:05:49 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1668171948; x=1699707948; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=SOHnGIhnQ7MsnOmlSCy+bgSFKgeTg1oB8GLr2mkHikw=; b=dPXRGeUYpi5BnNKOGDz67fmS01bbVTPaHurjPIxLWmKxt6BR0zJG67kE 7cxLJlZcfdF6oZyDmzw5QbZBd+jSI21eeFtGA/RFNArLXQwvjtd2HQvyO XtfFBInlaVu97DTz16n3rBIzLZ8Wexg0dZzXcs0iQCBqLo8pmc6gxPpqw 93Z1FEUCYrfLdrD7hrq7tQinwDm5s61d15an3IjsNQwZjHqZ1S8eGHSfD d71AlYdldNFMJKb3QjCml9Y7ewwezq/xMY+45+r3c/n5ppZ3vIa3VLiib jSOzDjjU0+OBJPTzcu/MIOfAur1HYdEdtFMNKeGNagGj8dZQqcrIqMfaN 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221111_050547_321512_4D65DF06 X-CRM114-Status: GOOD ( 27.06 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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: 13040306 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A028EC43217 for ; Fri, 11 Nov 2022 13:08:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=vbEN7WUmmkW4fXifOYK5N2kfbjasd8j5n8TeqDm/Lq0=; b=RRSlwhXEgz8seb ktrmUVSWCr/HWiQkivuihKmSHrGCgYIbFIBPIfIW4gciFpOzP6cdffy/dPQo5V0zUVVnGp2p9b4LA gcpaJFVxH9kZE6ZGU8VnQTgkeoAiJAwoA/iIMeXvHne0cU7/5P0Up4c8bRjjrk+FoEyH2qlqDxCwa hje71dPGgsd9qpw/urnp/yqu72TpKbnxRPa6Pv2mE+ucoN6shz/D31NrqGF4ewR6pUpQsRd/SVSxF bJNLaGk9rua1skZdGBcY0BjJW4lxJHV3gyJkHem7yhyksgKZ6S6BPoDDm9A7ANy7V8/vBVbZ1anqy mjpIH7wc07o+VYRX5cbg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTk7-00FmHl-PE; Fri, 11 Nov 2022 13:06:47 +0000 Received: from esa.microchip.iphmx.com ([68.232.154.123]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTjA-00FlfH-Ua for linux-arm-kernel@lists.infradead.org; Fri, 11 Nov 2022 13:05:51 +0000 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221111_050549_076297_287E00AC X-CRM114-Status: GOOD ( 21.75 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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: 13040307 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B3A00C4332F for ; Fri, 11 Nov 2022 13:08:29 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=LVjDHfiNoMY4v3KA1wlORMoLHtfH+xQSdqnmbRKN9dE=; b=REhfZUK5ulpHLZ 3WURGimOuOg2pFMOrgnvji2OKBaDYsK5wGekXM91Yj/CzBzOL14zCg0+vVuVsCg1C4tAAMiCZ0xm7 pKnAMYcJkq11bezEZJZoG23RgE/gXNex1nm88VViJkbDTeZN6SlR7FrdH9CMFPvbKFvJRoz0SddLt 1BMeL54GKfE85QcLoZKAktBT+BJk8Se/U0eOsJC8vYimu+sJ8vJaGdBZbMzdT+SSjkpiJyTqhRnba iFBMnC/gCSFGhkdJJ71hYg5504W4rEVy11dpzNeQuWuYq0f/Z+ITR5DwM+4W6K/DaLTSH4ZW9POmb 3pQYg/h3xN/Zs7wocXpA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTkP-00FmVP-64; Fri, 11 Nov 2022 13:07:05 +0000 Received: from esa.microchip.iphmx.com ([68.232.154.123]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTjK-00Fllf-Tl for linux-arm-kernel@lists.infradead.org; Fri, 11 Nov 2022 13:06:00 +0000 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221111_050559_107628_2CEC28EB X-CRM114-Status: GOOD ( 17.11 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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: 13040308 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C3917C4332F for ; Fri, 11 Nov 2022 13:08:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=RQ3HZTCYpe5hqZgECB1kMQR4+9PSXMAiPjneKHGL/5k=; b=eSGPmcyoXz1CpN algDDATElMLoLaKgYsgm9/n/wmE2KqOlm3eDdX2/2JglmKSyJNEZbZrYSlICJlhKMRE6u3upukUdf 3JARd1tKNDoKUNRUcny6nwIz09rrpUF3uLehVNBDFouR3+d0oyiCEOxvv8uErRF4NHG6yYo9Lixi+ i6QhCxki+YRSwEsYeCKnVJYKWLqCizG9bqbrfWqgsNChJ6wverEsJrmbYU8MSWhTwnsWLHUXDaSnp /gWCnq7DXwbDh69dae2lWPK5xYfHnj2tAN6qR0FFuYse9CQfmdFw0KsA2kABUUVN13PwofFW1y8Ma QMK3tZdhGTXspX0dG0oA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTkd-00FmeO-Uw; Fri, 11 Nov 2022 13:07:20 +0000 Received: from esa.microchip.iphmx.com ([68.232.154.123]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1otTjO-00Fllf-8W for linux-arm-kernel@lists.infradead.org; Fri, 11 Nov 2022 13:06:08 +0000 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20221111_050602_608153_301C2E84 X-CRM114-Status: GOOD ( 16.16 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.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);