From patchwork Tue Apr 13 13:24:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ioana Ciornei X-Patchwork-Id: 12200541 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 X-Spam-Level: X-Spam-Status: No, score=-14.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HK_RANDOM_FROM,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3CE44C433ED for ; Tue, 13 Apr 2021 13:26:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1E937613B2 for ; Tue, 13 Apr 2021 13:26:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231697AbhDMN0R (ORCPT ); Tue, 13 Apr 2021 09:26:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45156 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231673AbhDMN0K (ORCPT ); Tue, 13 Apr 2021 09:26:10 -0400 Received: from mail-pg1-x52f.google.com (mail-pg1-x52f.google.com [IPv6:2607:f8b0:4864:20::52f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9DDB8C061574 for ; Tue, 13 Apr 2021 06:25:50 -0700 (PDT) Received: by mail-pg1-x52f.google.com with SMTP id t22so11950600pgu.0 for ; Tue, 13 Apr 2021 06:25:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=dbyYSeZ4DCwW15hK/P0qMTsNp1GqAKx21GZyS5WmjkQ=; b=eaOVMMvsdI2/wqVhMskHzdbzEXIRW+KN4Nzm39pNJ5s352l8LUHi0ETuul/ghnq7Wk bxdhQsOVT9YqIjXFyBIwUzG9lPD5wS+/g/xBs0232Uj2TYP5IRyfnssdmySKQHOWbCW4 L+/e2gj9Kofe81zBWROyBHzN5+m+1nZTwLo8mQundSwAxg9dKrVMZMH9Jnpqpe0IEVJ1 sjmr+hupq08F3dlc+oDXsPzqg5pOQwx4yny8vnzPCR+X5X3JBYkQfQZrr2qDWdx/YvkA k2+EBo/G2+L0Q5ECywEhYFIB+7PqkEjlbQGcOxSD235G1VS9kvO836FWL1+MG7osqjZH 53Hw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=dbyYSeZ4DCwW15hK/P0qMTsNp1GqAKx21GZyS5WmjkQ=; b=UpXYMHapbT2OllWlfRHfZzS8iFafVoHHJue6b/2HUY9K0QrJr04tqOaO684Yc1BNqn szjzEbo7tHPNP0k9eIzBy/meFtRNLekl8ZAQGE4AKXItRqTzsZF5vIW/QUz1ruVRWOyZ 0N+2bGMx3hEax+eLJq5Une6hJMGF1cLAKQaJg4meO8CzGUiSO0KkVyWfCGmUe2/rnm+W rFlgeqGSd+V6kKUfUrM+Z1jPMvSeAzLjTwXarIyjXCw95rfN+pIuH/Cf15FI/8YxodGt iQCBPWgq8eCt4p8JssNsM+hYqmkot4xDZ6bk2p9bgS2NxBIn2uddY+VeB3hdhA+ki5Ot XWgQ== X-Gm-Message-State: AOAM530DxOWJvlsw928R+utshACiUSYo9ghzdfFe2TVWXCVRGENPdfFM oQzVGByq4lhXmaiuTx9R9dc= X-Google-Smtp-Source: ABdhPJwlIZOwKOxBt/Lckj3qRG6ByToJCJmdWSNiI6j8aI/b4jDD9L1W3/xW3SYMziyZGtX0li7oOg== X-Received: by 2002:a05:6a00:1743:b029:215:225d:9e78 with SMTP id j3-20020a056a001743b0290215225d9e78mr29104622pfc.18.1618320350069; Tue, 13 Apr 2021 06:25:50 -0700 (PDT) Received: from yoga-910.localhost (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id z18sm12417650pfa.39.2021.04.13.06.25.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 06:25:49 -0700 (PDT) From: Ioana Ciornei To: davem@davemloft.net, kuba@kernel.org, netdev@vger.kernel.org Cc: ruxandra.radulescu@nxp.com, Ioana Ciornei Subject: [PATCH net-next 1/5] dpaa2-switch: create a central dpaa2_switch_acl_tbl structure Date: Tue, 13 Apr 2021 16:24:44 +0300 Message-Id: <20210413132448.4141787-2-ciorneiioana@gmail.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210413132448.4141787-1-ciorneiioana@gmail.com> References: <20210413132448.4141787-1-ciorneiioana@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Ioana Ciornei Introduce a new structure - dpaa2_switch_acl_tbl - to hold all data related to an ACL table: number of rules added, ACL table id, etc. This will be used more in the next patches when adding support for sharing an ACL table between ports. Signed-off-by: Ioana Ciornei --- .../ethernet/freescale/dpaa2/dpaa2-switch.c | 44 +++++++++++++++---- .../ethernet/freescale/dpaa2/dpaa2-switch.h | 10 ++++- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index 80efc8116963..351ee8f7461c 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -40,6 +40,17 @@ static struct dpaa2_switch_fdb *dpaa2_switch_fdb_get_unused(struct ethsw_core *e return NULL; } +static struct dpaa2_switch_acl_tbl * +dpaa2_switch_acl_tbl_get_unused(struct ethsw_core *ethsw) +{ + int i; + + for (i = 0; i < ethsw->sw_attr.num_ifs; i++) + if (!ethsw->acls[i].in_use) + return ðsw->acls[i]; + return NULL; +} + static u16 dpaa2_switch_port_set_fdb(struct ethsw_port_priv *port_priv, struct net_device *bridge_dev) { @@ -2689,7 +2700,7 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv, acl_h = &acl_key.match; acl_m = &acl_key.mask; - if (port_priv->acl_num_rules >= DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES) { + if (port_priv->acl_tbl->num_rules >= DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES) { netdev_err(netdev, "ACL full\n"); return -ENOMEM; } @@ -2707,7 +2718,7 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv, dpsw_acl_prepare_entry_cfg(&acl_key, cmd_buff); memset(&acl_entry_cfg, 0, sizeof(acl_entry_cfg)); - acl_entry_cfg.precedence = port_priv->acl_num_rules; + acl_entry_cfg.precedence = port_priv->acl_tbl->num_rules; acl_entry_cfg.result.action = DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF; acl_entry_cfg.key_iova = dma_map_single(dev, cmd_buff, DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, @@ -2719,7 +2730,7 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv, err = dpsw_acl_add_entry(port_priv->ethsw_data->mc_io, 0, port_priv->ethsw_data->dpsw_handle, - port_priv->acl_tbl, &acl_entry_cfg); + port_priv->acl_tbl->id, &acl_entry_cfg); dma_unmap_single(dev, acl_entry_cfg.key_iova, sizeof(cmd_buff), DMA_TO_DEVICE); @@ -2728,7 +2739,7 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv, return err; } - port_priv->acl_num_rules++; + port_priv->acl_tbl->num_rules++; return 0; } @@ -2743,12 +2754,13 @@ static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port) }; struct net_device *netdev = port_priv->netdev; struct ethsw_core *ethsw = port_priv->ethsw_data; + struct dpaa2_switch_acl_tbl *acl_tbl; struct dpsw_fdb_cfg fdb_cfg = {0}; struct dpsw_acl_if_cfg acl_if_cfg; struct dpsw_if_attr dpsw_if_attr; struct dpaa2_switch_fdb *fdb; struct dpsw_acl_cfg acl_cfg; - u16 fdb_id; + u16 fdb_id, acl_tbl_id; int err; /* Get the Tx queue for this specific port */ @@ -2792,7 +2804,7 @@ static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port) /* Create an ACL table to be used by this switch port */ acl_cfg.max_entries = DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES; err = dpsw_acl_add(ethsw->mc_io, 0, ethsw->dpsw_handle, - &port_priv->acl_tbl, &acl_cfg); + &acl_tbl_id, &acl_cfg); if (err) { netdev_err(netdev, "dpsw_acl_add err %d\n", err); return err; @@ -2801,13 +2813,19 @@ static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port) acl_if_cfg.if_id[0] = port_priv->idx; acl_if_cfg.num_ifs = 1; err = dpsw_acl_add_if(ethsw->mc_io, 0, ethsw->dpsw_handle, - port_priv->acl_tbl, &acl_if_cfg); + acl_tbl_id, &acl_if_cfg); if (err) { netdev_err(netdev, "dpsw_acl_add_if err %d\n", err); dpsw_acl_remove(ethsw->mc_io, 0, ethsw->dpsw_handle, - port_priv->acl_tbl); + acl_tbl_id); } + acl_tbl = dpaa2_switch_acl_tbl_get_unused(ethsw); + acl_tbl->id = acl_tbl_id; + acl_tbl->in_use = true; + acl_tbl->num_rules = 0; + port_priv->acl_tbl = acl_tbl; + err = dpaa2_switch_port_trap_mac_addr(port_priv, stpa); if (err) return err; @@ -2858,6 +2876,7 @@ static int dpaa2_switch_remove(struct fsl_mc_device *sw_dev) } kfree(ethsw->fdbs); + kfree(ethsw->acls); kfree(ethsw->ports); dpaa2_switch_takedown(sw_dev); @@ -2983,6 +3002,13 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev) goto err_free_ports; } + ethsw->acls = kcalloc(ethsw->sw_attr.num_ifs, sizeof(*ethsw->acls), + GFP_KERNEL); + if (!ethsw->acls) { + err = -ENOMEM; + goto err_free_fdbs; + } + for (i = 0; i < ethsw->sw_attr.num_ifs; i++) { err = dpaa2_switch_probe_port(ethsw, i); if (err) @@ -3031,6 +3057,8 @@ static int dpaa2_switch_probe(struct fsl_mc_device *sw_dev) err_free_netdev: for (i--; i >= 0; i--) free_netdev(ethsw->ports[i]->netdev); + kfree(ethsw->acls); +err_free_fdbs: kfree(ethsw->fdbs); err_free_ports: kfree(ethsw->ports); diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h index 0ae1d27c811e..a2c0ff23c7e9 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h @@ -101,6 +101,12 @@ struct dpaa2_switch_fdb { bool in_use; }; +struct dpaa2_switch_acl_tbl { + u16 id; + u8 num_rules; + bool in_use; +}; + /* Per port private data */ struct ethsw_port_priv { struct net_device *netdev; @@ -118,8 +124,7 @@ struct ethsw_port_priv { bool ucast_flood; bool learn_ena; - u16 acl_tbl; - u8 acl_num_rules; + struct dpaa2_switch_acl_tbl *acl_tbl; }; /* Switch data */ @@ -145,6 +150,7 @@ struct ethsw_core { int napi_users; struct dpaa2_switch_fdb *fdbs; + struct dpaa2_switch_acl_tbl *acls; }; static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw) From patchwork Tue Apr 13 13:24:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ioana Ciornei X-Patchwork-Id: 12200543 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 X-Spam-Level: X-Spam-Status: No, score=-14.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HK_RANDOM_FROM,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 113B8C433ED for ; Tue, 13 Apr 2021 13:26:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E82EF613B1 for ; Tue, 13 Apr 2021 13:26:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345913AbhDMN0W (ORCPT ); Tue, 13 Apr 2021 09:26:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45180 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241658AbhDMN0R (ORCPT ); Tue, 13 Apr 2021 09:26:17 -0400 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 13822C061574 for ; Tue, 13 Apr 2021 06:25:56 -0700 (PDT) Received: by mail-pj1-x1032.google.com with SMTP id s14so3616012pjl.5 for ; Tue, 13 Apr 2021 06:25:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=JMtB3sTR+OLp053ETHSfMwDWfNuUQ0eFZhxyaM8Kg78=; b=Y5k68lrtZD3rwlPLfIsn6XsnrCDZ3QPLJNN1VmVSCT+lJr862+WEI2DaC8llyWtrrb goUhVXv8HqvA2GF9DesywhGw5ff6j7ORaf4ciDSpOCiUfGui5gRq9EA1eVcrlUT+ag8n 0p8oOmu8wNHXEaVufGwuwvY+8WROIOmtETPy6IfxP82GG2Ced/F0PGFdbi4O9RDCTtXH VtNYOX8oCQ7s5K+d8rqPQdRbEi/MwyKKU0GaXFrQO3a/MsfsCTkGFT3pDMF0xl+P5jcs P1JmSZ+Nm/U8a9nMYyTsLQRKjO/NssjzmcfVFCEbMEF7LYloII7wv8VOH1mKL+gifrZT TU1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=JMtB3sTR+OLp053ETHSfMwDWfNuUQ0eFZhxyaM8Kg78=; b=PJxi7SOPppgtILGeU5sImIHxF8dQ4fxc6uojHm5tmt2wlybuibdJ86UZQLJFoxqyVu 4OvR6ZFgptwFdYFjSdHwaVD6vf8GQ5jMClHxwKH4Oh5iQN1S7+Q507pzCyDH3NYZoW/0 aYZ1U/CbAHfjtco/z5dBsx2oIvM7AedbppLcV7m5+uzGvI1cx40GylUqwMv9L7p/HpVS b6oZJCYjSbB7GfTv2eKC+RlvxTGQDTZpkswOE1eB1TB51QIpqNaM3ACsd8pfECzrjw4+ vHX/FDd16snpKfbQj757JuYuiPK2uvdp+bmbjBS75s7hWuvD8dACsburlsyMPM6edD5q 8Zew== X-Gm-Message-State: AOAM531LsxiHeCAOU0nsZ5w3CmPwAhb1VSqdHTrhsiTDmPeLvmMf/9HJ U4rpbX5uNeYtZsngWvdfhig= X-Google-Smtp-Source: ABdhPJzYK3EV5jPdzovCexfLOjszJtYcA6s4BPmw73D3uDWdWvhc0crVqBgPeWGuiq+UWKakL2VMyg== X-Received: by 2002:a17:90a:28a1:: with SMTP id f30mr20006pjd.198.1618320355601; Tue, 13 Apr 2021 06:25:55 -0700 (PDT) Received: from yoga-910.localhost (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id z18sm12417650pfa.39.2021.04.13.06.25.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 06:25:55 -0700 (PDT) From: Ioana Ciornei To: davem@davemloft.net, kuba@kernel.org, netdev@vger.kernel.org Cc: ruxandra.radulescu@nxp.com, Ioana Ciornei Subject: [PATCH net-next 2/5] dpaa2-switch: install default STP trap rule with the highest priority Date: Tue, 13 Apr 2021 16:24:45 +0300 Message-Id: <20210413132448.4141787-3-ciorneiioana@gmail.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210413132448.4141787-1-ciorneiioana@gmail.com> References: <20210413132448.4141787-1-ciorneiioana@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Ioana Ciornei Change the default ACL trap rule for STP frames to have the highest priority. In the same ACL table will reside both default rules added by the driver for its internal use as well as rules added with tc flower. In this case, the default rules such as the STP one that we already have should have the highest priority. Also, remove the check for a full ACL table since we already know that it's sized so that we don't hit this case. The last thing changes is that default trap filters will not be counted in the acl_tbl's num_rules variable since their number doesn't change. Signed-off-by: Ioana Ciornei --- drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index 351ee8f7461c..fc9e2eb0ad11 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -2700,11 +2700,6 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv, acl_h = &acl_key.match; acl_m = &acl_key.mask; - if (port_priv->acl_tbl->num_rules >= DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES) { - netdev_err(netdev, "ACL full\n"); - return -ENOMEM; - } - memset(&acl_entry_cfg, 0, sizeof(acl_entry_cfg)); memset(&acl_key, 0, sizeof(acl_key)); @@ -2718,7 +2713,7 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv, dpsw_acl_prepare_entry_cfg(&acl_key, cmd_buff); memset(&acl_entry_cfg, 0, sizeof(acl_entry_cfg)); - acl_entry_cfg.precedence = port_priv->acl_tbl->num_rules; + acl_entry_cfg.precedence = 0; acl_entry_cfg.result.action = DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF; acl_entry_cfg.key_iova = dma_map_single(dev, cmd_buff, DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, @@ -2739,8 +2734,6 @@ static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv, return err; } - port_priv->acl_tbl->num_rules++; - return 0; } From patchwork Tue Apr 13 13:24:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ioana Ciornei X-Patchwork-Id: 12200545 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 X-Spam-Level: X-Spam-Status: No, score=-14.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HK_RANDOM_FROM,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98376C43460 for ; Tue, 13 Apr 2021 13:26:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 77CE4613B6 for ; Tue, 13 Apr 2021 13:26:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345953AbhDMN0Y (ORCPT ); Tue, 13 Apr 2021 09:26:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45204 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345738AbhDMN0V (ORCPT ); Tue, 13 Apr 2021 09:26:21 -0400 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1F07CC061574 for ; Tue, 13 Apr 2021 06:26:02 -0700 (PDT) Received: by mail-pl1-x62d.google.com with SMTP id w8so5873639plg.9 for ; Tue, 13 Apr 2021 06:26:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kV0nBeGD4juT23ScwjRlCjxpVKrz4wR66jJ5QfFJBQw=; b=cYrb3zPdQjxDzkZmMuIb2p3IFVRemc47H7OPoBjR4jXyyFcU0tZE1JHcgRtHG3cAyr UYXKTRkSaFhsZBwyWSCQLazqnH+nCmpM4dtw1KCHm5ec1g5qIceQ/OafQVosee8WT//v amAsxa++0pis2FxEA94yaL7GYqXDJbNC2d2i0u5zhXnKIlI0I5ob8YImsSbieYW2tdxJ Q1OD5i3nN/YTpJGEbmv09uIx7Ymduv6DWGkgpgmOLmweJng8VajrH6bgIspKgJTm95RD 7LRb5OUd7yQSyyNJiHxJVBr+IiEe1kPXnp0fsPb64AzUnw5HQO1tgPyvp71BGOtVvuMN SQ9Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kV0nBeGD4juT23ScwjRlCjxpVKrz4wR66jJ5QfFJBQw=; b=G5Gi6fPJU8xpzEQdSa8ydx7fSho/bPmIdwbbO14i+c1wTYdneskeomcbEAaaRFuvNK b5Q6vqhBBqa7fvVwolcQ/5oQ67LNiCUZrbiI+TbKawBjBdIt1vzN4LaL5FPTPGdK3TXI ZvtCvVlIsdfB/W1K6EROMYK9PZumnk9MnUBGFUe7EeRQ8pAW12UjI1WHl85lvPuITnHd gm/pWxFd2uTnpXZoz1NxS5vaLVsVvSkQtiKubyx3WjHCFXKGDo7LYvSMAe0AzT1JCbLu g1syLDb4vfwJ17AQDJUodlK8IvWMG/ORMJjPjEc/8Ysu7ePpNFEmRm7uDr4TQ3eCK+dv YLZg== X-Gm-Message-State: AOAM533p2jblObCbGyQqyL6jNMwEron9WRJYii8IDsMeD4kj4Uoom+Tq cNW/bbRhatxwwKahHHPUsVqjg1nMdLq6hA== X-Google-Smtp-Source: ABdhPJwYKsVLlz7iX5C76RlkWyJYuu2s1MNR8RpQp+3kV2tWqcfibK9g5gSmnYjrlL3ETFLFXnbZWg== X-Received: by 2002:a17:90a:a10c:: with SMTP id s12mr26775pjp.166.1618320361490; Tue, 13 Apr 2021 06:26:01 -0700 (PDT) Received: from yoga-910.localhost (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id z18sm12417650pfa.39.2021.04.13.06.25.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 06:26:00 -0700 (PDT) From: Ioana Ciornei To: davem@davemloft.net, kuba@kernel.org, netdev@vger.kernel.org Cc: ruxandra.radulescu@nxp.com, Ioana Ciornei Subject: [PATCH net-next 3/5] dpaa2-switch: add tc flower hardware offload on ingress traffic Date: Tue, 13 Apr 2021 16:24:46 +0300 Message-Id: <20210413132448.4141787-4-ciorneiioana@gmail.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210413132448.4141787-1-ciorneiioana@gmail.com> References: <20210413132448.4141787-1-ciorneiioana@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Ioana Ciornei This patch adds support for tc flower hardware offload on the ingress path. Shared filter blocks are supported by sharing a single ACL table between multiple ports. The following flow keys are supported: - Ethernet: dst_mac/src_mac - IPv4: dst_ip/src_ip/ip_proto/tos - VLAN: vlan_id/vlan_prio/vlan_tpid/vlan_dei - L4: dst_port/src_port As per flow actions, the following are supported: - drop - mirred egress redirect - trap Each ACL entry (filter) can be setup with only one of the listed actions. A sorted single linked list is used to keep the ACL entries by their order of priority. When adding a new filter, this enables us to quickly ascertain if the new entry has the highest priority of the entire block or if we should make some space in the ACL table by increasing the priority of the filters already in the table. Signed-off-by: Ioana Ciornei --- drivers/net/ethernet/freescale/dpaa2/Makefile | 2 +- .../freescale/dpaa2/dpaa2-switch-flower.c | 436 ++++++++++++++++++ .../ethernet/freescale/dpaa2/dpaa2-switch.c | 261 ++++++++++- .../ethernet/freescale/dpaa2/dpaa2-switch.h | 44 ++ .../net/ethernet/freescale/dpaa2/dpsw-cmd.h | 1 + drivers/net/ethernet/freescale/dpaa2/dpsw.c | 35 ++ drivers/net/ethernet/freescale/dpaa2/dpsw.h | 3 + 7 files changed, 768 insertions(+), 14 deletions(-) create mode 100644 drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c diff --git a/drivers/net/ethernet/freescale/dpaa2/Makefile b/drivers/net/ethernet/freescale/dpaa2/Makefile index 644ef9ae02a3..c2ef74052ef8 100644 --- a/drivers/net/ethernet/freescale/dpaa2/Makefile +++ b/drivers/net/ethernet/freescale/dpaa2/Makefile @@ -11,7 +11,7 @@ fsl-dpaa2-eth-objs := dpaa2-eth.o dpaa2-ethtool.o dpni.o dpaa2-mac.o dpmac.o dpa fsl-dpaa2-eth-${CONFIG_FSL_DPAA2_ETH_DCB} += dpaa2-eth-dcb.o fsl-dpaa2-eth-${CONFIG_DEBUG_FS} += dpaa2-eth-debugfs.o fsl-dpaa2-ptp-objs := dpaa2-ptp.o dprtc.o -fsl-dpaa2-switch-objs := dpaa2-switch.o dpaa2-switch-ethtool.o dpsw.o +fsl-dpaa2-switch-objs := dpaa2-switch.o dpaa2-switch-ethtool.o dpsw.o dpaa2-switch-flower.o # Needed by the tracing framework CFLAGS_dpaa2-eth.o := -I$(src) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c new file mode 100644 index 000000000000..ee987fa02f0d --- /dev/null +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c @@ -0,0 +1,436 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DPAA2 Ethernet Switch flower support + * + * Copyright 2021 NXP + * + */ + +#include "dpaa2-switch.h" + +static int dpaa2_switch_flower_parse_key(struct flow_cls_offload *cls, + struct dpsw_acl_key *acl_key) +{ + struct flow_rule *rule = flow_cls_offload_flow_rule(cls); + struct flow_dissector *dissector = rule->match.dissector; + struct netlink_ext_ack *extack = cls->common.extack; + struct dpsw_acl_fields *acl_h, *acl_m; + + if (dissector->used_keys & + ~(BIT(FLOW_DISSECTOR_KEY_BASIC) | + BIT(FLOW_DISSECTOR_KEY_CONTROL) | + BIT(FLOW_DISSECTOR_KEY_ETH_ADDRS) | + BIT(FLOW_DISSECTOR_KEY_VLAN) | + BIT(FLOW_DISSECTOR_KEY_PORTS) | + BIT(FLOW_DISSECTOR_KEY_IP) | + BIT(FLOW_DISSECTOR_KEY_IPV6_ADDRS) | + BIT(FLOW_DISSECTOR_KEY_IPV4_ADDRS))) { + NL_SET_ERR_MSG_MOD(extack, + "Unsupported keys used"); + return -EOPNOTSUPP; + } + + acl_h = &acl_key->match; + acl_m = &acl_key->mask; + + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_BASIC)) { + struct flow_match_basic match; + + flow_rule_match_basic(rule, &match); + acl_h->l3_protocol = match.key->ip_proto; + acl_h->l2_ether_type = be16_to_cpu(match.key->n_proto); + acl_m->l3_protocol = match.mask->ip_proto; + acl_m->l2_ether_type = be16_to_cpu(match.mask->n_proto); + } + + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ETH_ADDRS)) { + struct flow_match_eth_addrs match; + + flow_rule_match_eth_addrs(rule, &match); + ether_addr_copy(acl_h->l2_dest_mac, &match.key->dst[0]); + ether_addr_copy(acl_h->l2_source_mac, &match.key->src[0]); + ether_addr_copy(acl_m->l2_dest_mac, &match.mask->dst[0]); + ether_addr_copy(acl_m->l2_source_mac, &match.mask->src[0]); + } + + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_VLAN)) { + struct flow_match_vlan match; + + flow_rule_match_vlan(rule, &match); + acl_h->l2_vlan_id = match.key->vlan_id; + acl_h->l2_tpid = be16_to_cpu(match.key->vlan_tpid); + acl_h->l2_pcp_dei = match.key->vlan_priority << 1 | + match.key->vlan_dei; + + acl_m->l2_vlan_id = match.mask->vlan_id; + acl_m->l2_tpid = be16_to_cpu(match.mask->vlan_tpid); + acl_m->l2_pcp_dei = match.mask->vlan_priority << 1 | + match.mask->vlan_dei; + } + + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPV4_ADDRS)) { + struct flow_match_ipv4_addrs match; + + flow_rule_match_ipv4_addrs(rule, &match); + acl_h->l3_source_ip = be32_to_cpu(match.key->src); + acl_h->l3_dest_ip = be32_to_cpu(match.key->dst); + acl_m->l3_source_ip = be32_to_cpu(match.mask->src); + acl_m->l3_dest_ip = be32_to_cpu(match.mask->dst); + } + + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) { + struct flow_match_ports match; + + flow_rule_match_ports(rule, &match); + acl_h->l4_source_port = be16_to_cpu(match.key->src); + acl_h->l4_dest_port = be16_to_cpu(match.key->dst); + acl_m->l4_source_port = be16_to_cpu(match.mask->src); + acl_m->l4_dest_port = be16_to_cpu(match.mask->dst); + } + + if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) { + struct flow_match_ip match; + + flow_rule_match_ip(rule, &match); + if (match.mask->ttl != 0) { + NL_SET_ERR_MSG_MOD(extack, + "Matching on TTL not supported"); + return -EOPNOTSUPP; + } + + if ((match.mask->tos & 0x3) != 0) { + NL_SET_ERR_MSG_MOD(extack, + "Matching on ECN not supported, only DSCP"); + return -EOPNOTSUPP; + } + + acl_h->l3_dscp = match.key->tos >> 2; + acl_m->l3_dscp = match.mask->tos >> 2; + } + + return 0; +} + +static int dpaa2_switch_acl_entry_add(struct dpaa2_switch_acl_tbl *acl_tbl, + struct dpaa2_switch_acl_entry *entry) +{ + struct dpsw_acl_entry_cfg *acl_entry_cfg = &entry->cfg; + struct ethsw_core *ethsw = acl_tbl->ethsw; + struct dpsw_acl_key *acl_key = &entry->key; + struct device *dev = ethsw->dev; + u8 *cmd_buff; + int err; + + cmd_buff = kzalloc(DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, GFP_KERNEL); + if (!cmd_buff) + return -ENOMEM; + + dpsw_acl_prepare_entry_cfg(acl_key, cmd_buff); + + acl_entry_cfg->key_iova = dma_map_single(dev, cmd_buff, + DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) { + dev_err(dev, "DMA mapping failed\n"); + return -EFAULT; + } + + err = dpsw_acl_add_entry(ethsw->mc_io, 0, ethsw->dpsw_handle, + acl_tbl->id, acl_entry_cfg); + + dma_unmap_single(dev, acl_entry_cfg->key_iova, sizeof(cmd_buff), + DMA_TO_DEVICE); + if (err) { + dev_err(dev, "dpsw_acl_add_entry() failed %d\n", err); + return err; + } + + kfree(cmd_buff); + + return 0; +} + +static int dpaa2_switch_acl_entry_remove(struct dpaa2_switch_acl_tbl *acl_tbl, + struct dpaa2_switch_acl_entry *entry) +{ + struct dpsw_acl_entry_cfg *acl_entry_cfg = &entry->cfg; + struct dpsw_acl_key *acl_key = &entry->key; + struct ethsw_core *ethsw = acl_tbl->ethsw; + struct device *dev = ethsw->dev; + u8 *cmd_buff; + int err; + + cmd_buff = kzalloc(DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, GFP_KERNEL); + if (!cmd_buff) + return -ENOMEM; + + dpsw_acl_prepare_entry_cfg(acl_key, cmd_buff); + + acl_entry_cfg->key_iova = dma_map_single(dev, cmd_buff, + DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, + DMA_TO_DEVICE); + if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) { + dev_err(dev, "DMA mapping failed\n"); + return -EFAULT; + } + + err = dpsw_acl_remove_entry(ethsw->mc_io, 0, ethsw->dpsw_handle, + acl_tbl->id, acl_entry_cfg); + + dma_unmap_single(dev, acl_entry_cfg->key_iova, sizeof(cmd_buff), + DMA_TO_DEVICE); + if (err) { + dev_err(dev, "dpsw_acl_remove_entry() failed %d\n", err); + return err; + } + + kfree(cmd_buff); + + return 0; +} + +static int +dpaa2_switch_acl_entry_add_to_list(struct dpaa2_switch_acl_tbl *acl_tbl, + struct dpaa2_switch_acl_entry *entry) +{ + struct dpaa2_switch_acl_entry *tmp; + struct list_head *pos, *n; + int index = 0; + + if (list_empty(&acl_tbl->entries)) { + list_add(&entry->list, &acl_tbl->entries); + return index; + } + + list_for_each_safe(pos, n, &acl_tbl->entries) { + tmp = list_entry(pos, struct dpaa2_switch_acl_entry, list); + if (entry->prio < tmp->prio) + break; + index++; + } + list_add(&entry->list, pos->prev); + return index; +} + +static struct dpaa2_switch_acl_entry* +dpaa2_switch_acl_entry_get_by_index(struct dpaa2_switch_acl_tbl *acl_tbl, + int index) +{ + struct dpaa2_switch_acl_entry *tmp; + int i = 0; + + list_for_each_entry(tmp, &acl_tbl->entries, list) { + if (i == index) + return tmp; + ++i; + } + + return NULL; +} + +static int +dpaa2_switch_acl_entry_set_precedence(struct dpaa2_switch_acl_tbl *acl_tbl, + struct dpaa2_switch_acl_entry *entry, + int precedence) +{ + int err; + + err = dpaa2_switch_acl_entry_remove(acl_tbl, entry); + if (err) + return err; + + entry->cfg.precedence = precedence; + return dpaa2_switch_acl_entry_add(acl_tbl, entry); +} + +static int dpaa2_switch_acl_tbl_add_entry(struct dpaa2_switch_acl_tbl *acl_tbl, + struct dpaa2_switch_acl_entry *entry) +{ + struct dpaa2_switch_acl_entry *tmp; + int index, i, precedence, err; + + /* Add the new ACL entry to the linked list and get its index */ + index = dpaa2_switch_acl_entry_add_to_list(acl_tbl, entry); + + /* Move up in priority the ACL entries to make space + * for the new filter. + */ + precedence = DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES - acl_tbl->num_rules - 1; + for (i = 0; i < index; i++) { + tmp = dpaa2_switch_acl_entry_get_by_index(acl_tbl, i); + + err = dpaa2_switch_acl_entry_set_precedence(acl_tbl, tmp, + precedence); + if (err) + return err; + + precedence++; + } + + /* Add the new entry to hardware */ + entry->cfg.precedence = precedence; + err = dpaa2_switch_acl_entry_add(acl_tbl, entry); + acl_tbl->num_rules++; + + return err; +} + +static struct dpaa2_switch_acl_entry * +dpaa2_switch_acl_tbl_find_entry_by_cookie(struct dpaa2_switch_acl_tbl *acl_tbl, + unsigned long cookie) +{ + struct dpaa2_switch_acl_entry *tmp, *n; + + list_for_each_entry_safe(tmp, n, &acl_tbl->entries, list) { + if (tmp->cookie == cookie) + return tmp; + } + return NULL; +} + +static int +dpaa2_switch_acl_entry_get_index(struct dpaa2_switch_acl_tbl *acl_tbl, + struct dpaa2_switch_acl_entry *entry) +{ + struct dpaa2_switch_acl_entry *tmp, *n; + int index = 0; + + list_for_each_entry_safe(tmp, n, &acl_tbl->entries, list) { + if (tmp->cookie == entry->cookie) + return index; + index++; + } + return -ENOENT; +} + +static int +dpaa2_switch_acl_tbl_remove_entry(struct dpaa2_switch_acl_tbl *acl_tbl, + struct dpaa2_switch_acl_entry *entry) +{ + struct dpaa2_switch_acl_entry *tmp; + int index, i, precedence, err; + + index = dpaa2_switch_acl_entry_get_index(acl_tbl, entry); + + /* Remove from hardware the ACL entry */ + err = dpaa2_switch_acl_entry_remove(acl_tbl, entry); + if (err) + return err; + + acl_tbl->num_rules--; + + /* Remove it from the list also */ + list_del(&entry->list); + + /* Move down in priority the entries over the deleted one */ + precedence = entry->cfg.precedence; + for (i = index - 1; i >= 0; i--) { + tmp = dpaa2_switch_acl_entry_get_by_index(acl_tbl, i); + err = dpaa2_switch_acl_entry_set_precedence(acl_tbl, tmp, + precedence); + if (err) + return err; + + precedence--; + } + + kfree(entry); + + return 0; +} + +static int dpaa2_switch_tc_parse_action(struct ethsw_core *ethsw, + struct flow_action_entry *cls_act, + struct dpsw_acl_result *dpsw_act, + struct netlink_ext_ack *extack) +{ + int err = 0; + + switch (cls_act->id) { + case FLOW_ACTION_TRAP: + dpsw_act->action = DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF; + break; + case FLOW_ACTION_REDIRECT: + if (!dpaa2_switch_port_dev_check(cls_act->dev)) { + NL_SET_ERR_MSG_MOD(extack, + "Destination not a DPAA2 switch port"); + return -EOPNOTSUPP; + } + + dpsw_act->if_id = dpaa2_switch_get_index(ethsw, cls_act->dev); + dpsw_act->action = DPSW_ACL_ACTION_REDIRECT; + break; + case FLOW_ACTION_DROP: + dpsw_act->action = DPSW_ACL_ACTION_DROP; + break; + default: + NL_SET_ERR_MSG_MOD(extack, + "Action not supported"); + err = -EOPNOTSUPP; + goto out; + } + +out: + return err; +} + +int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_acl_tbl *acl_tbl, + struct flow_cls_offload *cls) +{ + struct flow_rule *rule = flow_cls_offload_flow_rule(cls); + struct netlink_ext_ack *extack = cls->common.extack; + struct ethsw_core *ethsw = acl_tbl->ethsw; + struct dpaa2_switch_acl_entry *acl_entry; + struct flow_action_entry *act; + int err; + + if (!flow_offload_has_one_action(&rule->action)) { + NL_SET_ERR_MSG(extack, "Only singular actions are supported"); + return -EOPNOTSUPP; + } + + if (dpaa2_switch_acl_tbl_is_full(acl_tbl)) { + NL_SET_ERR_MSG(extack, "Maximum filter capacity reached"); + return -ENOMEM; + } + + acl_entry = kzalloc(sizeof(*acl_entry), GFP_KERNEL); + if (!acl_entry) + return -ENOMEM; + + err = dpaa2_switch_flower_parse_key(cls, &acl_entry->key); + if (err) + goto free_acl_entry; + + act = &rule->action.entries[0]; + err = dpaa2_switch_tc_parse_action(ethsw, act, + &acl_entry->cfg.result, extack); + if (err) + goto free_acl_entry; + + acl_entry->prio = cls->common.prio; + acl_entry->cookie = cls->cookie; + + err = dpaa2_switch_acl_tbl_add_entry(acl_tbl, acl_entry); + if (err) + goto free_acl_entry; + + return 0; + +free_acl_entry: + kfree(acl_entry); + + return err; +} + +int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl, + struct flow_cls_offload *cls) +{ + struct dpaa2_switch_acl_entry *entry; + + entry = dpaa2_switch_acl_tbl_find_entry_by_cookie(acl_tbl, cls->cookie); + if (!entry) + return 0; + + return dpaa2_switch_acl_tbl_remove_entry(acl_tbl, entry); +} diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index fc9e2eb0ad11..5080788c692b 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -1125,6 +1126,243 @@ static netdev_tx_t dpaa2_switch_port_tx(struct sk_buff *skb, return NETDEV_TX_OK; } +static int +dpaa2_switch_setup_tc_cls_flower(struct dpaa2_switch_acl_tbl *acl_tbl, + struct flow_cls_offload *f) +{ + switch (f->command) { + case FLOW_CLS_REPLACE: + return dpaa2_switch_cls_flower_replace(acl_tbl, f); + case FLOW_CLS_DESTROY: + return dpaa2_switch_cls_flower_destroy(acl_tbl, f); + default: + return -EOPNOTSUPP; + } +} + +static int dpaa2_switch_port_setup_tc_block_cb_ig(enum tc_setup_type type, + void *type_data, + void *cb_priv) +{ + switch (type) { + case TC_SETUP_CLSFLOWER: + return dpaa2_switch_setup_tc_cls_flower(cb_priv, type_data); + default: + return -EOPNOTSUPP; + } +} + +static LIST_HEAD(dpaa2_switch_block_cb_list); + +static int dpaa2_switch_port_acl_tbl_bind(struct ethsw_port_priv *port_priv, + struct dpaa2_switch_acl_tbl *acl_tbl) +{ + struct ethsw_core *ethsw = port_priv->ethsw_data; + struct net_device *netdev = port_priv->netdev; + struct dpsw_acl_if_cfg acl_if_cfg; + int err; + + if (port_priv->acl_tbl) + return -EINVAL; + + acl_if_cfg.if_id[0] = port_priv->idx; + acl_if_cfg.num_ifs = 1; + err = dpsw_acl_add_if(ethsw->mc_io, 0, ethsw->dpsw_handle, + acl_tbl->id, &acl_if_cfg); + if (err) { + netdev_err(netdev, "dpsw_acl_add_if err %d\n", err); + return err; + } + + acl_tbl->ports |= BIT(port_priv->idx); + port_priv->acl_tbl = acl_tbl; + + return 0; +} + +static int +dpaa2_switch_port_acl_tbl_unbind(struct ethsw_port_priv *port_priv, + struct dpaa2_switch_acl_tbl *acl_tbl) +{ + struct ethsw_core *ethsw = port_priv->ethsw_data; + struct net_device *netdev = port_priv->netdev; + struct dpsw_acl_if_cfg acl_if_cfg; + int err; + + if (port_priv->acl_tbl != acl_tbl) + return -EINVAL; + + acl_if_cfg.if_id[0] = port_priv->idx; + acl_if_cfg.num_ifs = 1; + err = dpsw_acl_remove_if(ethsw->mc_io, 0, ethsw->dpsw_handle, + acl_tbl->id, &acl_if_cfg); + if (err) { + netdev_err(netdev, "dpsw_acl_add_if err %d\n", err); + return err; + } + + acl_tbl->ports &= ~BIT(port_priv->idx); + port_priv->acl_tbl = NULL; + return 0; +} + +static int dpaa2_switch_port_block_bind(struct ethsw_port_priv *port_priv, + struct dpaa2_switch_acl_tbl *acl_tbl) +{ + struct dpaa2_switch_acl_tbl *old_acl_tbl = port_priv->acl_tbl; + int err; + + /* If the port is already bound to this ACL table then do nothing. This + * can happen when this port is the first one to join a tc block + */ + if (port_priv->acl_tbl == acl_tbl) + return 0; + + err = dpaa2_switch_port_acl_tbl_unbind(port_priv, old_acl_tbl); + if (err) + return err; + + /* Mark the previous ACL table as being unused if this was the last + * port that was using it. + */ + if (old_acl_tbl->ports == 0) + old_acl_tbl->in_use = false; + + return dpaa2_switch_port_acl_tbl_bind(port_priv, acl_tbl); +} + +static int dpaa2_switch_port_block_unbind(struct ethsw_port_priv *port_priv, + struct dpaa2_switch_acl_tbl *acl_tbl) +{ + struct ethsw_core *ethsw = port_priv->ethsw_data; + struct dpaa2_switch_acl_tbl *new_acl_tbl; + int err; + + /* We are the last port that leaves a block (an ACL table). + * We'll continue to use this table. + */ + if (acl_tbl->ports == BIT(port_priv->idx)) + return 0; + + err = dpaa2_switch_port_acl_tbl_unbind(port_priv, acl_tbl); + if (err) + return err; + + if (acl_tbl->ports == 0) + acl_tbl->in_use = false; + + new_acl_tbl = dpaa2_switch_acl_tbl_get_unused(ethsw); + new_acl_tbl->in_use = true; + return dpaa2_switch_port_acl_tbl_bind(port_priv, new_acl_tbl); +} + +static int dpaa2_switch_setup_tc_block_bind(struct net_device *netdev, + struct flow_block_offload *f) +{ + struct ethsw_port_priv *port_priv = netdev_priv(netdev); + struct ethsw_core *ethsw = port_priv->ethsw_data; + struct dpaa2_switch_acl_tbl *acl_tbl; + struct flow_block_cb *block_cb; + bool register_block = false; + int err; + + block_cb = flow_block_cb_lookup(f->block, + dpaa2_switch_port_setup_tc_block_cb_ig, + ethsw); + + if (!block_cb) { + /* If the ACL table is not already known, then this port must + * be the first to join it. In this case, we can just continue + * to use our private table + */ + acl_tbl = port_priv->acl_tbl; + + block_cb = flow_block_cb_alloc(dpaa2_switch_port_setup_tc_block_cb_ig, + ethsw, acl_tbl, NULL); + if (IS_ERR(block_cb)) + return PTR_ERR(block_cb); + + register_block = true; + } else { + acl_tbl = flow_block_cb_priv(block_cb); + } + + flow_block_cb_incref(block_cb); + err = dpaa2_switch_port_block_bind(port_priv, acl_tbl); + if (err) + goto err_block_bind; + + if (register_block) { + flow_block_cb_add(block_cb, f); + list_add_tail(&block_cb->driver_list, + &dpaa2_switch_block_cb_list); + } + + return 0; + +err_block_bind: + if (!flow_block_cb_decref(block_cb)) + flow_block_cb_free(block_cb); + return err; +} + +static void dpaa2_switch_setup_tc_block_unbind(struct net_device *netdev, + struct flow_block_offload *f) +{ + struct ethsw_port_priv *port_priv = netdev_priv(netdev); + struct ethsw_core *ethsw = port_priv->ethsw_data; + struct dpaa2_switch_acl_tbl *acl_tbl; + struct flow_block_cb *block_cb; + int err; + + block_cb = flow_block_cb_lookup(f->block, + dpaa2_switch_port_setup_tc_block_cb_ig, + ethsw); + if (!block_cb) + return; + + acl_tbl = flow_block_cb_priv(block_cb); + err = dpaa2_switch_port_block_unbind(port_priv, acl_tbl); + if (!err && !flow_block_cb_decref(block_cb)) { + flow_block_cb_remove(block_cb, f); + list_del(&block_cb->driver_list); + } +} + +static int dpaa2_switch_setup_tc_block(struct net_device *netdev, + struct flow_block_offload *f) +{ + if (f->binder_type != FLOW_BLOCK_BINDER_TYPE_CLSACT_INGRESS) + return -EOPNOTSUPP; + + f->driver_block_list = &dpaa2_switch_block_cb_list; + + switch (f->command) { + case FLOW_BLOCK_BIND: + return dpaa2_switch_setup_tc_block_bind(netdev, f); + case FLOW_BLOCK_UNBIND: + dpaa2_switch_setup_tc_block_unbind(netdev, f); + return 0; + default: + return -EOPNOTSUPP; + } +} + +static int dpaa2_switch_port_setup_tc(struct net_device *netdev, + enum tc_setup_type type, + void *type_data) +{ + switch (type) { + case TC_SETUP_BLOCK: { + return dpaa2_switch_setup_tc_block(netdev, type_data); + } + default: + return -EOPNOTSUPP; + } + + return 0; +} + static const struct net_device_ops dpaa2_switch_port_ops = { .ndo_open = dpaa2_switch_port_open, .ndo_stop = dpaa2_switch_port_stop, @@ -1141,6 +1379,7 @@ static const struct net_device_ops dpaa2_switch_port_ops = { .ndo_start_xmit = dpaa2_switch_port_tx, .ndo_get_port_parent_id = dpaa2_switch_port_parent_id, .ndo_get_phys_port_name = dpaa2_switch_port_get_phys_name, + .ndo_setup_tc = dpaa2_switch_port_setup_tc, }; bool dpaa2_switch_port_dev_check(const struct net_device *netdev) @@ -2749,7 +2988,6 @@ static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port) struct ethsw_core *ethsw = port_priv->ethsw_data; struct dpaa2_switch_acl_tbl *acl_tbl; struct dpsw_fdb_cfg fdb_cfg = {0}; - struct dpsw_acl_if_cfg acl_if_cfg; struct dpsw_if_attr dpsw_if_attr; struct dpaa2_switch_fdb *fdb; struct dpsw_acl_cfg acl_cfg; @@ -2803,21 +3041,16 @@ static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port) return err; } - acl_if_cfg.if_id[0] = port_priv->idx; - acl_if_cfg.num_ifs = 1; - err = dpsw_acl_add_if(ethsw->mc_io, 0, ethsw->dpsw_handle, - acl_tbl_id, &acl_if_cfg); - if (err) { - netdev_err(netdev, "dpsw_acl_add_if err %d\n", err); - dpsw_acl_remove(ethsw->mc_io, 0, ethsw->dpsw_handle, - acl_tbl_id); - } - acl_tbl = dpaa2_switch_acl_tbl_get_unused(ethsw); + acl_tbl->ethsw = ethsw; acl_tbl->id = acl_tbl_id; acl_tbl->in_use = true; acl_tbl->num_rules = 0; - port_priv->acl_tbl = acl_tbl; + INIT_LIST_HEAD(&acl_tbl->entries); + + err = dpaa2_switch_port_acl_tbl_bind(port_priv, acl_tbl); + if (err) + return err; err = dpaa2_switch_port_trap_mac_addr(port_priv, stpa); if (err) @@ -2927,7 +3160,9 @@ static int dpaa2_switch_probe_port(struct ethsw_core *ethsw, /* The DPAA2 switch's ingress path depends on the VLAN table, * thus we are not able to disable VLAN filtering. */ - port_netdev->features = NETIF_F_HW_VLAN_CTAG_FILTER | NETIF_F_HW_VLAN_STAG_FILTER; + port_netdev->features = NETIF_F_HW_VLAN_CTAG_FILTER | + NETIF_F_HW_VLAN_STAG_FILTER | + NETIF_F_HW_TC; err = dpaa2_switch_port_init(port_priv, port_idx); if (err) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h index a2c0ff23c7e9..629186208b58 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h @@ -80,6 +80,8 @@ (DPAA2_SWITCH_TX_DATA_OFFSET + DPAA2_SWITCH_TX_BUF_ALIGN) #define DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES 16 +#define DPAA2_ETHSW_PORT_DEFAULT_TRAPS 1 + #define DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE 256 extern const struct ethtool_ops dpaa2_switch_port_ethtool_ops; @@ -101,12 +103,34 @@ struct dpaa2_switch_fdb { bool in_use; }; +struct dpaa2_switch_acl_entry { + struct list_head list; + u16 prio; + unsigned long cookie; + + struct dpsw_acl_entry_cfg cfg; + struct dpsw_acl_key key; +}; + struct dpaa2_switch_acl_tbl { + struct list_head entries; + struct ethsw_core *ethsw; + u64 ports; + u16 id; u8 num_rules; bool in_use; }; +static inline bool +dpaa2_switch_acl_tbl_is_full(struct dpaa2_switch_acl_tbl *acl_tbl) +{ + if ((acl_tbl->num_rules + DPAA2_ETHSW_PORT_DEFAULT_TRAPS) >= + DPAA2_ETHSW_PORT_MAX_ACL_ENTRIES) + return true; + return false; +} + /* Per port private data */ struct ethsw_port_priv { struct net_device *netdev; @@ -153,6 +177,18 @@ struct ethsw_core { struct dpaa2_switch_acl_tbl *acls; }; +static inline int dpaa2_switch_get_index(struct ethsw_core *ethsw, + struct net_device *netdev) +{ + int i; + + for (i = 0; i < ethsw->sw_attr.num_ifs; i++) + if (ethsw->ports[i]->netdev == netdev) + return ethsw->ports[i]->idx; + + return -EINVAL; +} + static inline bool dpaa2_switch_supports_cpu_traffic(struct ethsw_core *ethsw) { if (ethsw->sw_attr.options & DPSW_OPT_CTRL_IF_DIS) { @@ -189,4 +225,12 @@ int dpaa2_switch_port_vlans_del(struct net_device *netdev, typedef int dpaa2_switch_fdb_cb_t(struct ethsw_port_priv *port_priv, struct fdb_dump_entry *fdb_entry, void *data); + +/* TC offload */ + +int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_acl_tbl *acl_tbl, + struct flow_cls_offload *cls); + +int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl, + struct flow_cls_offload *cls); #endif /* __ETHSW_H */ diff --git a/drivers/net/ethernet/freescale/dpaa2/dpsw-cmd.h b/drivers/net/ethernet/freescale/dpaa2/dpsw-cmd.h index 1747cee19a72..cb13e740f72b 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpsw-cmd.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpsw-cmd.h @@ -77,6 +77,7 @@ #define DPSW_CMDID_ACL_ADD DPSW_CMD_ID(0x090) #define DPSW_CMDID_ACL_REMOVE DPSW_CMD_ID(0x091) #define DPSW_CMDID_ACL_ADD_ENTRY DPSW_CMD_ID(0x092) +#define DPSW_CMDID_ACL_REMOVE_ENTRY DPSW_CMD_ID(0x093) #define DPSW_CMDID_ACL_ADD_IF DPSW_CMD_ID(0x094) #define DPSW_CMDID_ACL_REMOVE_IF DPSW_CMD_ID(0x095) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpsw.c b/drivers/net/ethernet/freescale/dpaa2/dpsw.c index 6704efe89bc1..6352d6d1ecba 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpsw.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpsw.c @@ -1544,3 +1544,38 @@ int dpsw_acl_add_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, return mc_send_command(mc_io, &cmd); } + +/** + * dpsw_acl_remove_entry() - Removes an entry from ACL. + * @mc_io: Pointer to MC portal's I/O object + * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_' + * @token: Token of DPSW object + * @acl_id: ACL ID + * @cfg: Entry configuration + * + * warning: This function has to be called after dpsw_acl_set_entry_cfg() + * + * Return: '0' on Success; Error code otherwise. + */ +int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, + u16 acl_id, const struct dpsw_acl_entry_cfg *cfg) +{ + struct dpsw_cmd_acl_entry *cmd_params; + struct fsl_mc_command cmd = { 0 }; + + /* prepare command */ + cmd.header = mc_encode_cmd_header(DPSW_CMDID_ACL_REMOVE_ENTRY, + cmd_flags, + token); + cmd_params = (struct dpsw_cmd_acl_entry *)cmd.params; + cmd_params->acl_id = cpu_to_le16(acl_id); + cmd_params->result_if_id = cpu_to_le16(cfg->result.if_id); + cmd_params->precedence = cpu_to_le32(cfg->precedence); + cmd_params->key_iova = cpu_to_le64(cfg->key_iova); + dpsw_set_field(cmd_params->result_action, + RESULT_ACTION, + cfg->result.action); + + /* send command to mc*/ + return mc_send_command(mc_io, &cmd); +} diff --git a/drivers/net/ethernet/freescale/dpaa2/dpsw.h b/drivers/net/ethernet/freescale/dpaa2/dpsw.h index 08e37c475ae8..5ef221a25b02 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpsw.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpsw.h @@ -749,4 +749,7 @@ void dpsw_acl_prepare_entry_cfg(const struct dpsw_acl_key *key, int dpsw_acl_add_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, u16 acl_id, const struct dpsw_acl_entry_cfg *cfg); + +int dpsw_acl_remove_entry(struct fsl_mc_io *mc_io, u32 cmd_flags, u16 token, + u16 acl_id, const struct dpsw_acl_entry_cfg *cfg); #endif /* __FSL_DPSW_H */ From patchwork Tue Apr 13 13:24:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ioana Ciornei X-Patchwork-Id: 12200547 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 X-Spam-Level: X-Spam-Status: No, score=-14.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HK_RANDOM_FROM,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06AFBC433ED for ; Tue, 13 Apr 2021 13:26:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DCB5661369 for ; Tue, 13 Apr 2021 13:26:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345967AbhDMN0c (ORCPT ); Tue, 13 Apr 2021 09:26:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45224 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345738AbhDMN00 (ORCPT ); Tue, 13 Apr 2021 09:26:26 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C725CC061574 for ; Tue, 13 Apr 2021 06:26:06 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id lr1-20020a17090b4b81b02900ea0a3f38c1so1327925pjb.0 for ; Tue, 13 Apr 2021 06:26:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=cgu8hmxXAkpNCdeO9Q62EwQ7P/NjTWNkUUJyq5bafN0=; b=n3F68KbhRBZP1fuv/TbJA8EywHCVUc+GprP7hEjdxc5Vd1PMFbqpSmzcqa85aEr8b1 zBx0szrcz90jq1NZf1eUjGIg3f0juKiduCo/a6aNYO1XPsRjaBitCbDx2Q9ZrpqLhfXs ydL7YTV4/E4rsBorrNDFl987o/TaH3f/D2ZrBn4Egg601GyrlgSFbYFmYlvN60UQxQ98 BUyFlgEb4oj0XP+1MJPjy+Ysq4Tb6vVaS3UgC80osVuVP8a+1usVwUoPypd/bRxmPWhJ KNzk3k+/byMtzHopQmy9RaGoeyipj5Rdt8V8kcdT37eRxQPr+sQw5AddHieXfHoLiofZ HdOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cgu8hmxXAkpNCdeO9Q62EwQ7P/NjTWNkUUJyq5bafN0=; b=AAwhhKvPILYl3GPUQmuFM/vW0QKNUxrBPM6LPzf0O5LssK68fr/sjd0hNH8NizFwKn 6wXOO8rpZmQwFUrw2LCWA6gLq+suwQpbch4IBSV8E0JGlLNHpYYSa0Qe/QHyHSjoJEec i7SNt2ponQvQEhhNt2EAzTACeangG76mxPQ2kTeF0ZAlqSoPM2cm62cHyxy9jzZo9F4b jOaPQLSl33R2emolM5teTMItoTSOEv2PC9LiVlzFv2C5GkX71eD769MxdPxpCPX0QIe6 t23G2m66bZvvru04cDssjTg5cb0rx82avva237rO8IUKcabIMqz8rIH7/muR9Fi5iBo3 NNpg== X-Gm-Message-State: AOAM530idDHVJNmIMGrH3S/jpzkZlMGabpP5OPcATjzoyPZTDFZ3KUrb WRQVpEqjC4oWSG6NelFOW24= X-Google-Smtp-Source: ABdhPJw91tUHyxIOOL+ms25PUmCnuMTJo7bcoCrU+avgxmi8fBcg8qp4oBg1pFCPO98VG8ALcY2Fmw== X-Received: by 2002:a17:90b:714:: with SMTP id s20mr43206pjz.62.1618320366303; Tue, 13 Apr 2021 06:26:06 -0700 (PDT) Received: from yoga-910.localhost (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id z18sm12417650pfa.39.2021.04.13.06.26.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 06:26:05 -0700 (PDT) From: Ioana Ciornei To: davem@davemloft.net, kuba@kernel.org, netdev@vger.kernel.org Cc: ruxandra.radulescu@nxp.com, Ioana Ciornei Subject: [PATCH net-next 4/5] dpaa2-switch: add tc matchall filter support Date: Tue, 13 Apr 2021 16:24:47 +0300 Message-Id: <20210413132448.4141787-5-ciorneiioana@gmail.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210413132448.4141787-1-ciorneiioana@gmail.com> References: <20210413132448.4141787-1-ciorneiioana@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Ioana Ciornei Add support TC_SETUP_CLSMATCHALL by using the same ACL table entries framework as for tc flower. Adding a matchall rule is done by installing an entry which has a mask of all zeroes, thus matching on any packet. This can be used as a catch-all type of rule if used correctly, ie the priority of the matchall filter should be kept as the lowest one in the entire filter block. Signed-off-by: Ioana Ciornei --- .../freescale/dpaa2/dpaa2-switch-flower.c | 56 +++++++++++++++++++ .../ethernet/freescale/dpaa2/dpaa2-switch.c | 16 ++++++ .../ethernet/freescale/dpaa2/dpaa2-switch.h | 7 +++ 3 files changed, 79 insertions(+) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c index ee987fa02f0d..b4807ddc2011 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c @@ -434,3 +434,59 @@ int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl, return dpaa2_switch_acl_tbl_remove_entry(acl_tbl, entry); } + +int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_acl_tbl *acl_tbl, + struct tc_cls_matchall_offload *cls) +{ + struct netlink_ext_ack *extack = cls->common.extack; + struct ethsw_core *ethsw = acl_tbl->ethsw; + struct dpaa2_switch_acl_entry *acl_entry; + struct flow_action_entry *act; + int err; + + if (!flow_offload_has_one_action(&cls->rule->action)) { + NL_SET_ERR_MSG(extack, "Only singular actions are supported"); + return -EOPNOTSUPP; + } + + if (dpaa2_switch_acl_tbl_is_full(acl_tbl)) { + NL_SET_ERR_MSG(extack, "Maximum filter capacity reached"); + return -ENOMEM; + } + + acl_entry = kzalloc(sizeof(*acl_entry), GFP_KERNEL); + if (!acl_entry) + return -ENOMEM; + + act = &cls->rule->action.entries[0]; + err = dpaa2_switch_tc_parse_action(ethsw, act, + &acl_entry->cfg.result, extack); + if (err) + goto free_acl_entry; + + acl_entry->prio = cls->common.prio; + acl_entry->cookie = cls->cookie; + + err = dpaa2_switch_acl_tbl_add_entry(acl_tbl, acl_entry); + if (err) + goto free_acl_entry; + + return 0; + +free_acl_entry: + kfree(acl_entry); + + return err; +} + +int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_acl_tbl *acl_tbl, + struct tc_cls_matchall_offload *cls) +{ + struct dpaa2_switch_acl_entry *entry; + + entry = dpaa2_switch_acl_tbl_find_entry_by_cookie(acl_tbl, cls->cookie); + if (!entry) + return 0; + + return dpaa2_switch_acl_tbl_remove_entry(acl_tbl, entry); +} diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index 5080788c692b..adf9e5880d89 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -1140,6 +1140,20 @@ dpaa2_switch_setup_tc_cls_flower(struct dpaa2_switch_acl_tbl *acl_tbl, } } +static int +dpaa2_switch_setup_tc_cls_matchall(struct dpaa2_switch_acl_tbl *acl_tbl, + struct tc_cls_matchall_offload *f) +{ + switch (f->command) { + case TC_CLSMATCHALL_REPLACE: + return dpaa2_switch_cls_matchall_replace(acl_tbl, f); + case TC_CLSMATCHALL_DESTROY: + return dpaa2_switch_cls_matchall_destroy(acl_tbl, f); + default: + return -EOPNOTSUPP; + } +} + static int dpaa2_switch_port_setup_tc_block_cb_ig(enum tc_setup_type type, void *type_data, void *cb_priv) @@ -1147,6 +1161,8 @@ static int dpaa2_switch_port_setup_tc_block_cb_ig(enum tc_setup_type type, switch (type) { case TC_SETUP_CLSFLOWER: return dpaa2_switch_setup_tc_cls_flower(cb_priv, type_data); + case TC_SETUP_CLSMATCHALL: + return dpaa2_switch_setup_tc_cls_matchall(cb_priv, type_data); default: return -EOPNOTSUPP; } diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h index 629186208b58..8575eed02d15 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "dpsw.h" @@ -233,4 +234,10 @@ int dpaa2_switch_cls_flower_replace(struct dpaa2_switch_acl_tbl *acl_tbl, int dpaa2_switch_cls_flower_destroy(struct dpaa2_switch_acl_tbl *acl_tbl, struct flow_cls_offload *cls); + +int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_acl_tbl *acl_tbl, + struct tc_cls_matchall_offload *cls); + +int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_acl_tbl *acl_tbl, + struct tc_cls_matchall_offload *cls); #endif /* __ETHSW_H */ From patchwork Tue Apr 13 13:24:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ioana Ciornei X-Patchwork-Id: 12200549 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 X-Spam-Level: X-Spam-Status: No, score=-14.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,HK_RANDOM_FROM,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 000F2C433ED for ; Tue, 13 Apr 2021 13:26:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D6E37613B2 for ; Tue, 13 Apr 2021 13:26:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345976AbhDMN0g (ORCPT ); Tue, 13 Apr 2021 09:26:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45250 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345966AbhDMN0b (ORCPT ); Tue, 13 Apr 2021 09:26:31 -0400 Received: from mail-pf1-x42f.google.com (mail-pf1-x42f.google.com [IPv6:2607:f8b0:4864:20::42f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA52DC061574 for ; Tue, 13 Apr 2021 06:26:11 -0700 (PDT) Received: by mail-pf1-x42f.google.com with SMTP id o123so11425256pfb.4 for ; Tue, 13 Apr 2021 06:26:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=SWxGpoV3SCRWa+W6YjE4yu30JcgXPuVhZUtCPgreIz0=; b=gDGB2t75LFPCtJQmpjKPwDHJldS/E/k913VpTKDvpG5O0bmQTIWywK8WC2mZHj+n8u VZKGAsifbKVa3VE1jo6VeMNsB5+wwGuQRelnKOX8kL2qDdjuQLqaQYbDKvEZ5mk/QSrW vR6t52v3kLNTw8Er6sc2bRAovp5al1peTLtqIcpkIA+4HHcSkUoaK1vhiTHkPk6kWlvs Tv/k9QMlmwD/RfKX+VihqNZkENTU7sa8Kx4PhDyKwhyGnMV8LMiKugx8kPqKFSn0BmQB q8o10AMkIKme06xn6Y1ASrCeqIX7izXIrUEeim9Phjb+8x+tCaTaa8d1NHHf4a7IKChw w9cQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=SWxGpoV3SCRWa+W6YjE4yu30JcgXPuVhZUtCPgreIz0=; b=pksHfGNhdXLPNWIDzv6ONhZ2Ek+XyB8LWUDuG8DaDVtix/gxr8vozUbdSfxHjz4h+J TRWZgKyciyLPf5xF2HcxaJLJ9UntjlVnNt7Tln7X0koyUfNfEvlGuvMSF3xhCK6Z38Fu 8zlc27263y1fNJZJXqJql8jEsJ+WTQoiWLJnSkhZsm7wIlHBDi/jFfbWSPDYi2yY5dvy OG+2iRGa/CafFfGIQfJKuws51pW1FTWo5cGSo8L10eD3DOn+yPjS95R8+X2hgbKEDm07 3anVrzWyoy4M2pVfmVq2b68sQbPCuljmBSG5rQPGL5OWkezvm34ka0GhDVdwCw8vGp9E TtoQ== X-Gm-Message-State: AOAM532rRG3K8BetZ8TOxrw9WdNevO4L20fL5ORE0TJ78hsPVbMv8qyL cF4Qz/Jlr1ETfbI5C4a895c= X-Google-Smtp-Source: ABdhPJzzQFmAN2dBVXD0aaKKxexC0wwiaoPotMAEcbR76zZe/cn55cjDuOPhyp/x6TT8JAXviSDDgw== X-Received: by 2002:a65:4281:: with SMTP id j1mr3408951pgp.348.1618320371293; Tue, 13 Apr 2021 06:26:11 -0700 (PDT) Received: from yoga-910.localhost (5-12-16-165.residential.rdsnet.ro. [5.12.16.165]) by smtp.gmail.com with ESMTPSA id z18sm12417650pfa.39.2021.04.13.06.26.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 13 Apr 2021 06:26:10 -0700 (PDT) From: Ioana Ciornei To: davem@davemloft.net, kuba@kernel.org, netdev@vger.kernel.org Cc: ruxandra.radulescu@nxp.com, Ioana Ciornei Subject: [PATCH net-next 5/5] dpaa2-switch: reuse dpaa2_switch_acl_entry_add() for STP frames trap Date: Tue, 13 Apr 2021 16:24:48 +0300 Message-Id: <20210413132448.4141787-6-ciorneiioana@gmail.com> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210413132448.4141787-1-ciorneiioana@gmail.com> References: <20210413132448.4141787-1-ciorneiioana@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org From: Ioana Ciornei Since we added the dpaa2_switch_acl_entry_add() function in the previous patches to hide all the details of actually adding the ACL entry by issuing a firmware command, let's use it also for adding a CPU trap for the STP frames. Signed-off-by: Ioana Ciornei --- .../freescale/dpaa2/dpaa2-switch-flower.c | 4 +- .../ethernet/freescale/dpaa2/dpaa2-switch.c | 51 +++---------------- .../ethernet/freescale/dpaa2/dpaa2-switch.h | 3 ++ 3 files changed, 12 insertions(+), 46 deletions(-) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c index b4807ddc2011..f9451ec5f2cb 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch-flower.c @@ -111,8 +111,8 @@ static int dpaa2_switch_flower_parse_key(struct flow_cls_offload *cls, return 0; } -static int dpaa2_switch_acl_entry_add(struct dpaa2_switch_acl_tbl *acl_tbl, - struct dpaa2_switch_acl_entry *entry) +int dpaa2_switch_acl_entry_add(struct dpaa2_switch_acl_tbl *acl_tbl, + struct dpaa2_switch_acl_entry *entry) { struct dpsw_acl_entry_cfg *acl_entry_cfg = &entry->cfg; struct ethsw_core *ethsw = acl_tbl->ethsw; diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c index adf9e5880d89..5250d51d783c 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.c @@ -2942,54 +2942,17 @@ static int dpaa2_switch_init(struct fsl_mc_device *sw_dev) static int dpaa2_switch_port_trap_mac_addr(struct ethsw_port_priv *port_priv, const char *mac) { - struct net_device *netdev = port_priv->netdev; - struct dpsw_acl_entry_cfg acl_entry_cfg; - struct dpsw_acl_fields *acl_h; - struct dpsw_acl_fields *acl_m; - struct dpsw_acl_key acl_key; - struct device *dev; - u8 *cmd_buff; - int err; - - dev = port_priv->netdev->dev.parent; - acl_h = &acl_key.match; - acl_m = &acl_key.mask; - - memset(&acl_entry_cfg, 0, sizeof(acl_entry_cfg)); - memset(&acl_key, 0, sizeof(acl_key)); + struct dpaa2_switch_acl_entry acl_entry = {0}; /* Match on the destination MAC address */ - ether_addr_copy(acl_h->l2_dest_mac, mac); - eth_broadcast_addr(acl_m->l2_dest_mac); - - cmd_buff = kzalloc(DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, GFP_KERNEL); - if (!cmd_buff) - return -ENOMEM; - dpsw_acl_prepare_entry_cfg(&acl_key, cmd_buff); + ether_addr_copy(acl_entry.key.match.l2_dest_mac, mac); + eth_broadcast_addr(acl_entry.key.mask.l2_dest_mac); - memset(&acl_entry_cfg, 0, sizeof(acl_entry_cfg)); - acl_entry_cfg.precedence = 0; - acl_entry_cfg.result.action = DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF; - acl_entry_cfg.key_iova = dma_map_single(dev, cmd_buff, - DPAA2_ETHSW_PORT_ACL_CMD_BUF_SIZE, - DMA_TO_DEVICE); - if (unlikely(dma_mapping_error(dev, acl_entry_cfg.key_iova))) { - netdev_err(netdev, "DMA mapping failed\n"); - return -EFAULT; - } + /* Trap to CPU */ + acl_entry.cfg.precedence = 0; + acl_entry.cfg.result.action = DPSW_ACL_ACTION_REDIRECT_TO_CTRL_IF; - err = dpsw_acl_add_entry(port_priv->ethsw_data->mc_io, 0, - port_priv->ethsw_data->dpsw_handle, - port_priv->acl_tbl->id, &acl_entry_cfg); - - dma_unmap_single(dev, acl_entry_cfg.key_iova, sizeof(cmd_buff), - DMA_TO_DEVICE); - if (err) { - netdev_err(netdev, "dpsw_acl_add_entry() failed %d\n", err); - return err; - } - - return 0; + return dpaa2_switch_acl_entry_add(port_priv->acl_tbl, &acl_entry); } static int dpaa2_switch_port_init(struct ethsw_port_priv *port_priv, u16 port) diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h index 8575eed02d15..bdef71f234cb 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-switch.h @@ -240,4 +240,7 @@ int dpaa2_switch_cls_matchall_replace(struct dpaa2_switch_acl_tbl *acl_tbl, int dpaa2_switch_cls_matchall_destroy(struct dpaa2_switch_acl_tbl *acl_tbl, struct tc_cls_matchall_offload *cls); + +int dpaa2_switch_acl_entry_add(struct dpaa2_switch_acl_tbl *acl_tbl, + struct dpaa2_switch_acl_entry *entry); #endif /* __ETHSW_H */