From patchwork Mon Apr 26 17:04:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 428410 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 94F31C433B4 for ; Mon, 26 Apr 2021 17:05:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5D943613AA for ; Mon, 26 Apr 2021 17:05:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235274AbhDZRFl (ORCPT ); Mon, 26 Apr 2021 13:05:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53684 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235223AbhDZRFd (ORCPT ); Mon, 26 Apr 2021 13:05:33 -0400 Received: from mail-lf1-x12d.google.com (mail-lf1-x12d.google.com [IPv6:2a00:1450:4864:20::12d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 36510C06175F for ; Mon, 26 Apr 2021 10:04:50 -0700 (PDT) Received: by mail-lf1-x12d.google.com with SMTP id d27so32518893lfv.9 for ; Mon, 26 Apr 2021 10:04:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=OOyB/1EE0eWY12Fb0O+Ry3sAB71ImU80hOCuCFisolk=; b=0HxjTxUqm16Mjfaxqs+3gIH6mIXzFURaMQXnQTxOWVr/b1qcz/uuVMvXrH4PIkKHkt E0of8vDgA0EnZ/7ghKu9m3qVi8i2U8tX46qT6tUf58bHMHPKoyWIx2Myyi3XdpWHnPai 361UPhyG0ytSzko2v1PqsnWDTKm/+5i22SzYBDzwmE5ZBnl7MMMwRPIhsKpRZyyUJz8N HkZH702ly+zqHvMI5mi00tLT5FFcBFdiqT4r6nwkqMQOCo0TgQYBE+sTvsy0XHaYvIIa TqkiHTN6zFfAt9sDvyURfitCnKpGZ0j6l3uDComxii0BQaHOgBWygUe5GY/Joy+U36Iy 0cUQ== 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:organization:content-transfer-encoding; bh=OOyB/1EE0eWY12Fb0O+Ry3sAB71ImU80hOCuCFisolk=; b=sekRKatpMPOPxPz7GeoirB8ecJyNpRTEG9LB5KguBs8jrOnE0PfKIAvGlh1Z9LkH62 JgwkIGDquvmuXjp0qm8Xz0IRdVQYtGvQBqpeVdXh7tB9ByNjwDJ0PdUA7WsYc39fhm4M eLCkogX4dKs+M8FmFMiUcQLRYuqD/gHflp5cdAZ36WUu7zJh4+bJUOESoR1XNDeEMBPV fRW0O/VV4J169R1wq5iweVB/SipjiBeDaZ9PHMIK6FjcaeIDJAZ2YC+dYV0oMNy8N/8G 8w+cR0vLP7tQPeb7EfE9BkWcvxYcN82lWmW1OegViLpLmSTEJT8QdZGFJLQRjYQMDrTO USWQ== X-Gm-Message-State: AOAM532ozrphDBReeurIk0FbU12ujoHrPxJvRlUBZ+zKbsM1Q0cRg3L5 HOn+meZmVDyoEePTmEbCjU+shw== X-Google-Smtp-Source: ABdhPJyBuqqrojOvqZwoXps/D2lJd/hUbwvs/OaDJtNxxT3mmaXpza+LFxDwuMR7dWk7xGkVt1hhQQ== X-Received: by 2002:ac2:5cb3:: with SMTP id e19mr13168782lfq.89.1619456687593; Mon, 26 Apr 2021 10:04:47 -0700 (PDT) Received: from veiron.westermo.com (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id c18sm59140ljd.66.2021.04.26.10.04.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Apr 2021 10:04:47 -0700 (PDT) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, roopa@nvidia.com, nikolay@nvidia.com, jiri@resnulli.us, idosch@idosch.org, stephen@networkplumber.org, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [RFC net-next 1/9] net: dfwd: Constrain existing users to macvlan subordinates Date: Mon, 26 Apr 2021 19:04:03 +0200 Message-Id: <20210426170411.1789186-2-tobias@waldekranz.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210426170411.1789186-1-tobias@waldekranz.com> References: <20210426170411.1789186-1-tobias@waldekranz.com> MIME-Version: 1.0 Organization: Westermo Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The dfwd_add/del_station NDOs are currently only used by the macvlan subsystem to request L2 forwarding offload from lower devices. In order add support for other types of devices (like bridges), we constrain the current users to make sure that the subordinate requesting the offload is in fact a macvlan. Signed-off-by: Tobias Waldekranz --- drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 3 +++ drivers/net/ethernet/intel/i40e/i40e_main.c | 3 +++ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +++ 3 files changed, 9 insertions(+) diff --git a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c index 2fb52bd6fc0e..4dba6e6a282d 100644 --- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c +++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c @@ -1352,6 +1352,9 @@ static void *fm10k_dfwd_add_station(struct net_device *dev, int size, i; u16 vid, glort; + if (!netif_is_macvlan(sdev)) + return ERR_PTR(-EOPNOTSUPP); + /* The hardware supported by fm10k only filters on the destination MAC * address. In order to avoid issues we only support offloading modes * where the hardware can actually provide the functionality. diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index c2d145a56b5e..b90b79f7ee46 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c @@ -7663,6 +7663,9 @@ static void *i40e_fwd_add(struct net_device *netdev, struct net_device *vdev) struct i40e_fwd_adapter *fwd; int avail_macvlan, ret; + if (!netif_is_macvlan(vdev)) + return ERR_PTR(-EOPNOTSUPP); + if ((pf->flags & I40E_FLAG_DCB_ENABLED)) { netdev_info(netdev, "Macvlans are not supported when DCB is enabled\n"); return ERR_PTR(-EINVAL); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index c5ec17d19c59..ff5334faf6c5 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c @@ -9940,6 +9940,9 @@ static void *ixgbe_fwd_add(struct net_device *pdev, struct net_device *vdev) int tcs = adapter->hw_tcs ? : 1; int pool, err; + if (!netif_is_macvlan(vdev)) + return ERR_PTR(-EOPNOTSUPP); + if (adapter->xdp_prog) { e_warn(probe, "L2FW offload is not supported with XDP\n"); return ERR_PTR(-EINVAL); From patchwork Mon Apr 26 17:04:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 428411 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 739F4C433ED for ; Mon, 26 Apr 2021 17:04:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4C339613AA for ; Mon, 26 Apr 2021 17:04:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235271AbhDZRFf (ORCPT ); Mon, 26 Apr 2021 13:05:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53678 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235197AbhDZRFc (ORCPT ); Mon, 26 Apr 2021 13:05:32 -0400 Received: from mail-lj1-x22a.google.com (mail-lj1-x22a.google.com [IPv6:2a00:1450:4864:20::22a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C0704C061574 for ; Mon, 26 Apr 2021 10:04:49 -0700 (PDT) Received: by mail-lj1-x22a.google.com with SMTP id u20so64975533lja.13 for ; Mon, 26 Apr 2021 10:04:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=LtsleOeb+xmEjnjVcOQVav1US/7Y1octau7gSB29ozs=; b=H+AhWmPpTmJe8HW0sbNeE+T8GJrZ3C84h99VtOMsch+btpamSpove6N3BbUrp7Una1 XGzSxCBwm2TTaV4Lx8pI9se03vYQb5KroqreADw0pZuwtiBFFmGDsduoG/o4WcNCBNx+ mjFDGcA78oqeghApMKAXmxhW09cQM0Wp6bSfvfxdxghMG047Skc7bTUyR6TJa0xhWSsE 7xWS/ASH7cjm6dLOzRkdap/LxgbGX419d/Duvx4AN62QWIbGFuQQsoGSI2IhesR8tz8Q YnRzbx67utWgkfcgskuR32xjAGETPg2NuTRSkaPTn6maU/UcDZbGtZ6F2uGqkSVktzPo GNJQ== 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:organization:content-transfer-encoding; bh=LtsleOeb+xmEjnjVcOQVav1US/7Y1octau7gSB29ozs=; b=m9HC8Kq8OygwQbBPeD13ceewygxkhJFhL7saLTVS3GX+IHOBpKvhTppxODoAA11Z/Q VyhBfAeKiB/2JAvnTatGvBwrDx5090ZuNKk3x8iX4MQo1RT0a7+G6+q3Fw0e8AKyqOpO oSg4DvQ0cXMHCRQQFotQK06Ct+731ADTVLrTDDHyZmym9z1xtCjR/+4LXRyFEHuP/JbR RmjroZN/KgSNDYcBNRdIHhPmL4BGetuG/J0T6oq/7rzMy01JTKQXy4RfW7lDDgO7AHx+ G50jnoLMvsmR81TZEKxj7pdQ2Itb3QGMIWRHh4XO/hDgLN+XHG1SJ5WqgWZQc9pRA22+ DsZQ== X-Gm-Message-State: AOAM531Jupls612l383JYgP3GBG0HyMDR21kUBfMDdDGDJOhqPNUTdWb vs8Ykg/3GFDQR7WigkPymM8A/w== X-Google-Smtp-Source: ABdhPJzS+q86QG1WC4CA1enp1D8sx/7jIVDECKuvXOkXhP8wiuyPwezscYlfYxpfSJVQuEwFBBJNNA== X-Received: by 2002:a2e:555:: with SMTP id 82mr13793764ljf.200.1619456688259; Mon, 26 Apr 2021 10:04:48 -0700 (PDT) Received: from veiron.westermo.com (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id c18sm59140ljd.66.2021.04.26.10.04.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Apr 2021 10:04:47 -0700 (PDT) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, roopa@nvidia.com, nikolay@nvidia.com, jiri@resnulli.us, idosch@idosch.org, stephen@networkplumber.org, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [RFC net-next 2/9] net: bridge: Disambiguate offload_fwd_mark Date: Mon, 26 Apr 2021 19:04:04 +0200 Message-Id: <20210426170411.1789186-3-tobias@waldekranz.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210426170411.1789186-1-tobias@waldekranz.com> References: <20210426170411.1789186-1-tobias@waldekranz.com> MIME-Version: 1.0 Organization: Westermo Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Before this change, four related - but distinct - concepts where named offload_fwd_mark: - skb->offload_fwd_mark: Set by the switchdev driver if the underlying hardware has already forwarded this frame to the other ports in the same hardware domain. - nbp->offload_fwd_mark: An idetifier used to group ports that share the same hardware forwarding domain. - br->offload_fwd_mark: Counter used to make sure that unique IDs are used in cases where a bridge contains ports from multiple hardware domains. - skb->cb->offload_fwd_mark: The hardware domain on which the frame ingressed and was forwarded. Introduce the term "hardware forwarding domain" ("hwdom") in the bridge to denote a set of ports with the following property: If an skb with skb->offload_fwd_mark set, is received on a port belonging to hwdom N, that frame has already been forwarded to all other ports in hwdom N. By decoupling the name from "offload_fwd_mark", we can extend the term's definition in the future - e.g. to add constraints that describe expected egress behavior - without overloading the meaning of "offload_fwd_mark". - nbp->offload_fwd_mark thus becomes nbp->hwdom. - br->offload_fwd_mark becomes br->last_hwdom. - skb->cb->offload_fwd_mark becomes skb->cb->src_hwdom. There is a slight change here: Whereas previously this was only set for offloaded packets, we now always track the incoming hwdom. As all uses where already gated behind checks of skb->offload_fwd_mark, this will not introduce any functional change, but it paves the way for future changes where the ingressing hwdom must be known both for offloaded and non-offloaded frames. Signed-off-by: Tobias Waldekranz --- net/bridge/br_if.c | 2 +- net/bridge/br_private.h | 10 +++++----- net/bridge/br_switchdev.c | 16 ++++++++-------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index f7d2f472ae24..73fa703f8df5 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -643,7 +643,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, if (err) goto err5; - err = nbp_switchdev_mark_set(p); + err = nbp_switchdev_hwdom_set(p); if (err) goto err6; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 7ce8a77cc6b6..53248715f631 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -327,7 +327,7 @@ struct net_bridge_port { struct netpoll *np; #endif #ifdef CONFIG_NET_SWITCHDEV - int offload_fwd_mark; + int hwdom; #endif u16 group_fwd_mask; u16 backup_redirected_cnt; @@ -472,7 +472,7 @@ struct net_bridge { u32 auto_cnt; #ifdef CONFIG_NET_SWITCHDEV - int offload_fwd_mark; + int last_hwdom; #endif struct hlist_head fdb_list; @@ -502,7 +502,7 @@ struct br_input_skb_cb { #endif #ifdef CONFIG_NET_SWITCHDEV - int offload_fwd_mark; + int src_hwdom; #endif }; @@ -1593,7 +1593,7 @@ static inline void br_sysfs_delbr(struct net_device *dev) { return; } /* br_switchdev.c */ #ifdef CONFIG_NET_SWITCHDEV -int nbp_switchdev_mark_set(struct net_bridge_port *p); +int nbp_switchdev_hwdom_set(struct net_bridge_port *p); void nbp_switchdev_frame_mark(const struct net_bridge_port *p, struct sk_buff *skb); bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p, @@ -1613,7 +1613,7 @@ static inline void br_switchdev_frame_unmark(struct sk_buff *skb) skb->offload_fwd_mark = 0; } #else -static inline int nbp_switchdev_mark_set(struct net_bridge_port *p) +static inline int nbp_switchdev_hwdom_set(struct net_bridge_port *p) { return 0; } diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c index a5e601e41cb9..bc085077ae71 100644 --- a/net/bridge/br_switchdev.c +++ b/net/bridge/br_switchdev.c @@ -8,20 +8,20 @@ #include "br_private.h" -static int br_switchdev_mark_get(struct net_bridge *br, struct net_device *dev) +static int br_switchdev_hwdom_get(struct net_bridge *br, struct net_device *dev) { struct net_bridge_port *p; /* dev is yet to be added to the port list. */ list_for_each_entry(p, &br->port_list, list) { if (netdev_port_same_parent_id(dev, p->dev)) - return p->offload_fwd_mark; + return p->hwdom; } - return ++br->offload_fwd_mark; + return ++br->last_hwdom; } -int nbp_switchdev_mark_set(struct net_bridge_port *p) +int nbp_switchdev_hwdom_set(struct net_bridge_port *p) { struct netdev_phys_item_id ppid = { }; int err; @@ -35,7 +35,7 @@ int nbp_switchdev_mark_set(struct net_bridge_port *p) return err; } - p->offload_fwd_mark = br_switchdev_mark_get(p->br, p->dev); + p->hwdom = br_switchdev_hwdom_get(p->br, p->dev); return 0; } @@ -43,15 +43,15 @@ int nbp_switchdev_mark_set(struct net_bridge_port *p) void nbp_switchdev_frame_mark(const struct net_bridge_port *p, struct sk_buff *skb) { - if (skb->offload_fwd_mark && !WARN_ON_ONCE(!p->offload_fwd_mark)) - BR_INPUT_SKB_CB(skb)->offload_fwd_mark = p->offload_fwd_mark; + if (p->hwdom) + BR_INPUT_SKB_CB(skb)->src_hwdom = p->hwdom; } bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p, const struct sk_buff *skb) { return !skb->offload_fwd_mark || - BR_INPUT_SKB_CB(skb)->offload_fwd_mark != p->offload_fwd_mark; + BR_INPUT_SKB_CB(skb)->src_hwdom != p->hwdom; } /* Flags that can be offloaded to hardware */ From patchwork Mon Apr 26 17:04:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 427738 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 20AF2C433B4 for ; Mon, 26 Apr 2021 17:04:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EACE761077 for ; Mon, 26 Apr 2021 17:04:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235226AbhDZRFe (ORCPT ); Mon, 26 Apr 2021 13:05:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53686 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233736AbhDZRFc (ORCPT ); Mon, 26 Apr 2021 13:05:32 -0400 Received: from mail-lf1-x134.google.com (mail-lf1-x134.google.com [IPv6:2a00:1450:4864:20::134]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E19B2C061760 for ; Mon, 26 Apr 2021 10:04:50 -0700 (PDT) Received: by mail-lf1-x134.google.com with SMTP id 12so89087210lfq.13 for ; Mon, 26 Apr 2021 10:04:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=9e8JRkG41zW/5KdiIxv2KB6MG/HZU7gsqYrz+vYOpJM=; b=HjoP7SFxBGd9DCxY6qTHb1EN6VrJ69lc1OJYEGtW/i50YnmGqpunHIhuv0lP131Zl6 ASYDIPoJaspQR0Pm4YxugNQ9106oYo2MfrZpOQLqvbtuZmtbK4cReZBVDQ8yblBwpXoZ 9KzoY9thc7onAqtVGBlaqGGFP1YnrZpEqF986de+U7liBMf3HEhQL60Bs3DRMZFeYhAl Vjs6G1L4sHcidEFUjhAtiaYtmPD1cykij0g4XDBWCENVMjAJJ+ZroXGKVrDIF5GuSzgi 2SPhsOmwZvhVC8gdQAp5ZxfONiy2Mcm5nwMe9/YV3gqnteCUa58FN7cxNU8MktBBe48a yJ4w== 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:organization:content-transfer-encoding; bh=9e8JRkG41zW/5KdiIxv2KB6MG/HZU7gsqYrz+vYOpJM=; b=EGiu7OMhfxH/aZ4JLrWknXlOh4QYKGq5BLE4sXW79bj3Gj+Tn8eCmet6q7OnBgH6RK e8GRvCTACAKyS23T/DJIEYkWUxNYqRSgKotb4yYwbb8s0lb21Q215zh3san9yrVCYQ2U PkjWhk8OuNfP0bQct36L7bd2EXnUacEQH3lQnU434yKl/k8C3jMyfG2KH60EH12DCJc2 vMjehi0Z+JOW+OegqLElbZ7m1QX4EXEfrttIvRHhTH0Vpciq+G1H51W2EqaQvxVUIOWO yFAKEjWNmSVNvtm+voJt2sXCHaNU2gJ2fsizwRS8cKZ2OEMeGsShWkos7sbE3U1MD2ok H70A== X-Gm-Message-State: AOAM530YSGULFARHfdcJ8PgryxHZXaU9UCoJBysWmzvfSJUj0OwB5OHS aqOfsrPhHsLBEkOE7kcq5m5fhg== X-Google-Smtp-Source: ABdhPJw0nXAc2CGqQhULo8nzWIi7CH+xSqi2Y1PfnvUMJVyeawnTqvpD8XUtE3Dh1ugNUxO6VY/bPw== X-Received: by 2002:ac2:43b8:: with SMTP id t24mr13941382lfl.661.1619456689235; Mon, 26 Apr 2021 10:04:49 -0700 (PDT) Received: from veiron.westermo.com (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id c18sm59140ljd.66.2021.04.26.10.04.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Apr 2021 10:04:48 -0700 (PDT) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, roopa@nvidia.com, nikolay@nvidia.com, jiri@resnulli.us, idosch@idosch.org, stephen@networkplumber.org, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [RFC net-next 3/9] net: bridge: switchdev: Recycle unused hwdoms Date: Mon, 26 Apr 2021 19:04:05 +0200 Message-Id: <20210426170411.1789186-4-tobias@waldekranz.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210426170411.1789186-1-tobias@waldekranz.com> References: <20210426170411.1789186-1-tobias@waldekranz.com> MIME-Version: 1.0 Organization: Westermo Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Since hwdoms has thus far only been used for equality comparisons, the bridge has used the simplest possible assignment policy; using a counter to keep track of the last value handed out. With the upcoming transmit offloading, we need to perform set operations efficiently based on hwdoms, e.g. we want to answer questions like "has this skb been forwarded to any port within this hwdom?" Move to a bitmap-based allocation scheme that recycles hwdoms once all members leaves the bridge. This means that we can use a single unsigned long to keep track of the hwdoms that have received an skb. Signed-off-by: Tobias Waldekranz --- net/bridge/br_if.c | 4 +- net/bridge/br_private.h | 29 +++++++++--- net/bridge/br_switchdev.c | 94 ++++++++++++++++++++++++++------------- 3 files changed, 87 insertions(+), 40 deletions(-) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 73fa703f8df5..adaf78e45c23 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -349,6 +349,7 @@ static void del_nbp(struct net_bridge_port *p) nbp_backup_clear(p); nbp_update_port_count(br); + nbp_switchdev_del(p); netdev_upper_dev_unlink(dev, br->dev); @@ -643,7 +644,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, if (err) goto err5; - err = nbp_switchdev_hwdom_set(p); + err = nbp_switchdev_add(p); if (err) goto err6; @@ -704,6 +705,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, list_del_rcu(&p->list); br_fdb_delete_by_port(br, p, 0, 1); nbp_update_port_count(br); + nbp_switchdev_del(p); err6: netdev_upper_dev_unlink(dev, br->dev); err5: diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 53248715f631..aba92864d285 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -29,6 +29,8 @@ #define BR_MULTICAST_DEFAULT_HASH_MAX 4096 +#define BR_HWDOM_MAX BITS_PER_LONG + #define BR_VERSION "2.3" /* Control of forwarding link local multicast */ @@ -54,6 +56,8 @@ typedef struct bridge_id bridge_id; typedef struct mac_addr mac_addr; typedef __u16 port_id; +typedef DECLARE_BITMAP(br_hwdom_map_t, BR_HWDOM_MAX); + struct bridge_id { unsigned char prio[2]; unsigned char addr[ETH_ALEN]; @@ -472,7 +476,7 @@ struct net_bridge { u32 auto_cnt; #ifdef CONFIG_NET_SWITCHDEV - int last_hwdom; + br_hwdom_map_t busy_hwdoms; #endif struct hlist_head fdb_list; @@ -1593,7 +1597,6 @@ static inline void br_sysfs_delbr(struct net_device *dev) { return; } /* br_switchdev.c */ #ifdef CONFIG_NET_SWITCHDEV -int nbp_switchdev_hwdom_set(struct net_bridge_port *p); void nbp_switchdev_frame_mark(const struct net_bridge_port *p, struct sk_buff *skb); bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p, @@ -1607,17 +1610,15 @@ void br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int br_switchdev_port_vlan_add(struct net_device *dev, u16 vid, u16 flags, struct netlink_ext_ack *extack); int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid); +int nbp_switchdev_add(struct net_bridge_port *p); +void nbp_switchdev_del(struct net_bridge_port *p); +void br_switchdev_init(struct net_bridge *br); static inline void br_switchdev_frame_unmark(struct sk_buff *skb) { skb->offload_fwd_mark = 0; } #else -static inline int nbp_switchdev_hwdom_set(struct net_bridge_port *p) -{ - return 0; -} - static inline void nbp_switchdev_frame_mark(const struct net_bridge_port *p, struct sk_buff *skb) { @@ -1657,6 +1658,20 @@ br_switchdev_fdb_notify(const struct net_bridge_fdb_entry *fdb, int type) static inline void br_switchdev_frame_unmark(struct sk_buff *skb) { } + +static inline int nbp_switchdev_add(struct net_bridge_port *p) +{ + return 0; +} + +static inline void nbp_switchdev_del(struct net_bridge_port *p) +{ +} + +static inline void br_switchdev_init(struct net_bridge *br) +{ +} + #endif /* CONFIG_NET_SWITCHDEV */ /* br_arp_nd_proxy.c */ diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c index bc085077ae71..54bd7205bfb5 100644 --- a/net/bridge/br_switchdev.c +++ b/net/bridge/br_switchdev.c @@ -8,38 +8,6 @@ #include "br_private.h" -static int br_switchdev_hwdom_get(struct net_bridge *br, struct net_device *dev) -{ - struct net_bridge_port *p; - - /* dev is yet to be added to the port list. */ - list_for_each_entry(p, &br->port_list, list) { - if (netdev_port_same_parent_id(dev, p->dev)) - return p->hwdom; - } - - return ++br->last_hwdom; -} - -int nbp_switchdev_hwdom_set(struct net_bridge_port *p) -{ - struct netdev_phys_item_id ppid = { }; - int err; - - ASSERT_RTNL(); - - err = dev_get_port_parent_id(p->dev, &ppid, true); - if (err) { - if (err == -EOPNOTSUPP) - return 0; - return err; - } - - p->hwdom = br_switchdev_hwdom_get(p->br, p->dev); - - return 0; -} - void nbp_switchdev_frame_mark(const struct net_bridge_port *p, struct sk_buff *skb) { @@ -156,3 +124,65 @@ int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid) return switchdev_port_obj_del(dev, &v.obj); } + +static int nbp_switchdev_hwdom_set(struct net_bridge_port *joining) +{ + struct net_bridge *br = joining->br; + struct net_bridge_port *p; + int hwdom; + + /* joining is yet to be added to the port list. */ + list_for_each_entry(p, &br->port_list, list) { + if (netdev_port_same_parent_id(joining->dev, p->dev)) { + joining->hwdom = p->hwdom; + return 0; + } + } + + hwdom = find_next_zero_bit(br->busy_hwdoms, BR_HWDOM_MAX, 1); + if (hwdom >= BR_HWDOM_MAX) + return -EBUSY; + + set_bit(hwdom, br->busy_hwdoms); + joining->hwdom = hwdom; + return 0; +} + +static void nbp_switchdev_hwdom_put(struct net_bridge_port *leaving) +{ + struct net_bridge *br = leaving->br; + struct net_bridge_port *p; + + /* leaving is no longer in the port list. */ + list_for_each_entry(p, &br->port_list, list) { + if (p->hwdom == leaving->hwdom) + return; + } + + clear_bit(leaving->hwdom, br->busy_hwdoms); +} + +int nbp_switchdev_add(struct net_bridge_port *p) +{ + struct netdev_phys_item_id ppid = { }; + int err; + + ASSERT_RTNL(); + + err = dev_get_port_parent_id(p->dev, &ppid, true); + if (err) { + if (err == -EOPNOTSUPP) + return 0; + return err; + } + + return nbp_switchdev_hwdom_set(p); +} + +void nbp_switchdev_del(struct net_bridge_port *p) +{ + ASSERT_RTNL(); + + if (p->hwdom) + nbp_switchdev_hwdom_put(p); +} From patchwork Mon Apr 26 17:04:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 428409 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 E977CC433ED for ; Mon, 26 Apr 2021 17:05:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BA0E0613A9 for ; Mon, 26 Apr 2021 17:05:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235384AbhDZRFv (ORCPT ); Mon, 26 Apr 2021 13:05:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235238AbhDZRFf (ORCPT ); Mon, 26 Apr 2021 13:05:35 -0400 Received: from mail-lj1-x22d.google.com (mail-lj1-x22d.google.com [IPv6:2a00:1450:4864:20::22d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 16527C061760 for ; Mon, 26 Apr 2021 10:04:53 -0700 (PDT) Received: by mail-lj1-x22d.google.com with SMTP id a5so27989160ljk.0 for ; Mon, 26 Apr 2021 10:04:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=/cToQRV0mJaSSO0QEmQ51Ug3Puq0Aydk1IJ9qqf2Bqc=; b=IN7uLMxPZgDf04DhBNQ/M0LSB4xFCnTKIft27Dqa2FtVsn0wMjCmmq2QdOt8ydaDGs Oa4vsDz7GsRRepffcsSNmQUygJYPf7JlTk77Mn6S6iaRQ0K39Ar/8IFh7TCDgEQoSb5K r32fFyO44b3NEEbhrEO0M9005/ni2C7qJfWo1jleNraYHtixZBA4n+wYIDY+066PUQ1k AwwnLrZ4k21NzkVVHYi3IrJ1sNqmcp5xvTqMMbGSeQoFVQqzBKgpaVJKtU1BLmTQlJ47 SBmC0GE9Za+hk1NVIWAtPtRwNVpJvNpZeb1E9bltFjYn9zGEjBx1LA3IrHHI/XqGy+1z I4Fg== 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:organization:content-transfer-encoding; bh=/cToQRV0mJaSSO0QEmQ51Ug3Puq0Aydk1IJ9qqf2Bqc=; b=QBzdE4DILqMHs32uOLNMXRfoJp12aMyRlVqawtR+Azi/6Fy+H7GNauv08ur9Dele11 RsBYngLZoPsIPuRtZaxMS/VD+R3Rha+cwp4Os5vCW0jXIHTBKNo+Uiah+QuB2YA4ejen 9Bsm3pHdzAlZ2rPaYWO7OxKirDPIDIhTJHna0B/UzgOCZWYrK/9E+Pd49mqTlE8D7mF+ 265C/3Nk/myyxOihsI547yQrw4T+W1jqqY1BlGMyzcgdVkxxZEa3QZFDNYEco0zH4dlp pWypVSRIQo6sE8gL9fwXE6Hn4qpiRvTXB8Ude25FRo1w/nMV5moDjuggvhTdwLOMnFd1 OcUA== X-Gm-Message-State: AOAM530Nz57/9y6RfM/xVRnntY6wG8uWuaNX7j4IbUzRM+cC9/0FgxNj vjYXgnVbr4UxO+aPoUig/YXA7A== X-Google-Smtp-Source: ABdhPJwiwIAzhAYQlfgSh7oEM6DQaIlug0eAJkF1KcAFAV0VzQAr36jqkj2FGm5jsj8jRP0DBt48sg== X-Received: by 2002:a05:651c:1308:: with SMTP id u8mr13954449lja.425.1619456690143; Mon, 26 Apr 2021 10:04:50 -0700 (PDT) Received: from veiron.westermo.com (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id c18sm59140ljd.66.2021.04.26.10.04.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Apr 2021 10:04:49 -0700 (PDT) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, roopa@nvidia.com, nikolay@nvidia.com, jiri@resnulli.us, idosch@idosch.org, stephen@networkplumber.org, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [RFC net-next 4/9] net: bridge: switchdev: Forward offloading Date: Mon, 26 Apr 2021 19:04:06 +0200 Message-Id: <20210426170411.1789186-5-tobias@waldekranz.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210426170411.1789186-1-tobias@waldekranz.com> References: <20210426170411.1789186-1-tobias@waldekranz.com> MIME-Version: 1.0 Organization: Westermo Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Allow switchdevs to forward frames from the CPU in accordance with the bridge configuration in the same way as is done between bridge ports. This means that the bridge will only send a single skb towards one of the ports under the switchdev's control, and expects the driver to deliver the packet to all eligible ports in its domain. Primarily this improves the performance of multicast flows with multiple subscribers, as it allows the hardware to perform the frame replication. The basic flow between the driver and the bridge is as follows: - The switchdev accepts the offload by returning a non-null pointer from .ndo_dfwd_add_station when the port is added to the bridge. - The bridge sends offloadable skbs to one of the ports under the switchdev's control using dev_queue_xmit_accel. - The switchdev notices the offload by checking for a non-NULL "sb_dev" in the core's call to .ndo_select_queue. Signed-off-by: Tobias Waldekranz --- net/bridge/br_forward.c | 11 +++++++- net/bridge/br_private.h | 27 ++++++++++++++++++ net/bridge/br_switchdev.c | 59 +++++++++++++++++++++++++++++++++++++-- 3 files changed, 93 insertions(+), 4 deletions(-) diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 6e9b049ae521..b4fb3b0bb1ec 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c @@ -32,6 +32,8 @@ static inline int should_deliver(const struct net_bridge_port *p, int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb) { + struct net_device *sb_dev = NULL; + skb_push(skb, ETH_HLEN); if (!is_skb_forwardable(skb->dev, skb)) goto drop; @@ -48,7 +50,10 @@ int br_dev_queue_push_xmit(struct net *net, struct sock *sk, struct sk_buff *skb skb_set_network_header(skb, depth); } - dev_queue_xmit(skb); + if (br_switchdev_accels_skb(skb)) + sb_dev = BR_INPUT_SKB_CB(skb)->brdev; + + dev_queue_xmit_accel(skb, sb_dev); return 0; @@ -105,6 +110,8 @@ static void __br_forward(const struct net_bridge_port *to, indev = NULL; } + nbp_switchdev_frame_mark_accel(to, skb); + NF_HOOK(NFPROTO_BRIDGE, br_hook, net, NULL, skb, indev, skb->dev, br_forward_finish); @@ -174,6 +181,8 @@ static struct net_bridge_port *maybe_deliver( if (!should_deliver(p, skb)) return prev; + nbp_switchdev_frame_mark_fwd(p, skb); + if (!prev) goto out; diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index aba92864d285..933e951b0d7a 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -332,6 +332,7 @@ struct net_bridge_port { #endif #ifdef CONFIG_NET_SWITCHDEV int hwdom; + void *accel_priv; #endif u16 group_fwd_mask; u16 backup_redirected_cnt; @@ -506,7 +507,9 @@ struct br_input_skb_cb { #endif #ifdef CONFIG_NET_SWITCHDEV + u8 fwd_accel:1; int src_hwdom; + br_hwdom_map_t fwd_hwdoms; #endif }; @@ -1597,6 +1600,15 @@ static inline void br_sysfs_delbr(struct net_device *dev) { return; } /* br_switchdev.c */ #ifdef CONFIG_NET_SWITCHDEV +static inline bool br_switchdev_accels_skb(struct sk_buff *skb) +{ + return BR_INPUT_SKB_CB(skb)->fwd_accel; +} + +void nbp_switchdev_frame_mark_accel(const struct net_bridge_port *p, + struct sk_buff *skb); +void nbp_switchdev_frame_mark_fwd(const struct net_bridge_port *p, + struct sk_buff *skb); void nbp_switchdev_frame_mark(const struct net_bridge_port *p, struct sk_buff *skb); bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p, @@ -1619,6 +1631,21 @@ static inline void br_switchdev_frame_unmark(struct sk_buff *skb) skb->offload_fwd_mark = 0; } #else +static inline bool br_switchdev_accels_skb(struct sk_buff *skb) +{ + return false; +} + +static inline void nbp_switchdev_frame_mark_accel(const struct net_bridge_port *p, + struct sk_buff *skb) +{ +} + +static inline void nbp_switchdev_frame_mark_fwd(const struct net_bridge_port *p, + struct sk_buff *skb) +{ +} + static inline void nbp_switchdev_frame_mark(const struct net_bridge_port *p, struct sk_buff *skb) { diff --git a/net/bridge/br_switchdev.c b/net/bridge/br_switchdev.c index 54bd7205bfb5..c903171ad291 100644 --- a/net/bridge/br_switchdev.c +++ b/net/bridge/br_switchdev.c @@ -8,6 +8,26 @@ #include "br_private.h" +static bool nbp_switchdev_can_accel(const struct net_bridge_port *p, + const struct sk_buff *skb) +{ + return p->accel_priv && (p->hwdom != BR_INPUT_SKB_CB(skb)->src_hwdom); +} + +void nbp_switchdev_frame_mark_accel(const struct net_bridge_port *p, + struct sk_buff *skb) +{ + if (nbp_switchdev_can_accel(p, skb)) + BR_INPUT_SKB_CB(skb)->fwd_accel = true; +} + +void nbp_switchdev_frame_mark_fwd(const struct net_bridge_port *p, + struct sk_buff *skb) +{ + if (nbp_switchdev_can_accel(p, skb)) + set_bit(p->hwdom, BR_INPUT_SKB_CB(skb)->fwd_hwdoms); +} + void nbp_switchdev_frame_mark(const struct net_bridge_port *p, struct sk_buff *skb) { @@ -18,8 +38,10 @@ void nbp_switchdev_frame_mark(const struct net_bridge_port *p, bool nbp_switchdev_allowed_egress(const struct net_bridge_port *p, const struct sk_buff *skb) { - return !skb->offload_fwd_mark || - BR_INPUT_SKB_CB(skb)->src_hwdom != p->hwdom; + struct br_input_skb_cb *cb = BR_INPUT_SKB_CB(skb); + + return !test_bit(p->hwdom, cb->fwd_hwdoms) && + (!skb->offload_fwd_mark || cb->src_hwdom != p->hwdom); } /* Flags that can be offloaded to hardware */ @@ -125,6 +147,27 @@ int br_switchdev_port_vlan_del(struct net_device *dev, u16 vid) return switchdev_port_obj_del(dev, &v.obj); } +static void nbp_switchdev_fwd_offload_add(struct net_bridge_port *p) +{ + void *priv; + + if (!(p->dev->features & NETIF_F_HW_L2FW_DOFFLOAD)) + return; + + priv = p->dev->netdev_ops->ndo_dfwd_add_station(p->dev, p->br->dev); + if (!IS_ERR_OR_NULL(priv)) + p->accel_priv = priv; +} + +static void nbp_switchdev_fwd_offload_del(struct net_bridge_port *p) +{ + if (!p->accel_priv) + return; + + p->dev->netdev_ops->ndo_dfwd_del_station(p->dev, p->accel_priv); + p->accel_priv = NULL; +} + static int nbp_switchdev_hwdom_set(struct net_bridge_port *joining) { struct net_bridge *br = joining->br; @@ -176,13 +219,23 @@ int nbp_switchdev_add(struct net_bridge_port *p) return err; } - return nbp_switchdev_hwdom_set(p); + err = nbp_switchdev_hwdom_set(p); + if (err) + return err; + + if (p->hwdom) + nbp_switchdev_fwd_offload_add(p); + + return 0; } void nbp_switchdev_del(struct net_bridge_port *p) { ASSERT_RTNL(); + if (p->accel_priv) + nbp_switchdev_fwd_offload_del(p); + if (p->hwdom) nbp_switchdev_hwdom_put(p); } From patchwork Mon Apr 26 17:04:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 427736 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 DB0AEC433B4 for ; Mon, 26 Apr 2021 17:05:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B63D361103 for ; Mon, 26 Apr 2021 17:05:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235357AbhDZRFs (ORCPT ); Mon, 26 Apr 2021 13:05:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235228AbhDZRFe (ORCPT ); Mon, 26 Apr 2021 13:05:34 -0400 Received: from mail-lf1-x136.google.com (mail-lf1-x136.google.com [IPv6:2a00:1450:4864:20::136]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CD2E7C061574 for ; Mon, 26 Apr 2021 10:04:52 -0700 (PDT) Received: by mail-lf1-x136.google.com with SMTP id d27so32519117lfv.9 for ; Mon, 26 Apr 2021 10:04:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=gIoM+pn92FmZ7l7fGywvcoFz7NhbL6+Ajxhl2csuoH4=; b=h/DCxncDj/YrNnh8RNeWnko9Hu+QqSLcJ+7SmZtNXPDB6Nh2VR+UlmwFU1HyMbQJw1 KJpaxslG4hLz5Q2WlS3v+DiLNCf1XQW/+daYTnRGmiGadi9/SDdfUuq19ZdPkYIpXa/V 9ISJ8Aw/EUuaS1D6Yi7P+RG4Vey6DytR+g5MzCzLY17JH8HqDikcR/POHLDrHJueGY18 McuL/u8ZtlTcefFr9/Wh3HFlVu4/pNpwWF9wubfLn/AdRkoQrse8PCxfldEQNDn4L411 eAN/roayikrAn+4ea3s93LZBdXWBt34HBokMNAVG3WTKHTJZOnuMq9lL9wLdBeziGOD1 UxVQ== 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:organization:content-transfer-encoding; bh=gIoM+pn92FmZ7l7fGywvcoFz7NhbL6+Ajxhl2csuoH4=; b=oSRoJZNmP8KiW2BD4QQh4bm/Y/JBPdf0FccDK5GzWrclSgFM/yRDGTfWq8RLfu20E0 +PHMxPZy7FGkxjHzdUfF4+jDXfFLmeHR7nju71VXBYYkjpKDDoqfo/kA9bZmUbvqc2rT AKrYOj3aOaCginVH78GTMUJtQ6ghYGi/g+vZNdO8Y+uzQ5TuRFipvU7ylJa1GasCS9sr AZuKVjPjym9kNuUtYMzQp2CrEBIPH/bBvUE56Xv/doCtIAQUtBaNGA7qbrn5FYlfq1G9 07LNY4ShYLeL6EADIXGNgrJN95DBL312AVm/RY2vo4kYxXKWiGPabR9fzhIymozul1cU Ag2w== X-Gm-Message-State: AOAM530G/oXM48XcrAmnvC4CIR2SF5HpZpL8SM88E3wjA4XbIlkDnQKF Cg9XD1p4E4L3giepG3xAcgD91g== X-Google-Smtp-Source: ABdhPJxbcXo+aROPYbeQTvaHsvvv3yjXsCfK4qwS5i4OyRmvKeWwRH5gj22iV2Sb0NOn5SpRl2TV2Q== X-Received: by 2002:a19:520b:: with SMTP id m11mr13318514lfb.157.1619456691254; Mon, 26 Apr 2021 10:04:51 -0700 (PDT) Received: from veiron.westermo.com (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id c18sm59140ljd.66.2021.04.26.10.04.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Apr 2021 10:04:50 -0700 (PDT) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, roopa@nvidia.com, nikolay@nvidia.com, jiri@resnulli.us, idosch@idosch.org, stephen@networkplumber.org, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [RFC net-next 5/9] net: dsa: Track port PVIDs Date: Mon, 26 Apr 2021 19:04:07 +0200 Message-Id: <20210426170411.1789186-6-tobias@waldekranz.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210426170411.1789186-1-tobias@waldekranz.com> References: <20210426170411.1789186-1-tobias@waldekranz.com> MIME-Version: 1.0 Organization: Westermo Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In some scenarios a tagger must know which VLAN to assign to a packet, even if the packet is set to egress untagged. Since the VLAN information in the skb will be removed by the bridge in this case, track each port's PVID such that the VID of an outgoing frame can always be determined. Signed-off-by: Tobias Waldekranz --- include/net/dsa.h | 1 + net/dsa/port.c | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/include/net/dsa.h b/include/net/dsa.h index 507082959aa4..1f9ba9889034 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -270,6 +270,7 @@ struct dsa_port { unsigned int ageing_time; bool vlan_filtering; u8 stp_state; + u16 pvid; struct net_device *bridge_dev; struct devlink_port devlink_port; bool devlink_port_setup; diff --git a/net/dsa/port.c b/net/dsa/port.c index 6379d66a6bb3..02d96aebfcc6 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -651,8 +651,14 @@ int dsa_port_vlan_add(struct dsa_port *dp, .vlan = vlan, .extack = extack, }; + int err; + + err = dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info); - return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_ADD, &info); + if (!err && (vlan->flags & BRIDGE_VLAN_INFO_PVID)) + dp->pvid = vlan->vid; + + return err; } int dsa_port_vlan_del(struct dsa_port *dp, @@ -663,8 +669,14 @@ int dsa_port_vlan_del(struct dsa_port *dp, .port = dp->index, .vlan = vlan, }; + int err; + + err = dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info); - return dsa_port_notify(dp, DSA_NOTIFIER_VLAN_DEL, &info); + if (!err && vlan->vid == dp->pvid) + dp->pvid = 0; + + return err; } int dsa_port_mrp_add(const struct dsa_port *dp, From patchwork Mon Apr 26 17:04:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 427735 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 6DD39C433B4 for ; Mon, 26 Apr 2021 17:05:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 37D8361104 for ; Mon, 26 Apr 2021 17:05:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235223AbhDZRFw (ORCPT ); Mon, 26 Apr 2021 13:05:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53708 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235197AbhDZRFh (ORCPT ); Mon, 26 Apr 2021 13:05:37 -0400 Received: from mail-lf1-x12b.google.com (mail-lf1-x12b.google.com [IPv6:2a00:1450:4864:20::12b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3D90C061763 for ; Mon, 26 Apr 2021 10:04:53 -0700 (PDT) Received: by mail-lf1-x12b.google.com with SMTP id 12so89087483lfq.13 for ; Mon, 26 Apr 2021 10:04:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=6jO9lKWvNXYqdJyM5lCPEQQkRdWVnlQlbjfM8XXf2v8=; b=qPnr7n8CwJXjEsTLB4rmYkKB8NRheLcxrmx5roLwS/+3SaNuQnp1P8uP+pPTYuzkz7 OFaVyG16nqOObJ8KcxNZ3dp+RUUTG9BWrs+lc5w5V+72xzFB/2FggGas8E34uLPN9ahW kYegr964IiRipmBOt/wWmJHWi2xS0UaoLqYHAGzpi230EE25kuyK7KLouF15fmzfv4Mi VlBbxEYrj+s4qnB+IpbKVzh4Upf3QeppIQ6xhhBy31Yqc1qPp0u21s9oHYVZCi1v8AZ0 rVvZ2gp01kwbTuVzSrlPlJXy0UTgtWqH07fq0tmYxV3P/3dMr/dNg5V5U/Ps4wyqgozO rZOQ== 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:organization:content-transfer-encoding; bh=6jO9lKWvNXYqdJyM5lCPEQQkRdWVnlQlbjfM8XXf2v8=; b=fYIW1mGXkFFHr6zLFmhfeNZfcybosWbEtgVlGdFV2vugW4Sw7lwwEAI3XAnKeZTSCY Jwhe3w0lx3r8qizH6ek055WyRv5uKdCuSSzoo8picAvdrs0JhadvNqJSkgClGjfm8ZcA SeZRYLl4t22En/eZIqVixfwPfu0xeJdvU/rwl4b0cg+zN0SQrhYQOS4rSBNAQcKk8VTa 8cclv1rNU3hnEUrUtfG1m3pB8uba17cnng8drE7bGvaq5x3OkDENS5a/rlIW70lJOMPd lz+/At1Br0/a3mXnFEXgndFULnWw8i6apvMsKfeOulLs6MM45ISsCvi96pMXIDcofzd0 QDbA== X-Gm-Message-State: AOAM532nXgnWx1w8KEkkR0Wh6rDcrB1n2X02IXWP9kHXwaIU+zn78/HG PxOvXX7v9VS5Z00M7omU4uhFtx/RImZo8w== X-Google-Smtp-Source: ABdhPJwojJ85VjAYnTpem4HGCSwPQtiHLBY5RdNMmwq6GgALnObnYL9JSM1J5TMn7t+873jUy+3eRw== X-Received: by 2002:a19:ec0a:: with SMTP id b10mr7823784lfa.53.1619456692412; Mon, 26 Apr 2021 10:04:52 -0700 (PDT) Received: from veiron.westermo.com (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id c18sm59140ljd.66.2021.04.26.10.04.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Apr 2021 10:04:51 -0700 (PDT) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, roopa@nvidia.com, nikolay@nvidia.com, jiri@resnulli.us, idosch@idosch.org, stephen@networkplumber.org, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [RFC net-next 6/9] net: dsa: Forward offloading Date: Mon, 26 Apr 2021 19:04:08 +0200 Message-Id: <20210426170411.1789186-7-tobias@waldekranz.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210426170411.1789186-1-tobias@waldekranz.com> References: <20210426170411.1789186-1-tobias@waldekranz.com> MIME-Version: 1.0 Organization: Westermo Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Allow DSA drivers to support forward offloading from a bridge by: - Passing calls to .ndo_dfwd_{add,del}_station to the drivers. - Recording the subordinate device of offloaded skbs in the control buffer so that the tagger can take the appropriate action. Signed-off-by: Tobias Waldekranz --- include/net/dsa.h | 7 +++++++ net/dsa/slave.c | 36 ++++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/include/net/dsa.h b/include/net/dsa.h index 1f9ba9889034..77d4df819299 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -119,6 +119,7 @@ struct dsa_netdevice_ops { struct dsa_skb_cb { struct sk_buff *clone; + struct net_device *sb_dev; }; struct __dsa_skb_cb { @@ -828,6 +829,12 @@ struct dsa_switch_ops { const struct switchdev_obj_ring_role_mrp *mrp); int (*port_mrp_del_ring_role)(struct dsa_switch *ds, int port, const struct switchdev_obj_ring_role_mrp *mrp); + + /* L2 forward offloading */ + void * (*dfwd_add_station)(struct dsa_switch *ds, int port, + struct net_device *sb_dev); + void (*dfwd_del_station)(struct dsa_switch *ds, int port, + struct net_device *sb_dev); }; #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \ diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 77b33bd161b8..3689ffa2dbb8 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -657,6 +657,13 @@ static netdev_tx_t dsa_slave_xmit(struct sk_buff *skb, struct net_device *dev) return dsa_enqueue_skb(nskb, dev); } +static u16 dsa_slave_select_queue(struct net_device *dev, struct sk_buff *skb, + struct net_device *sb_dev) +{ + DSA_SKB_CB(skb)->sb_dev = sb_dev; + return netdev_pick_tx(dev, skb, sb_dev); +} + /* ethtool operations *******************************************************/ static void dsa_slave_get_drvinfo(struct net_device *dev, @@ -1708,10 +1715,33 @@ static int dsa_slave_fill_forward_path(struct net_device_path_ctx *ctx, return 0; } +static void *dsa_slave_dfwd_add_station(struct net_device *dev, + struct net_device *sb_dev) +{ + struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_switch *ds = dp->ds; + + if (ds->ops->dfwd_add_station) + return ds->ops->dfwd_add_station(ds, dp->index, sb_dev); + + return ERR_PTR(-EOPNOTSUPP); +} + +static void dsa_slave_dfwd_del_station(struct net_device *dev, + void *sb_dev) +{ + struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_switch *ds = dp->ds; + + if (ds->ops->dfwd_del_station) + ds->ops->dfwd_del_station(ds, dp->index, sb_dev); +} + static const struct net_device_ops dsa_slave_netdev_ops = { .ndo_open = dsa_slave_open, .ndo_stop = dsa_slave_close, .ndo_start_xmit = dsa_slave_xmit, + .ndo_select_queue = dsa_slave_select_queue, .ndo_change_rx_flags = dsa_slave_change_rx_flags, .ndo_set_rx_mode = dsa_slave_set_rx_mode, .ndo_set_mac_address = dsa_slave_set_mac_address, @@ -1734,6 +1764,8 @@ static const struct net_device_ops dsa_slave_netdev_ops = { .ndo_get_devlink_port = dsa_slave_get_devlink_port, .ndo_change_mtu = dsa_slave_change_mtu, .ndo_fill_forward_path = dsa_slave_fill_forward_path, + .ndo_dfwd_add_station = dsa_slave_dfwd_add_station, + .ndo_dfwd_del_station = dsa_slave_dfwd_del_station, }; static struct device_type dsa_type = { @@ -1914,8 +1946,8 @@ int dsa_slave_create(struct dsa_port *port) slave_dev->features = master->vlan_features | NETIF_F_HW_TC; if (ds->ops->port_vlan_add && ds->ops->port_vlan_del) slave_dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; - slave_dev->hw_features |= NETIF_F_HW_TC; - slave_dev->features |= NETIF_F_LLTX; + slave_dev->hw_features |= NETIF_F_HW_TC | NETIF_F_HW_L2FW_DOFFLOAD; + slave_dev->features |= NETIF_F_LLTX | NETIF_F_HW_L2FW_DOFFLOAD; slave_dev->ethtool_ops = &dsa_slave_ethtool_ops; if (!is_zero_ether_addr(port->mac)) ether_addr_copy(slave_dev->dev_addr, port->mac); From patchwork Mon Apr 26 17:04:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 427734 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 4D6ECC433ED for ; Mon, 26 Apr 2021 17:05:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1BDD661104 for ; Mon, 26 Apr 2021 17:05:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235308AbhDZRF5 (ORCPT ); Mon, 26 Apr 2021 13:05:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53720 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235203AbhDZRFh (ORCPT ); Mon, 26 Apr 2021 13:05:37 -0400 Received: from mail-lf1-x12d.google.com (mail-lf1-x12d.google.com [IPv6:2a00:1450:4864:20::12d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CE5B3C06138C for ; Mon, 26 Apr 2021 10:04:54 -0700 (PDT) Received: by mail-lf1-x12d.google.com with SMTP id y4so49137076lfl.10 for ; Mon, 26 Apr 2021 10:04:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=yKMCo3mPhrZ7sJPdBS64GxI1OnhjCpUrX0VbNAl+h84=; b=LOlH96YAZjSjX+pTnrjjLbz1OUNxMfEVOSOcKxp/tsjp9n1t1Zjx0r5u8ihoOv00D5 uCLzTk/gNmNw5JBPuzaFt8RPD+agNDnbRmg/8WyqjYxOHxrzsJgWEpq4B29cYLFNOa1T 3G3/1FDJY2GkehMdncswfhP4hRa83LSWVIUsuekIKJeTOcZnuZVyOoWPHkGQlWJQ0O4D pIoSmdyZKlMTfIvADyFaFFpf3YlGaZ+Wml8kYwp/xUa6C0wIr4zMT/Pot5oFtxm1OD7u +m6h/XWUSCOB6K9OVCykPBKgxC+tLMK8i1ejQ6Njl4bVwI5SG5O92WDX3yhij2MyykCq ACmQ== 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:organization:content-transfer-encoding; bh=yKMCo3mPhrZ7sJPdBS64GxI1OnhjCpUrX0VbNAl+h84=; b=p7wEMFjKAgJ8iQSUu+8W6Ps8YjMXms7YVfFfKRz1FRP9xNgpThA/Zcz44bnzioVcvk w4URENNTYKPZd7twWvOAu7aYsLtJp4lDqJ1VU7rW4EdGobBt3qPXpfSB9e12ivd0ZOPB o+9NX7BhxKBusO6Z2mPu/Y3kkKqLnVzOKJm9d3lFXCKabVZ/KcHrRDPkhNn2ywH2MpxE YNBcOvv9YEfdE1bIzDzDvAuYkPR9KezNs2sz/C4sWkTW1JMIdWzPJxvbpBwglQ6BShxJ 842Q2FTgasMbErlmgcA+/+zPtqqZfXEwirqtZk1yalTFU+DeJFaA8EFcRj5Ynzuqdsyc 8PhQ== X-Gm-Message-State: AOAM530mmGj9Z1LCWR9AW9v/sfIXaGj5kDTz0U9rWn5Vfq96VqeIVMpJ +6N6H36joEvPjIrNrv2vtOwe0Q== X-Google-Smtp-Source: ABdhPJxqOTMcL7SlRN+5JOCgPnJrZNhi9qvc1VVqJ46aydzwhI2e/PhlwK/ZEoed314+ZEfESHPkkQ== X-Received: by 2002:ac2:5f42:: with SMTP id 2mr6995959lfz.85.1619456693328; Mon, 26 Apr 2021 10:04:53 -0700 (PDT) Received: from veiron.westermo.com (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id c18sm59140ljd.66.2021.04.26.10.04.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Apr 2021 10:04:52 -0700 (PDT) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, roopa@nvidia.com, nikolay@nvidia.com, jiri@resnulli.us, idosch@idosch.org, stephen@networkplumber.org, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [RFC net-next 7/9] net: dsa: mv88e6xxx: Allocate a virtual DSA port for each bridge Date: Mon, 26 Apr 2021 19:04:09 +0200 Message-Id: <20210426170411.1789186-8-tobias@waldekranz.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210426170411.1789186-1-tobias@waldekranz.com> References: <20210426170411.1789186-1-tobias@waldekranz.com> MIME-Version: 1.0 Organization: Westermo Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In the near future we want to offload transmission of both unicasts and multicasts from a bridge by sending a single FORWARD and use the switches' config to determine the destination(s). Much in the same way as we have already relied on them to do between user ports in the past. As isolation between bridges must still be maintained, we need to pass an identifier in the DSA tag that the switches can use to determine the set of physical ports that make up a particular flooding domain. Therefore: allocate a DSA device/port tuple that is not used by any physical device to each bridge we are offloading. We can then in upcoming changes use this tuple to setup cross-chip port based VLANs to restrict the set of valid egress ports to only contain the ports that are offloading the same bridge. Signed-off-by: Tobias Waldekranz --- drivers/net/dsa/mv88e6xxx/Makefile | 1 + drivers/net/dsa/mv88e6xxx/chip.c | 11 +++ drivers/net/dsa/mv88e6xxx/dst.c | 127 +++++++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx/dst.h | 12 +++ include/net/dsa.h | 5 ++ 5 files changed, 156 insertions(+) create mode 100644 drivers/net/dsa/mv88e6xxx/dst.c create mode 100644 drivers/net/dsa/mv88e6xxx/dst.h diff --git a/drivers/net/dsa/mv88e6xxx/Makefile b/drivers/net/dsa/mv88e6xxx/Makefile index c8eca2b6f959..20e00695b28d 100644 --- a/drivers/net/dsa/mv88e6xxx/Makefile +++ b/drivers/net/dsa/mv88e6xxx/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx.o mv88e6xxx-objs := chip.o mv88e6xxx-objs += devlink.o +mv88e6xxx-objs += dst.o mv88e6xxx-objs += global1.o mv88e6xxx-objs += global1_atu.o mv88e6xxx-objs += global1_vtu.o diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index eca285aaf72f..06ef654472b7 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -33,6 +33,7 @@ #include "chip.h" #include "devlink.h" +#include "dst.h" #include "global1.h" #include "global2.h" #include "hwtstamp.h" @@ -2371,6 +2372,10 @@ static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, struct mv88e6xxx_chip *chip = ds->priv; int err; + err = mv88e6xxx_dst_bridge_join(ds->dst, br); + if (err) + return err; + mv88e6xxx_reg_lock(chip); err = mv88e6xxx_bridge_map(chip, br); mv88e6xxx_reg_unlock(chip); @@ -2388,6 +2393,8 @@ static void mv88e6xxx_port_bridge_leave(struct dsa_switch *ds, int port, mv88e6xxx_port_vlan_map(chip, port)) dev_err(ds->dev, "failed to remap in-chip Port VLAN\n"); mv88e6xxx_reg_unlock(chip); + + mv88e6xxx_dst_bridge_leave(ds->dst, br); } static int mv88e6xxx_crosschip_bridge_join(struct dsa_switch *ds, @@ -3027,6 +3034,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds) mv88e6xxx_reg_lock(chip); + err = mv88e6xxx_dst_add_chip(chip); + if (err) + goto unlock; + if (chip->info->ops->setup_errata) { err = chip->info->ops->setup_errata(chip); if (err) diff --git a/drivers/net/dsa/mv88e6xxx/dst.c b/drivers/net/dsa/mv88e6xxx/dst.c new file mode 100644 index 000000000000..399a818063bf --- /dev/null +++ b/drivers/net/dsa/mv88e6xxx/dst.c @@ -0,0 +1,127 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mv88e6xxx global DSA switch tree state + */ + +#include +#include +#include +#include +#include +#include + +#include "chip.h" +#include "dst.h" +#include "global2.h" + +struct mv88e6xxx_br { + struct list_head list; + + struct net_device *brdev; + u8 dev; + u8 port; +}; + +struct mv88e6xxx_dst { + struct list_head bridges; + + DECLARE_BITMAP(busy_ports, MV88E6XXX_MAX_PVT_ENTRIES); + +#define DEV_PORT_TO_BIT(_dev, _port) \ + ((_dev) * MV88E6XXX_MAX_PVT_PORTS + (_port)) +#define DEV_FROM_BIT(_bit) ((_bit) / MV88E6XXX_MAX_PVT_PORTS) +#define PORT_FROM_BIT(_bit) ((_bit) % (MV88E6XXX_MAX_PVT_PORTS)) +}; + +int mv88e6xxx_dst_bridge_join(struct dsa_switch_tree *dst, + struct net_device *brdev) +{ + struct mv88e6xxx_dst *mvdst = dst->priv; + struct mv88e6xxx_br *mvbr; + unsigned int bit; + + list_for_each_entry(mvbr, &mvdst->bridges, list) { + if (mvbr->brdev == brdev) + return 0; + } + + bit = find_first_zero_bit(mvdst->busy_ports, + MV88E6XXX_MAX_PVT_ENTRIES); + + if (bit >= MV88E6XXX_MAX_PVT_ENTRIES) { + pr_err("Unable to allocate virtual port for %s in DSA tree %d\n", + netdev_name(brdev), dst->index); + return -ENOSPC; + } + + mvbr = kzalloc(sizeof(*mvbr), GFP_KERNEL); + if (!mvbr) + return -ENOMEM; + + mvbr->brdev = brdev; + mvbr->dev = DEV_FROM_BIT(bit); + mvbr->port = PORT_FROM_BIT(bit); + + INIT_LIST_HEAD(&mvbr->list); + list_add_tail(&mvbr->list, &mvdst->bridges); + set_bit(bit, mvdst->busy_ports); + return 0; +} + +void mv88e6xxx_dst_bridge_leave(struct dsa_switch_tree *dst, + struct net_device *brdev) +{ + struct mv88e6xxx_dst *mvdst = dst->priv; + struct mv88e6xxx_br *mvbr; + struct dsa_port *dp; + + list_for_each_entry(dp, &dst->ports, list) { + if (dp->bridge_dev == brdev) + return; + } + + list_for_each_entry(mvbr, &mvdst->bridges, list) { + if (mvbr->brdev == brdev) { + clear_bit(DEV_PORT_TO_BIT(mvbr->dev, mvbr->port), + mvdst->busy_ports); + list_del(&mvbr->list); + kfree(mvbr); + return; + } + } +} + +static struct mv88e6xxx_dst *mv88e6xxx_dst_get(struct dsa_switch_tree *dst) +{ + struct mv88e6xxx_dst *mvdst; + + if (dst->priv) + return dst->priv; + + mvdst = kzalloc(sizeof(*mvdst), GFP_KERNEL); + if (!mvdst) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&mvdst->bridges); + + bitmap_set(mvdst->busy_ports, + DEV_PORT_TO_BIT(MV88E6XXX_G2_PVT_ADDR_DEV_TRUNK, 0), + MV88E6XXX_MAX_PVT_PORTS); + + dst->priv = mvdst; + return mvdst; +} + +int mv88e6xxx_dst_add_chip(struct mv88e6xxx_chip *chip) +{ + struct dsa_switch_tree *dst = chip->ds->dst; + struct mv88e6xxx_dst *mvdst; + + mvdst = mv88e6xxx_dst_get(dst); + if (IS_ERR(mvdst)) + return PTR_ERR(mvdst); + + bitmap_set(mvdst->busy_ports, DEV_PORT_TO_BIT(chip->ds->index, 0), + MV88E6XXX_MAX_PVT_PORTS); + return 0; +} diff --git a/drivers/net/dsa/mv88e6xxx/dst.h b/drivers/net/dsa/mv88e6xxx/dst.h new file mode 100644 index 000000000000..3845a19192ef --- /dev/null +++ b/drivers/net/dsa/mv88e6xxx/dst.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _MV88E6XXX_DST_H +#define _MV88E6XXX_DST_H + +int mv88e6xxx_dst_bridge_join(struct dsa_switch_tree *dst, + struct net_device *brdev); +void mv88e6xxx_dst_bridge_leave(struct dsa_switch_tree *dst, + struct net_device *brdev); +int mv88e6xxx_dst_add_chip(struct mv88e6xxx_chip *chip); + +#endif /* _MV88E6XXX_DST_H */ diff --git a/include/net/dsa.h b/include/net/dsa.h index 77d4df819299..c01e74d6e134 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -172,6 +172,11 @@ struct dsa_switch_tree { */ struct net_device **lags; unsigned int lags_len; + + /* Give the switch driver somewhere to hang its tree-wide + * private data structure. + */ + void *priv; }; #define dsa_lags_foreach_id(_id, _dst) \ From patchwork Mon Apr 26 17:04:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 428408 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 400FFC43460 for ; Mon, 26 Apr 2021 17:05:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1238E61077 for ; Mon, 26 Apr 2021 17:05:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235418AbhDZRFy (ORCPT ); Mon, 26 Apr 2021 13:05:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53722 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235279AbhDZRFh (ORCPT ); Mon, 26 Apr 2021 13:05:37 -0400 Received: from mail-lf1-x12d.google.com (mail-lf1-x12d.google.com [IPv6:2a00:1450:4864:20::12d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BD743C06138D for ; Mon, 26 Apr 2021 10:04:55 -0700 (PDT) Received: by mail-lf1-x12d.google.com with SMTP id 4so29461848lfp.11 for ; Mon, 26 Apr 2021 10:04:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=kKkucO9X6ibabos7fPcUypA+Pj+E3QMe4AxVgMyLmmM=; b=prMeCvrE5BIq1CAbTQB2gFw4BYxHfwr8Sex94hsd4mhnxxc+xmWJqONge1srAd0Nbw DXhcY8J+Ms7r+OUk+cTTW7x9DLBhgzCaEUezpWI2aQqoXXxz1RnpMjUOUJTAi6lbpwFB 9RVlZsws1Ov7fUr4ginu/eGjC/6qsbq610kF1apAzVREqulpf2ef5izYFl7BomPQh2eY bLIdtA9ztWdhM5JYVjUiGp2j3n5A3HN/+0RW8hM3pK7FCrwIG6NDKQheiYvvcAalAAoY q247BMgG3pp8R3eqzLPAfPDoiSSsN3TZPBwafrTJyS26qptnJKXnZmnWO5vtw+whv8dn Yrdg== 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:organization:content-transfer-encoding; bh=kKkucO9X6ibabos7fPcUypA+Pj+E3QMe4AxVgMyLmmM=; b=eizcY/ssJ1D1DDxhEg5rAikurEoMzTCB4IjwToZ6KvpjSl9CkSEVGbd4uHC6S2HGVL tpNrClaqtUrkM7nCC21zxY3Cc5K11oQcMyktIQuy37k7WOnQ+4oUmiZB5wkvIZeZ/YBa YB5uC7lZXh+WfYHLZvy5bLTUn+Ha6is/7i3cZp7KkeWhv8CP/U+ZHeLA+1WdnGwDKJLO ojR3cxLr5YAAfrXXsaRApnj/VK8IfmdU4uow4qMyRIOn5ATUFjq8NtDWohUm8NHmV7Rf XujIAZfRYEC1GB7Ez0HddnK7FslpiDVnR1C0X3Q1deoD0VJSk9KsVRkvOie0W8hRa1vy qw2g== X-Gm-Message-State: AOAM5331BUtiQoDNhZ4emsRhZUZG/AViULqEfzeBc1ecHhcAR9IGM4+G MFdFxSIT+Sf83uhqQjcz6AV7iA== X-Google-Smtp-Source: ABdhPJzI+VtQpR+B3VOAI1EFBQwSMslc6j+PBjb01GOCCeArUfc249Xml6Jm6xzM3uZzpKhK3cY/pQ== X-Received: by 2002:ac2:4e8c:: with SMTP id o12mr13546072lfr.211.1619456694279; Mon, 26 Apr 2021 10:04:54 -0700 (PDT) Received: from veiron.westermo.com (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id c18sm59140ljd.66.2021.04.26.10.04.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Apr 2021 10:04:53 -0700 (PDT) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, roopa@nvidia.com, nikolay@nvidia.com, jiri@resnulli.us, idosch@idosch.org, stephen@networkplumber.org, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [RFC net-next 8/9] net: dsa: mv88e6xxx: Map virtual bridge port in PVT Date: Mon, 26 Apr 2021 19:04:10 +0200 Message-Id: <20210426170411.1789186-9-tobias@waldekranz.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210426170411.1789186-1-tobias@waldekranz.com> References: <20210426170411.1789186-1-tobias@waldekranz.com> MIME-Version: 1.0 Organization: Westermo Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Now that each bridge has a unique DSA device/port tuple, make sure that each chip limits forwarding from the bridge to only include fabric ports and local ports that are members of the same bridge. Signed-off-by: Tobias Waldekranz --- MAINTAINERS | 1 + drivers/net/dsa/mv88e6xxx/chip.c | 33 ++++++++++++++++++++++++-------- drivers/net/dsa/mv88e6xxx/dst.c | 33 ++++++++++++++++++++++++++++++++ drivers/net/dsa/mv88e6xxx/dst.h | 2 ++ include/linux/dsa/mv88e6xxx.h | 13 +++++++++++++ 5 files changed, 74 insertions(+), 8 deletions(-) create mode 100644 include/linux/dsa/mv88e6xxx.h diff --git a/MAINTAINERS b/MAINTAINERS index c3c8fa572580..8794b05793b2 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10647,6 +10647,7 @@ S: Maintained F: Documentation/devicetree/bindings/net/dsa/marvell.txt F: Documentation/networking/devlink/mv88e6xxx.rst F: drivers/net/dsa/mv88e6xxx/ +F: include/linux/dsa/mv88e6xxx.h F: include/linux/platform_data/mv88e6xxx.h MARVELL ARMADA 3700 PHY DRIVERS diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 06ef654472b7..6975cf16da65 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -1229,15 +1230,25 @@ static u16 mv88e6xxx_port_vlan(struct mv88e6xxx_chip *chip, int dev, int port) } } - /* Prevent frames from unknown switch or port */ - if (!found) - return 0; + if (found) { + /* Frames from DSA links and CPU ports can egress any + * local port. + */ + if (dp->type == DSA_PORT_TYPE_CPU || + dp->type == DSA_PORT_TYPE_DSA) + return mv88e6xxx_port_mask(chip); - /* Frames from DSA links and CPU ports can egress any local port */ - if (dp->type == DSA_PORT_TYPE_CPU || dp->type == DSA_PORT_TYPE_DSA) - return mv88e6xxx_port_mask(chip); + br = dp->bridge_dev; + } else { + br = mv88e6xxx_dst_bridge_from_dsa(dst, dev, port); + + /* Reject frames from ports that are neither physical + * nor virtual bridge ports. + */ + if (!br) + return 0; + } - br = dp->bridge_dev; pvlan = 0; /* Frames from user ports can egress any local DSA links and CPU ports, @@ -2340,6 +2351,7 @@ static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip, struct dsa_switch *ds = chip->ds; struct dsa_switch_tree *dst = ds->dst; struct dsa_port *dp; + u8 dev, port; int err; list_for_each_entry(dp, &dst->ports, list) { @@ -2363,7 +2375,12 @@ static int mv88e6xxx_bridge_map(struct mv88e6xxx_chip *chip, } } - return 0; + /* Map the virtual bridge port if one is assigned. */ + err = mv88e6xxx_dst_bridge_to_dsa(dst, br, &dev, &port); + if (!err) + err = mv88e6xxx_pvt_map(chip, dev, port); + + return err; } static int mv88e6xxx_port_bridge_join(struct dsa_switch *ds, int port, diff --git a/drivers/net/dsa/mv88e6xxx/dst.c b/drivers/net/dsa/mv88e6xxx/dst.c index 399a818063bf..a5f9077e5b3f 100644 --- a/drivers/net/dsa/mv88e6xxx/dst.c +++ b/drivers/net/dsa/mv88e6xxx/dst.c @@ -33,6 +33,39 @@ struct mv88e6xxx_dst { #define PORT_FROM_BIT(_bit) ((_bit) % (MV88E6XXX_MAX_PVT_PORTS)) }; +struct net_device *mv88e6xxx_dst_bridge_from_dsa(struct dsa_switch_tree *dst, + u8 dev, u8 port) +{ + struct mv88e6xxx_dst *mvdst = dst->priv; + struct mv88e6xxx_br *mvbr; + + list_for_each_entry(mvbr, &mvdst->bridges, list) { + if (mvbr->dev == dev && mvbr->port == port) + return mvbr->brdev; + } + + return NULL; +} + +int mv88e6xxx_dst_bridge_to_dsa(const struct dsa_switch_tree *dst, + const struct net_device *brdev, + u8 *dev, u8 *port) +{ + struct mv88e6xxx_dst *mvdst = dst->priv; + struct mv88e6xxx_br *mvbr; + + list_for_each_entry(mvbr, &mvdst->bridges, list) { + if (mvbr->brdev == brdev) { + *dev = mvbr->dev; + *port = mvbr->port; + return 0; + } + } + + return -ENODEV; +} +EXPORT_SYMBOL_GPL(mv88e6xxx_dst_bridge_to_dsa); + int mv88e6xxx_dst_bridge_join(struct dsa_switch_tree *dst, struct net_device *brdev) { diff --git a/drivers/net/dsa/mv88e6xxx/dst.h b/drivers/net/dsa/mv88e6xxx/dst.h index 3845a19192ef..911890ec4792 100644 --- a/drivers/net/dsa/mv88e6xxx/dst.h +++ b/drivers/net/dsa/mv88e6xxx/dst.h @@ -3,6 +3,8 @@ #ifndef _MV88E6XXX_DST_H #define _MV88E6XXX_DST_H +struct net_device *mv88e6xxx_dst_bridge_from_dsa(struct dsa_switch_tree *dst, + u8 dev, u8 port); int mv88e6xxx_dst_bridge_join(struct dsa_switch_tree *dst, struct net_device *brdev); void mv88e6xxx_dst_bridge_leave(struct dsa_switch_tree *dst, diff --git a/include/linux/dsa/mv88e6xxx.h b/include/linux/dsa/mv88e6xxx.h new file mode 100644 index 000000000000..fa486dfe9808 --- /dev/null +++ b/include/linux/dsa/mv88e6xxx.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _NET_DSA_MV88E6XXX_H +#define _NET_DSA_MV88E6XXX_H + +#include +#include + +int mv88e6xxx_dst_bridge_to_dsa(const struct dsa_switch_tree *dst, + const struct net_device *brdev, + u8 *dev, u8 *port); + +#endif /* _NET_DSA_MV88E6XXX_H */ From patchwork Mon Apr 26 17:04:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tobias Waldekranz X-Patchwork-Id: 428407 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=-16.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, 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 BBAC1C433B4 for ; Mon, 26 Apr 2021 17:05:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 94263613AB for ; Mon, 26 Apr 2021 17:05:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235509AbhDZRF6 (ORCPT ); Mon, 26 Apr 2021 13:05:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53724 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235200AbhDZRFi (ORCPT ); Mon, 26 Apr 2021 13:05:38 -0400 Received: from mail-lj1-x231.google.com (mail-lj1-x231.google.com [IPv6:2a00:1450:4864:20::231]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D71EEC061574 for ; Mon, 26 Apr 2021 10:04:56 -0700 (PDT) Received: by mail-lj1-x231.google.com with SMTP id u20so64975953lja.13 for ; Mon, 26 Apr 2021 10:04:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=waldekranz-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:organization:content-transfer-encoding; bh=gzQDdQ618Jx3kzdjnFlYcMdSiOavctKmFQ8g/5KX7GA=; b=uq1FHOyIjawGvTLS4Jqu5xKTO74wCskKAAgWI4HOIaiQtlmIN3asnrE6CGoqYDageY roWg5fZLf/xqzTxEvtiqLOtu7pyNrBxPaZmAZ8K6x2xJGZkmpkyFrwuNQLLkGYhFOFte W37JiN4CiUXrrTOLwx2NeyavFs8wuYFMucJ+mj3hzM1xGrNaS1IbYVg+xklCz61ZpAPY RpL2BgMq81x2E9J0PCAQFvcX2sTguJQi848TgK8r6AZUJ5+V8ofGNaIW6NSc9I8pWnyG zL6KF6ZNadKfbyVhIZCIVxyTFfCjqIoUYNpumBGOHtGmE2ve44wXACWxyYvDCnYhdB+5 B1rg== 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:organization:content-transfer-encoding; bh=gzQDdQ618Jx3kzdjnFlYcMdSiOavctKmFQ8g/5KX7GA=; b=PbnG/YjMZBm93jA84YsFW/eceys0ojJWK0iAm6s9lRO+GP4gap+yHmRh1oyulkvgJm 7U2SMcvZUV6r+2oKNW23k2Ps/j9YRxytcBumB8a3hECIwJ8SuuklI0TPULaq5iawk7Xe g5evaWmMgyNrtkWY3C0WQ/BdviEqCVbRgFkpfOypmfbsisVfNmNtwBNi4v9uC/+t24h6 M4Y28zXJy7WilC5jJzyMlF+2q/8WQASv7hg5vkKpe5ZkDmJBJOWq8d/5pqTk9Wl5YIOd Dk8wrRhxFzJwvAlS5qvy7BdInptePGcjB+BcZW2BBKZsNkMyQaesdF2LxhjDMVDTPgBt N5Rg== X-Gm-Message-State: AOAM530pXOEJwa6JENb9u5bpKTTABFFrjb30VGTKK3FskI0P+VS6sp9p 0aj1XW5t+qH5QGnYdeurpZWhRA== X-Google-Smtp-Source: ABdhPJzVnp6iB9poyGk0MI1D6PC44k8j/S9TEtbBs47jLnvBteFxwn0mPPOcmZ/nS1yjuP32bl2v5w== X-Received: by 2002:a2e:9b51:: with SMTP id o17mr13479013ljj.315.1619456695317; Mon, 26 Apr 2021 10:04:55 -0700 (PDT) Received: from veiron.westermo.com (static-193-12-47-89.cust.tele2.se. [193.12.47.89]) by smtp.gmail.com with ESMTPSA id c18sm59140ljd.66.2021.04.26.10.04.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Apr 2021 10:04:54 -0700 (PDT) From: Tobias Waldekranz To: davem@davemloft.net, kuba@kernel.org Cc: andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, roopa@nvidia.com, nikolay@nvidia.com, jiri@resnulli.us, idosch@idosch.org, stephen@networkplumber.org, netdev@vger.kernel.org, bridge@lists.linux-foundation.org Subject: [RFC net-next 9/9] net: dsa: mv88e6xxx: Forward offloading Date: Mon, 26 Apr 2021 19:04:11 +0200 Message-Id: <20210426170411.1789186-10-tobias@waldekranz.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210426170411.1789186-1-tobias@waldekranz.com> References: <20210426170411.1789186-1-tobias@waldekranz.com> MIME-Version: 1.0 Organization: Westermo Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Allow the DSA tagger to generate FORWARD frames for offloaded skbs sent from a bridge that we offload, allowing the switch to handle any frame replication that may be required. This also means that source address learning takes place on packets sent from the CPU, meaning that return traffic no longer needs to be flooded as unknown unicast. Signed-off-by: Tobias Waldekranz --- drivers/net/dsa/mv88e6xxx/chip.c | 17 ++++++++++++++++ net/dsa/tag_dsa.c | 33 ++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 6975cf16da65..00ed1aa2a55a 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -6077,6 +6077,21 @@ static int mv88e6xxx_crosschip_lag_leave(struct dsa_switch *ds, int sw_index, return err_sync ? : err_pvt; } +static void *mv88e6xxx_dfwd_add_station(struct dsa_switch *ds, int port, + struct net_device *sb_dev) +{ + struct dsa_port *dp = dsa_to_port(ds, port); + struct mv88e6xxx_chip *chip = ds->priv; + + if (!mv88e6xxx_has_pvt(chip)) + return ERR_PTR(-EOPNOTSUPP); + + if (sb_dev == dp->bridge_dev) + return sb_dev; + + return ERR_PTR(-EOPNOTSUPP); +} + static const struct dsa_switch_ops mv88e6xxx_switch_ops = { .get_tag_protocol = mv88e6xxx_get_tag_protocol, .change_tag_protocol = mv88e6xxx_change_tag_protocol, @@ -6138,6 +6153,7 @@ static const struct dsa_switch_ops mv88e6xxx_switch_ops = { .crosschip_lag_change = mv88e6xxx_crosschip_lag_change, .crosschip_lag_join = mv88e6xxx_crosschip_lag_join, .crosschip_lag_leave = mv88e6xxx_crosschip_lag_leave, + .dfwd_add_station = mv88e6xxx_dfwd_add_station, }; static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip) @@ -6156,6 +6172,7 @@ static int mv88e6xxx_register_switch(struct mv88e6xxx_chip *chip) ds->ops = &mv88e6xxx_switch_ops; ds->ageing_time_min = chip->info->age_time_coeff; ds->ageing_time_max = chip->info->age_time_coeff * U8_MAX; + ds->num_tx_queues = 2; /* Some chips support up to 32, but that requires enabling the * 5-bit port mode, which we do not support. 640k^W16 ought to diff --git a/net/dsa/tag_dsa.c b/net/dsa/tag_dsa.c index 7e7b7decdf39..09cdf77697b2 100644 --- a/net/dsa/tag_dsa.c +++ b/net/dsa/tag_dsa.c @@ -46,6 +46,7 @@ */ #include +#include #include #include @@ -126,7 +127,22 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev, u8 extra) { struct dsa_port *dp = dsa_slave_to_port(dev); + u16 pvid = dp->pvid; + enum dsa_cmd cmd; u8 *dsa_header; + u8 tag_dev, tag_port; + + if (DSA_SKB_CB(skb)->sb_dev) { + cmd = DSA_CMD_FORWARD; + if (mv88e6xxx_dst_bridge_to_dsa(dp->ds->dst, + DSA_SKB_CB(skb)->sb_dev, + &tag_dev, &tag_port)) + return NULL; + } else { + cmd = DSA_CMD_FROM_CPU; + tag_dev = dp->ds->index; + tag_port = dp->index; + } if (skb->protocol == htons(ETH_P_8021Q)) { if (extra) { @@ -134,10 +150,10 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev, memmove(skb->data, skb->data + extra, 2 * ETH_ALEN); } - /* Construct tagged FROM_CPU DSA tag from 802.1Q tag. */ + /* Construct tagged DSA tag from 802.1Q tag. */ dsa_header = skb->data + 2 * ETH_ALEN + extra; - dsa_header[0] = (DSA_CMD_FROM_CPU << 6) | 0x20 | dp->ds->index; - dsa_header[1] = dp->index << 3; + dsa_header[0] = (cmd << 6) | 0x20 | tag_dev; + dsa_header[1] = tag_port << 3; /* Move CFI field from byte 2 to byte 1. */ if (dsa_header[2] & 0x10) { @@ -148,12 +164,13 @@ static struct sk_buff *dsa_xmit_ll(struct sk_buff *skb, struct net_device *dev, skb_push(skb, DSA_HLEN + extra); memmove(skb->data, skb->data + DSA_HLEN + extra, 2 * ETH_ALEN); - /* Construct untagged FROM_CPU DSA tag. */ + /* Construct untagged DSA tag. */ dsa_header = skb->data + 2 * ETH_ALEN + extra; - dsa_header[0] = (DSA_CMD_FROM_CPU << 6) | dp->ds->index; - dsa_header[1] = dp->index << 3; - dsa_header[2] = 0x00; - dsa_header[3] = 0x00; + + dsa_header[0] = (cmd << 6) | tag_dev; + dsa_header[1] = tag_port << 3; + dsa_header[2] = pvid >> 8; + dsa_header[3] = pvid & 0xff; } return skb;