From patchwork Sun May 8 22:48:45 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hauke Mehrtens X-Patchwork-Id: 12842962 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98B47C433F5 for ; Sun, 8 May 2022 22:49:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233398AbiEHWxa (ORCPT ); Sun, 8 May 2022 18:53:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43162 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229790AbiEHWx3 (ORCPT ); Sun, 8 May 2022 18:53:29 -0400 Received: from mout-p-101.mailbox.org (mout-p-101.mailbox.org [IPv6:2001:67c:2050:0:465::101]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A64C03896 for ; Sun, 8 May 2022 15:49:36 -0700 (PDT) Received: from smtp1.mailbox.org (smtp1.mailbox.org [10.196.197.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4KxKHd2hGQz9sQp; Mon, 9 May 2022 00:49:33 +0200 (CEST) From: Hauke Mehrtens DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hauke-m.de; s=MBO0001; t=1652050171; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=w15Bl0kWKh9ytJ0DDSsmIBoP7JeJ85M+oT79ZYhI1hg=; b=TUCCIe8TFGF0OdV6A21Ddz7RuDjVrQzWVHx03Fr3XUzMlcj+X3c0FdqXj3uumOg+U32PkS 3ep1cmWZ4zE12NnO5jEG66UxK4wwmN4C315vgp28kADseVDKE1wH3kF/JNlpFsKeCjLh2F kUipEKQwO7X0Z2jIR6jmtD0fUPyjRtr443SK4ymzE+GLEW2P024FE6jC2soauHdlRWsPRR 2iL5myc/Ug2YpkcgfO6B4h5EgwUMYlDCdTCyZOhNPCs6CiUFV3w1yDfKkaDyasV3XWb4d3 GO50wmmrcr/GZdIGb7UK5ABSAvmt1tWVkNMndMd/EQWIcuQsU9zR8v/4PNwWNw== To: davem@davemloft.net, kuba@kernel.org Cc: linus.walleij@linaro.org, alsi@bang-olufsen.dk, andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, netdev@vger.kernel.org, Hauke Mehrtens Subject: [PATCH 1/4] net: dsa: realtek: rtl8365mb: Fix interface type mask Date: Mon, 9 May 2022 00:48:45 +0200 Message-Id: <20220508224848.2384723-2-hauke@hauke-m.de> In-Reply-To: <20220508224848.2384723-1-hauke@hauke-m.de> References: <20220508224848.2384723-1-hauke@hauke-m.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The mask should be shifted like the offset. Signed-off-by: Hauke Mehrtens Reviewed-by: Alvin Šipraga --- drivers/net/dsa/realtek/rtl8365mb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c index 3d70e8a77ecf..2cb722a9e096 100644 --- a/drivers/net/dsa/realtek/rtl8365mb.c +++ b/drivers/net/dsa/realtek/rtl8365mb.c @@ -237,7 +237,7 @@ static const int rtl8365mb_extint_port_map[] = { -1, -1, -1, -1, -1, -1, 1, 2, (_extint) == 2 ? RTL8365MB_DIGITAL_INTERFACE_SELECT_REG1 : \ 0x0) #define RTL8365MB_DIGITAL_INTERFACE_SELECT_MODE_MASK(_extint) \ - (0xF << (((_extint) % 2))) + (0xF << (((_extint) % 2) * 4)) #define RTL8365MB_DIGITAL_INTERFACE_SELECT_MODE_OFFSET(_extint) \ (((_extint) % 2) * 4) From patchwork Sun May 8 22:48:46 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hauke Mehrtens X-Patchwork-Id: 12842964 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 90E44C433FE for ; Sun, 8 May 2022 22:49:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233401AbiEHWxc (ORCPT ); Sun, 8 May 2022 18:53:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43180 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233382AbiEHWxa (ORCPT ); Sun, 8 May 2022 18:53:30 -0400 Received: from mout-p-101.mailbox.org (mout-p-101.mailbox.org [IPv6:2001:67c:2050:0:465::101]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 36175DEB7 for ; Sun, 8 May 2022 15:49:38 -0700 (PDT) Received: from smtp1.mailbox.org (smtp1.mailbox.org [10.196.197.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4KxKHf5JzYz9sQG; Mon, 9 May 2022 00:49:34 +0200 (CEST) From: Hauke Mehrtens DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hauke-m.de; s=MBO0001; t=1652050172; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Vk2eisPI/VyxABU4xjO9Q/GhOq1Ba18tj/qKipBo7/M=; b=fVgwp7dOGycFxxXfg/ctj1G1kIe7sELJLSWb0UcrdPXsxyfD1g+PcPV819oZBKyX8dLvFH WaAq3WjFDc6Y4uLPAEERRb60LRxZOKcxYKpjhXeXrM4ooCXTzOivHJiZUk9VokM8jrDvXY C1mLku370BGAQUPHhDR02F96dJk/9raAZTyb5D29yVsrextusm3E9B8vrrrMCWpXKveLlU FNebelK5YtYoF2sSGBV1+Xmg2Ut5poL2HjTBb20oAiDjRw9KfJp36OqWAMcpiYizZWq/Ib 3EPFKiWyNfNioZlC6sOXDai7UGalN2JAvj0hwZXrzkxQuXe1whb4sepEwk2CiQ== To: davem@davemloft.net, kuba@kernel.org Cc: linus.walleij@linaro.org, alsi@bang-olufsen.dk, andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, netdev@vger.kernel.org, Hauke Mehrtens Subject: [PATCH 2/4] net: dsa: realtek: rtl8365mb: Get chip option Date: Mon, 9 May 2022 00:48:46 +0200 Message-Id: <20220508224848.2384723-3-hauke@hauke-m.de> In-Reply-To: <20220508224848.2384723-1-hauke@hauke-m.de> References: <20220508224848.2384723-1-hauke@hauke-m.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org Read the option register in addition to the other registers to identify the chip. The SGMII initialization is different for the different chip options. Signed-off-by: Hauke Mehrtens --- drivers/net/dsa/realtek/rtl8365mb.c | 43 +++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c index 2cb722a9e096..be64cfdeccc7 100644 --- a/drivers/net/dsa/realtek/rtl8365mb.c +++ b/drivers/net/dsa/realtek/rtl8365mb.c @@ -127,6 +127,9 @@ static const int rtl8365mb_extint_port_map[] = { -1, -1, -1, -1, -1, -1, 1, 2, #define RTL8365MB_CHIP_VER_REG 0x1301 +#define RTL8365MB_CHIP_OPTION_REG 0x13C1 + +#define RTL8365MB_MAGIC_OPT_REG 0x13C0 #define RTL8365MB_MAGIC_REG 0x13C2 #define RTL8365MB_MAGIC_VALUE 0x0249 @@ -579,6 +582,7 @@ struct rtl8365mb { int irq; u32 chip_id; u32 chip_ver; + u32 chip_option; u32 port_mask; u32 learn_limit_max; struct rtl8365mb_cpu cpu; @@ -1959,7 +1963,7 @@ static void rtl8365mb_teardown(struct dsa_switch *ds) rtl8365mb_irq_teardown(priv); } -static int rtl8365mb_get_chip_id_and_ver(struct regmap *map, u32 *id, u32 *ver) +static int rtl8365mb_get_chip_id_and_ver(struct regmap *map, u32 *id, u32 *ver, u32 *option) { int ret; @@ -1983,6 +1987,19 @@ static int rtl8365mb_get_chip_id_and_ver(struct regmap *map, u32 *id, u32 *ver) if (ret) return ret; + ret = regmap_write(map, RTL8365MB_MAGIC_OPT_REG, RTL8365MB_MAGIC_VALUE); + if (ret) + return ret; + + ret = regmap_read(map, RTL8365MB_CHIP_OPTION_REG, option); + if (ret) + return ret; + + /* Reset magic register */ + ret = regmap_write(map, RTL8365MB_MAGIC_OPT_REG, 0); + if (ret) + return ret; + return 0; } @@ -1991,9 +2008,10 @@ static int rtl8365mb_detect(struct realtek_priv *priv) struct rtl8365mb *mb = priv->chip_data; u32 chip_id; u32 chip_ver; + u32 chip_option; int ret; - ret = rtl8365mb_get_chip_id_and_ver(priv->map, &chip_id, &chip_ver); + ret = rtl8365mb_get_chip_id_and_ver(priv->map, &chip_id, &chip_ver, &chip_option); if (ret) { dev_err(priv->dev, "failed to read chip id and version: %d\n", ret); @@ -2005,22 +2023,22 @@ static int rtl8365mb_detect(struct realtek_priv *priv) switch (chip_ver) { case RTL8365MB_CHIP_VER_8365MB_VC: dev_info(priv->dev, - "found an RTL8365MB-VC switch (ver=0x%04x)\n", - chip_ver); + "found an RTL8365MB-VC switch (ver=0x%04x, opt=0x%04x)\n", + chip_ver, chip_option); break; case RTL8365MB_CHIP_VER_8367RB: dev_info(priv->dev, - "found an RTL8367RB-VB switch (ver=0x%04x)\n", - chip_ver); + "found an RTL8367RB-VB switch (ver=0x%04x, opt=0x%04x)\n", + chip_ver, chip_option); break; case RTL8365MB_CHIP_VER_8367S: dev_info(priv->dev, - "found an RTL8367S switch (ver=0x%04x)\n", - chip_ver); + "found an RTL8367S switch (ver=0x%04x, opt=0x%04x)\n", + chip_ver, chip_option); break; default: - dev_err(priv->dev, "unrecognized switch version (ver=0x%04x)", - chip_ver); + dev_err(priv->dev, "unrecognized switch version (ver=0x%04x, opt=0x%04x)", + chip_ver, chip_option); return -ENODEV; } @@ -2029,6 +2047,7 @@ static int rtl8365mb_detect(struct realtek_priv *priv) mb->priv = priv; mb->chip_id = chip_id; mb->chip_ver = chip_ver; + mb->chip_option = chip_option; mb->port_mask = GENMASK(priv->num_ports - 1, 0); mb->learn_limit_max = RTL8365MB_LEARN_LIMIT_MAX; mb->jam_table = rtl8365mb_init_jam_8365mb_vc; @@ -2043,8 +2062,8 @@ static int rtl8365mb_detect(struct realtek_priv *priv) break; default: dev_err(priv->dev, - "found an unknown Realtek switch (id=0x%04x, ver=0x%04x)\n", - chip_id, chip_ver); + "found an unknown Realtek switch (id=0x%04x, ver=0x%04x, opt=0x%04x)\n", + chip_id, chip_ver, chip_option); return -ENODEV; } From patchwork Sun May 8 22:48:47 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hauke Mehrtens X-Patchwork-Id: 12842966 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D43FAC433EF for ; Sun, 8 May 2022 22:49:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233437AbiEHWxf (ORCPT ); Sun, 8 May 2022 18:53:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43196 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233405AbiEHWxc (ORCPT ); Sun, 8 May 2022 18:53:32 -0400 Received: from mout-p-202.mailbox.org (mout-p-202.mailbox.org [IPv6:2001:67c:2050:0:465::202]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3EDCB3896 for ; Sun, 8 May 2022 15:49:39 -0700 (PDT) Received: from smtp1.mailbox.org (smtp1.mailbox.org [10.196.197.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 4KxKHg4np3z9swV; Mon, 9 May 2022 00:49:35 +0200 (CEST) From: Hauke Mehrtens DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hauke-m.de; s=MBO0001; t=1652050173; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/LpIvSbdSirR439IcRLy27XAI6T3D+Euff6M1MgxD9Y=; b=sz3bDuhE0zqbDFLXKDxN2Y1ookQ4D0thvC+WiK9psjqx3QJmjma1PFl9/BKJbD/YEwFzvo Ryxa0d4Usi3A4bQrWKLMeyKTA61GnkfhDv2O0RMdRXtNVKk6aXq/o88Mcbey8tOwtK+lQx hCb2Z6/LvYEAaWDsY+x1rJumYv5iIYiOO9cmStT5ODnFcuiixbZ3J/bGT5mAqif5PHATIn efEoKmUg3KzURZNS0j5WA6oD2pkEmmGn3PVV+LTYmGgk6M8ViAStrAgUCsNTiK+HiQ6M87 ge95i1XP3aBQxuK38PuiKkUAB40A9nL7wPZ2QvXEN63yHTkbvjKnouJ5MkK7LQ== To: davem@davemloft.net, kuba@kernel.org Cc: linus.walleij@linaro.org, alsi@bang-olufsen.dk, andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, netdev@vger.kernel.org, Hauke Mehrtens Subject: [PATCH 3/4] net: dsa: realtek: rtl8365mb: Add setting MTU Date: Mon, 9 May 2022 00:48:47 +0200 Message-Id: <20220508224848.2384723-4-hauke@hauke-m.de> In-Reply-To: <20220508224848.2384723-1-hauke@hauke-m.de> References: <20220508224848.2384723-1-hauke@hauke-m.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org The switch does not support per port MTU setting, but only a MRU setting. Implement this by setting the MTU on the CPU port. Without this patch the MRU was always set to 1536, not it is set by the DSA subsystem and the user scan change it. Signed-off-by: Hauke Mehrtens --- drivers/net/dsa/realtek/rtl8365mb.c | 43 ++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c index be64cfdeccc7..f9b690251155 100644 --- a/drivers/net/dsa/realtek/rtl8365mb.c +++ b/drivers/net/dsa/realtek/rtl8365mb.c @@ -1132,6 +1132,38 @@ static int rtl8365mb_port_set_isolation(struct realtek_priv *priv, int port, return regmap_write(priv->map, RTL8365MB_PORT_ISOLATION_REG(port), mask); } +static int rtl8365mb_port_change_mtu(struct dsa_switch *ds, int port, + int new_mtu) +{ + struct dsa_port *dp = dsa_to_port(ds, port); + struct realtek_priv *priv = ds->priv; + int length; + + /* When a new MTU is set, DSA always set the CPU port's MTU to the + * largest MTU of the slave ports. Because the switch only has a global + * RX length register, only allowing CPU port here is enough. + */ + if (!dsa_is_cpu_port(ds, port)) + return 0; + + length = new_mtu + ETH_HLEN + ETH_FCS_LEN; + length += dp->tag_ops->needed_headroom; + length += dp->tag_ops->needed_tailroom; + + if (length > RTL8365MB_CFG0_MAX_LEN_MASK) + return -EINVAL; + + return regmap_update_bits(priv->map, RTL8365MB_CFG0_MAX_LEN_REG, + RTL8365MB_CFG0_MAX_LEN_MASK, + FIELD_PREP(RTL8365MB_CFG0_MAX_LEN_MASK, + length)); +} + +static int rtl8365mb_port_max_mtu(struct dsa_switch *ds, int port) +{ + return RTL8365MB_CFG0_MAX_LEN_MASK - ETH_HLEN - ETH_FCS_LEN - 8; +} + static int rtl8365mb_mib_counter_read(struct realtek_priv *priv, int port, u32 offset, u32 length, u64 *mibvalue) { @@ -1928,13 +1960,6 @@ static int rtl8365mb_setup(struct dsa_switch *ds) p->index = i; } - /* Set maximum packet length to 1536 bytes */ - ret = regmap_update_bits(priv->map, RTL8365MB_CFG0_MAX_LEN_REG, - RTL8365MB_CFG0_MAX_LEN_MASK, - FIELD_PREP(RTL8365MB_CFG0_MAX_LEN_MASK, 1536)); - if (ret) - goto out_teardown_irq; - if (priv->setup_interface) { ret = priv->setup_interface(ds); if (ret) { @@ -2080,6 +2105,8 @@ static const struct dsa_switch_ops rtl8365mb_switch_ops_smi = { .phylink_mac_link_down = rtl8365mb_phylink_mac_link_down, .phylink_mac_link_up = rtl8365mb_phylink_mac_link_up, .port_stp_state_set = rtl8365mb_port_stp_state_set, + .port_change_mtu = rtl8365mb_port_change_mtu, + .port_max_mtu = rtl8365mb_port_max_mtu, .get_strings = rtl8365mb_get_strings, .get_ethtool_stats = rtl8365mb_get_ethtool_stats, .get_sset_count = rtl8365mb_get_sset_count, @@ -2101,6 +2128,8 @@ static const struct dsa_switch_ops rtl8365mb_switch_ops_mdio = { .phy_read = rtl8365mb_dsa_phy_read, .phy_write = rtl8365mb_dsa_phy_write, .port_stp_state_set = rtl8365mb_port_stp_state_set, + .port_change_mtu = rtl8365mb_port_change_mtu, + .port_max_mtu = rtl8365mb_port_max_mtu, .get_strings = rtl8365mb_get_strings, .get_ethtool_stats = rtl8365mb_get_ethtool_stats, .get_sset_count = rtl8365mb_get_sset_count, From patchwork Sun May 8 22:48:48 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Hauke Mehrtens X-Patchwork-Id: 12842965 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B29A6C4332F for ; Sun, 8 May 2022 22:49:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233384AbiEHWxd (ORCPT ); Sun, 8 May 2022 18:53:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233391AbiEHWxa (ORCPT ); Sun, 8 May 2022 18:53:30 -0400 Received: from mout-p-101.mailbox.org (mout-p-101.mailbox.org [IPv6:2001:67c:2050:0:465::101]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6563DDEB9 for ; Sun, 8 May 2022 15:49:38 -0700 (PDT) Received: from smtp1.mailbox.org (smtp1.mailbox.org [IPv6:2001:67c:2050:b231:465::1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (P-384) server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-101.mailbox.org (Postfix) with ESMTPS id 4KxKHj06yPz9sTC; Mon, 9 May 2022 00:49:37 +0200 (CEST) From: Hauke Mehrtens DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=hauke-m.de; s=MBO0001; t=1652050175; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dkXcTENQtIAeneycUG2bE+HIcmONCcRyiCk1d9LCYZ4=; b=z+8sDvy5EeoXxlRNvzZ902wRmAG50mRfk6rhS1Xkr86vylnNnybPapqC/s4ZAK/Xp+Vmgw zsNAl5wyIafFQIjlo4GhbZ2fD2fQT0dE6G3QGkc2uut7XfEnh7pI/4Hr6kAT6nUp+yLVG2 Sb2eex1PsknBP01nDQ/AxN78xBIeVcyp1Eyhj6/Zqjog8OrZMzBTMex/b3qy0D37wV51Th 584SJulYxP723V2hlcm1Ud6gCKui0g27biVerM8M4QwAMbChLxhN9vwBoi8OFGIWGf2g/p v5OPp4ORU8DKvqrVjt2NVChLygqRFGWsHMk92HvJpkpiq1MpQYu7UgAZEiXvEg== To: davem@davemloft.net, kuba@kernel.org Cc: linus.walleij@linaro.org, alsi@bang-olufsen.dk, andrew@lunn.ch, vivien.didelot@gmail.com, f.fainelli@gmail.com, olteanv@gmail.com, netdev@vger.kernel.org, Hauke Mehrtens Subject: [PATCH 4/4] net: dsa: realtek: rtl8365mb: Add SGMII and HSGMII support Date: Mon, 9 May 2022 00:48:48 +0200 Message-Id: <20220508224848.2384723-5-hauke@hauke-m.de> In-Reply-To: <20220508224848.2384723-1-hauke@hauke-m.de> References: <20220508224848.2384723-1-hauke@hauke-m.de> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org This adds support for SGMII and HSGMII on RTL8367S switches. HSGMII is configured using the 2500BASEX mode. This is baed on the rtl8367c driver found in OpenWrt. For (H)SGMII mode we have to load a firmware into some memory which gets executed on the integrated 8051. The firmware binary was added as a array into the driver with a GPL license notice on top. This was tested on RTL8367S (ver=0x00a0, opt=0x0001). Signed-off-by: Hauke Mehrtens --- drivers/net/dsa/realtek/rtl8365mb.c | 356 +++++++++++++++++++++++++++- 1 file changed, 345 insertions(+), 11 deletions(-) diff --git a/drivers/net/dsa/realtek/rtl8365mb.c b/drivers/net/dsa/realtek/rtl8365mb.c index f9b690251155..5504a34fffeb 100644 --- a/drivers/net/dsa/realtek/rtl8365mb.c +++ b/drivers/net/dsa/realtek/rtl8365mb.c @@ -3,6 +3,7 @@ * * Copyright (C) 2021 Alvin Šipraga * Copyright (C) 2021 Michael Rasmussen + * Copyright (C) 2022 Hauke Mehrtens * * The RTL8365MB-VC is a 4+1 port 10/100/1000M switch controller. It includes 4 * integrated PHYs for the user facing ports, and an extension interface which @@ -98,6 +99,7 @@ #include #include #include +#include #include "realtek.h" @@ -135,6 +137,7 @@ static const int rtl8365mb_extint_port_map[] = { -1, -1, -1, -1, -1, -1, 1, 2, /* Chip reset register */ #define RTL8365MB_CHIP_RESET_REG 0x1322 +#define RTL8365MB_CHIP_RESET_DW8051 BIT(4) #define RTL8365MB_CHIP_RESET_SW_MASK 0x0002 #define RTL8365MB_CHIP_RESET_HW_MASK 0x0001 @@ -278,6 +281,29 @@ static const int rtl8365mb_extint_port_map[] = { -1, -1, -1, -1, -1, -1, 1, 2, #define RTL8365MB_DIGITAL_INTERFACE_FORCE_DUPLEX_MASK 0x0004 #define RTL8365MB_DIGITAL_INTERFACE_FORCE_SPEED_MASK 0x0003 +#define RTL8365MB_SDS_MISC 0x1d11 +#define RTL8365MB_CFG_SGMII_RXFC 0x4000 +#define RTL8365MB_CFG_SGMII_TXFC 0x2000 +#define RTL8365MB_INB_ARB 0x1000 +#define RTL8365MB_CFG_MAC8_SEL_HSGMII 0x0800 +#define RTL8365MB_CFG_SGMII_FDUP 0x0400 +#define RTL8365MB_CFG_SGMII_LINK 0x0200 +#define RTL8365MB_CFG_SGMII_SPD 0x0180 +#define RTL8365MB_CFG_MAC8_SEL_SGMII 0x0040 +#define RTL8365MB_CFG_INB_SEL 0x0038 +#define RTL8365MB_CFG_SDS_MODE_18C 0x0007 + +#define RTL8365MB_SDS_INDACS_CMD 0x6600 +#define RTL8365MB_SDS_INDACS_ADR 0x6601 +#define RTL8365MB_SDS_INDACS_DATA 0x6602 + +#define RTL8365MB_MISC_CFG0 0x130c +#define RTL8365MB_MISC_CFG0_DW8051_EN BIT(5) + +#define RTL8365MB_DW8051_RDY 0x1336 +#define RTL8365MB_DW8051_RDY_IROM_MSB BIT(2) +#define RTL8365MB_DW8051_RDY_ACS_IROM_EN BIT(1) + /* CPU port mask register - controls which ports are treated as CPU ports */ #define RTL8365MB_CPU_PORT_MASK_REG 0x1219 #define RTL8365MB_CPU_PORT_MASK_MASK 0x07FF @@ -296,6 +322,8 @@ static const int rtl8365mb_extint_port_map[] = { -1, -1, -1, -1, -1, -1, 1, 2, #define RTL8365MB_CFG0_MAX_LEN_REG 0x088C #define RTL8365MB_CFG0_MAX_LEN_MASK 0x3FFF +#define RTL8365MB_BYPASS_LINE_RATE 0x03f7 + /* Port learning limit registers */ #define RTL8365MB_LUT_PORT_LEARN_LIMIT_BASE 0x0A20 #define RTL8365MB_LUT_PORT_LEARN_LIMIT_REG(_physport) \ @@ -493,6 +521,39 @@ static const struct rtl8365mb_jam_tbl_entry rtl8365mb_init_jam_common[] = { { 0x1D32, 0x0002 }, }; +struct rtl8365mb_sds_init { + unsigned int data; + unsigned int addr; +}; + +static const struct rtl8365mb_sds_init redData[] = { + {0x04D7, 0x0480}, {0xF994, 0x0481}, {0x21A2, 0x0482}, {0x6960, 0x0483}, + {0x9728, 0x0484}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x83F2, 0x002E} +}; + +static const struct rtl8365mb_sds_init redDataSB[] = { + {0x04D7, 0x0480}, {0xF994, 0x0481}, {0x31A2, 0x0482}, {0x6960, 0x0483}, + {0x9728, 0x0484}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x83F2, 0x002E} +}; + +static const struct rtl8365mb_sds_init redData1_5_6[] = { + {0x82F1, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, + {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, + {0x83F2, 0x002E} +}; + +static const struct rtl8365mb_sds_init redData8_9[] = { + {0x82F1, 0x0500}, {0xF995, 0x0501}, {0x31A2, 0x0502}, {0x796C, 0x0503}, + {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, + {0x83F2, 0x002E} +}; + +static const struct rtl8365mb_sds_init redDataHB[] = { + {0x82F0, 0x0500}, {0xF195, 0x0501}, {0x31A2, 0x0502}, {0x7960, 0x0503}, + {0x9728, 0x0504}, {0x9D85, 0x0423}, {0xD810, 0x0424}, {0x0F80, 0x0001}, + {0x83F2, 0x002E} +}; + enum rtl8365mb_stp_state { RTL8365MB_STP_STATE_DISABLED = 0, RTL8365MB_STP_STATE_BLOCKING = 1, @@ -801,6 +862,232 @@ rtl8365mb_get_tag_protocol(struct dsa_switch *ds, int port, return DSA_TAG_PROTO_RTL8_4; } +static int rtl8365mb_sds_indacs_write(struct realtek_priv *priv, unsigned int addr, + unsigned int data) +{ + int ret; + + ret = regmap_write(priv->map, RTL8365MB_SDS_INDACS_DATA, data); + if (ret) + return ret; + + ret = regmap_write(priv->map, RTL8365MB_SDS_INDACS_ADR, addr); + if (ret) + return ret; + + return regmap_write(priv->map, RTL8365MB_SDS_INDACS_CMD, 0x00C0); +} + +static int rtl8365mb_sds_indacs_read(struct realtek_priv *priv, unsigned int addr, + unsigned int *data) +{ + int ret; + + ret = regmap_write(priv->map, RTL8365MB_SDS_INDACS_ADR, addr); + if (ret) + return ret; + + ret = regmap_write(priv->map, RTL8365MB_SDS_INDACS_CMD, 0x00C0); + if (ret) + return ret; + + return regmap_write(priv->map, RTL8365MB_SDS_INDACS_DATA, *data); +} + +static int rtl8365mb_ext_init_sgmii_fw(struct realtek_priv *priv) +{ + struct device *dev = priv->dev; + const struct firmware *fw; + int ret; + int i; + + ret = request_firmware(&fw, "rtl_switch/rtl8367s-sgmii.bin", dev); + if (ret) { + dev_err(dev, "failed to load firmware rtl_switch/rtl8367s-sgmii.bin, error: %i\n", + ret); + return ret; + } + + ret = regmap_update_bits(priv->map, RTL8365MB_CHIP_RESET_REG, + RTL8365MB_CHIP_RESET_DW8051, + FIELD_PREP(RTL8365MB_CHIP_RESET_DW8051, 1)); + if (ret) + goto release_fw; + + ret = regmap_update_bits(priv->map, RTL8365MB_MISC_CFG0, + RTL8365MB_MISC_CFG0_DW8051_EN, + FIELD_PREP(RTL8365MB_MISC_CFG0_DW8051_EN, 1)); + if (ret) + goto release_fw; + + ret = regmap_update_bits(priv->map, RTL8365MB_DW8051_RDY, + RTL8365MB_DW8051_RDY_ACS_IROM_EN, + FIELD_PREP(RTL8365MB_DW8051_RDY_ACS_IROM_EN, 1)); + if (ret) + goto release_fw; + + ret = regmap_update_bits(priv->map, RTL8365MB_DW8051_RDY, + RTL8365MB_DW8051_RDY_IROM_MSB, + FIELD_PREP(RTL8365MB_DW8051_RDY_IROM_MSB, 0)); + if (ret) + goto release_fw; + + for (i = 0; i < fw->size; i++) { + ret = regmap_write(priv->map, 0xE000 + i, fw->data[i]); + if (ret) + goto release_fw; + } + + ret = regmap_update_bits(priv->map, RTL8365MB_DW8051_RDY, + RTL8365MB_DW8051_RDY_IROM_MSB, + FIELD_PREP(RTL8365MB_DW8051_RDY_IROM_MSB, 0)); + if (ret) + goto release_fw; + + ret = regmap_update_bits(priv->map, RTL8365MB_DW8051_RDY, + RTL8365MB_DW8051_RDY_ACS_IROM_EN, + FIELD_PREP(RTL8365MB_DW8051_RDY_ACS_IROM_EN, 0)); + if (ret) + goto release_fw; + + ret = regmap_update_bits(priv->map, RTL8365MB_CHIP_RESET_REG, + RTL8365MB_CHIP_RESET_DW8051, + FIELD_PREP(RTL8365MB_CHIP_RESET_DW8051, 0)); + +release_fw: + release_firmware(fw); + return ret; +} + +static int rtl8365mb_ext_init_sgmii(struct realtek_priv *priv, int port, phy_interface_t interface) +{ + struct rtl8365mb *mb; + int interface_mode; + int sds_mode; + const struct rtl8365mb_sds_init *sds_init; + size_t sds_init_len; + int ext_int; + int ret; + int i; + int val; + int mask; + + mb = priv->chip_data; + + if (mb->chip_id != RTL8365MB_CHIP_ID_8365MB_VC) + return -EINVAL; + + ext_int = rtl8365mb_extint_port_map[port]; + if (ext_int != 1) + return -EINVAL; + + if (interface == PHY_INTERFACE_MODE_SGMII) { + sds_mode = FIELD_PREP(RTL8365MB_CFG_MAC8_SEL_SGMII, 1); + interface_mode = RTL8365MB_EXT_PORT_MODE_SGMII; + + if (mb->chip_option == 0) { + sds_init = redData; + sds_init_len = ARRAY_SIZE(redData); + } else { + sds_init = redDataSB; + sds_init_len = ARRAY_SIZE(redDataSB); + } + } else if (interface == PHY_INTERFACE_MODE_2500BASEX) { + sds_mode = FIELD_PREP(RTL8365MB_CFG_MAC8_SEL_HSGMII, 1); + interface_mode = RTL8365MB_EXT_PORT_MODE_HSGMII; + + if (mb->chip_option == 0) { + switch (mb->chip_ver & 0x00F0) { + case 0x0010: + case 0x0050: + case 0x0060: + sds_init = redData1_5_6; + sds_init_len = ARRAY_SIZE(redData1_5_6); + break; + case 0x0080: + case 0x0090: + sds_init = redData8_9; + sds_init_len = ARRAY_SIZE(redData8_9); + break; + default: + return -EINVAL; + } + } else { + sds_init = redDataHB; + sds_init_len = ARRAY_SIZE(redDataHB); + } + } else { + return -EINVAL; + } + + for (i = 0; i < sds_init_len; i++) { + ret = rtl8365mb_sds_indacs_write(priv, sds_init[i].addr, sds_init[i].data); + if (ret) + return ret; + } + + mask = RTL8365MB_CFG_MAC8_SEL_SGMII | RTL8365MB_CFG_MAC8_SEL_HSGMII; + ret = regmap_update_bits(priv->map, + RTL8365MB_SDS_MISC, + mask, + sds_mode); + if (ret) + return ret; + + mask = RTL8365MB_DIGITAL_INTERFACE_SELECT_MODE_MASK(ext_int); + val = interface_mode << RTL8365MB_DIGITAL_INTERFACE_SELECT_MODE_OFFSET(ext_int); + ret = regmap_update_bits(priv->map, + RTL8365MB_DIGITAL_INTERFACE_SELECT_REG(ext_int), + mask, + val); + if (ret) + return ret; + + ret = regmap_write(priv->map, RTL8365MB_BYPASS_LINE_RATE, 0x0); + if (ret) + return ret; + + /* Serdes not reset */ + ret = rtl8365mb_sds_indacs_write(priv, 0x0003, 0x7106); + if (ret) + return ret; + + return rtl8365mb_ext_init_sgmii_fw(priv); +} + +static int rtl8365mb_ext_sgmii_nway(struct realtek_priv *priv, bool state) +{ + u32 running; + u32 regValue; + int ret; + + ret = regmap_read(priv->map, RTL8365MB_MISC_CFG0, &running); + if (running & RTL8365MB_MISC_CFG0_DW8051_EN) { + ret = regmap_update_bits(priv->map, RTL8365MB_MISC_CFG0, + RTL8365MB_MISC_CFG0_DW8051_EN, + FIELD_PREP(RTL8365MB_MISC_CFG0_DW8051_EN, 0)); + if (ret) + return ret; + } + + ret = rtl8365mb_sds_indacs_read(priv, 0x0002, ®Value); + if (ret) + return ret; + + if (state) + regValue |= 0x0200; + else + regValue &= ~0x0200; + regValue |= 0x0100; + + ret = rtl8365mb_sds_indacs_write(priv, 0x0002, regValue); + if (ret) + return ret; + return regmap_update_bits(priv->map, RTL8365MB_MISC_CFG0, + RTL8365MB_MISC_CFG0_DW8051_EN, + FIELD_PREP(RTL8365MB_MISC_CFG0_DW8051_EN, 1)); +} + static int rtl8365mb_ext_config_rgmii(struct realtek_priv *priv, int port, phy_interface_t interface) { @@ -886,6 +1173,7 @@ static int rtl8365mb_ext_config_rgmii(struct realtek_priv *priv, int port, } static int rtl8365mb_ext_config_forcemode(struct realtek_priv *priv, int port, + phy_interface_t interface, bool link, int speed, int duplex, bool tx_pause, bool rx_pause) { @@ -911,7 +1199,7 @@ static int rtl8365mb_ext_config_forcemode(struct realtek_priv *priv, int port, r_rx_pause = rx_pause ? 1 : 0; r_tx_pause = tx_pause ? 1 : 0; - if (speed == SPEED_1000) { + if (speed == SPEED_1000 || speed == SPEED_2500) { r_speed = RTL8365MB_PORT_SPEED_1000M; } else if (speed == SPEED_100) { r_speed = RTL8365MB_PORT_SPEED_100M; @@ -941,6 +1229,25 @@ static int rtl8365mb_ext_config_forcemode(struct realtek_priv *priv, int port, r_duplex = 0; } + if (interface == PHY_INTERFACE_MODE_SGMII || + interface == PHY_INTERFACE_MODE_2500BASEX) { + val = FIELD_PREP(RTL8365MB_CFG_SGMII_FDUP, r_duplex) | + FIELD_PREP(RTL8365MB_CFG_SGMII_SPD, r_speed) | + FIELD_PREP(RTL8365MB_CFG_SGMII_LINK, r_link) | + FIELD_PREP(RTL8365MB_CFG_SGMII_TXFC, r_tx_pause) | + FIELD_PREP(RTL8365MB_CFG_SGMII_RXFC, r_rx_pause); + ret = regmap_update_bits(priv->map, + RTL8365MB_SDS_MISC, + RTL8365MB_CFG_SGMII_FDUP | + RTL8365MB_CFG_SGMII_SPD | + RTL8365MB_CFG_SGMII_LINK | + RTL8365MB_CFG_SGMII_TXFC | + RTL8365MB_CFG_SGMII_RXFC, + val); + if (ret) + return ret; + } + val = FIELD_PREP(RTL8365MB_DIGITAL_INTERFACE_FORCE_EN_MASK, 1) | FIELD_PREP(RTL8365MB_DIGITAL_INTERFACE_FORCE_TXPAUSE_MASK, r_tx_pause) | @@ -972,10 +1279,15 @@ static bool rtl8365mb_phy_mode_supported(struct dsa_switch *ds, int port, interface == PHY_INTERFACE_MODE_GMII)) /* Internal PHY */ return true; - else if ((ext_int >= 1) && - phy_interface_mode_is_rgmii(interface)) + else if ((ext_int == 1) && + (phy_interface_mode_is_rgmii(interface) || + interface == PHY_INTERFACE_MODE_SGMII || + interface == PHY_INTERFACE_MODE_2500BASEX)) /* Extension MAC */ return true; + else if ((ext_int >= 2) && + phy_interface_mode_is_rgmii(interface)) + return true; return false; } @@ -983,14 +1295,25 @@ static bool rtl8365mb_phy_mode_supported(struct dsa_switch *ds, int port, static void rtl8365mb_phylink_get_caps(struct dsa_switch *ds, int port, struct phylink_config *config) { - if (dsa_is_user_port(ds, port)) + int ext_int = rtl8365mb_extint_port_map[port]; + + config->mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | + MAC_10 | MAC_100 | MAC_1000FD; + + if (dsa_is_user_port(ds, port)) { __set_bit(PHY_INTERFACE_MODE_INTERNAL, config->supported_interfaces); - else if (dsa_is_cpu_port(ds, port)) + } else if (dsa_is_cpu_port(ds, port)) { + if (ext_int == 1) { + __set_bit(PHY_INTERFACE_MODE_SGMII, + config->supported_interfaces); + __set_bit(PHY_INTERFACE_MODE_2500BASEX, + config->supported_interfaces); + config->mac_capabilities |= MAC_2500FD; + } phy_interface_set_rgmii(config->supported_interfaces); + } - config->mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | - MAC_10 | MAC_100 | MAC_1000FD; } static void rtl8365mb_phylink_mac_config(struct dsa_switch *ds, int port, @@ -1020,6 +1343,10 @@ static void rtl8365mb_phylink_mac_config(struct dsa_switch *ds, int port, "failed to configure RGMII mode on port %d: %d\n", port, ret); return; + } else if (state->interface == PHY_INTERFACE_MODE_SGMII || + state->interface == PHY_INTERFACE_MODE_2500BASEX) { + rtl8365mb_ext_init_sgmii(priv, port, state->interface); + rtl8365mb_ext_sgmii_nway(priv, false); } /* TODO: Implement MII and RMII modes, which the RTL8365MB-VC also @@ -1040,8 +1367,11 @@ static void rtl8365mb_phylink_mac_link_down(struct dsa_switch *ds, int port, p = &mb->ports[port]; cancel_delayed_work_sync(&p->mib_work); - if (phy_interface_mode_is_rgmii(interface)) { - ret = rtl8365mb_ext_config_forcemode(priv, port, false, 0, 0, + if (phy_interface_mode_is_rgmii(interface) || + interface == PHY_INTERFACE_MODE_SGMII || + interface == PHY_INTERFACE_MODE_2500BASEX) { + ret = rtl8365mb_ext_config_forcemode(priv, port, interface, + false, 0, 0, false, false); if (ret) dev_err(priv->dev, @@ -1068,8 +1398,11 @@ static void rtl8365mb_phylink_mac_link_up(struct dsa_switch *ds, int port, p = &mb->ports[port]; schedule_delayed_work(&p->mib_work, 0); - if (phy_interface_mode_is_rgmii(interface)) { - ret = rtl8365mb_ext_config_forcemode(priv, port, true, speed, + if (phy_interface_mode_is_rgmii(interface) || + interface == PHY_INTERFACE_MODE_SGMII || + interface == PHY_INTERFACE_MODE_2500BASEX) { + ret = rtl8365mb_ext_config_forcemode(priv, port, interface, + true, speed, duplex, tx_pause, rx_pause); if (ret) @@ -2156,6 +2489,7 @@ const struct realtek_variant rtl8365mb_variant = { }; EXPORT_SYMBOL_GPL(rtl8365mb_variant); +MODULE_FIRMWARE("rtl_switch/rtl8367s-sgmii.bin"); MODULE_AUTHOR("Alvin Šipraga "); MODULE_DESCRIPTION("Driver for RTL8365MB-VC ethernet switch"); MODULE_LICENSE("GPL");