From patchwork Wed Mar 25 15:22:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 221857 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=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, 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 A0E88C1975A for ; Wed, 25 Mar 2020 15:22:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 69BBB20772 for ; Wed, 25 Mar 2020 15:22:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="hK83mvwB" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727738AbgCYPWV (ORCPT ); Wed, 25 Mar 2020 11:22:21 -0400 Received: from mail-wm1-f66.google.com ([209.85.128.66]:38809 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727556AbgCYPWT (ORCPT ); Wed, 25 Mar 2020 11:22:19 -0400 Received: by mail-wm1-f66.google.com with SMTP id l20so3142897wmi.3 for ; Wed, 25 Mar 2020 08:22:17 -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; bh=OFpN5nKaNXjh0T0y/rKbE7gyucXsn8yrY1eh+J8Xdi8=; b=hK83mvwBO8qSReraVRQATuQOMyoLtwkk6MZ5oLDzj+lZ69thH0/WGiWGuijCqeIhwo ZxOkeysqki8/k0zTZoMIiQFeIrW0/r/FTtgYHUnJFwk5mxDvvJtCdQ0EHShF4NDs9u8l tjeE9VQ2VrVafUag+AevPRlZ2LZt3gkm/sHmd07kAek5u9RHiVbcDMY8uwaGZjWQkwp8 c+BBfiXSsO7bUwXe8W+2XG8BAJsh1vDbAF3wEclH1rRzmacYEiMXT2Gk61pY+l8ND3YY sQpJtZmr3KYVjeOlLbbnpe4TqMqh1t2r00Vo/lqN1Qlcwxa9WWTJKdVWG4kMM7uNJRaE tX8w== 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; bh=OFpN5nKaNXjh0T0y/rKbE7gyucXsn8yrY1eh+J8Xdi8=; b=do3CJ1lMUAzGN11E2nB635APbne2vWkXuXI1EJFz/wWIZGEeZeW2xS4x9Zosxr5OWU 92XOqVIcLOlzp/v/91YcqGii4ly7cue5LmSWZ8ON2t22jsZlKGPSyUrUllyUaheFBJnq yLNuVSrHUSpQ4M2IaP7ZZUwk9fNn24/XobCb4d8nIz4IuPzUH02MLalxZ+y0DvY8WnhM zdf/uxuGnW2gPglY8EwX/HMh4qrbRhNwRFtjph/uFF7gP0qkKK2zQcCpyOlZ6f7IZnKF hPODSMFwMXZzC9Fr8hcVqmBG/ZeDpRzTVffhZRKV0UrNjpqBWdkee/Ai63HkwB6f27e1 Jn/w== X-Gm-Message-State: ANhLgQ3pXjFrN2guggPinf7g2lmoMzaRhLWTOfcPxoESBWA8jAKPVUas OUcsn0TIt24g6TyM88OOWzA= X-Google-Smtp-Source: ADFU+vvimtseBvK6EeZksiiH/cJMsNxWwqFgGPQQuAL1zk7SCgy1HCC/05ePHUu44OwUb8lKNYR5wg== X-Received: by 2002:a1c:2d11:: with SMTP id t17mr3984472wmt.89.1585149736202; Wed, 25 Mar 2020 08:22:16 -0700 (PDT) Received: from localhost.localdomain ([79.115.60.40]) by smtp.gmail.com with ESMTPSA id n9sm6309165wru.50.2020.03.25.08.22.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Mar 2020 08:22:15 -0700 (PDT) From: Vladimir Oltean To: andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, davem@davemloft.net, jakub.kicinski@netronome.com Cc: murali.policharla@broadcom.com, stephen@networkplumber.org, jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org, nikolay@cumulusnetworks.com, netdev@vger.kernel.org Subject: [PATCH v2 net-next 01/10] net: dsa: configure the MTU for switch ports Date: Wed, 25 Mar 2020 17:22:00 +0200 Message-Id: <20200325152209.3428-2-olteanv@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200325152209.3428-1-olteanv@gmail.com> References: <20200325152209.3428-1-olteanv@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean It is useful be able to configure port policers on a switch to accept frames of various sizes: - Increase the MTU for better throughput from the default of 1500 if it is known that there is no 10/100 Mbps device in the network. - Decrease the MTU to limit the latency of high-priority frames under congestion. For DSA slave ports, this is mostly a pass-through callback, called through the regular ndo ops and at probe time (to ensure consistency across all supported switches). The CPU port is called with an MTU equal to the largest configured MTU of the slave ports. The assumption is that the user might want to sustain a bidirectional conversation with a partner over any switch port. The DSA master is configured the same as the CPU port, plus the tagger overhead. Since the MTU is by definition L2 payload (sans Ethernet header), it is up to each individual driver to figure out if it needs to do anything special for its frame tags on the CPU port (it shouldn't except in special cases). So the MTU does not contain the tagger overhead on the CPU port. However the MTU of the DSA master, minus the tagger overhead, is used as a proxy for the MTU of the CPU port, which does not have a net device. This is to avoid uselessly calling the .change_mtu function on the CPU port when nothing should change. So it is safe to assume that the DSA master and the CPU port MTUs are apart by exactly the tagger's overhead in bytes. This patch also makes MTU configuration on the DSA master interface mandatory (errors from dsa_master_set_mtu now really are propagated). The reasoning is that it's better to be safe than sorry. With cascaded DSA setups, things can easily spiral out of control if they're ignored, since the user is not notified of what went wrong, and large packets just get lost. Some inspiration (mainly in the MTU DSA notifier) was taken from a vaguely similar patch from Murali and Florian, who are credited as co-developers down below. Co-developed-by: Murali Krishna Policharla Signed-off-by: Murali Krishna Policharla Co-developed-by: Florian Fainelli Signed-off-by: Florian Fainelli Signed-off-by: Vladimir Oltean --- include/net/dsa.h | 10 +++++ net/dsa/dsa_priv.h | 10 +++++ net/dsa/master.c | 14 +++--- net/dsa/port.c | 11 +++++ net/dsa/slave.c | 104 ++++++++++++++++++++++++++++++++++++++++++++- net/dsa/switch.c | 34 +++++++++++++++ 6 files changed, 174 insertions(+), 9 deletions(-) diff --git a/include/net/dsa.h b/include/net/dsa.h index beeb81a532e3..1bb1e0852e31 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -579,6 +579,16 @@ struct dsa_switch_ops { struct devlink_param_gset_ctx *ctx); int (*devlink_param_set)(struct dsa_switch *ds, u32 id, struct devlink_param_gset_ctx *ctx); + + /* + * MTU change functionality. Switches can also adjust their MRU through + * this method. By MTU, one understands the SDU, aka L2 payload length. + * If the switch needs to account for the DSA tag on the CPU port, this + * method needs to to do so privately. + */ + int (*port_change_mtu)(struct dsa_switch *ds, int port, + int new_mtu); + int (*port_max_mtu)(struct dsa_switch *ds, int port); }; #define DSA_DEVLINK_PARAM_DRIVER(_id, _name, _type, _cmodes) \ diff --git a/net/dsa/dsa_priv.h b/net/dsa/dsa_priv.h index 760e6ea3178a..b43d5713ff90 100644 --- a/net/dsa/dsa_priv.h +++ b/net/dsa/dsa_priv.h @@ -22,6 +22,7 @@ enum { DSA_NOTIFIER_MDB_DEL, DSA_NOTIFIER_VLAN_ADD, DSA_NOTIFIER_VLAN_DEL, + DSA_NOTIFIER_MTU, }; /* DSA_NOTIFIER_AGEING_TIME */ @@ -61,6 +62,13 @@ struct dsa_notifier_vlan_info { int port; }; +/* DSA_NOTIFIER_MTU */ +struct dsa_notifier_mtu_info { + int sw_index; + int port; + int mtu; +}; + struct dsa_slave_priv { /* Copy of CPU port xmit for faster access in slave transmit hot path */ struct sk_buff * (*xmit)(struct sk_buff *skb, @@ -98,6 +106,7 @@ int dsa_legacy_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], /* master.c */ int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp); void dsa_master_teardown(struct net_device *dev); +int dsa_master_set_mtu(struct net_device *dev, int mtu); static inline struct net_device *dsa_master_find_slave(struct net_device *dev, int device, int port) @@ -127,6 +136,7 @@ int dsa_port_vlan_filtering(struct dsa_port *dp, bool vlan_filtering, struct switchdev_trans *trans); int dsa_port_ageing_time(struct dsa_port *dp, clock_t ageing_clock, struct switchdev_trans *trans); +int dsa_port_mtu_change(struct dsa_port *dp, int new_mtu); int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr, u16 vid); int dsa_port_fdb_del(struct dsa_port *dp, const unsigned char *addr, diff --git a/net/dsa/master.c b/net/dsa/master.c index bd44bde272f4..e37f14d6a8a6 100644 --- a/net/dsa/master.c +++ b/net/dsa/master.c @@ -314,18 +314,18 @@ static const struct attribute_group dsa_group = { .attrs = dsa_slave_attrs, }; -static void dsa_master_set_mtu(struct net_device *dev, struct dsa_port *cpu_dp) +/* Needs to be called under rtnl_lock */ +int dsa_master_set_mtu(struct net_device *dev, int mtu) { - unsigned int mtu = ETH_DATA_LEN + cpu_dp->tag_ops->overhead; - int err; + int err = -ERANGE; - rtnl_lock(); if (mtu <= dev->max_mtu) { err = dev_set_mtu(dev, mtu); if (err) - netdev_dbg(dev, "Unable to set MTU to include for DSA overheads\n"); + netdev_err(dev, "Unable to set MTU to include for DSA overheads\n"); } - rtnl_unlock(); + + return err; } static void dsa_master_reset_mtu(struct net_device *dev) @@ -344,8 +344,6 @@ int dsa_master_setup(struct net_device *dev, struct dsa_port *cpu_dp) { int ret; - dsa_master_set_mtu(dev, cpu_dp); - /* If we use a tagging format that doesn't have an ethertype * field, make sure that all packets from this point on get * sent to the tag format's receive function. diff --git a/net/dsa/port.c b/net/dsa/port.c index a18e65a474a5..428d02d3c2e7 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c @@ -297,6 +297,17 @@ int dsa_port_mrouter(struct dsa_port *dp, bool mrouter, return ds->ops->port_egress_floods(ds, port, true, mrouter); } +int dsa_port_mtu_change(struct dsa_port *dp, int new_mtu) +{ + struct dsa_notifier_mtu_info info = { + .sw_index = dp->ds->index, + .port = dp->index, + .mtu = new_mtu, + }; + + return dsa_port_notify(dp, DSA_NOTIFIER_MTU, &info); +} + int dsa_port_fdb_add(struct dsa_port *dp, const unsigned char *addr, u16 vid) { diff --git a/net/dsa/slave.c b/net/dsa/slave.c index 5f782fa3029f..8d8fc20ce4c6 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c @@ -1218,6 +1218,100 @@ static int dsa_slave_vlan_rx_kill_vid(struct net_device *dev, __be16 proto, return dsa_port_vid_del(dp, vid); } +static int dsa_slave_change_mtu(struct net_device *dev, int new_mtu) +{ + struct net_device *master = dsa_slave_to_master(dev); + struct dsa_port *dp = dsa_slave_to_port(dev); + struct dsa_slave_priv *p = netdev_priv(dev); + struct dsa_switch *ds = p->dp->ds; + struct dsa_port *cpu_dp; + int port = p->dp->index; + int largest_mtu = 0; + int new_master_mtu; + int old_master_mtu; + int mtu_limit; + int cpu_mtu; + int err, i; + + if (!ds->ops->port_change_mtu) + return -EOPNOTSUPP; + + for (i = 0; i < ds->num_ports; i++) { + int slave_mtu; + + if (!dsa_is_user_port(ds, i)) + continue; + + /* During probe, this function will be called for each slave + * device, while not all of them have been allocated. That's + * ok, it doesn't change what the maximum is, so ignore it. + */ + if (!dsa_to_port(ds, i)->slave) + continue; + + /* Pretend that we already applied the setting, which we + * actually haven't (still haven't done all integrity checks) + */ + if (i == port) + slave_mtu = new_mtu; + else + slave_mtu = dsa_to_port(ds, i)->slave->mtu; + + if (largest_mtu < slave_mtu) + largest_mtu = slave_mtu; + } + + cpu_dp = dsa_to_port(ds, port)->cpu_dp; + + mtu_limit = min_t(int, master->max_mtu, dev->max_mtu); + old_master_mtu = master->mtu; + new_master_mtu = largest_mtu + cpu_dp->tag_ops->overhead; + if (new_master_mtu > mtu_limit) + return -ERANGE; + + /* If the master MTU isn't over limit, there's no need to check the CPU + * MTU, since that surely isn't either. + */ + cpu_mtu = largest_mtu; + + /* Start applying stuff */ + if (new_master_mtu != old_master_mtu) { + err = dsa_master_set_mtu(master, new_master_mtu); + if (err < 0) + goto out_master_failed; + + err = dsa_port_mtu_change(cpu_dp, cpu_mtu); + if (err) { + netdev_err(dev, "Failed to change MTU on CPU port\n"); + goto out_cpu_failed; + } + } + + err = dsa_port_mtu_change(dp, new_mtu); + if (err) { + netdev_err(dev, "Failed to change MTU\n"); + goto out_port_failed; + } + + dev->mtu = new_mtu; + + return 0; + +out_port_failed: + if (new_master_mtu != old_master_mtu) { + if (dsa_port_mtu_change(cpu_dp, old_master_mtu - + cpu_dp->tag_ops->overhead)) + dev_err(ds->dev, "Failed to restore MTU on CPU port\n"); + } +out_cpu_failed: + if (new_master_mtu != old_master_mtu) { + if (dsa_master_set_mtu(master, old_master_mtu)) + netdev_err(master, "Failed to restore MTU\n"); + } +out_master_failed: + return err; +} + static const struct ethtool_ops dsa_slave_ethtool_ops = { .get_drvinfo = dsa_slave_get_drvinfo, .get_regs_len = dsa_slave_get_regs_len, @@ -1295,6 +1389,7 @@ static const struct net_device_ops dsa_slave_netdev_ops = { .ndo_vlan_rx_add_vid = dsa_slave_vlan_rx_add_vid, .ndo_vlan_rx_kill_vid = dsa_slave_vlan_rx_kill_vid, .ndo_get_devlink_port = dsa_slave_get_devlink_port, + .ndo_change_mtu = dsa_slave_change_mtu, }; static struct device_type dsa_type = { @@ -1465,7 +1560,10 @@ int dsa_slave_create(struct dsa_port *port) slave_dev->priv_flags |= IFF_NO_QUEUE; slave_dev->netdev_ops = &dsa_slave_netdev_ops; slave_dev->min_mtu = 0; - slave_dev->max_mtu = ETH_MAX_MTU; + if (ds->ops->port_max_mtu) + slave_dev->max_mtu = ds->ops->port_max_mtu(ds, port->index); + else + slave_dev->max_mtu = ETH_MAX_MTU; SET_NETDEV_DEVTYPE(slave_dev, &dsa_type); SET_NETDEV_DEV(slave_dev, port->ds->dev); @@ -1483,6 +1581,10 @@ int dsa_slave_create(struct dsa_port *port) p->xmit = cpu_dp->tag_ops->xmit; port->slave = slave_dev; + rtnl_lock(); + dsa_slave_change_mtu(slave_dev, ETH_DATA_LEN); + rtnl_unlock(); + netif_carrier_off(slave_dev); ret = dsa_slave_phy_setup(slave_dev); diff --git a/net/dsa/switch.c b/net/dsa/switch.c index df4abe897ed6..6b0b6f9d219c 100644 --- a/net/dsa/switch.c +++ b/net/dsa/switch.c @@ -52,6 +52,37 @@ static int dsa_switch_ageing_time(struct dsa_switch *ds, return 0; } +static bool dsa_switch_mtu_match(struct dsa_switch *ds, int port, + struct dsa_notifier_mtu_info *info) +{ + if (ds->index == info->sw_index && port == info->port) + return true; + + if (dsa_is_dsa_port(ds, port) || dsa_is_cpu_port(ds, port)) + return true; + + return false; +} + +static int dsa_switch_mtu(struct dsa_switch *ds, + struct dsa_notifier_mtu_info *info) +{ + int port, ret; + + if (!ds->ops->port_change_mtu) + return -EOPNOTSUPP; + + for (port = 0; port < ds->num_ports; port++) { + if (dsa_switch_mtu_match(ds, port, info)) { + ret = ds->ops->port_change_mtu(ds, port, info->mtu); + if (ret) + return ret; + } + } + + return 0; +} + static int dsa_switch_bridge_join(struct dsa_switch *ds, struct dsa_notifier_bridge_info *info) { @@ -328,6 +359,9 @@ static int dsa_switch_event(struct notifier_block *nb, case DSA_NOTIFIER_VLAN_DEL: err = dsa_switch_vlan_del(ds, info); break; + case DSA_NOTIFIER_MTU: + err = dsa_switch_mtu(ds, info); + break; default: err = -EOPNOTSUPP; break; From patchwork Wed Mar 25 15:22:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 221861 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=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, 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 2AA74C1975A for ; Wed, 25 Mar 2020 15:22:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 025882076A for ; Wed, 25 Mar 2020 15:22:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="V8ao8dbp" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727720AbgCYPWU (ORCPT ); Wed, 25 Mar 2020 11:22:20 -0400 Received: from mail-wm1-f66.google.com ([209.85.128.66]:55349 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726838AbgCYPWT (ORCPT ); Wed, 25 Mar 2020 11:22:19 -0400 Received: by mail-wm1-f66.google.com with SMTP id z5so2892273wml.5 for ; Wed, 25 Mar 2020 08:22:18 -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; bh=xtdHx3Qt30vc8vJyYfOQLaBLiscuFHmf8TqUqenHKXI=; b=V8ao8dbptUaJfu3AiNjVCYfvys3QRcAyl733OfoHocvoTxN2slwwOgW6Zo/8B26a1V 8v2ooE2fDmORaDKx+Oq5x2bRoCCsDB/pv+3nFyf9/56iwZFvZcuwkCJUq55v8galMkly WoUVyHSe8OdCUxFqnZgx3JwGQggwaQBvOSehXy3rSB6NPk0oVetnmpKGHdM1LIMidPUS 4rCgvEC2FlmZJvEVVojFGvTCXDes9J8DpWpW/bXFwXceV23kBtMwtv/yTPf1rIkXGonw m2yytNaECQAj59u+9YPm6n1M4CEOdKPRj7mdMPgD5yCTLcWYxI1nvJIi7DCJmbD8CpXz pp7w== 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; bh=xtdHx3Qt30vc8vJyYfOQLaBLiscuFHmf8TqUqenHKXI=; b=X52zQ+O3//IXrCuTHMOyH8PneVQ+f68yS5gpz2RGmbvB5F3DbENbp0TU9UDukRjyzS vIeNHVafXJg/HDxfrIVs7j5BI9OZRW+Xr0uAIMIkr6Q9f6lhAUjaMPd6bh3WwJC2rcL3 aWpbkFhx6qqy3MB0FLAClVqNhw4WB4uiwx1D7EIJ6Wd9glKwOHMGFZX5t1wDP0225zPH PA6FQiCgg5ZLU7TcGNymhyVjZKZEjPqkm+qrTbHHr1EItR0TB49Zp8mLS9ZJwazLIy5W SHd3HjH6zk/G9QHv/AR39zMAsIJa5TG+p//pBqfkFt7g1DDMVGzyzOma+8tqtGVC48eR bKjA== X-Gm-Message-State: ANhLgQ3c5v1B5+dvBiY6zZI+EhyYGHENcyc7+UtB8MaavPshXSPdXcog WrhJ5SOmb/+7kAjiQ9h3Yq4= X-Google-Smtp-Source: ADFU+vu6h+IR+brZGgN8zBn/omNn9IkXCgZpjKUCJvVC/RVX2Vv2jDc5uEAAXQRaKKXgTceyL/EL+w== X-Received: by 2002:a1c:f70a:: with SMTP id v10mr3859770wmh.72.1585149737552; Wed, 25 Mar 2020 08:22:17 -0700 (PDT) Received: from localhost.localdomain ([79.115.60.40]) by smtp.gmail.com with ESMTPSA id n9sm6309165wru.50.2020.03.25.08.22.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Mar 2020 08:22:17 -0700 (PDT) From: Vladimir Oltean To: andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, davem@davemloft.net, jakub.kicinski@netronome.com Cc: murali.policharla@broadcom.com, stephen@networkplumber.org, jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org, nikolay@cumulusnetworks.com, netdev@vger.kernel.org Subject: [PATCH v2 net-next 02/10] net: phy: bcm7xx: Add jumbo frame configuration to PHY Date: Wed, 25 Mar 2020 17:22:01 +0200 Message-Id: <20200325152209.3428-3-olteanv@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200325152209.3428-1-olteanv@gmail.com> References: <20200325152209.3428-1-olteanv@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Murali Krishna Policharla Add API to configure jumbo frame settings in PHY during initial PHY configuration. Signed-off-by: Murali Krishna Policharla Reviewed-by: Scott Branden Signed-off-by: Vladimir Oltean --- drivers/net/phy/bcm-phy-lib.c | 28 ++++++++++++++++++++++++++++ drivers/net/phy/bcm-phy-lib.h | 1 + drivers/net/phy/bcm7xxx.c | 4 ++++ include/linux/brcmphy.h | 1 + 4 files changed, 34 insertions(+) diff --git a/drivers/net/phy/bcm-phy-lib.c b/drivers/net/phy/bcm-phy-lib.c index e0d3310957ff..a26c80e13b43 100644 --- a/drivers/net/phy/bcm-phy-lib.c +++ b/drivers/net/phy/bcm-phy-lib.c @@ -423,6 +423,34 @@ int bcm_phy_28nm_a0b0_afe_config_init(struct phy_device *phydev) } EXPORT_SYMBOL_GPL(bcm_phy_28nm_a0b0_afe_config_init); +int bcm_phy_enable_jumbo(struct phy_device *phydev) +{ + int val = 0, ret = 0; + + ret = phy_write(phydev, MII_BCM54XX_AUX_CTL, + MII_BCM54XX_AUXCTL_SHDWSEL_MISC); + if (ret < 0) + return ret; + + val = phy_read(phydev, MII_BCM54XX_AUX_CTL); + + /* Enable extended length packet reception */ + val |= MII_BCM54XX_AUXCTL_ACTL_EXT_PKT_LEN; + ret = phy_write(phydev, MII_BCM54XX_AUX_CTL, val); + + if (ret < 0) + return ret; + + val = phy_read(phydev, MII_BCM54XX_ECR); + + /* Enable 10K byte packet length reception */ + val |= BIT(0); + ret = phy_write(phydev, MII_BCM54XX_ECR, val); + + return ret; +} +EXPORT_SYMBOL_GPL(bcm_phy_enable_jumbo); + MODULE_DESCRIPTION("Broadcom PHY Library"); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Broadcom Corporation"); diff --git a/drivers/net/phy/bcm-phy-lib.h b/drivers/net/phy/bcm-phy-lib.h index c86fb9d1240c..129df819be8c 100644 --- a/drivers/net/phy/bcm-phy-lib.h +++ b/drivers/net/phy/bcm-phy-lib.h @@ -65,5 +65,6 @@ void bcm_phy_get_stats(struct phy_device *phydev, u64 *shadow, struct ethtool_stats *stats, u64 *data); void bcm_phy_r_rc_cal_reset(struct phy_device *phydev); int bcm_phy_28nm_a0b0_afe_config_init(struct phy_device *phydev); +int bcm_phy_enable_jumbo(struct phy_device *phydev); #endif /* _LINUX_BCM_PHY_LIB_H */ diff --git a/drivers/net/phy/bcm7xxx.c b/drivers/net/phy/bcm7xxx.c index af8eabe7a6d4..692048d86ab1 100644 --- a/drivers/net/phy/bcm7xxx.c +++ b/drivers/net/phy/bcm7xxx.c @@ -178,6 +178,10 @@ static int bcm7xxx_28nm_config_init(struct phy_device *phydev) break; } + if (ret) + return ret; + + ret = bcm_phy_enable_jumbo(phydev); if (ret) return ret; diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h index b475e7f20d28..19bd86019e93 100644 --- a/include/linux/brcmphy.h +++ b/include/linux/brcmphy.h @@ -119,6 +119,7 @@ #define MII_BCM54XX_AUXCTL_SHDWSEL_AUXCTL 0x00 #define MII_BCM54XX_AUXCTL_ACTL_TX_6DB 0x0400 #define MII_BCM54XX_AUXCTL_ACTL_SMDSP_ENA 0x0800 +#define MII_BCM54XX_AUXCTL_ACTL_EXT_PKT_LEN 0x4000 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC 0x07 #define MII_BCM54XX_AUXCTL_SHDWSEL_MISC_WIRESPEED_EN 0x0010 From patchwork Wed Mar 25 15:22:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 221860 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=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, 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 EAAE5C54FD0 for ; Wed, 25 Mar 2020 15:22:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C226420772 for ; Wed, 25 Mar 2020 15:22:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QzYFQ1Ji" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727832AbgCYPW1 (ORCPT ); Wed, 25 Mar 2020 11:22:27 -0400 Received: from mail-wm1-f67.google.com ([209.85.128.67]:54605 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727751AbgCYPWX (ORCPT ); Wed, 25 Mar 2020 11:22:23 -0400 Received: by mail-wm1-f67.google.com with SMTP id c81so2902956wmd.4 for ; Wed, 25 Mar 2020 08:22:20 -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; bh=JLymD2YDtsJoQzONTyDrYjpbzC4xrXQOzwSHXU9sgYo=; b=QzYFQ1JiCPGx65MPOxjyKdK15bCyfa/8RzlmoSSwKZPluaU+DmP+okdL5U0F+8oD5L Ywnl0FihWlCSYZbiJWRlj+A5U9biUDCaL4xsQQfPFW4PilFwkpp5Nio+oOCd3Fd3v4LJ 2qyACPopWGFWklqEvyiAazAjB8+VbCfLU3RRtD9G8IBAQGu0uf9ZfcuuiWUI1a7EdYjO IdfKKDhl9/YArKbJIZMaB72no9SAGhft4+OYF7BnGY3kwsIpS68FKxZXmdk3y6y3+4Or 3OuzoclKoiI7Kg02fOMPl2Z7lSVgdIcUODrWDQwcZaZ3N5KFu4cmRcLHdb4nBtT1Vgoq ixTw== 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; bh=JLymD2YDtsJoQzONTyDrYjpbzC4xrXQOzwSHXU9sgYo=; b=Hv9FrM3l2fcaPqs2D+muD0lczpM56DMCJU+VteRlBbC512w6zcm8Oa827hoPK05HMS o6Ms+sIIDgDny6zG30DEnfSFP4yrT5GIBSueDUmJZa8ddhCnk0WOuqmSKZ0slUE2xdGJ PAIrnR/b0R/7rS+nENdyXuH/bZNEPrxiNUf5viSkulyV/Xu+0TPe7ANndCdvH+6ItqKB /kBBXE3VE7yth+8B1V2VEKBfVP72denqb6SThD6q0kp/zkU93J8F9WhKFa7VHZ2yfO9x /EKM4YdTnweH2PNE/SpIbopplZapRXImv1Ut2sClTn+y5Tsx62gjQyiZMjiC6OQ4wYSI HEAA== X-Gm-Message-State: ANhLgQ0L7pQ7ijEE3hOXOWqTYgnKRDuEmClp1B5778xzuGUKGh1vDmyz hYQ6IJNSALwsX2C0nfEfO68= X-Google-Smtp-Source: ADFU+vss+/mILGFjQGrpVv6MJld6HiJzWFLvrXhCUXKmT+3JZZiaQ0NJABc5yzF7C5cvR54nMxkKQw== X-Received: by 2002:a1c:63c4:: with SMTP id x187mr3938501wmb.124.1585149740000; Wed, 25 Mar 2020 08:22:20 -0700 (PDT) Received: from localhost.localdomain ([79.115.60.40]) by smtp.gmail.com with ESMTPSA id n9sm6309165wru.50.2020.03.25.08.22.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Mar 2020 08:22:19 -0700 (PDT) From: Vladimir Oltean To: andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, davem@davemloft.net, jakub.kicinski@netronome.com Cc: murali.policharla@broadcom.com, stephen@networkplumber.org, jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org, nikolay@cumulusnetworks.com, netdev@vger.kernel.org Subject: [PATCH v2 net-next 04/10] bgmac: Add MTU configuration support to the driver Date: Wed, 25 Mar 2020 17:22:03 +0200 Message-Id: <20200325152209.3428-5-olteanv@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200325152209.3428-1-olteanv@gmail.com> References: <20200325152209.3428-1-olteanv@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Murali Krishna Policharla Add bgmac_change_mtu API to configure new mtu settings in bgmac driver. Signed-off-by: Murali Krishna Policharla Signed-off-by: Vladimir Oltean --- drivers/net/ethernet/broadcom/bgmac.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c index 1bb07a5d82c9..c530dff0353b 100644 --- a/drivers/net/ethernet/broadcom/bgmac.c +++ b/drivers/net/ethernet/broadcom/bgmac.c @@ -1248,6 +1248,14 @@ static int bgmac_set_mac_address(struct net_device *net_dev, void *addr) return 0; } +static int bgmac_change_mtu(struct net_device *net_dev, int mtu) +{ + struct bgmac *bgmac = netdev_priv(net_dev); + + bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + mtu); + return 0; +} + static const struct net_device_ops bgmac_netdev_ops = { .ndo_open = bgmac_open, .ndo_stop = bgmac_stop, @@ -1256,6 +1264,7 @@ static const struct net_device_ops bgmac_netdev_ops = { .ndo_set_mac_address = bgmac_set_mac_address, .ndo_validate_addr = eth_validate_addr, .ndo_do_ioctl = phy_do_ioctl_running, + .ndo_change_mtu = bgmac_change_mtu, }; /************************************************** @@ -1529,6 +1538,7 @@ int bgmac_enet_probe(struct bgmac *bgmac) net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; net_dev->hw_features = net_dev->features; net_dev->vlan_features = net_dev->features; + net_dev->max_mtu = BGMAC_RX_MAX_FRAME_SIZE; err = register_netdev(bgmac->net_dev); if (err) { From patchwork Wed Mar 25 15:22:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 221858 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=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, 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 CF2B7C54FD0 for ; Wed, 25 Mar 2020 15:22:34 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A148F20772 for ; Wed, 25 Mar 2020 15:22:34 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QEGJRDGf" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727815AbgCYPW0 (ORCPT ); Wed, 25 Mar 2020 11:22:26 -0400 Received: from mail-wr1-f68.google.com ([209.85.221.68]:46341 "EHLO mail-wr1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727742AbgCYPWY (ORCPT ); Wed, 25 Mar 2020 11:22:24 -0400 Received: by mail-wr1-f68.google.com with SMTP id j17so3550917wru.13 for ; Wed, 25 Mar 2020 08:22:23 -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; bh=tvQtsw0ICTvjn7fc59FPmyf50Xjv75M/Lj9Ga3yqMGo=; b=QEGJRDGf0JVThrbSUH+h7NStEwfHb932hjAZAtXO4A0sRVZd49v6eDxaYhcbq/csGf pRa63GZdnkKtNNU8fyM1zu+48Y4IUC3H2MpLR83PwFW8oYTsRk/9D70mKUMnl8vf2kD2 LX57pky5WorlUwdwLbQuUQrDuIJGB6v+y8mrCIRVte6Brhgh7DdrkqbwiPYICyG4vj/3 1X1P5gBUw4qQH493XYM/xgeEDTGBn05RZJPLk3EALlOIeOQKa+aAbBXj0M8U3eXO5h8n UChMRgFcYU2D1xwSiu01u98nW2QyFzk6nPC3iTdE7bVL954E/wrEHNqfuS/hPIWA4y3w bmDQ== 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; bh=tvQtsw0ICTvjn7fc59FPmyf50Xjv75M/Lj9Ga3yqMGo=; b=lklSjddwD7mmpZBtWAI2sgMUzpm1wYnEsgEXx4VQ76ov5l0iQlF1S4iFA5RIkUhuI2 B7YpXdeSKY2jjsqsqHSfR8LVQN9XYOXyfZX0Sde742b58CUb9+QbL52U1MXBz+Gdq4YQ VDJYc+PZnaDPl70bl++lM8wMuv+OAUgmKnkPkvKbnWySmY6OK2RjZqCQzEykPIvTe4Ra 1nohqhkwT5d1TpZuybk8ZgDV2WDRJMRpoPCrzk+ziOY/GvLODoUS8MXz4qtekpbExZpR sNBGhCzOX87Q35xSRbp8WBK3kDYBZa/C81MdU/wyfmegfLElpLJQm4acu//1Sq9BtFtD 1jCg== X-Gm-Message-State: ANhLgQ2DWRsD8V9GNj7yxj5PZVUu9iwPtukiSaJzJ+GHP4BWOnndDz1i ih2FWLJ16yiRNFPfLnurrEI= X-Google-Smtp-Source: ADFU+vtd+AYkfx7+liA4HDeIgtgLl2c/U2F8tqU34ccfkmbdXabh6GlaaffNTXitSJio9mUKWU/9IA== X-Received: by 2002:a5d:6044:: with SMTP id j4mr3804270wrt.232.1585149742401; Wed, 25 Mar 2020 08:22:22 -0700 (PDT) Received: from localhost.localdomain ([79.115.60.40]) by smtp.gmail.com with ESMTPSA id n9sm6309165wru.50.2020.03.25.08.22.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Mar 2020 08:22:21 -0700 (PDT) From: Vladimir Oltean To: andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, davem@davemloft.net, jakub.kicinski@netronome.com Cc: murali.policharla@broadcom.com, stephen@networkplumber.org, jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org, nikolay@cumulusnetworks.com, netdev@vger.kernel.org Subject: [PATCH v2 net-next 06/10] net: dsa: b53: Add MTU configuration support Date: Wed, 25 Mar 2020 17:22:05 +0200 Message-Id: <20200325152209.3428-7-olteanv@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200325152209.3428-1-olteanv@gmail.com> References: <20200325152209.3428-1-olteanv@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Murali Krishna Policharla Add b53_change_mtu API to configure mtu settings in B53 switch. Enable jumbo frame support if configured mtu size is for jumbo frame. Also configure BCM583XX devices to send and receive jumbo frames when ports are configured with 10/100 Mbps speed. Signed-off-by: Murali Krishna Policharla Signed-off-by: Vladimir Oltean --- drivers/net/dsa/b53/b53_common.c | 35 ++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/drivers/net/dsa/b53/b53_common.c b/drivers/net/dsa/b53/b53_common.c index ceafce446317..e32e05803800 100644 --- a/drivers/net/dsa/b53/b53_common.c +++ b/drivers/net/dsa/b53/b53_common.c @@ -644,6 +644,7 @@ EXPORT_SYMBOL(b53_brcm_hdr_setup); static void b53_enable_cpu_port(struct b53_device *dev, int port) { + u32 port_mask; u8 port_ctrl; /* BCM5325 CPU port is at 8 */ @@ -658,6 +659,14 @@ static void b53_enable_cpu_port(struct b53_device *dev, int port) b53_brcm_hdr_setup(dev->ds, port); b53_br_egress_floods(dev->ds, port, true, true); + + b53_read32(dev, B53_JUMBO_PAGE, dev->jumbo_pm_reg, &port_mask); + + if (dev->chip_id == BCM583XX_DEVICE_ID) + port_mask |= JPM_10_100_JUMBO_EN; + + port_mask |= BIT(port); + b53_write32(dev, B53_JUMBO_PAGE, dev->jumbo_pm_reg, port_mask); } static void b53_enable_mib(struct b53_device *dev) @@ -2065,6 +2074,30 @@ int b53_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) } EXPORT_SYMBOL(b53_set_mac_eee); +static int b53_change_mtu(struct dsa_switch *ds, int port, int mtu) +{ + struct b53_device *dev = ds->priv; + u32 port_mask; + + if (dev->chip_id == BCM58XX_DEVICE_ID || + is5325(dev) || is5365(dev)) + return -EOPNOTSUPP; + + b53_read32(dev, B53_JUMBO_PAGE, dev->jumbo_pm_reg, &port_mask); + + if (mtu >= JMS_MIN_SIZE) + port_mask |= BIT(port); + else + port_mask &= ~BIT(port); + + return b53_write32(dev, B53_JUMBO_PAGE, dev->jumbo_pm_reg, port_mask); +} + +static int b53_get_max_mtu(struct dsa_switch *ds, int port) +{ + return JMS_MAX_SIZE; +} + static const struct dsa_switch_ops b53_switch_ops = { .get_tag_protocol = b53_get_tag_protocol, .setup = b53_setup, @@ -2102,6 +2135,8 @@ static const struct dsa_switch_ops b53_switch_ops = { .port_mdb_prepare = b53_mdb_prepare, .port_mdb_add = b53_mdb_add, .port_mdb_del = b53_mdb_del, + .port_max_mtu = b53_get_max_mtu, + .port_change_mtu = b53_change_mtu, }; struct b53_chip_data { From patchwork Wed Mar 25 15:22:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 221859 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=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, 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 ADABAC54FCF for ; Wed, 25 Mar 2020 15:22:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7BF7F20774 for ; Wed, 25 Mar 2020 15:22:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="J1vohO+p" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727843AbgCYPWb (ORCPT ); Wed, 25 Mar 2020 11:22:31 -0400 Received: from mail-wm1-f67.google.com ([209.85.128.67]:36963 "EHLO mail-wm1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727751AbgCYPW3 (ORCPT ); Wed, 25 Mar 2020 11:22:29 -0400 Received: by mail-wm1-f67.google.com with SMTP id d1so3161601wmb.2 for ; Wed, 25 Mar 2020 08:22:28 -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; bh=6iRPv1lM2JYm9JzaSdpzNx0DiYcPcVAOEsGAUR9MeD0=; b=J1vohO+p9nQiLUnP2SVUe7lejW91XxPsnc8jHc7NyMySa6sSSUhkakPzg1pvYIv25K LhkmlKBrQtziwcu5fVZ3K8Mp9V4M/sILpmEp3DcBvDkHOz/n6dPo0G5j38X/LTr899oY quZuRX/NRS5IthpfOa/X9UTOdwnELl/JOyCuNtU7dK+iJOERIwfaat8Uw3CUPxc6+VhZ q9ORUvXwjtW4mpK0KfRsIprQ6ccPnMK/8lPs5vQKseEaFThXmwXHOTRUPmiBXLCvIZb6 F33A8BcTnaufEierI8Mm2tHjp9CCGfVKxRE0eu2uBnRvcw5OhTmECk0YdZvKHUd0NRNH Dxtg== 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; bh=6iRPv1lM2JYm9JzaSdpzNx0DiYcPcVAOEsGAUR9MeD0=; b=p40PqcatTM0FaUJoQSHL/PxaPF2vVObhaKxjF/s7/If8g1ghPXxXg6ZjLSE/hBTkhc TRDJRoVmXcvtKTZonCuBO++NcoJR8Kk6fFU5VVsof4PIKfb9ZMM8o2omJIewsKzgWt2h D3RBZrfBcTQPoQ0V0TGZWePHQmdyjjVIGMFp3lPrc8HF/fY9wGgU89xFO8Aj2rNdISBX GZbJD/PE7HBUKye8DDl/I8hks+OZX0tgFwGQcnZyKdLEYsT4WAyoUzPe72Ze7cXZjCgI gYCTQ7J2ErhdayConmOcWX7EjMo+znVSZSRsqLGLwu0m472gjS6P5ZxE92M7IT7kSt8p /9OQ== X-Gm-Message-State: ANhLgQ2WCVYnVpYH044BsxGK6v+dwGuXeO0BtoX896RTzNazar/odq4+ NdYop8OLyYWkIEcdgEjgf0Q= X-Google-Smtp-Source: ADFU+vuSyti+yJq9hAaOrDF7T3o3BD874e0GXBOWFy1q4FFsWu7yy6v6GY6CedDWHoqRxrFsqB0Tbw== X-Received: by 2002:a1c:b4c6:: with SMTP id d189mr3774315wmf.132.1585149747995; Wed, 25 Mar 2020 08:22:27 -0700 (PDT) Received: from localhost.localdomain ([79.115.60.40]) by smtp.gmail.com with ESMTPSA id n9sm6309165wru.50.2020.03.25.08.22.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 25 Mar 2020 08:22:27 -0700 (PDT) From: Vladimir Oltean To: andrew@lunn.ch, f.fainelli@gmail.com, vivien.didelot@gmail.com, davem@davemloft.net, jakub.kicinski@netronome.com Cc: murali.policharla@broadcom.com, stephen@networkplumber.org, jiri@resnulli.us, idosch@idosch.org, kuba@kernel.org, nikolay@cumulusnetworks.com, netdev@vger.kernel.org Subject: [PATCH v2 net-next 10/10] net: bridge: implement auto-normalization of MTU for hardware datapath Date: Wed, 25 Mar 2020 17:22:09 +0200 Message-Id: <20200325152209.3428-11-olteanv@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200325152209.3428-1-olteanv@gmail.com> References: <20200325152209.3428-1-olteanv@gmail.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean In the initial attempt to add MTU configuration for DSA: https://patchwork.ozlabs.org/cover/1199868/ Florian raised a concern about the bridge MTU normalization logic (when you bridge an interface with MTU 9000 and one with MTU 1500). His expectation was that the bridge would automatically change the MTU of all its slave ports to the minimum MTU, if those slaves are part of the same hardware bridge. However, it doesn't do that, and for good reason, I think. What br_mtu_auto_adjust() does is it adjusts the MTU of the bridge net device itself, and not that of any slave port. If it were to modify the MTU of the slave ports, the effect would be that the user wouldn't be able to increase the MTU of any bridge slave port as long as it was part of the bridge, which would be a bit annoying to say the least. The idea behind this behavior is that normal termination from Linux over the L2 forwarding domain described by DSA should happen over the bridge net device, which _is_ properly limited by the minimum MTU. And termination over individual slave device is possible even if those are bridged. But that is not "forwarding", so there's no reason to do normalization there, since only a single interface sees that packet. The real problem is with the offloaded data path, where of course, the bridge net device MTU is ignored. So a packet received on an interface with MTU 9000 would still be forwarded to an interface with MTU 1500. And that is exactly what this patch is trying to prevent from happening. Florian's idea was that all hardware ports having the same netdev_port_same_parent_id should be adjusted to have the same MTU. The MTU that we attempt to configure the ports to is the most recently modified MTU. The attempt is to follow user intention as closely as possible and not be annoying at that. So there are 2 cases really: ip link set dev sw0p0 master br0 ip link set dev sw0p1 mtu 1400 ip link set dev sw0p1 master br0 The above sequence will make sw0p0 inherit MTU 1400 as well. The second case: ip link set dev sw0p0 master br0 ip link set dev sw0p1 master br0 ip link set dev sw0p0 mtu 1400 This sequence will make sw0p1 inherit MTU 1400 from sw0p0. Suggested-by: Florian Fainelli Signed-off-by: Vladimir Oltean --- net/bridge/br.c | 1 + net/bridge/br_if.c | 93 +++++++++++++++++++++++++++++++++++++++++ net/bridge/br_private.h | 1 + 3 files changed, 95 insertions(+) diff --git a/net/bridge/br.c b/net/bridge/br.c index b6fe30e3768f..5f05380df1ee 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -57,6 +57,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v switch (event) { case NETDEV_CHANGEMTU: + br_mtu_normalization(br, dev); br_mtu_auto_adjust(br); break; diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 4fe30b182ee7..a228668920a6 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -514,6 +514,98 @@ void br_mtu_auto_adjust(struct net_bridge *br) br_opt_toggle(br, BROPT_MTU_SET_BY_USER, false); } +struct br_hw_port { + struct list_head list; + struct net_device *dev; + int old_mtu; +}; + +static int br_hw_port_list_set_mtu(struct list_head *hw_port_list, int mtu) +{ + const struct br_hw_port *p; + int err; + + list_for_each_entry(p, hw_port_list, list) { + if (p->dev->mtu == mtu) + continue; + + err = dev_set_mtu(p->dev, mtu); + if (err) + goto rollback; + } + + return 0; + +rollback: + list_for_each_entry_continue_reverse(p, hw_port_list, list) { + if (p->dev->mtu == p->old_mtu) + continue; + + if (dev_set_mtu(p->dev, p->old_mtu)) + netdev_err(p->dev, "Failed to restore MTU\n"); + } + + return err; +} + +static void br_hw_port_list_free(struct list_head *hw_port_list) +{ + struct br_hw_port *p, *n; + + list_for_each_entry_safe(p, n, hw_port_list, list) + kfree(p); +} + +/* Make the hardware datapath to/from @br_if limited to a common MTU */ +void br_mtu_normalization(struct net_bridge *br, struct net_device *br_if) +{ + const struct net_bridge_port *p; + struct list_head hw_port_list; + int min_mtu = ETH_MAX_MTU; + int err; + + INIT_LIST_HEAD(&hw_port_list); + + /* Populate the list of ports that are part of the same hardware bridge + * as the newly added port + */ + list_for_each_entry(p, &br->port_list, list) { + struct br_hw_port *hw_port; + + if (!netdev_port_same_parent_id(p->dev, br_if)) + continue; + + if (min_mtu > p->dev->mtu) + min_mtu = p->dev->mtu; + + hw_port = kzalloc(sizeof(*hw_port), GFP_KERNEL); + if (!hw_port) + goto out; + + hw_port->dev = p->dev; + hw_port->old_mtu = p->dev->mtu; + + list_add(&hw_port->list, &hw_port_list); + } + + /* Attempt to configure the entire hardware bridge to the newly added + * interface's MTU first, regardless of whether the intention of the + * user was to raise or lower it. + */ + err = br_hw_port_list_set_mtu(&hw_port_list, br_if->mtu); + if (!err) + goto out; + + /* Clearly that didn't work out so well, so just set the minimum MTU on + * all hardware bridge ports now. If this fails too, then all ports will + * still have their old MTU rolled back anyway. + */ + br_hw_port_list_set_mtu(&hw_port_list, min_mtu); + +out: + br_hw_port_list_free(&hw_port_list); +} + static void br_set_gso_limits(struct net_bridge *br) { unsigned int gso_max_size = GSO_MAX_SIZE; @@ -676,6 +768,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, if (changed_addr) call_netdevice_notifiers(NETDEV_CHANGEADDR, br->dev); + br_mtu_normalization(br, dev); br_mtu_auto_adjust(br); br_set_gso_limits(br); diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 1f97703a52ff..df010e36228e 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -693,6 +693,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, struct netlink_ext_ack *extack); int br_del_if(struct net_bridge *br, struct net_device *dev); void br_mtu_auto_adjust(struct net_bridge *br); +void br_mtu_normalization(struct net_bridge *br, struct net_device *br_if); netdev_features_t br_features_recompute(struct net_bridge *br, netdev_features_t features); void br_port_flags_change(struct net_bridge_port *port, unsigned long mask);