From patchwork Sun Jun 25 11:53:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pawel Dembicki X-Patchwork-Id: 13291938 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E1009ECE for ; Sun, 25 Jun 2023 11:54:52 +0000 (UTC) Received: from mail-lj1-x232.google.com (mail-lj1-x232.google.com [IPv6:2a00:1450:4864:20::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9C717E74; Sun, 25 Jun 2023 04:54:49 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id 38308e7fff4ca-2b466744368so33275421fa.0; Sun, 25 Jun 2023 04:54:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687694087; x=1690286087; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=D6QUBDRqa2Wrr4CQ5qPtzCdJP57iv7TLCuj/rtuOYPQ=; b=dk2KLS6Js8BYTMjIFK6RLM6Jxr02D5lf1hgbdwTvfH7L6x3QMcNi8bwZVJkIwFMogc kpcEkkLyqOOJ0UZMQPbz/kot0ibOC7h8tfuP3ynrJLm8tTRuLhQvwai6WEYeBQEW1sSn kzyBv0zKjM9aQdtn9W7E8mq/gftSHBCWvpw8UTCOo2xfilWLfhPJGyx0sl6lyjDjBito K8tc6Y+MDztbmwJhIiyHaPUs/GwycnYWMYzkBHFpxHlqA1fcxUUoGfLPV2VUTUvr2mvO 0QIs9jEtLCBlronpOkQzghKBrpL7vYQmd7v2e4DQsDQaELecUu2u+NfQ5cYkhN5LL0mG nQOQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687694087; x=1690286087; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=D6QUBDRqa2Wrr4CQ5qPtzCdJP57iv7TLCuj/rtuOYPQ=; b=Kt6Brzihjmlg9nlRN2kLmIh8xX0LezXidxnNZpQBY4GdxSv1i1hgCUsnVO6LoYYC2o Njab4pyyuoIdJFPfOsviROhqM6R9CgZi0BA9Wi+5ahWyw+Sb3wTQZ1YnBmno3iplu9jc JvGlUjjJi0MPCgjgmMGc+rMdeZQ8reVtNGaiayYobm9uWN3VmwV9Gr+e4gOxysOTnyAc vJoukf/Zhm09zl2ddNOuTAMMi1I9tosk9OSP/ZOZmPBq7byTa2T8oToSZrJJYgqkziXu d/qT2kZmwDWn5v/MXyFq7BS/LKPOpfQHG5b/9HsDxKz/5LrqxxjODAA73X36jGf62cOG XUIw== X-Gm-Message-State: AC+VfDz2xuR5aj0jeviHXrEbEyWwtRuzXRyPxLe7O8t1f669qewIyKWb euJfeNTRHk0Pt15Bjes+aCdQaH98oA6G9Q== X-Google-Smtp-Source: ACHHUZ7+M8ECB7lsgkgBNWrO5HgnfjjxTOyiGJRySCO0rV4Hoc+QnZVXcDpOQIbRB4CIpYAJ4Odjuw== X-Received: by 2002:a2e:9c82:0:b0:2b4:6678:da57 with SMTP id x2-20020a2e9c82000000b002b46678da57mr14500983lji.6.1687694087138; Sun, 25 Jun 2023 04:54:47 -0700 (PDT) Received: from WBEC325.dom.local ([185.188.71.122]) by smtp.gmail.com with ESMTPSA id w21-20020a2e9595000000b002b6993b9665sm416043ljh.65.2023.06.25.04.54.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:54:46 -0700 (PDT) From: Pawel Dembicki To: netdev@vger.kernel.org Cc: Pawel Dembicki , Russell King , Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 1/7] net: dsa: vsc73xx: use read_poll_timeout instead delay loop Date: Sun, 25 Jun 2023 13:53:36 +0200 Message-Id: <20230625115343.1603330-1-paweldembicki@gmail.com> X-Mailer: git-send-email 2.34.1 Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org This commit switches delay loop to read_poll_timeout macro durring Arbiter empty check in adjust link function. As Russel King suggested: "This [change] avoids the issue that on the last iteration, the code reads the register, test it, find the condition that's being waiting for is false, _then_ waits and end up printing the error message - that last wait is rather useless, and as the arbiter state isn't checked after waiting, it could be that we had success during the last wait." It also remove one short msleep delay. Suggested-by: Russell King Signed-off-by: Pawel Dembicki Reviewed-by: Andrew Lunn --- v2: - introduced patch drivers/net/dsa/vitesse-vsc73xx-core.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c index ae55167ce0a6..bea5ec7a89fd 100644 --- a/drivers/net/dsa/vitesse-vsc73xx-core.c +++ b/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -780,7 +780,7 @@ static void vsc73xx_adjust_link(struct dsa_switch *ds, int port, * after a PHY or the CPU port comes up or down. */ if (!phydev->link) { - int maxloop = 10; + int ret, err; dev_dbg(vsc->dev, "port %d: went down\n", port); @@ -795,19 +795,16 @@ static void vsc73xx_adjust_link(struct dsa_switch *ds, int port, VSC73XX_ARBDISC, BIT(port), BIT(port)); /* Wait until queue is empty */ - vsc73xx_read(vsc, VSC73XX_BLOCK_ARBITER, 0, - VSC73XX_ARBEMPTY, &val); - while (!(val & BIT(port))) { - msleep(1); - vsc73xx_read(vsc, VSC73XX_BLOCK_ARBITER, 0, - VSC73XX_ARBEMPTY, &val); - if (--maxloop == 0) { - dev_err(vsc->dev, - "timeout waiting for block arbiter\n"); - /* Continue anyway */ - break; - } - } + ret = read_poll_timeout(vsc73xx_read, err, + err < 0 || (val & BIT(port)), + 1000, 10000, false, + vsc, VSC73XX_BLOCK_ARBITER, 0, + VSC73XX_ARBEMPTY, &val); + if (ret) + dev_err(vsc->dev, + "timeout waiting for block arbiter\n"); + else if (err < 0) + dev_err(vsc->dev, "error reading arbiter\n"); /* Put this port into reset */ vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG, From patchwork Sun Jun 25 11:53:37 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pawel Dembicki X-Patchwork-Id: 13291939 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 731C8442C for ; Sun, 25 Jun 2023 11:54:54 +0000 (UTC) Received: from mail-lj1-x235.google.com (mail-lj1-x235.google.com [IPv6:2a00:1450:4864:20::235]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A7805E47; Sun, 25 Jun 2023 04:54:50 -0700 (PDT) Received: by mail-lj1-x235.google.com with SMTP id 38308e7fff4ca-2b699a2fe86so8302411fa.3; Sun, 25 Jun 2023 04:54:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687694088; x=1690286088; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TnIWcZ1ZlXJJvtOUIT1yhuwFRiZT1JlqjJYQsTmV7EI=; b=Yf9tbRNAu6fmDIEcxL/uhWB4Oo/mXunh/50qHMDypNM63TBrJdXlhJEsBJ6hxxhW1a icycLaN/sipV9pjZz17qS3GbvAGKkcUw2IZ7k7YuIvwHd6tJzlkyQhP7cMzFN+kARR5Y aVw1aYQKIzWNwZ5tBWqFTyUb3Mh849Ql9WgQfKA0GiC3C9L9VdO6HCvu95jtZUCQQHxf fgqZqbGtuTJD1EL48B0jQi3oWPY9S2kEBj9i02jOcvPPnBwnN/pC5bOA7VhYqFgtjxqv UMtwIfk9MfpCgDMRZ7uqVfRkYmjDAsdujswCnIwTqfuvR0elQ89RBPgoeMa29ISyY7Un ypCg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687694088; x=1690286088; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TnIWcZ1ZlXJJvtOUIT1yhuwFRiZT1JlqjJYQsTmV7EI=; b=P+RFl1Df+6/MVI5qIZkiN70NJ/E+6ceBTZfp5NZnCjYE8fJQyzzBBD2WJ5QUCgxWwt H9NbHa+b4IRi0o4SZJP0/jAnZi1lqvT6WX5bqJ5di8Kne3RqHMqos6B12grNL68eaPlM zeFJ2JZmIfLF1e0Y1Rh+hwpft3Qm09ZcbyNsYLsAe3FdWQCSyqVG5a4diK0ieNhzIZ9P jA/XCMr8Is4JZouGc+VANmlS+TbyLqwSgEPLMiv9wyxQ0Ie8A65cyiLcqWVyuSD7EjbF 50PWmNVfgV+D/froIDdL06D3abVaDO46cguHKbadEkNfu9BgU3DfzjO9c838H2EPrf/f 8/3A== X-Gm-Message-State: AC+VfDxDMkaLZCCNxJs5dkce6/HfNOrtgjobJMUSNirbCvzJLY29apIF FtvFx/JsLKskB/4iqzqDKH1Qm/FXV7Q3nA== X-Google-Smtp-Source: ACHHUZ5nEkPsDkAK9OV7mxLQ3qI5lY+O29jhpmMUw1HYuOPS169glK0MNBaei78auVGz3uYN00Hoew== X-Received: by 2002:a2e:94c1:0:b0:2b1:daca:676f with SMTP id r1-20020a2e94c1000000b002b1daca676fmr15874730ljh.36.1687694088562; Sun, 25 Jun 2023 04:54:48 -0700 (PDT) Received: from WBEC325.dom.local ([185.188.71.122]) by smtp.gmail.com with ESMTPSA id w21-20020a2e9595000000b002b6993b9665sm416043ljh.65.2023.06.25.04.54.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:54:48 -0700 (PDT) From: Pawel Dembicki To: netdev@vger.kernel.org Cc: Pawel Dembicki , Linus Walleij , Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , Russell King , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 2/7] net: dsa: vsc73xx: convert to PHYLINK Date: Sun, 25 Jun 2023 13:53:37 +0200 Message-Id: <20230625115343.1603330-2-paweldembicki@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230625115343.1603330-1-paweldembicki@gmail.com> References: <20230625115343.1603330-1-paweldembicki@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org This patch replaces the adjust_link api with the phylink apis that provide equivalent functionality. The remaining functionality from the adjust_link is now covered in the phylink_mac_link_* and phylink_mac_config. Removes: .adjust_link Adds: .phylink_get_caps .phylink_mac_link_down .phylink_mac_link_up .phylink_mac_link_down Reviewed-by: Linus Walleij Signed-off-by: Pawel Dembicki --- v2: - replace switch to if and get rid of macros in vsc73xx_phylink_mac_link_up function drivers/net/dsa/vitesse-vsc73xx-core.c | 196 +++++++++++++------------ 1 file changed, 102 insertions(+), 94 deletions(-) diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c index bea5ec7a89fd..221672b9e17f 100644 --- a/drivers/net/dsa/vitesse-vsc73xx-core.c +++ b/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -715,8 +715,7 @@ static void vsc73xx_init_port(struct vsc73xx *vsc, int port) } static void vsc73xx_adjust_enable_port(struct vsc73xx *vsc, - int port, struct phy_device *phydev, - u32 initval) + int port, u32 initval) { u32 val = initval; u8 seed; @@ -754,12 +753,40 @@ static void vsc73xx_adjust_enable_port(struct vsc73xx *vsc, VSC73XX_MAC_CFG_TX_EN | VSC73XX_MAC_CFG_RX_EN); } -static void vsc73xx_adjust_link(struct dsa_switch *ds, int port, - struct phy_device *phydev) +static void vsc73xx_phylink_get_caps(struct dsa_switch *ds, int port, + struct phylink_config *config) { - struct vsc73xx *vsc = ds->priv; - u32 val; + /* This switch only supports full-duplex at 1Gbps */ + config->mac_capabilities = MAC_10 | MAC_100 | MAC_1000FD | + MAC_ASYM_PAUSE | MAC_SYM_PAUSE; + + if (port == CPU_PORT) { + __set_bit(PHY_INTERFACE_MODE_RGMII, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_GMII, + config->supported_interfaces); + } else { + __set_bit(PHY_INTERFACE_MODE_INTERNAL, + config->supported_interfaces); + /* Compatibility for phylib's default interface type when the + * phy-mode property is absent + */ + __set_bit(PHY_INTERFACE_MODE_GMII, + config->supported_interfaces); + } + + /* This driver does not make use of the speed, duplex, pause or the + * advertisement in its mac_config, so it is safe to mark this driver + * as non-legacy. + */ + config->legacy_pre_march2020 = false; +} +static void vsc73xx_phylink_mac_config(struct dsa_switch *ds, int port, + unsigned int mode, + const struct phylink_link_state *state) +{ + struct vsc73xx *vsc = ds->priv; /* Special handling of the CPU-facing port */ if (port == CPU_PORT) { /* Other ports are already initialized but not this one */ @@ -775,101 +802,79 @@ static void vsc73xx_adjust_link(struct dsa_switch *ds, int port, VSC73XX_ADVPORTM_ENA_GTX | VSC73XX_ADVPORTM_DDR_MODE); } +} - /* This is the MAC confiuration that always need to happen - * after a PHY or the CPU port comes up or down. - */ - if (!phydev->link) { - int ret, err; - - dev_dbg(vsc->dev, "port %d: went down\n", - port); - - /* Disable RX on this port */ - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, - VSC73XX_MAC_CFG, - VSC73XX_MAC_CFG_RX_EN, 0); - - /* Discard packets */ - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, - VSC73XX_ARBDISC, BIT(port), BIT(port)); - - /* Wait until queue is empty */ - ret = read_poll_timeout(vsc73xx_read, err, - err < 0 || (val & BIT(port)), - 1000, 10000, false, - vsc, VSC73XX_BLOCK_ARBITER, 0, - VSC73XX_ARBEMPTY, &val); - if (ret) - dev_err(vsc->dev, - "timeout waiting for block arbiter\n"); - else if (err < 0) - dev_err(vsc->dev, "error reading arbiter\n"); - - /* Put this port into reset */ - vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG, - VSC73XX_MAC_CFG_RESET); - - /* Accept packets again */ - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, - VSC73XX_ARBDISC, BIT(port), 0); - - /* Allow backward dropping of frames from this port */ - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, - VSC73XX_SBACKWDROP, BIT(port), BIT(port)); - - /* Receive mask (disable forwarding) */ - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, - VSC73XX_RECVMASK, BIT(port), 0); +static void vsc73xx_phylink_mac_link_down(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface) +{ + struct vsc73xx *vsc = ds->priv; + int ret, err; + u32 val; - return; - } + /* Disable RX on this port */ + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_MAC_CFG, + VSC73XX_MAC_CFG_RX_EN, 0); - /* Figure out what speed was negotiated */ - if (phydev->speed == SPEED_1000) { - dev_dbg(vsc->dev, "port %d: 1000 Mbit mode full duplex\n", - port); - - /* Set up default for internal port or external RGMII */ - if (phydev->interface == PHY_INTERFACE_MODE_RGMII) - val = VSC73XX_MAC_CFG_1000M_F_RGMII; - else - val = VSC73XX_MAC_CFG_1000M_F_PHY; - vsc73xx_adjust_enable_port(vsc, port, phydev, val); - } else if (phydev->speed == SPEED_100) { - if (phydev->duplex == DUPLEX_FULL) { - val = VSC73XX_MAC_CFG_100_10M_F_PHY; - dev_dbg(vsc->dev, - "port %d: 100 Mbit full duplex mode\n", - port); - } else { - val = VSC73XX_MAC_CFG_100_10M_H_PHY; - dev_dbg(vsc->dev, - "port %d: 100 Mbit half duplex mode\n", - port); - } - vsc73xx_adjust_enable_port(vsc, port, phydev, val); - } else if (phydev->speed == SPEED_10) { - if (phydev->duplex == DUPLEX_FULL) { - val = VSC73XX_MAC_CFG_100_10M_F_PHY; - dev_dbg(vsc->dev, - "port %d: 10 Mbit full duplex mode\n", - port); - } else { - val = VSC73XX_MAC_CFG_100_10M_H_PHY; - dev_dbg(vsc->dev, - "port %d: 10 Mbit half duplex mode\n", - port); - } - vsc73xx_adjust_enable_port(vsc, port, phydev, val); - } else { + /* Discard packets */ + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, + VSC73XX_ARBDISC, BIT(port), BIT(port)); + + /* Wait until queue is empty */ + ret = read_poll_timeout(vsc73xx_read, err, err < 0 || (val & BIT(port)), + 1000, 10000, false, vsc, VSC73XX_BLOCK_ARBITER, + 0, VSC73XX_ARBEMPTY, &val); + if (ret) dev_err(vsc->dev, - "could not adjust link: unknown speed\n"); - } + "timeout waiting for block arbiter\n"); + else if (err < 0) + dev_err(vsc->dev, "error reading arbiter\n"); + + /* Put this port into reset */ + vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_MAC_CFG, + VSC73XX_MAC_CFG_RESET); + + /* Accept packets again */ + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, + VSC73XX_ARBDISC, BIT(port), 0); + + /* Allow backward dropping of frames from this port */ + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ARBITER, 0, + VSC73XX_SBACKWDROP, BIT(port), BIT(port)); + + /* Receive mask (disable forwarding) */ + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_RECVMASK, BIT(port), 0); +} + +static void vsc73xx_phylink_mac_link_up(struct dsa_switch *ds, int port, + unsigned int mode, + phy_interface_t interface, + struct phy_device *phydev, + int speed, int duplex, + bool tx_pause, bool rx_pause) +{ + struct vsc73xx *vsc = ds->priv; + u32 val; + + if (speed == SPEED_1000) + val = VSC73XX_MAC_CFG_GIGA_MODE | VSC73XX_MAC_CFG_TX_IPG_1000M; + else + val = VSC73XX_MAC_CFG_TX_IPG_100_10M; + + if (interface == PHY_INTERFACE_MODE_RGMII) + val |= VSC73XX_MAC_CFG_CLK_SEL_1000M; + else + val |= VSC73XX_MAC_CFG_CLK_SEL_EXT; + + if (duplex == DUPLEX_FULL) + val |= VSC73XX_MAC_CFG_FDX; /* Enable port (forwarding) in the receieve mask */ vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_RECVMASK, BIT(port), BIT(port)); + vsc73xx_adjust_enable_port(vsc, port, val); } static int vsc73xx_port_enable(struct dsa_switch *ds, int port, @@ -1040,7 +1045,10 @@ static const struct dsa_switch_ops vsc73xx_ds_ops = { .setup = vsc73xx_setup, .phy_read = vsc73xx_phy_read, .phy_write = vsc73xx_phy_write, - .adjust_link = vsc73xx_adjust_link, + .phylink_get_caps = vsc73xx_phylink_get_caps, + .phylink_mac_config = vsc73xx_phylink_mac_config, + .phylink_mac_link_down = vsc73xx_phylink_mac_link_down, + .phylink_mac_link_up = vsc73xx_phylink_mac_link_up, .get_strings = vsc73xx_get_strings, .get_ethtool_stats = vsc73xx_get_ethtool_stats, .get_sset_count = vsc73xx_get_sset_count, From patchwork Sun Jun 25 11:53:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pawel Dembicki X-Patchwork-Id: 13291940 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BCB805670 for ; Sun, 25 Jun 2023 11:54:56 +0000 (UTC) Received: from mail-lj1-x22f.google.com (mail-lj1-x22f.google.com [IPv6:2a00:1450:4864:20::22f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EFDAAE6B; Sun, 25 Jun 2023 04:54:51 -0700 (PDT) Received: by mail-lj1-x22f.google.com with SMTP id 38308e7fff4ca-2b47a15ca10so33629171fa.1; Sun, 25 Jun 2023 04:54:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687694090; x=1690286090; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=OALd4eb7UL8T5fpkRECjHOOzQFxYtFTTgkr+9lZkN8Q=; b=F4O5IztO6leg3x7gXZ7Z5Q/JgW/cuSVKlN5Qy+Ze7z0rjNahI83B6mnsstCoacvaIR Z+9y26PZRxoJrhybWPzU+WhEC6XTBvpwWHX9O7qaKUXn2dRAXtr2Epjp2RcYp2nbWshZ d3kz178Etkbnhplpuq1x9wmQX2geTpI1+eWGYV4LbIN88Oja10GWGv/tgg1iYMkd8xWM +i69h0Hk9gwcaykId70yYOJF4Ybgk5VXQ6mskihWFc+YgxhSStfoSNwtTT7Dvwd+tjUY ny+ebjOh7BNy6Y+OcT4wsyZQ+tYYLP0Qu5lJV4UlBurUm5ui6DDg+2etP9knquFpczEx ncYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687694090; x=1690286090; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OALd4eb7UL8T5fpkRECjHOOzQFxYtFTTgkr+9lZkN8Q=; b=VrLr/KXL23JTqW2SP3ekUPobkRMEKLWjTWJBqgWe0diNFJigajFMWML8HlbR5UHxXT yQR2PNhpMfgCY6XIcsfBDP2nQWDQI3L9v1gVFx49EPprLt58ZVht4ukT/emk1UaQDauz fPfOnBbKYnjTCjsNJeVLBMk4de2zBzNpF34wGlXXukIKv6VlrBI1FjqgAhutq8KQ6ooG CCWbtlZ/LTdvOiZ/EbeQ9Tz3VGpHgTcEIRUT1Wnzy1lb4Pv3FlNRYEqzAJvuqMw/0NP3 /Tzu8Y4rcOdAU5EMzhjcMlPK8ZxqVPpFLC/o7MEIJxH02Gk8E9ndRg8mShxiLptu8qIB BJmg== X-Gm-Message-State: AC+VfDxVC1nvjkSj8/xMtqmt+d4ZAkNJMbKqwmV9dUIfGzltUGA5jss7 4KObiIJx6s9YNWwrfbIRql5SCKaQRB/6Mg== X-Google-Smtp-Source: ACHHUZ5I4noyBNS26MkTgQPpxBmaHYHG6mr+XqPurb/R43wD1yMa3SpcjKZpogO3NsoCa51CHn4y/w== X-Received: by 2002:a2e:9dc4:0:b0:2b6:9ed2:f61c with SMTP id x4-20020a2e9dc4000000b002b69ed2f61cmr384700ljj.7.1687694089668; Sun, 25 Jun 2023 04:54:49 -0700 (PDT) Received: from WBEC325.dom.local ([185.188.71.122]) by smtp.gmail.com with ESMTPSA id w21-20020a2e9595000000b002b6993b9665sm416043ljh.65.2023.06.25.04.54.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:54:49 -0700 (PDT) From: Pawel Dembicki To: netdev@vger.kernel.org Cc: Pawel Dembicki , Linus Walleij , Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 3/7] net: dsa: vsc73xx: add port_stp_state_set function Date: Sun, 25 Jun 2023 13:53:38 +0200 Message-Id: <20230625115343.1603330-3-paweldembicki@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230625115343.1603330-1-paweldembicki@gmail.com> References: <20230625115343.1603330-1-paweldembicki@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org This isn't fully functional implementation of 802.1D, but port_stp_state_set is required for future tag8021q operations. This implementation handle properly all states, but vsc 73xx don't forward STP packets. Reviewed-by: Linus Walleij Signed-off-by: Pawel Dembicki --- v2: - fix kdoc drivers/net/dsa/vitesse-vsc73xx-core.c | 51 +++++++++++++++++++++++--- drivers/net/dsa/vitesse-vsc73xx.h | 2 + 2 files changed, 47 insertions(+), 6 deletions(-) diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c index 221672b9e17f..f123ce2ed244 100644 --- a/drivers/net/dsa/vitesse-vsc73xx-core.c +++ b/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -164,6 +164,10 @@ #define VSC73XX_AGENCTRL 0xf0 #define VSC73XX_CAPRST 0xff +#define VSC73XX_SRCMASKS_CPU_COPY BIT(27) +#define VSC73XX_SRCMASKS_MIRROR BIT(26) +#define VSC73XX_SRCMASKS_PORTS_MASK GENMASK(7, 0) + #define VSC73XX_MACACCESS_CPU_COPY BIT(14) #define VSC73XX_MACACCESS_FWD_KILL BIT(13) #define VSC73XX_MACACCESS_IGNORE_VLAN BIT(12) @@ -620,15 +624,17 @@ static int vsc73xx_setup(struct dsa_switch *ds) vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GMIIDELAY, VSC73XX_GMIIDELAY_GMII0_GTXDELAY_2_0_NS | VSC73XX_GMIIDELAY_GMII0_RXDELAY_2_0_NS); - /* Enable reception of frames on all ports */ - vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_RECVMASK, - 0x5f); /* IP multicast flood mask (table 144) */ vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_IFLODMSK, 0xff); mdelay(50); + /*configure forward map to CPU <-> port only*/ + for (i = 0; i < vsc->ds->num_ports; i++) + vsc->forward_map[i] = VSC73XX_SRCMASKS_PORTS_MASK & BIT(CPU_PORT); + vsc->forward_map[CPU_PORT] = VSC73XX_SRCMASKS_PORTS_MASK & ~BIT(CPU_PORT); + /* Release reset from the internal PHYs */ vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GLORESET, VSC73XX_GLORESET_PHY_RESET); @@ -871,9 +877,6 @@ static void vsc73xx_phylink_mac_link_up(struct dsa_switch *ds, int port, if (duplex == DUPLEX_FULL) val |= VSC73XX_MAC_CFG_FDX; - /* Enable port (forwarding) in the receieve mask */ - vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, - VSC73XX_RECVMASK, BIT(port), BIT(port)); vsc73xx_adjust_enable_port(vsc, port, val); } @@ -1040,6 +1043,41 @@ static int vsc73xx_get_max_mtu(struct dsa_switch *ds, int port) return 9600; } +static void vsc73xx_port_stp_state_set(struct dsa_switch *ds, int port, + u8 state) +{ + struct vsc73xx *vsc = ds->priv; + /* FIXME: STP frames isn't forwarded at this moment. BPDU frames are + * forwarded only from to PI/SI interface. For more info see chapter + * 2.7.1 (CPU Forwarding) in datasheet. + * This function is required for tag8021q operations. + */ + + if (state == BR_STATE_BLOCKING) + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_RECVMASK, BIT(port), 0); + else + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_RECVMASK, BIT(port), BIT(port)); + + if (state == BR_STATE_LEARNING || state == BR_STATE_FORWARDING) + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_LEARNMASK, BIT(port), BIT(port)); + else + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_LEARNMASK, BIT(port), 0); + + if (state == BR_STATE_FORWARDING) + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_SRCMASKS + port, + VSC73XX_SRCMASKS_PORTS_MASK, + vsc->forward_map[port]); + else + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_SRCMASKS + port, + VSC73XX_SRCMASKS_PORTS_MASK, 0); +} + static const struct dsa_switch_ops vsc73xx_ds_ops = { .get_tag_protocol = vsc73xx_get_tag_protocol, .setup = vsc73xx_setup, @@ -1056,6 +1094,7 @@ static const struct dsa_switch_ops vsc73xx_ds_ops = { .port_disable = vsc73xx_port_disable, .port_change_mtu = vsc73xx_change_mtu, .port_max_mtu = vsc73xx_get_max_mtu, + .port_stp_state_set = vsc73xx_port_stp_state_set, }; static int vsc73xx_gpio_get(struct gpio_chip *chip, unsigned int offset) diff --git a/drivers/net/dsa/vitesse-vsc73xx.h b/drivers/net/dsa/vitesse-vsc73xx.h index 30b1f0a36566..c4d5398edeeb 100644 --- a/drivers/net/dsa/vitesse-vsc73xx.h +++ b/drivers/net/dsa/vitesse-vsc73xx.h @@ -5,6 +5,7 @@ /** * struct vsc73xx - VSC73xx state container + * @forward_map: Forward table cache */ struct vsc73xx { struct device *dev; @@ -15,6 +16,7 @@ struct vsc73xx { u8 addr[ETH_ALEN]; const struct vsc73xx_ops *ops; void *priv; + u8 forward_map[8]; }; struct vsc73xx_ops { From patchwork Sun Jun 25 11:53:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pawel Dembicki X-Patchwork-Id: 13291945 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DCF976112 for ; Sun, 25 Jun 2023 11:54:59 +0000 (UTC) Received: from mail-lj1-x230.google.com (mail-lj1-x230.google.com [IPv6:2a00:1450:4864:20::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6380BE4A; Sun, 25 Jun 2023 04:54:54 -0700 (PDT) Received: by mail-lj1-x230.google.com with SMTP id 38308e7fff4ca-2b5c231c23aso12764121fa.0; Sun, 25 Jun 2023 04:54:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687694092; x=1690286092; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Cf3CF5aGKtesB3Oxr1mONeZqwHPtROx9J4/pZOmkcSM=; b=atc++516BGsTegjbwHRtvEnj16goAGK2YRjCETMQmE04TLumn179D145xlnr+ee8BQ 7goRfAbx88fqWgE4kAtdwGkIwlA3aW6PB7FpdkZqnrLiJikT6Zya9eDbU0UJ3aFHcR5l HHSNZig4Cwh2LWv+22Go38EcU7gQDDPTSti4vPa7QhV/XvJtYKn14TSU3fcqr41Y/ALQ 3RQKhwTaL+KBYMoxO5FlsJ3Loheyz0O7lRw6+7xp+67TkHHkv5S4R1TQI7+tj6d8nCRu KeyKLN9469gQSwZ8cKXonkpXI/SAN4y7GGIhd4DS9TLSuu5bmkutuGQzEMJjJb+BLXxV U5iQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687694092; x=1690286092; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Cf3CF5aGKtesB3Oxr1mONeZqwHPtROx9J4/pZOmkcSM=; b=YqDHJPyYCSnY+G+SgOsAOy9PceN8zzP68cajIRwk06oBs3pnyD5JanOfE1QXlN9mnf Cjrwu/lakzKgqkwQ2ZuyeuZ0GSKs7k2o1ByxjDuWJ8Zht/yqgUv69kJcAzxGjwQ7TdMC smiMtpCtWoDF5MNrCAzg8DPgVNtx+sb4X8P++xnO+IIFC1bPGwAv+7LgALet9hTUkrnB MbGuXt4G+6s6+2JiJdAkkaVKZ3Viz/Od+Jr7L5qtZLc59j99Oow498MLU28/7/SKspXU d13vCvqK4PVAleL8d+uKS/F5KwiSK6pQ2vFrStyU25eW4kh2Vw9ZGXEIOGYYsUPMp3+a S04w== X-Gm-Message-State: AC+VfDyi0BoRneqTG+VD6ZEZJahVfGlG0O5AcLE1MJ+oZas+zXi13xRK WZFZIksQPfRqMdH8GuYG4FH1BX76441A9A== X-Google-Smtp-Source: ACHHUZ7oTvKuYS2b98H+0/Dyz65VkfXHaBAzAjkI5mMGPlL3GWcqOjwPKgLuq91ct1/j9zGQEi1bAQ== X-Received: by 2002:a2e:874a:0:b0:2b5:8f85:bf67 with SMTP id q10-20020a2e874a000000b002b58f85bf67mr5762178ljj.53.1687694092101; Sun, 25 Jun 2023 04:54:52 -0700 (PDT) Received: from WBEC325.dom.local ([185.188.71.122]) by smtp.gmail.com with ESMTPSA id w21-20020a2e9595000000b002b6993b9665sm416043ljh.65.2023.06.25.04.54.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:54:51 -0700 (PDT) From: Pawel Dembicki To: netdev@vger.kernel.org Cc: Pawel Dembicki , Linus Walleij , Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 4/7] net: dsa: vsc73xx: Add dsa tagging based on 8021q Date: Sun, 25 Jun 2023 13:53:39 +0200 Message-Id: <20230625115343.1603330-4-paweldembicki@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230625115343.1603330-1-paweldembicki@gmail.com> References: <20230625115343.1603330-1-paweldembicki@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org This patch is simple implementation of 8021q tagging in vsc73xx driver. At this moment devices with DSA_TAG_PROTO_NONE are useless. VSC73XX family doesn't provide any tag support for external ethernet ports. The only way is vlan-based tagging. It require constant hardware vlan filtering. VSC73XX family support provider bridging but QinQ only without fully implemented 802.1AD. It allow only doubled 0x8100 TPID. In simple port mode QinQ is enabled to preserve forwarding vlan tagged frames. Tag driver introduce most simple funcionality required for proper taging support. Reviewed-by: Linus Walleij Signed-off-by: Pawel Dembicki --- v2: - change poll loop into dedicated macro - fix style issues drivers/net/dsa/Kconfig | 2 +- drivers/net/dsa/vitesse-vsc73xx-core.c | 532 +++++++++++++++++++++---- include/net/dsa.h | 2 + net/dsa/Kconfig | 6 + net/dsa/Makefile | 1 + net/dsa/tag_vsc73xx_8021q.c | 87 ++++ 6 files changed, 544 insertions(+), 86 deletions(-) create mode 100644 net/dsa/tag_vsc73xx_8021q.c diff --git a/drivers/net/dsa/Kconfig b/drivers/net/dsa/Kconfig index 3ed5391bb18d..4cf0166fef7b 100644 --- a/drivers/net/dsa/Kconfig +++ b/drivers/net/dsa/Kconfig @@ -125,7 +125,7 @@ config NET_DSA_SMSC_LAN9303_MDIO config NET_DSA_VITESSE_VSC73XX tristate - select NET_DSA_TAG_NONE + select NET_DSA_TAG_VSC73XX select FIXED_PHY select VITESSE_PHY select GPIOLIB diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c index f123ce2ed244..f7c38f9a81a8 100644 --- a/drivers/net/dsa/vitesse-vsc73xx-core.c +++ b/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -25,6 +26,7 @@ #include #include #include +#include #include #include @@ -62,6 +64,8 @@ #define VSC73XX_CAT_DROP 0x6e #define VSC73XX_CAT_PR_MISC_L2 0x6f #define VSC73XX_CAT_PR_USR_PRIO 0x75 +#define VSC73XX_CAT_VLAN_MISC 0x79 +#define VSC73XX_CAT_PORT_VLAN 0x7a #define VSC73XX_Q_MISC_CONF 0xdf /* MAC_CFG register bits */ @@ -122,6 +126,17 @@ #define VSC73XX_ADVPORTM_IO_LOOPBACK BIT(1) #define VSC73XX_ADVPORTM_HOST_LOOPBACK BIT(0) +/* TXUPDCFG transmit modify setup bits */ +#define VSC73XX_TXUPDCFG_DSCP_REWR_MODE GENMASK(20, 19) +#define VSC73XX_TXUPDCFG_DSCP_REWR_ENA BIT(18) +#define VSC73XX_TXUPDCFG_TX_INT_TO_USRPRIO_ENA BIT(17) +#define VSC73XX_TXUPDCFG_TX_UNTAGGED_VID GENMASK(15, 4) +#define VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_ENA BIT(3) +#define VSC73XX_TXUPDCFG_TX_UPDATE_CRC_CPU_ENA BIT(1) +#define VSC73XX_TXUPDCFG_TX_INSERT_TAG BIT(0) + +#define VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_SHIFT 4 + /* CAT_DROP categorizer frame dropping register bits */ #define VSC73XX_CAT_DROP_DROP_MC_SMAC_ENA BIT(6) #define VSC73XX_CAT_DROP_FWD_CTRL_ENA BIT(4) @@ -135,6 +150,15 @@ #define VSC73XX_Q_MISC_CONF_EARLY_TX_512 (1 << 1) #define VSC73XX_Q_MISC_CONF_MAC_PAUSE_MODE BIT(0) +/* CAT_VLAN_MISC categorizer VLAN miscellaneous bits*/ +#define VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA BIT(8) +#define VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA BIT(7) + +/* CAT_PORT_VLAN categorizer port VLAN*/ +#define VSC73XX_CAT_PORT_VLAN_VLAN_CFI BIT(15) +#define VSC73XX_CAT_PORT_VLAN_VLAN_USR_PRIO GENMASK(14, 12) +#define VSC73XX_CAT_PORT_VLAN_VLAN_VID GENMASK(11, 0) + /* Frame analyzer block 2 registers */ #define VSC73XX_STORMLIMIT 0x02 #define VSC73XX_ADVLEARN 0x03 @@ -189,7 +213,8 @@ #define VSC73XX_VLANACCESS_VLAN_MIRROR BIT(29) #define VSC73XX_VLANACCESS_VLAN_SRC_CHECK BIT(28) #define VSC73XX_VLANACCESS_VLAN_PORT_MASK GENMASK(9, 2) -#define VSC73XX_VLANACCESS_VLAN_TBL_CMD_MASK GENMASK(2, 0) +#define VSC73XX_VLANACCESS_VLAN_PORT_MASK_SHIFT 2 +#define VSC73XX_VLANACCESS_VLAN_TBL_CMD_MASK GENMASK(1, 0) #define VSC73XX_VLANACCESS_VLAN_TBL_CMD_IDLE 0 #define VSC73XX_VLANACCESS_VLAN_TBL_CMD_READ_ENTRY 1 #define VSC73XX_VLANACCESS_VLAN_TBL_CMD_WRITE_ENTRY 2 @@ -344,6 +369,13 @@ static const struct vsc73xx_counter vsc73xx_tx_counters[] = { { 29, "TxQoSClass3" }, /* non-standard counter */ }; +enum vsc73xx_port_vlan_conf { + VSC73XX_VLAN_UNAWARE, + VSC73XX_VLAN_AWARE, + VSC73XX_DOUBLE_VLAN_AWARE, + VSC73XX_DOUBLE_VLAN_CPU_AWARE, +}; + int vsc73xx_is_addr_valid(u8 block, u8 subblock) { switch (block) { @@ -558,90 +590,7 @@ static enum dsa_tag_protocol vsc73xx_get_tag_protocol(struct dsa_switch *ds, * cannot access the tag. (See "Internal frame header" section * 3.9.1 in the manual.) */ - return DSA_TAG_PROTO_NONE; -} - -static int vsc73xx_setup(struct dsa_switch *ds) -{ - struct vsc73xx *vsc = ds->priv; - int i; - - dev_info(vsc->dev, "set up the switch\n"); - - /* Issue RESET */ - vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GLORESET, - VSC73XX_GLORESET_MASTER_RESET); - usleep_range(125, 200); - - /* Initialize memory, initialize RAM bank 0..15 except 6 and 7 - * This sequence appears in the - * VSC7385 SparX-G5 datasheet section 6.6.1 - * VSC7395 SparX-G5e datasheet section 6.6.1 - * "initialization sequence". - * No explanation is given to the 0x1010400 magic number. - */ - for (i = 0; i <= 15; i++) { - if (i != 6 && i != 7) { - vsc73xx_write(vsc, VSC73XX_BLOCK_MEMINIT, - 2, - 0, 0x1010400 + i); - mdelay(1); - } - } - mdelay(30); - - /* Clear MAC table */ - vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, - VSC73XX_MACACCESS, - VSC73XX_MACACCESS_CMD_CLEAR_TABLE); - - /* Clear VLAN table */ - vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, - VSC73XX_VLANACCESS, - VSC73XX_VLANACCESS_VLAN_TBL_CMD_CLEAR_TABLE); - - msleep(40); - - /* Use 20KiB buffers on all ports on VSC7395 - * The VSC7385 has 16KiB buffers and that is the - * default if we don't set this up explicitly. - * Port "31" is "all ports". - */ - if (IS_739X(vsc)) - vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, 0x1f, - VSC73XX_Q_MISC_CONF, - VSC73XX_Q_MISC_CONF_EXTENT_MEM); - - /* Put all ports into reset until enabled */ - for (i = 0; i < 7; i++) { - if (i == 5) - continue; - vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, 4, - VSC73XX_MAC_CFG, VSC73XX_MAC_CFG_RESET); - } - - /* MII delay, set both GTX and RX delay to 2 ns */ - vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GMIIDELAY, - VSC73XX_GMIIDELAY_GMII0_GTXDELAY_2_0_NS | - VSC73XX_GMIIDELAY_GMII0_RXDELAY_2_0_NS); - /* IP multicast flood mask (table 144) */ - vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_IFLODMSK, - 0xff); - - mdelay(50); - - /*configure forward map to CPU <-> port only*/ - for (i = 0; i < vsc->ds->num_ports; i++) - vsc->forward_map[i] = VSC73XX_SRCMASKS_PORTS_MASK & BIT(CPU_PORT); - vsc->forward_map[CPU_PORT] = VSC73XX_SRCMASKS_PORTS_MASK & ~BIT(CPU_PORT); - - /* Release reset from the internal PHYs */ - vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GLORESET, - VSC73XX_GLORESET_PHY_RESET); - - udelay(4); - - return 0; + return DSA_TAG_PROTO_VSC73XX_8021Q; } static void vsc73xx_init_port(struct vsc73xx *vsc, int port) @@ -1078,6 +1027,417 @@ static void vsc73xx_port_stp_state_set(struct dsa_switch *ds, int port, VSC73XX_SRCMASKS_PORTS_MASK, 0); } +static int +vsc73xx_port_wait_for_vlan_table_cmd(struct vsc73xx *vsc) +{ + u32 val; + int ret, err; + + ret = read_poll_timeout(vsc73xx_read, err, + err < 0 || ((val & VSC73XX_VLANACCESS_VLAN_TBL_CMD_MASK) == + VSC73XX_VLANACCESS_VLAN_TBL_CMD_IDLE), + 1000, 10000, false, vsc, VSC73XX_BLOCK_ANALYZER, + 0, VSC73XX_VLANACCESS, &val); + if (ret) + return ret; + return err; +} + +static int +vsc73xx_port_read_vlan_table_entry(struct dsa_switch *ds, u16 vid, u8 *portmap) +{ + struct vsc73xx *vsc = ds->priv; + u32 val; + int ret; + + if (vid > 4095) + return -EPERM; + vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANTIDX, vid); + ret = vsc73xx_port_wait_for_vlan_table_cmd(vsc); + if (ret) + return ret; + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANACCESS, + VSC73XX_VLANACCESS_VLAN_TBL_CMD_MASK, + VSC73XX_VLANACCESS_VLAN_TBL_CMD_READ_ENTRY); + ret = vsc73xx_port_wait_for_vlan_table_cmd(vsc); + if (ret) + return ret; + vsc73xx_read(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANACCESS, &val); + *portmap = (val & VSC73XX_VLANACCESS_VLAN_PORT_MASK) >> + VSC73XX_VLANACCESS_VLAN_PORT_MASK_SHIFT; + return 0; +} + +static int +vsc73xx_port_write_vlan_table_entry(struct dsa_switch *ds, u16 vid, u8 portmap) +{ + struct vsc73xx *vsc = ds->priv; + int ret; + + if (vid > 4095) + return -EPERM; + vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANTIDX, vid); + ret = vsc73xx_port_wait_for_vlan_table_cmd(vsc); + if (ret) + return ret; + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANACCESS, + VSC73XX_VLANACCESS_VLAN_TBL_CMD_MASK | + VSC73XX_VLANACCESS_VLAN_SRC_CHECK | + VSC73XX_VLANACCESS_VLAN_PORT_MASK, + VSC73XX_VLANACCESS_VLAN_TBL_CMD_WRITE_ENTRY | + VSC73XX_VLANACCESS_VLAN_SRC_CHECK | + (portmap << + VSC73XX_VLANACCESS_VLAN_PORT_MASK_SHIFT)); + ret = vsc73xx_port_wait_for_vlan_table_cmd(vsc); + if (ret) + return ret; + return 0; +} + +static int +vsc73xx_port_update_vlan_table(struct dsa_switch *ds, int port, u16 vid, + bool set) +{ + u8 portmap; + int ret; + + if (vid > 4095) + return -EPERM; + + ret = vsc73xx_port_read_vlan_table_entry(ds, vid, &portmap); + if (ret) + return ret; + + if (set) + portmap |= BIT(port) | BIT(CPU_PORT); + else + portmap &= ~BIT(port); + + if (portmap == BIT(CPU_PORT)) + portmap = 0; + + ret = vsc73xx_port_write_vlan_table_entry(ds, vid, portmap); + + return ret; +} + +static void +vsc73xx_port_set_vlan_conf(struct dsa_switch *ds, int port, + enum vsc73xx_port_vlan_conf port_vlan_conf) +{ + struct vsc73xx *vsc = ds->priv; + + if (port_vlan_conf == VSC73XX_VLAN_UNAWARE) { + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_MAC_CFG, + VSC73XX_MAC_CFG_VLAN_AWR, 0); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_MAC_CFG, + VSC73XX_MAC_CFG_VLAN_DBLAWR, 0); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_VLAN_MISC, + VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA, + VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_VLAN_MISC, + VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA, + VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_DROP, + VSC73XX_CAT_DROP_TAGGED_ENA, 0); + } else { + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_MAC_CFG, + VSC73XX_MAC_CFG_VLAN_AWR, + VSC73XX_MAC_CFG_VLAN_AWR); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_DROP, + VSC73XX_CAT_DROP_TAGGED_ENA, 0); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_DROP, + VSC73XX_CAT_DROP_UNTAGGED_ENA, + VSC73XX_CAT_DROP_UNTAGGED_ENA); + + if (port_vlan_conf == VSC73XX_DOUBLE_VLAN_CPU_AWARE) + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_MAC_CFG, + VSC73XX_MAC_CFG_VLAN_DBLAWR, + VSC73XX_MAC_CFG_VLAN_DBLAWR); + else + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_MAC_CFG, + VSC73XX_MAC_CFG_VLAN_DBLAWR, 0); + + if (port_vlan_conf == VSC73XX_DOUBLE_VLAN_AWARE) { + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_VLAN_MISC, + VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA, + VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_VLAN_MISC, + VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA, + VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_TXUPDCFG, + VSC73XX_TXUPDCFG_TX_INSERT_TAG, 0); + } else { + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_VLAN_MISC, + VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA, + 0); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_VLAN_MISC, + VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA, + 0); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_TXUPDCFG, + VSC73XX_TXUPDCFG_TX_INSERT_TAG, + VSC73XX_TXUPDCFG_TX_INSERT_TAG); + } + + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_TXUPDCFG, + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_ENA, 0); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_TXUPDCFG, + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID, 0); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_PORT_VLAN, + VSC73XX_CAT_PORT_VLAN_VLAN_VID, 0); + } +} + +static int vsc73xx_port_set_double_vlan_aware(struct dsa_switch *ds, int port) +{ + int i, ret; + + if (port == CPU_PORT) + vsc73xx_port_set_vlan_conf(ds, port, + VSC73XX_DOUBLE_VLAN_CPU_AWARE); + else + vsc73xx_port_set_vlan_conf(ds, port, + VSC73XX_DOUBLE_VLAN_AWARE); + + for (i = 0; i <= 4095; i++) { + ret = vsc73xx_port_update_vlan_table(ds, port, i, 0); + if (ret) + return ret; + } + return ret; +} + +static int vsc73xx_vlan_set_untagged(struct dsa_switch *ds, int port, u16 vid, + bool port_vlan) +{ + struct vsc73xx *vsc = ds->priv; + u16 vlan_no; + u32 val; + + vsc73xx_read(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_TXUPDCFG, &val); + + if (port_vlan && (val & VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_ENA)) { + vsc73xx_read(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_TXUPDCFG, + &val); + vlan_no = (val & VSC73XX_TXUPDCFG_TX_UNTAGGED_VID) >> + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_SHIFT; + if (!vid_is_dsa_8021q(vlan_no) && !vid_is_dsa_8021q(vid) && + vlan_no != vid) { + dev_warn(vsc->dev, + "Port %d can have only one untagged vid! Now is: %d.\n", + port, vlan_no); + return -EPERM; + } + } + + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_CAT_DROP, + VSC73XX_CAT_DROP_UNTAGGED_ENA, 0); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_TXUPDCFG, + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_ENA, + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_ENA); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_TXUPDCFG, + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID, + (vid << VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_SHIFT) & + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID); + return 0; +} + +static int vsc73xx_vlan_set_pvid(struct dsa_switch *ds, int port, u16 vid, + bool port_vlan) +{ + struct dsa_port *dsa_port = dsa_to_port(ds, port); + struct vsc73xx *vsc = ds->priv; + u16 vlan_no; + u32 val; + + if (!dsa_port) + return -EINVAL; + + vsc73xx_read(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_CAT_PORT_VLAN, &val); + vlan_no = val & VSC73XX_CAT_PORT_VLAN_VLAN_VID; + + if (port_vlan && vlan_no && !vid_is_dsa_8021q(vlan_no) && + !vid_is_dsa_8021q(vid) && vlan_no != vid) { + dev_warn(vsc->dev, + "Port %d can have only one pvid! Now is: %d.\n", + port, vlan_no); + return -EPERM; + } + + if (dsa_port_is_vlan_filtering(dsa_port)) + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_VLAN_MISC, + VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA, + 0); + else + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_VLAN_MISC, + VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA, + VSC73XX_CAT_VLAN_MISC_VLAN_TCI_IGNORE_ENA); + + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_CAT_VLAN_MISC, + VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA, + VSC73XX_CAT_VLAN_MISC_VLAN_KEEP_TAG_ENA); + + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_CAT_PORT_VLAN, + VSC73XX_CAT_PORT_VLAN_VLAN_VID, + vid & VSC73XX_CAT_PORT_VLAN_VLAN_VID); + return 0; +} + +static int vsc73xx_tag_8021q_vlan_add(struct dsa_switch *ds, int port, u16 vid, + u16 flags) +{ + bool untagged = flags & BRIDGE_VLAN_INFO_UNTAGGED; + bool pvid = flags & BRIDGE_VLAN_INFO_PVID; + int ret; + + if (untagged) { + ret = vsc73xx_vlan_set_untagged(ds, port, vid, false); + if (ret) + return ret; + } + if (pvid) { + ret = vsc73xx_vlan_set_pvid(ds, port, vid, false); + if (ret) + return ret; + } + ret = vsc73xx_port_update_vlan_table(ds, port, vid, 1); + if (ret) + return ret; + + return 0; +} + +static int vsc73xx_tag_8021q_vlan_del(struct dsa_switch *ds, int port, u16 vid) +{ + return vsc73xx_port_update_vlan_table(ds, port, vid, 0); +} + +static int vsc73xx_setup(struct dsa_switch *ds) +{ + struct vsc73xx *vsc = ds->priv; + int i, ret; + + dev_info(vsc->dev, "set up the switch\n"); + + ds->vlan_filtering_is_global = false; + ds->configure_vlan_while_not_filtering = false; + + /* Issue RESET */ + vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GLORESET, + VSC73XX_GLORESET_MASTER_RESET); + usleep_range(125, 200); + + /* Initialize memory, initialize RAM bank 0..15 except 6 and 7 + * This sequence appears in the + * VSC7385 SparX-G5 datasheet section 6.6.1 + * VSC7395 SparX-G5e datasheet section 6.6.1 + * "initialization sequence". + * No explanation is given to the 0x1010400 magic number. + */ + for (i = 0; i <= 15; i++) { + if (i != 6 && i != 7) { + vsc73xx_write(vsc, VSC73XX_BLOCK_MEMINIT, + 2, + 0, 0x1010400 + i); + mdelay(1); + } + } + mdelay(30); + + /* Clear MAC table */ + vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_MACACCESS, + VSC73XX_MACACCESS_CMD_CLEAR_TABLE); + + /* Clear VLAN table */ + vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_VLANACCESS, + VSC73XX_VLANACCESS_VLAN_TBL_CMD_CLEAR_TABLE); + + msleep(40); + + /* Use 20KiB buffers on all ports on VSC7395 + * The VSC7385 has 16KiB buffers and that is the + * default if we don't set this up explicitly. + * Port "31" is "all ports". + */ + if (IS_739X(vsc)) + vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, 0x1f, + VSC73XX_Q_MISC_CONF, + VSC73XX_Q_MISC_CONF_EXTENT_MEM); + + /* Put all ports into reset until enabled */ + for (i = 0; i < 7; i++) { + if (i == 5) + continue; + vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, 4, + VSC73XX_MAC_CFG, VSC73XX_MAC_CFG_RESET); + } + + /* MII delay, set both GTX and RX delay to 2 ns */ + vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GMIIDELAY, + VSC73XX_GMIIDELAY_GMII0_GTXDELAY_2_0_NS | + VSC73XX_GMIIDELAY_GMII0_RXDELAY_2_0_NS); + /* Ingess VLAN reception mask (table 145) */ + vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_VLANMASK, + 0x5f); + /* IP multicast flood mask (table 144) */ + vsc73xx_write(vsc, VSC73XX_BLOCK_ANALYZER, 0, VSC73XX_IFLODMSK, + 0xff); + + mdelay(50); + + for (i = 0; i < vsc->ds->num_ports; i++) { + if (i == 5) + continue; + ret = vsc73xx_port_set_double_vlan_aware(ds, i); + if (ret) + return ret; + } + + rtnl_lock(); + ret = dsa_tag_8021q_register(ds, htons(ETH_P_8021Q)); + rtnl_unlock(); + if (ret) + return ret; + + /*configure forward map to CPU <-> port only*/ + for (i = 0; i < vsc->ds->num_ports; i++) + vsc->forward_map[i] = VSC73XX_SRCMASKS_PORTS_MASK & + BIT(CPU_PORT); + vsc->forward_map[CPU_PORT] = VSC73XX_SRCMASKS_PORTS_MASK & + ~BIT(CPU_PORT); + + /* Release reset from the internal PHYs */ + vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GLORESET, + VSC73XX_GLORESET_PHY_RESET); + + udelay(4); + + return 0; +} + static const struct dsa_switch_ops vsc73xx_ds_ops = { .get_tag_protocol = vsc73xx_get_tag_protocol, .setup = vsc73xx_setup, @@ -1095,6 +1455,8 @@ static const struct dsa_switch_ops vsc73xx_ds_ops = { .port_change_mtu = vsc73xx_change_mtu, .port_max_mtu = vsc73xx_get_max_mtu, .port_stp_state_set = vsc73xx_port_stp_state_set, + .tag_8021q_vlan_add = vsc73xx_tag_8021q_vlan_add, + .tag_8021q_vlan_del = vsc73xx_tag_8021q_vlan_del, }; static int vsc73xx_gpio_get(struct gpio_chip *chip, unsigned int offset) diff --git a/include/net/dsa.h b/include/net/dsa.h index 75022cf771cf..2440df7ea6c9 100644 --- a/include/net/dsa.h +++ b/include/net/dsa.h @@ -56,6 +56,7 @@ struct phylink_link_state; #define DSA_TAG_PROTO_RTL8_4T_VALUE 25 #define DSA_TAG_PROTO_RZN1_A5PSW_VALUE 26 #define DSA_TAG_PROTO_LAN937X_VALUE 27 +#define DSA_TAG_PROTO_VSC73XX_8021Q_VALUE 28 enum dsa_tag_protocol { DSA_TAG_PROTO_NONE = DSA_TAG_PROTO_NONE_VALUE, @@ -86,6 +87,7 @@ enum dsa_tag_protocol { DSA_TAG_PROTO_RTL8_4T = DSA_TAG_PROTO_RTL8_4T_VALUE, DSA_TAG_PROTO_RZN1_A5PSW = DSA_TAG_PROTO_RZN1_A5PSW_VALUE, DSA_TAG_PROTO_LAN937X = DSA_TAG_PROTO_LAN937X_VALUE, + DSA_TAG_PROTO_VSC73XX_8021Q = DSA_TAG_PROTO_VSC73XX_8021Q_VALUE, }; struct dsa_switch; diff --git a/net/dsa/Kconfig b/net/dsa/Kconfig index 8e698bea99a3..e59360071c67 100644 --- a/net/dsa/Kconfig +++ b/net/dsa/Kconfig @@ -166,6 +166,12 @@ config NET_DSA_TAG_TRAILER Say Y or M if you want to enable support for tagging frames at with a trailed. e.g. Marvell 88E6060. +config NET_DSA_TAG_VSC73XX_8021Q + tristate "Tag driver for Microchip/Vitesse VSC73xx family of switches, using VLAN" + help + Say Y or M if you want to enable support for tagging frames with a + custom VLAN-based header. + config NET_DSA_TAG_XRS700X tristate "Tag driver for XRS700x switches" help diff --git a/net/dsa/Makefile b/net/dsa/Makefile index 12e305824a96..bab8a933c514 100644 --- a/net/dsa/Makefile +++ b/net/dsa/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_NET_DSA_TAG_RTL8_4) += tag_rtl8_4.o obj-$(CONFIG_NET_DSA_TAG_RZN1_A5PSW) += tag_rzn1_a5psw.o obj-$(CONFIG_NET_DSA_TAG_SJA1105) += tag_sja1105.o obj-$(CONFIG_NET_DSA_TAG_TRAILER) += tag_trailer.o +obj-$(CONFIG_NET_DSA_TAG_VSC73XX_8021Q) += tag_vsc73xx_8021q.o obj-$(CONFIG_NET_DSA_TAG_XRS700X) += tag_xrs700x.o # for tracing framework to find trace.h diff --git a/net/dsa/tag_vsc73xx_8021q.c b/net/dsa/tag_vsc73xx_8021q.c new file mode 100644 index 000000000000..3d83dfecde31 --- /dev/null +++ b/net/dsa/tag_vsc73xx_8021q.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0 OR MIT +/* Copyright (C) 2022 Pawel Dembicki + * Based on tag_sja1105.c: + * Copyright (c) 2019, Vladimir Oltean + */ +#include + +#include "tag.h" +#include "tag_8021q.h" + +#define VSC73XX_8021Q_NAME "vsc73xx-8021q" + +static struct sk_buff *vsc73xx_xmit(struct sk_buff *skb, + struct net_device *netdev) +{ + struct dsa_port *dp = dsa_slave_to_port(netdev); + u16 queue_mapping = skb_get_queue_mapping(skb); + u8 pcp = netdev_txq_to_tc(netdev, queue_mapping); + u16 tx_vid = dsa_tag_8021q_standalone_vid(dp); + struct net_device *br = dsa_port_bridge_dev_get(dp); + + if (skb->offload_fwd_mark) { + unsigned int bridge_num = dsa_port_bridge_num_get(dp); + + if (br_vlan_enabled(br)) + return skb; + else + tx_vid = dsa_tag_8021q_bridge_vid(bridge_num); + } + + return dsa_8021q_xmit(skb, netdev, ETH_P_8021Q, + ((pcp << VLAN_PRIO_SHIFT) | tx_vid)); +} + +static void vsc73xx_vlan_rcv(struct sk_buff *skb, int *source_port, + int *switch_id, int *vbid, u16 *vid) +{ + if (vid_is_dsa_8021q(skb_vlan_tag_get(skb) & VLAN_VID_MASK)) + return dsa_8021q_rcv(skb, source_port, switch_id, vbid); + + /* Try our best with imprecise RX */ + *vid = skb_vlan_tag_get(skb) & VLAN_VID_MASK; +} + +static struct sk_buff *vsc73xx_rcv(struct sk_buff *skb, + struct net_device *netdev) +{ + int src_port = -1, switch_id = -1, vbid = -1; + u16 vid; + + if (skb_vlan_tag_present(skb)) + /* Normal traffic path. */ + vsc73xx_vlan_rcv(skb, &src_port, &switch_id, &vbid, &vid); + + if (vbid >= 1) + skb->dev = dsa_tag_8021q_find_port_by_vbid(netdev, vbid); + else if (src_port == -1 || switch_id == -1) + skb->dev = dsa_find_designated_bridge_port_by_vid(netdev, vid); + else + skb->dev = dsa_master_find_slave(netdev, switch_id, src_port); + if (!skb->dev) { + netdev_warn(netdev, "Couldn't decode source port\n"); + return NULL; + } + + dsa_default_offload_fwd_mark(skb); + + if (dsa_port_is_vlan_filtering(dsa_slave_to_port(skb->dev)) && + eth_hdr(skb)->h_proto == htons(ETH_P_8021Q)) + __vlan_hwaccel_clear_tag(skb); + + return skb; +} + +static const struct dsa_device_ops vsc73xx_8021q_netdev_ops = { + .name = VSC73XX_8021Q_NAME, + .proto = DSA_TAG_PROTO_VSC73XX_8021Q, + .xmit = vsc73xx_xmit, + .rcv = vsc73xx_rcv, + .needed_headroom = VLAN_HLEN, + .promisc_on_master = true, +}; + +MODULE_LICENSE("GPL"); +MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_VSC73XX_8021Q, VSC73XX_8021Q_NAME); + +module_dsa_tag_driver(vsc73xx_8021q_netdev_ops); From patchwork Sun Jun 25 11:53:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pawel Dembicki X-Patchwork-Id: 13291941 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5862A6112 for ; Sun, 25 Jun 2023 11:54:59 +0000 (UTC) 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 3301EE45; Sun, 25 Jun 2023 04:54:55 -0700 (PDT) Received: by mail-lf1-x12b.google.com with SMTP id 2adb3069b0e04-4fafe87c6fbso552478e87.3; Sun, 25 Jun 2023 04:54:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687694093; x=1690286093; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wsYPlWkKWx54UKPOm+m2MAyy1P9pH4wm4DWIQ7hUyQk=; b=itKXmVf0xhP6VzvddpCCYnLfK/tjp7wyGswQxWjwGU83DT2ubn/z9kWl4FH74WCMrn M8ah1F5NX8gr4x4bFqn69m3zyuG0OSLngUw93/a7wgmRUzbhZBwOkBJUQRctLUWSyFmg bu1fNztbTsUNfhWHM5VfuHNzRPNrIeFT1xwCI2rCKsPG8q9wEvr6ScDGcSzR5emo7r20 Z6ewTQOfh29je93tMjeg8v6HjVy68cTe7EnuEQ3Hc2R7Qb3+a8k+8fb5i2GlLCXb2hUv LEbsbKjmM0CNRAUY1Rj1FUz1/PV5WVXWgb2GcqTkcx/wHmw+r9fW2ZmgrqUyQCA/2s1H CfRg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687694093; x=1690286093; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wsYPlWkKWx54UKPOm+m2MAyy1P9pH4wm4DWIQ7hUyQk=; b=Ufr3JJ+vWMPGuknK6qjwZ3WRPfoFkUkNLyfY+fgBKHdI3iKonjARul+Q1ZpbQUWRZ7 SWehHfI0SGL2unpAVKsdlC6DVTE0gQwgCF2N5kQ1Ot+B+RFbfRuphKkeqYadsC1gTsEi PyHv8UkdoSnYIwLQTWByMUSLM5D6SXLmhiyH611gGt8AMQKRINQ7VDlEpbO84atJGNSt jwzU+HB+CQDY31l+4cRW0y2FXPkugCCeXJB3OSODhCP7/SuKpHAF9vmejDR5HeinGeib FJCYaI1guIiVb9CkwCS0mZqU4LlVfClZT9dvHapMj22ViUdCRfUgSdPHGTAQZTGmUao/ Jwhg== X-Gm-Message-State: AC+VfDx0/XA9PU8gXjp3KTTA2JJQmTKwUumJ4Ke+e7TKHAQFRBChQ0Db yupA8gRFQZeaJBryybXwJ/hg9abGjW6lKw== X-Google-Smtp-Source: ACHHUZ5+xI2K1G7gj8JY8uHTk9PI6ZEt5Y8M7C0xxDnsdvDu477m8AvCc6wM1p5RgG1YQQdXSIlAZw== X-Received: by 2002:a05:6512:3e25:b0:4f9:70fe:d92a with SMTP id i37-20020a0565123e2500b004f970fed92amr4177442lfv.5.1687694093127; Sun, 25 Jun 2023 04:54:53 -0700 (PDT) Received: from WBEC325.dom.local ([185.188.71.122]) by smtp.gmail.com with ESMTPSA id w21-20020a2e9595000000b002b6993b9665sm416043ljh.65.2023.06.25.04.54.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:54:52 -0700 (PDT) From: Pawel Dembicki To: netdev@vger.kernel.org Cc: Pawel Dembicki , Linus Walleij , Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 5/7] net: dsa: vsc73xx: Add bridge support Date: Sun, 25 Jun 2023 13:53:40 +0200 Message-Id: <20230625115343.1603330-5-paweldembicki@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230625115343.1603330-1-paweldembicki@gmail.com> References: <20230625115343.1603330-1-paweldembicki@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org This patch adds bridge support for vsc73xx driver. It introduce two functions for port_bridge_join and vsc73xx_port_bridge_leave handling. Those functions implement forwarding adjust and use dsa_tag_8021q_bridge_* api for adjust VLAN configuration. Reviewed-by: Linus Walleij Signed-off-by: Pawel Dembicki --- v2: - no changes done drivers/net/dsa/vitesse-vsc73xx-core.c | 69 ++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c index f7c38f9a81a8..457eb7fddf4c 100644 --- a/drivers/net/dsa/vitesse-vsc73xx-core.c +++ b/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -1304,6 +1304,72 @@ static int vsc73xx_vlan_set_pvid(struct dsa_switch *ds, int port, u16 vid, return 0; } +static void vsc73xx_update_forwarding_map(struct vsc73xx *vsc) +{ + int i; + + for (i = 0; i < vsc->ds->num_ports; i++) { + u32 val; + + vsc73xx_read(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_SRCMASKS + i, &val); + /* update only if port is in forwarding state*/ + if (val & VSC73XX_SRCMASKS_PORTS_MASK) + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_ANALYZER, 0, + VSC73XX_SRCMASKS + i, + VSC73XX_SRCMASKS_PORTS_MASK, + vsc->forward_map[i]); + } +} + +static int vsc73xx_port_bridge_join(struct dsa_switch *ds, int port, + struct dsa_bridge bridge, + bool *tx_fwd_offload, + struct netlink_ext_ack *extack) +{ + struct vsc73xx *vsc = ds->priv; + int i; + + *tx_fwd_offload = true; + + for (i = 0; i < ds->num_ports; i++) { + /* Add this port to the forwarding matrix of the + * other ports in the same bridge, and viceversa. + */ + if (!dsa_is_user_port(ds, i)) + continue; + + if (i == port) + continue; + + if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge)) + continue; + + vsc->forward_map[port] |= VSC73XX_SRCMASKS_PORTS_MASK & BIT(i); + vsc->forward_map[i] |= VSC73XX_SRCMASKS_PORTS_MASK & BIT(port); + } + vsc73xx_update_forwarding_map(vsc); + + return dsa_tag_8021q_bridge_join(ds, port, bridge); +} + +static void vsc73xx_port_bridge_leave(struct dsa_switch *ds, int port, + struct dsa_bridge bridge) +{ + struct vsc73xx *vsc = ds->priv; + int i; + /*configure forward map to CPU <-> port only*/ + for (i = 0; i < vsc->ds->num_ports; i++) { + if (i == CPU_PORT) + continue; + vsc->forward_map[i] &= VSC73XX_SRCMASKS_PORTS_MASK & ~BIT(port); + } + vsc->forward_map[port] = VSC73XX_SRCMASKS_PORTS_MASK & BIT(CPU_PORT); + + vsc73xx_update_forwarding_map(vsc); + dsa_tag_8021q_bridge_leave(ds, port, bridge); +} + static int vsc73xx_tag_8021q_vlan_add(struct dsa_switch *ds, int port, u16 vid, u16 flags) { @@ -1342,6 +1408,7 @@ static int vsc73xx_setup(struct dsa_switch *ds) ds->vlan_filtering_is_global = false; ds->configure_vlan_while_not_filtering = false; + ds->max_num_bridges = 7; /* Issue RESET */ vsc73xx_write(vsc, VSC73XX_BLOCK_SYSTEM, 0, VSC73XX_GLORESET, @@ -1452,6 +1519,8 @@ static const struct dsa_switch_ops vsc73xx_ds_ops = { .get_sset_count = vsc73xx_get_sset_count, .port_enable = vsc73xx_port_enable, .port_disable = vsc73xx_port_disable, + .port_bridge_join = vsc73xx_port_bridge_join, + .port_bridge_leave = vsc73xx_port_bridge_leave, .port_change_mtu = vsc73xx_change_mtu, .port_max_mtu = vsc73xx_get_max_mtu, .port_stp_state_set = vsc73xx_port_stp_state_set, From patchwork Sun Jun 25 11:53:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pawel Dembicki X-Patchwork-Id: 13291943 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0F56063B4 for ; Sun, 25 Jun 2023 11:54:59 +0000 (UTC) Received: from mail-lj1-x230.google.com (mail-lj1-x230.google.com [IPv6:2a00:1450:4864:20::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4A198E4E; Sun, 25 Jun 2023 04:54:56 -0700 (PDT) Received: by mail-lj1-x230.google.com with SMTP id 38308e7fff4ca-2b69ff54321so1270811fa.2; Sun, 25 Jun 2023 04:54:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687694094; x=1690286094; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=60Zazpocf6dvO7NBzRzsiGBzkHiKo0Zq0HLMlrfAmUs=; b=T9RvxzdXg42/05gDV629CPCIeBkFUTVZE/ckXCF4kVClsItOTXYuj7qB5dw53vtK/+ 80Ul3yLadV+wNgPXxHucIs5zyBTyFMS4EHLS963dOF9NN+9Ni8YWN81jdkBjJmnEEo/H GlSP7obO1LG5IItwhGDpGqVxIyWFBdOw0HZNcGqzBQ88Rdw2VF75NTFJdlq68X4dCBg/ bM1TODTxseOo4WgvuFmQXNF2sh/jEFPDLGQGXhZl5ysBf74ZPLQ+RsH0m0dbdMuQMKDO h2QsemTYGUbVUYA08Gd2bqNuk9GGWp/SOzdgPM0w6/lHbr28NdAYXDvupdqYino1Ua1A ufIQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687694094; x=1690286094; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=60Zazpocf6dvO7NBzRzsiGBzkHiKo0Zq0HLMlrfAmUs=; b=f9ELhFpWLeuI7BnJvYtGMvfO4y1XnvD0hWAn6zHrhIVyRTRyfWuIEuBZevFb2JaY4Q l4mqmTcfd9l9c7RMLLMb61iZ7niP67pjwnOix8b25NkZjr+KkwIZnlpzGvwgRtT1ZIiV 2QJpRqkUV+5LscpSO7CXp1bZl005ls2/FvhSYwO+LmHO38lOjSkDGx39Zyl7paY8iMCW mT6FP+mdk2MK/G9SKwB5FnSiqO5eVIb7Du4xhXtigwVz+t2LYZxGxUXMVKjh9qj3AmEW 7TK/+CYAM56mxpABjLK2Tk37+AzzxTHSWSVcfUsP2pQxFCWxw+GmYO5xsb3tOecQzOfP Fu5g== X-Gm-Message-State: AC+VfDxVXOUseLbFvrH3hSbwWG75noOZ1lE1DlAiClYWWqeuTfI6ULTk S98e2Kv3d2NKIcbQ8nJ/Zg/HunoduIHj+A== X-Google-Smtp-Source: ACHHUZ7ueOqiC+Xuh9d0k0eXYn0vBQ9cNSl2fyWjxWlcUVyDkE4ZQwhgx3sF5qzoI1hXM9UAuO3qbg== X-Received: by 2002:a2e:9f57:0:b0:2b6:99a3:c256 with SMTP id v23-20020a2e9f57000000b002b699a3c256mr848906ljk.38.1687694094148; Sun, 25 Jun 2023 04:54:54 -0700 (PDT) Received: from WBEC325.dom.local ([185.188.71.122]) by smtp.gmail.com with ESMTPSA id w21-20020a2e9595000000b002b6993b9665sm416043ljh.65.2023.06.25.04.54.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:54:53 -0700 (PDT) From: Pawel Dembicki To: netdev@vger.kernel.org Cc: Pawel Dembicki , Linus Walleij , Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 6/7] net: dsa: vsc73xx: Add vlan filtering Date: Sun, 25 Jun 2023 13:53:41 +0200 Message-Id: <20230625115343.1603330-6-paweldembicki@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230625115343.1603330-1-paweldembicki@gmail.com> References: <20230625115343.1603330-1-paweldembicki@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org This patch implement vlan filtering for vsc73xx driver. After vlan filtering start, switch is reconfigured from QinQ to simple vlan aware mode. It's required, because VSC73XX chips haven't support for inner vlan tag filter. Reviewed-by: Linus Walleij Signed-off-by: Pawel Dembicki --- v2: - no changes done drivers/net/dsa/vitesse-vsc73xx-core.c | 101 +++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c index 457eb7fddf4c..c946464489ab 100644 --- a/drivers/net/dsa/vitesse-vsc73xx-core.c +++ b/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -1226,6 +1226,30 @@ static int vsc73xx_port_set_double_vlan_aware(struct dsa_switch *ds, int port) return ret; } +static int +vsc73xx_port_vlan_filtering(struct dsa_switch *ds, int port, + bool vlan_filtering, struct netlink_ext_ack *extack) +{ + int ret, i; + + if (vlan_filtering) { + vsc73xx_port_set_vlan_conf(ds, port, VSC73XX_VLAN_AWARE); + } else { + if (port == CPU_PORT) + vsc73xx_port_set_vlan_conf(ds, port, VSC73XX_DOUBLE_VLAN_CPU_AWARE); + else + vsc73xx_port_set_vlan_conf(ds, port, VSC73XX_DOUBLE_VLAN_AWARE); + } + + for (i = 0; i <= 3072; i++) { + ret = vsc73xx_port_update_vlan_table(ds, port, i, 0); + if (ret) + return ret; + } + + return ret; +} + static int vsc73xx_vlan_set_untagged(struct dsa_switch *ds, int port, u16 vid, bool port_vlan) { @@ -1304,6 +1328,80 @@ static int vsc73xx_vlan_set_pvid(struct dsa_switch *ds, int port, u16 vid, return 0; } +static int vsc73xx_port_vlan_add(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan, + struct netlink_ext_ack *extack) +{ + bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED; + bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID; + int ret; + + /* Be sure to deny alterations to the configuration done by tag_8021q. + */ + if (vid_is_dsa_8021q(vlan->vid)) { + NL_SET_ERR_MSG_MOD(extack, + "Range 3072-4095 reserved for dsa_8021q operation"); + return -EBUSY; + } + + if (untagged && port != CPU_PORT) { + ret = vsc73xx_vlan_set_untagged(ds, port, vlan->vid, true); + if (ret) + return ret; + } + if (pvid && port != CPU_PORT) { + ret = vsc73xx_vlan_set_pvid(ds, port, vlan->vid, true); + if (ret) + return ret; + } + + ret = vsc73xx_port_update_vlan_table(ds, port, vlan->vid, 1); + + return ret; +} + +static int vsc73xx_port_vlan_del(struct dsa_switch *ds, int port, + const struct switchdev_obj_port_vlan *vlan) +{ + struct vsc73xx *vsc = ds->priv; + u16 vlan_no; + int ret; + u32 val; + + ret = + vsc73xx_port_update_vlan_table(ds, port, vlan->vid, 0); + if (ret) + return ret; + + vsc73xx_read(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_TXUPDCFG, &val); + + if (val & VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_ENA) { + vsc73xx_read(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_TXUPDCFG, &val); + vlan_no = (val & VSC73XX_TXUPDCFG_TX_UNTAGGED_VID) >> + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_SHIFT; + if (vlan_no == vlan->vid) { + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_TXUPDCFG, + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID_ENA, + 0); + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_TXUPDCFG, + VSC73XX_TXUPDCFG_TX_UNTAGGED_VID, 0); + } + } + + vsc73xx_read(vsc, VSC73XX_BLOCK_MAC, port, VSC73XX_CAT_PORT_VLAN, &val); + vlan_no = val & VSC73XX_CAT_PORT_VLAN_VLAN_VID; + if (vlan_no && vlan_no == vlan->vid) { + vsc73xx_update_bits(vsc, VSC73XX_BLOCK_MAC, port, + VSC73XX_CAT_PORT_VLAN, + VSC73XX_CAT_PORT_VLAN_VLAN_VID, 0); + } + + return 0; +} + static void vsc73xx_update_forwarding_map(struct vsc73xx *vsc) { int i; @@ -1524,6 +1622,9 @@ static const struct dsa_switch_ops vsc73xx_ds_ops = { .port_change_mtu = vsc73xx_change_mtu, .port_max_mtu = vsc73xx_get_max_mtu, .port_stp_state_set = vsc73xx_port_stp_state_set, + .port_vlan_filtering = vsc73xx_port_vlan_filtering, + .port_vlan_add = vsc73xx_port_vlan_add, + .port_vlan_del = vsc73xx_port_vlan_del, .tag_8021q_vlan_add = vsc73xx_tag_8021q_vlan_add, .tag_8021q_vlan_del = vsc73xx_tag_8021q_vlan_del, }; From patchwork Sun Jun 25 11:53:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pawel Dembicki X-Patchwork-Id: 13291942 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DFC4B613E for ; Sun, 25 Jun 2023 11:54:59 +0000 (UTC) Received: from mail-lj1-x232.google.com (mail-lj1-x232.google.com [IPv6:2a00:1450:4864:20::232]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 516FBE48; Sun, 25 Jun 2023 04:54:57 -0700 (PDT) Received: by mail-lj1-x232.google.com with SMTP id 38308e7fff4ca-2b5c231c23aso12764271fa.0; Sun, 25 Jun 2023 04:54:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1687694095; x=1690286095; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=P92bWlxvLPvIdpok+J0oz+l7hsQ5ESNWmNXsRKJJM8U=; b=STvo+L/c9+EnsmIy2Q9jnhy6YYDwi6zoMcibgrPcSEQZ/aBQ8/zDHtHOha+wENbtyh 5UpKnBR+3SU5/3C3AfNimfM4PjctTRUeMKhsY6+o+VPMFX/Wow3w/FfG3FgfuZY8fUnf 8qLHgPd63fcyTfFWl0UHFqTCvrdkPGN4vTBC+4nFnkuhH2wCmYVjnPeZwazkiYoIvY4K ftlkFAcKW+gE9f924mujEyhGrhKJmrCVLpmwoNUhhZAsxnt0VMrixuQY8q3yCQlxk8LQ 5mkatJ1fn3XdXK631rt4y7CdQ4hX3dm0xBrbIZiILOcE4YweosO7CmV2O8xtQcphr/DF vXeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687694095; x=1690286095; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=P92bWlxvLPvIdpok+J0oz+l7hsQ5ESNWmNXsRKJJM8U=; b=PZkzB5xnLjWSLIf0FOc25jXkOFRHEqIlNg3eyFrcYlDLBUngn9ifBxWcPk+u7pSpbc aG6HaUUtrpW2f4ZT/UQFpmpYKRwYdi7MPRT7AnvoL7kqgUzJoSUdhqmO3yxLtRV6IwKt c/5Hw1bA+jUIgisUuF6vQEjC9CUA/FNNAbx+j69JGNBHikb/5+N1abSgjIF+wvyOHun8 JwEBh3bZoIMYTdDOlM4iDlhx/OcpKlBGUhRnuqK5+pRauEKOhN1MH4nemrzbFV2mN7tO 7pKm3uKaC05JHYK0I3I51y5QTCfrlGXpZDO459UVsWJWK9q7PvkA2nFegQO7ec2I6PDq s6ig== X-Gm-Message-State: AC+VfDwnZk0YgQ/Gbs4d+31zDrVRyJSnSVQCSIX+UT9fJEiCJnV3IMnj 8H2WEaKLsK4yGRDWilbganmjCSHZitJ6oA== X-Google-Smtp-Source: ACHHUZ5W5Q5IDS5hMK/BmnU3K/CHXC8OrnfQXZO4x1oulh718H1qzA4mObooRGJsOIlXPFLgLlKoZA== X-Received: by 2002:a2e:9d59:0:b0:2b4:6e21:637d with SMTP id y25-20020a2e9d59000000b002b46e21637dmr12426985ljj.35.1687694095170; Sun, 25 Jun 2023 04:54:55 -0700 (PDT) Received: from WBEC325.dom.local ([185.188.71.122]) by smtp.gmail.com with ESMTPSA id w21-20020a2e9595000000b002b6993b9665sm416043ljh.65.2023.06.25.04.54.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:54:54 -0700 (PDT) From: Pawel Dembicki To: netdev@vger.kernel.org Cc: Pawel Dembicki , Linus Walleij , Andrew Lunn , Florian Fainelli , Vladimir Oltean , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 7/7] net: dsa: vsc73xx: fix MTU configuration Date: Sun, 25 Jun 2023 13:53:42 +0200 Message-Id: <20230625115343.1603330-7-paweldembicki@gmail.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230625115343.1603330-1-paweldembicki@gmail.com> References: <20230625115343.1603330-1-paweldembicki@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org Switch in MAXLEN register store maximum size of data frame. MTU size is 18 bytes smaller than frame size. Current settings causes problems with packet forwarding. This patch fix MTU settings to proper values. Fixes: fb77ffc6ec86 ("net: dsa: vsc73xx: make the MTU configurable") Reviewed-by: Linus Walleij Signed-off-by: Pawel Dembicki --- v2: - fix commit message style issue drivers/net/dsa/vitesse-vsc73xx-core.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/net/dsa/vitesse-vsc73xx-core.c b/drivers/net/dsa/vitesse-vsc73xx-core.c index c946464489ab..59bb3dbe780a 100644 --- a/drivers/net/dsa/vitesse-vsc73xx-core.c +++ b/drivers/net/dsa/vitesse-vsc73xx-core.c @@ -979,17 +979,18 @@ static int vsc73xx_change_mtu(struct dsa_switch *ds, int port, int new_mtu) struct vsc73xx *vsc = ds->priv; return vsc73xx_write(vsc, VSC73XX_BLOCK_MAC, port, - VSC73XX_MAXLEN, new_mtu); + VSC73XX_MAXLEN, new_mtu + ETH_HLEN + ETH_FCS_LEN); } /* According to application not "VSC7398 Jumbo Frames" setting - * up the MTU to 9.6 KB does not affect the performance on standard + * up the frame size to 9.6 KB does not affect the performance on standard * frames. It is clear from the application note that * "9.6 kilobytes" == 9600 bytes. */ static int vsc73xx_get_max_mtu(struct dsa_switch *ds, int port) { - return 9600; + /* max mtu = 9600 - ETH_HLEN - ETH_FCS_LEN */ + return 9582; } static void vsc73xx_port_stp_state_set(struct dsa_switch *ds, int port,