From patchwork Wed May 26 13:55:22 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281743 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0028CC47088 for ; Wed, 26 May 2021 13:55:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D23C7613EC for ; Wed, 26 May 2021 13:55:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234229AbhEZN5a (ORCPT ); Wed, 26 May 2021 09:57:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53494 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233903AbhEZN51 (ORCPT ); Wed, 26 May 2021 09:57:27 -0400 Received: from mail-ed1-x536.google.com (mail-ed1-x536.google.com [IPv6:2a00:1450:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9344C061756 for ; Wed, 26 May 2021 06:55:54 -0700 (PDT) Received: by mail-ed1-x536.google.com with SMTP id g7so1629876edm.4 for ; Wed, 26 May 2021 06:55:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=l6pTB7oPQFNwM4xkFgzQblCRLDf360qrnS/iDnNwL3Q=; b=R3uMM+rNdOIQ2i4/1FUWxPXqf2d3HuY//Q0oYLG/nDR1+409lAbvs9gDAtxcnGinkP myHCBXrBlTNzmRpPlvYVpAbzw0E8/2CDafmafN+HhrBbW8AfBTCcaCuuPWbLNI9jai2j a3fL/HOystyx+WSAvU9Bb1dvx2gyMR6TIanIlXgB1wkm33+8OjuBasQ3ZCIuEFJbe470 IBapqapcXanaSrFBKiLNNO0oqm+F6vvbMN66ZBqBbFYZKwro2Hkl1Z0IYVtBE70GOsh4 +xGPFxg3iAdoZRUIj95nGnMmpwjJIGlJ/DePRQYUd4VWdg/wbAnx28zD7w9Ieqp2+mVB 7yzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=l6pTB7oPQFNwM4xkFgzQblCRLDf360qrnS/iDnNwL3Q=; b=K5coUya3FfS2gLwB7O1Pz3urKY4utCwHLENqYFLTxINHWpLOi1FSf6BhHxyX2sNDm4 9CpaTVke5rYAnBrDm8w44NWqp8jcr/akt+mANp2yerxwh0aZxTYPU7q/Cu2UHXtcjmvV g9i/1r0qkxicwTlQ90STeJH9U1jmRZ4q+cQEFZfOPYSiE5/IW6UFklPK8XnJ9jAI/zIq s2wq6u3a/KFAd7fNnznGVr8Iju46DNajv3kQrzspvP4sqrpOeaVVn83pNeIcMYI391/c mMint+n1Cs8tkvm2Z37IOYv/gLFJm3c7tRdWOFtqm3GCTmWqsZiQfVxAwSUfFWW20wZ8 OvMA== X-Gm-Message-State: AOAM531h4ODB0XTXk3iDz5QUxt+vcr/ByKoiszMVuhH51Rept/kePXA+ U19zp8J7gyz65IlSamVEDqm+1XOoWDA= X-Google-Smtp-Source: ABdhPJz0PkbEk4itcvbcUGzTsy4Rlmxgq4kWtsiTK8GVZL/HvBGO8lS0YkrUn2kt5D62Krln8uiTeQ== X-Received: by 2002:aa7:c782:: with SMTP id n2mr38008336eds.77.1622037353346; Wed, 26 May 2021 06:55:53 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.55.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:55:52 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot Subject: [RFC PATCH v2 linux-next 01/14] net: dsa: sja1105: be compatible with "ethernet-ports" OF node name Date: Wed, 26 May 2021 16:55:22 +0300 Message-Id: <20210526135535.2515123-2-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC Since commit f2f3e09396be ("net: dsa: sja1105: be compatible with "ethernet-ports" OF node name"), DSA supports the "ethernet-ports" name for the container node of the ports, but the sja1105 driver doesn't, because it handles some device tree parsing of its own. Add the second node name as a fallback. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Changes in v2: None. drivers/net/dsa/sja1105/sja1105_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 11fffd332c74..b6a8ac3a0430 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -885,6 +885,8 @@ static int sja1105_parse_dt(struct sja1105_private *priv, int rc; ports_node = of_get_child_by_name(switch_node, "ports"); + if (!ports_node) + ports_node = of_get_child_by_name(switch_node, "ethernet-ports"); if (!ports_node) { dev_err(dev, "Incorrect bindings: absent \"ports\" node\n"); return -ENODEV; From patchwork Wed May 26 13:55:23 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281745 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 54785C47088 for ; Wed, 26 May 2021 13:56:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 397A4613F1 for ; Wed, 26 May 2021 13:56:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234432AbhEZN5c (ORCPT ); Wed, 26 May 2021 09:57:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233906AbhEZN51 (ORCPT ); Wed, 26 May 2021 09:57:27 -0400 Received: from mail-ej1-x62e.google.com (mail-ej1-x62e.google.com [IPv6:2a00:1450:4864:20::62e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B9AF7C061574 for ; Wed, 26 May 2021 06:55:55 -0700 (PDT) Received: by mail-ej1-x62e.google.com with SMTP id jt22so2606104ejb.7 for ; Wed, 26 May 2021 06:55:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qB4ZhNPqnrdosBrM+xw2PATgct++QlyBWnXEhS311SU=; b=EW7e+02MPbD6/EYqTj+3Wdlk5yIRNa8qjRoD9EeJB9bJtpRSCu4nw2cqcT5jac2iWW hwrpkPkjML8uWUnC9fRuXdPxNLwRR9JwtR9a0vN4NGBHw9Pbdc5uPIxr/A50lEgcl9RO thVMe5uQjriuI4X4UIY/X6sk/FQLhZ0DYdm7yZB5f9UG7+N2wIg1FQickqFl2K4vcyf9 pfgCLJ0gvIMNymeAu+IL9F1X25+2TDZcm159QBB9WdzC+HrYWmFW2jtxpZkEO+Ry/qNf drAt1ea20+TYUDukfhJ0EtGKiSsda5R6OY8HmMqiGiV+8lPRd8phbqLpZIl+f0WDat/p +1pA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qB4ZhNPqnrdosBrM+xw2PATgct++QlyBWnXEhS311SU=; b=tEK5JAvbGghfcdiwKId1GUVb/3sJOOlcBZJ0BEmxZkSTzo4rSeITQ8iCnNyqnlD9J5 Chl6cQRFlQatzuPWSbwJv7PZPT+4cDT7ZdnHMcPkN0aXtPOQFt8fCtOadw67BsFdGkkA xlEtyY4e5oyb2SWxxehf4dyL/Ee44Sycc0QHBbPYI22yXHf/HnH+agf49EdYCi88At9D 0VHWvplBi95J3duVxzyfCUf3D2ugbPiCP/CvN/TC3RAgU/51TZ+3FU8NR5J2XIfJzJJy b6F4oqnEuTEHfyb5EOE9D/R9bHKxF7uDy4qN1nW15AC0llgWlvb4bFLQZHLA/BMm3Xr2 S0Cg== X-Gm-Message-State: AOAM533hSvG3OvkEg7k7d9GrvEd4DFQBhWWs36+4G2ihWYLvXUOe3vfI F1YRZRQuZHWyZDkmXnyVQ5w= X-Google-Smtp-Source: ABdhPJzRhI2OGSBbHMxBj+U+rRXBWqsWQqIrWH6uijBGZ9PTeI7exiINddESQXedgkSj1AmZl20GdQ== X-Received: by 2002:a17:906:4789:: with SMTP id cw9mr34409496ejc.325.1622037354341; Wed, 26 May 2021 06:55:54 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.55.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:55:53 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot Subject: [RFC PATCH v2 linux-next 02/14] net: dsa: sja1105: allow SGMII PCS configuration to be per port Date: Wed, 26 May 2021 16:55:23 +0300 Message-Id: <20210526135535.2515123-3-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC The SJA1105 R and S switches have 1 SGMII port (port 4). Because there is only one such port, there is no "port" parameter in the configuration code for the SGMII PCS. However, the SJA1110 can have up to 4 SGMII ports, each with its own SGMII register map. So we need to generalize the logic. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Changes in v2: None. drivers/net/dsa/sja1105/sja1105_main.c | 75 +++++++++++++++----------- 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index b6a8ac3a0430..1a49cfce9611 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -898,36 +898,43 @@ static int sja1105_parse_dt(struct sja1105_private *priv, return rc; } -static int sja1105_sgmii_read(struct sja1105_private *priv, int pcs_reg) +static int sja1105_sgmii_read(struct sja1105_private *priv, int port, + int pcs_reg) { const struct sja1105_regs *regs = priv->info->regs; u32 val; int rc; - rc = sja1105_xfer_u32(priv, SPI_READ, regs->sgmii + pcs_reg, &val, - NULL); + if (port != SJA1105_SGMII_PORT) + return -ENODEV; + + rc = sja1105_xfer_u32(priv, SPI_READ, regs->sgmii + pcs_reg, + &val, NULL); if (rc < 0) return rc; return val; } -static int sja1105_sgmii_write(struct sja1105_private *priv, int pcs_reg, - u16 pcs_val) +static int sja1105_sgmii_write(struct sja1105_private *priv, int port, + int pcs_reg, u16 pcs_val) { const struct sja1105_regs *regs = priv->info->regs; u32 val = pcs_val; int rc; - rc = sja1105_xfer_u32(priv, SPI_WRITE, regs->sgmii + pcs_reg, &val, - NULL); + if (port != SJA1105_SGMII_PORT) + return -ENODEV; + + rc = sja1105_xfer_u32(priv, SPI_WRITE, regs->sgmii + pcs_reg, + &val, NULL); if (rc < 0) return rc; return val; } -static void sja1105_sgmii_pcs_config(struct sja1105_private *priv, +static void sja1105_sgmii_pcs_config(struct sja1105_private *priv, int port, bool an_enabled, bool an_master) { u16 ac = SJA1105_AC_AUTONEG_MODE_SGMII; @@ -936,27 +943,29 @@ static void sja1105_sgmii_pcs_config(struct sja1105_private *priv, * stop the clock during LPI mode, make the MAC reconfigure * autonomously after PCS autoneg is done, flush the internal FIFOs. */ - sja1105_sgmii_write(priv, SJA1105_DC1, SJA1105_DC1_EN_VSMMD1 | - SJA1105_DC1_CLOCK_STOP_EN | - SJA1105_DC1_MAC_AUTO_SW | - SJA1105_DC1_INIT); + sja1105_sgmii_write(priv, port, SJA1105_DC1, + SJA1105_DC1_EN_VSMMD1 | + SJA1105_DC1_CLOCK_STOP_EN | + SJA1105_DC1_MAC_AUTO_SW | + SJA1105_DC1_INIT); /* DIGITAL_CONTROL_2: No polarity inversion for TX and RX lanes */ - sja1105_sgmii_write(priv, SJA1105_DC2, SJA1105_DC2_TX_POL_INV_DISABLE); + sja1105_sgmii_write(priv, port, SJA1105_DC2, + SJA1105_DC2_TX_POL_INV_DISABLE); /* AUTONEG_CONTROL: Use SGMII autoneg */ if (an_master) ac |= SJA1105_AC_PHY_MODE | SJA1105_AC_SGMII_LINK; - sja1105_sgmii_write(priv, SJA1105_AC, ac); + sja1105_sgmii_write(priv, port, SJA1105_AC, ac); /* BASIC_CONTROL: enable in-band AN now, if requested. Otherwise, * sja1105_sgmii_pcs_force_speed must be called later for the link * to become operational. */ if (an_enabled) - sja1105_sgmii_write(priv, MII_BMCR, + sja1105_sgmii_write(priv, port, MII_BMCR, BMCR_ANENABLE | BMCR_ANRESTART); } static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv, - int speed) + int port, int speed) { int pcs_speed; @@ -974,7 +983,7 @@ static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv, dev_err(priv->ds->dev, "Invalid speed %d\n", speed); return; } - sja1105_sgmii_write(priv, MII_BMCR, pcs_speed | BMCR_FULLDPLX); + sja1105_sgmii_write(priv, port, MII_BMCR, pcs_speed | BMCR_FULLDPLX); } /* Convert link speed from SJA1105 to ethtool encoding */ @@ -1115,7 +1124,8 @@ static void sja1105_mac_config(struct dsa_switch *ds, int port, } if (is_sgmii) - sja1105_sgmii_pcs_config(priv, phylink_autoneg_inband(mode), + sja1105_sgmii_pcs_config(priv, port, + phylink_autoneg_inband(mode), false); } @@ -1138,7 +1148,7 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port, sja1105_adjust_port_config(priv, port, speed); if (sja1105_supports_sgmii(priv, port) && !phylink_autoneg_inband(mode)) - sja1105_sgmii_pcs_force_speed(priv, speed); + sja1105_sgmii_pcs_force_speed(priv, port, speed); sja1105_inhibit_tx(priv, BIT(port), false); } @@ -1191,7 +1201,7 @@ static int sja1105_mac_pcs_get_state(struct dsa_switch *ds, int port, int ais; /* Read the vendor-specific AUTONEG_INTR_STATUS register */ - ais = sja1105_sgmii_read(priv, SJA1105_AIS); + ais = sja1105_sgmii_read(priv, port, SJA1105_AIS); if (ais < 0) return ais; @@ -1873,11 +1883,11 @@ int sja1105_static_config_reload(struct sja1105_private *priv, struct ptp_system_timestamp ptp_sts_before; struct ptp_system_timestamp ptp_sts_after; int speed_mbps[SJA1105_MAX_NUM_PORTS]; + u16 bmcr[SJA1105_MAX_NUM_PORTS] = {0}; struct sja1105_mac_config_entry *mac; struct dsa_switch *ds = priv->ds; s64 t1, t2, t3, t4; s64 t12, t34; - u16 bmcr = 0; int rc, i; s64 now; @@ -1893,10 +1903,10 @@ int sja1105_static_config_reload(struct sja1105_private *priv, for (i = 0; i < ds->num_ports; i++) { speed_mbps[i] = sja1105_speed[mac[i].speed]; mac[i].speed = SJA1105_SPEED_AUTO; - } - if (sja1105_supports_sgmii(priv, SJA1105_SGMII_PORT)) - bmcr = sja1105_sgmii_read(priv, MII_BMCR); + if (sja1105_supports_sgmii(priv, i)) + bmcr[i] = sja1105_sgmii_read(priv, i, MII_BMCR); + } /* No PTP operations can run right now */ mutex_lock(&priv->ptp_data.lock); @@ -1943,27 +1953,30 @@ int sja1105_static_config_reload(struct sja1105_private *priv, goto out; for (i = 0; i < ds->num_ports; i++) { + bool an_enabled; + rc = sja1105_adjust_port_config(priv, i, speed_mbps[i]); if (rc < 0) goto out; - } - if (sja1105_supports_sgmii(priv, SJA1105_SGMII_PORT)) { - bool an_enabled = !!(bmcr & BMCR_ANENABLE); + if (!sja1105_supports_sgmii(priv, i)) + continue; + + an_enabled = !!(bmcr[i] & BMCR_ANENABLE); - sja1105_sgmii_pcs_config(priv, an_enabled, false); + sja1105_sgmii_pcs_config(priv, i, an_enabled, false); if (!an_enabled) { int speed = SPEED_UNKNOWN; - if (bmcr & BMCR_SPEED1000) + if (bmcr[i] & BMCR_SPEED1000) speed = SPEED_1000; - else if (bmcr & BMCR_SPEED100) + else if (bmcr[i] & BMCR_SPEED100) speed = SPEED_100; else speed = SPEED_10; - sja1105_sgmii_pcs_force_speed(priv, speed); + sja1105_sgmii_pcs_force_speed(priv, i, speed); } } From patchwork Wed May 26 13:55:24 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281747 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CB1AFC47082 for ; Wed, 26 May 2021 13:56:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AB2F0613E1 for ; Wed, 26 May 2021 13:56:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234504AbhEZN5e (ORCPT ); Wed, 26 May 2021 09:57:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53508 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234096AbhEZN5a (ORCPT ); Wed, 26 May 2021 09:57:30 -0400 Received: from mail-ej1-x62d.google.com (mail-ej1-x62d.google.com [IPv6:2a00:1450:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 977A8C061574 for ; Wed, 26 May 2021 06:55:56 -0700 (PDT) Received: by mail-ej1-x62d.google.com with SMTP id b9so2581987ejc.13 for ; Wed, 26 May 2021 06:55:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rBQiGdmKiViP+5BrFukQsjSpt9Gn23jXAPduAryoX0o=; b=GJ6AuAzKIwvSg9wqCI8EYYOsoijSW2FqMUddGDHyFXldExUZDRRRYijbuJ474/7ZyG WUN5SLAxsmY1sDYaKkblk/uk+UtbbU4Dk+T/ffwjbYT1UOgVlAFYRzUFtoTHYaEsh2ol tHPTAZadtmwFh9NNAKoxcnswqFJrvFKlFlVahPqjqhpeGwXcprcKAfr6TZa1ClIML4xP 3UDdo7eUrWVO+qkjc9iurBclFIkRUlyu5RBcEBTbuVpzv9o/vWJrIvx3lql+v4tvBKbX qmfifHI4OQi5jW7gwswNoFipfy/LI3DbXyz3ML7IEzqBA9P6xVnqbvqvi4zIO5pqyG34 iFfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=rBQiGdmKiViP+5BrFukQsjSpt9Gn23jXAPduAryoX0o=; b=IS7nd3hW7/Jm51YSbgQxh8CLpBue5rSRoOXQ8niCZsO5spWaL67d/zI83m21RFvQcp R1p74NWKK2gS4NgUPIDCKTs+oiObL/G0TrWsenAhaQghBnfsMw6cZK8x8t+bOs6nFwOH +dqUpFwzKSaqIVlrl/ovh4r3VUktq+wM4p+/00hbnnEOhWZ9LggHj06irWAFbgRucJul qHRchqtbc0cNNucRLwnHkAateKLDVpMt6l6Jhkf5PelAUm4iwN9kgib/lCAyj+RPapjF j0kWZp8FgUWKFMsa5VOLeJB07JMOP+fzz1Xbju6YGRWexHEljg0dg8lv3u2XkJGNI9Df diMg== X-Gm-Message-State: AOAM530G2RFew+/1f3SrQ7eRPGfD06zLAFVP0WB5E/iB+fM+0dJI0xWB 8Ut+bMJRuOsQk+ictE/Jtck= X-Google-Smtp-Source: ABdhPJw0X9cTNa+X0VuNG9sw9o3PsdTA1zZ707M/KWPbaWk15nV0B+LM8Lo8s8fdV7myBCh4vK8+JA== X-Received: by 2002:a17:906:6ad0:: with SMTP id q16mr34849090ejs.286.1622037355230; Wed, 26 May 2021 06:55:55 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.55.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:55:54 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Russell King , Heiner Kallweit Subject: [RFC PATCH v2 linux-next 03/14] net: dsa: sja1105: the 0x1F0000 SGMII "base address" is actually MDIO_MMD_VEND2 Date: Wed, 26 May 2021 16:55:24 +0300 Message-Id: <20210526135535.2515123-4-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC Looking at the SGMII PCS from SJA1110, which is accessed indirectly through a different base address as can be seen in the next patch, it appears odd that the address accessed through indirection still references the base address from the SJA1105S register map (first MDIO register is at 0x1f0000), when it could index the SGMII registers starting from zero. Except that the 0x1f0000 is not a base address at all, it seems. It is 0x1f << 16 | 0x0000, and 0x1f is coding for the vendor-specific MMD2. So, it turns out, the Synopsys PCS implements all its registers inside the vendor-specific MMDs 1 and 2 (0x1e and 0x1f). This explains why the PCS has no overlaps (for the other MMDs) with other register regions of the switch (because no other MMDs are implemented). Change the code to remove the SGMII "base address" and explicitly encode the MMD for reads/writes. This will become necessary for SJA1110 support. Cc: Russell King Cc: Heiner Kallweit Signed-off-by: Vladimir Oltean --- Changes in v2: None. drivers/net/dsa/sja1105/sja1105.h | 1 - drivers/net/dsa/sja1105/sja1105_main.c | 31 +++++++++++++------------- drivers/net/dsa/sja1105/sja1105_spi.c | 1 - 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 2ec03917feb3..830ea5ca359f 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -48,7 +48,6 @@ struct sja1105_regs { u64 rgu; u64 vl_status; u64 config; - u64 sgmii; u64 rmii_pll1; u64 ptppinst; u64 ptppindur; diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 1a49cfce9611..292490a2ea0e 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -898,36 +898,34 @@ static int sja1105_parse_dt(struct sja1105_private *priv, return rc; } -static int sja1105_sgmii_read(struct sja1105_private *priv, int port, +static int sja1105_sgmii_read(struct sja1105_private *priv, int port, int mmd, int pcs_reg) { - const struct sja1105_regs *regs = priv->info->regs; + u64 addr = (mmd << 16) | pcs_reg; u32 val; int rc; if (port != SJA1105_SGMII_PORT) return -ENODEV; - rc = sja1105_xfer_u32(priv, SPI_READ, regs->sgmii + pcs_reg, - &val, NULL); + rc = sja1105_xfer_u32(priv, SPI_READ, addr, &val, NULL); if (rc < 0) return rc; return val; } -static int sja1105_sgmii_write(struct sja1105_private *priv, int port, +static int sja1105_sgmii_write(struct sja1105_private *priv, int port, int mmd, int pcs_reg, u16 pcs_val) { - const struct sja1105_regs *regs = priv->info->regs; + u64 addr = (mmd << 16) | pcs_reg; u32 val = pcs_val; int rc; if (port != SJA1105_SGMII_PORT) return -ENODEV; - rc = sja1105_xfer_u32(priv, SPI_WRITE, regs->sgmii + pcs_reg, - &val, NULL); + rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &val, NULL); if (rc < 0) return rc; @@ -943,24 +941,24 @@ static void sja1105_sgmii_pcs_config(struct sja1105_private *priv, int port, * stop the clock during LPI mode, make the MAC reconfigure * autonomously after PCS autoneg is done, flush the internal FIFOs. */ - sja1105_sgmii_write(priv, port, SJA1105_DC1, + sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC1, SJA1105_DC1_EN_VSMMD1 | SJA1105_DC1_CLOCK_STOP_EN | SJA1105_DC1_MAC_AUTO_SW | SJA1105_DC1_INIT); /* DIGITAL_CONTROL_2: No polarity inversion for TX and RX lanes */ - sja1105_sgmii_write(priv, port, SJA1105_DC2, + sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC2, SJA1105_DC2_TX_POL_INV_DISABLE); /* AUTONEG_CONTROL: Use SGMII autoneg */ if (an_master) ac |= SJA1105_AC_PHY_MODE | SJA1105_AC_SGMII_LINK; - sja1105_sgmii_write(priv, port, SJA1105_AC, ac); + sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_AC, ac); /* BASIC_CONTROL: enable in-band AN now, if requested. Otherwise, * sja1105_sgmii_pcs_force_speed must be called later for the link * to become operational. */ if (an_enabled) - sja1105_sgmii_write(priv, port, MII_BMCR, + sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1, BMCR_ANENABLE | BMCR_ANRESTART); } @@ -983,7 +981,8 @@ static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv, dev_err(priv->ds->dev, "Invalid speed %d\n", speed); return; } - sja1105_sgmii_write(priv, port, MII_BMCR, pcs_speed | BMCR_FULLDPLX); + sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1, + pcs_speed | BMCR_FULLDPLX); } /* Convert link speed from SJA1105 to ethtool encoding */ @@ -1201,7 +1200,7 @@ static int sja1105_mac_pcs_get_state(struct dsa_switch *ds, int port, int ais; /* Read the vendor-specific AUTONEG_INTR_STATUS register */ - ais = sja1105_sgmii_read(priv, port, SJA1105_AIS); + ais = sja1105_sgmii_read(priv, port, MDIO_MMD_VEND2, SJA1105_AIS); if (ais < 0) return ais; @@ -1905,7 +1904,9 @@ int sja1105_static_config_reload(struct sja1105_private *priv, mac[i].speed = SJA1105_SPEED_AUTO; if (sja1105_supports_sgmii(priv, i)) - bmcr[i] = sja1105_sgmii_read(priv, i, MII_BMCR); + bmcr[i] = sja1105_sgmii_read(priv, i, + MDIO_MMD_VEND2, + MDIO_CTRL1); } /* No PTP operations can run right now */ diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index d0bc6cf90bfd..615e0906b1fa 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -440,7 +440,6 @@ static struct sja1105_regs sja1105pqrs_regs = { .pad_mii_tx = {0x100800, 0x100802, 0x100804, 0x100806, 0x100808}, .pad_mii_rx = {0x100801, 0x100803, 0x100805, 0x100807, 0x100809}, .pad_mii_id = {0x100810, 0x100811, 0x100812, 0x100813, 0x100814}, - .sgmii = 0x1F0000, .rmii_pll1 = 0x10000A, .cgu_idiv = {0x10000B, 0x10000C, 0x10000D, 0x10000E, 0x10000F}, .stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208}, From patchwork Wed May 26 13:55:25 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281749 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C885BC47082 for ; Wed, 26 May 2021 13:56:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6C2DB613E1 for ; Wed, 26 May 2021 13:56:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234447AbhEZN5i (ORCPT ); Wed, 26 May 2021 09:57:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53518 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234235AbhEZN5a (ORCPT ); Wed, 26 May 2021 09:57:30 -0400 Received: from mail-ej1-x630.google.com (mail-ej1-x630.google.com [IPv6:2a00:1450:4864:20::630]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D7A59C06175F for ; Wed, 26 May 2021 06:55:58 -0700 (PDT) Received: by mail-ej1-x630.google.com with SMTP id z16so1988692ejr.4 for ; Wed, 26 May 2021 06:55:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=nm1QpAvByWjEIfYQyVaJjbBeCpCNrxlaB33JNLFGKIc=; b=NlWspq1OGO/tHMSHR5FARl9jzz7IAmYcWohDzLI53vrhXIWXuAhU7vfSonffgttfb5 JygQ0vAPJ33J4iUyDGQ3QSgGb1Bx/Y8v3aQdmqVspl8LDUGSxVfjSRAl2nrANJsQQKRO Lua33TQESQwaPZyLRyF/yge0Zp6FqCGeOQbonaSEzEHYZsT0dIpHCthGbdH6mt0LYOaX Jg9T7jlViEmtLjXE1qpsUanu1t3dnGlAJCcMq8o2vXoqVUrEKu8QpFlVmcjbnOfMNZJt 9NZDxPdhS2cj+PitCXcSIyTTCGUQsbf3ZJ4pEyc60ptn4Qb6ndRfITCTIf38lAlErWEC KvPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=nm1QpAvByWjEIfYQyVaJjbBeCpCNrxlaB33JNLFGKIc=; b=mPNKNSoIxJ9HA06eAc1o8iAQHeQooZJXjHYPyHGL122ATxArc7YjRxlL1f4EGVxdNq 7JsBiTRDOYkq0uSntQDhOyWtSI3vncg9fdkIr6cqWCJQCApl7sfOB2MsWpLA5CQrzQXc wuzz+SP+mzdE0fZU4EVzrbT4UQgjtK0lmThZPQL6YRWz+sTubO2npvLarSeSsaLBFJSA AREFq87lMFvsNmRbMRr/Q/m/T3hetAmNewOtP2LiQG2TLYxCWQtfFu6TRlv+QbkUSmiU K5DBRXvTfyjmV+AWy7TGKSm9u0eTJyD21NL2rAEznZb4y2l3/vMjhHZdxE1ZO9spLkKp bYGQ== X-Gm-Message-State: AOAM531TFEbF9MR6M9LdhNfHvr/2n3WQXFCZgW7DuAja+VNdkqIValKx dyErepgrWLDZUzAcjFbKzQXlBbnETHY= X-Google-Smtp-Source: ABdhPJx1L5rfNESmnb+O64nAiMoPm4ei0zl4zI4fuMK6jYdzJEzVBwD3FSpFI2VSBMtPPXlwe3ptKw== X-Received: by 2002:a17:906:b74f:: with SMTP id fx15mr34109261ejb.85.1622037356004; Wed, 26 May 2021 06:55:56 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.55.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:55:55 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot Subject: [RFC PATCH v2 linux-next 04/14] net: dsa: sja1105: cache the phy-mode port property Date: Wed, 26 May 2021 16:55:25 +0300 Message-Id: <20210526135535.2515123-5-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC So far we've succeeded in operating without keeping a copy of the phy-mode in the driver, since we already have the static config and we can look at the xMII Mode Parameters Table which already holds that information. But with the SJA1110, we cannot make the distinction between sgmii and 2500base-x, because to the hardware's static config, it's all SGMII. So add a phy_mode property per port inside struct sja1105_private. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Changes in v2: None. drivers/net/dsa/sja1105/sja1105.h | 1 + drivers/net/dsa/sja1105/sja1105_main.c | 24 +++--------------------- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 830ea5ca359f..d5c0217b1f65 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -210,6 +210,7 @@ struct sja1105_private { struct sja1105_static_config static_config; bool rgmii_rx_delay[SJA1105_MAX_NUM_PORTS]; bool rgmii_tx_delay[SJA1105_MAX_NUM_PORTS]; + phy_interface_t phy_mode[SJA1105_MAX_NUM_PORTS]; bool best_effort_vlan_filtering; unsigned long learn_ena; unsigned long ucast_egress_floods; diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 292490a2ea0e..f33c23074bb5 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -871,6 +871,8 @@ static int sja1105_parse_ports_node(struct sja1105_private *priv, ports[index].role = XMII_MAC; else if (of_property_read_bool(child, "sja1105,role-phy")) ports[index].role = XMII_PHY; + + priv->phy_mode[index] = phy_mode; } return 0; @@ -1081,27 +1083,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, static bool sja1105_phy_mode_mismatch(struct sja1105_private *priv, int port, phy_interface_t interface) { - struct sja1105_xmii_params_entry *mii; - sja1105_phy_interface_t phy_mode; - - mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries; - phy_mode = mii->xmii_mode[port]; - - switch (interface) { - case PHY_INTERFACE_MODE_MII: - return (phy_mode != XMII_MODE_MII); - case PHY_INTERFACE_MODE_RMII: - return (phy_mode != XMII_MODE_RMII); - case PHY_INTERFACE_MODE_RGMII: - case PHY_INTERFACE_MODE_RGMII_ID: - case PHY_INTERFACE_MODE_RGMII_RXID: - case PHY_INTERFACE_MODE_RGMII_TXID: - return (phy_mode != XMII_MODE_RGMII); - case PHY_INTERFACE_MODE_SGMII: - return (phy_mode != XMII_MODE_SGMII); - default: - return true; - } + return priv->phy_mode[port] != interface; } static void sja1105_mac_config(struct dsa_switch *ds, int port, From patchwork Wed May 26 13:55:26 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281751 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 561D9C47089 for ; Wed, 26 May 2021 13:56:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3A223611C9 for ; Wed, 26 May 2021 13:56:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233304AbhEZN5k (ORCPT ); Wed, 26 May 2021 09:57:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53514 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234282AbhEZN5b (ORCPT ); Wed, 26 May 2021 09:57:31 -0400 Received: from mail-ej1-x635.google.com (mail-ej1-x635.google.com [IPv6:2a00:1450:4864:20::635]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 654F0C061756 for ; Wed, 26 May 2021 06:55:58 -0700 (PDT) Received: by mail-ej1-x635.google.com with SMTP id lz27so2582926ejb.11 for ; Wed, 26 May 2021 06:55:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=oS+6W66HcoQuB/oLBDJ9kgSSWP/V+pYyYvcxM3pyL4w=; b=FLLk7tjiIH4OIn06oznHRAOT0544QJUw4ez8unBnCHKcZv/ssJ7WhZDvbWuvBnxJv/ OF8qXH1t/LImS14KDhiQGkoKwtS+hYAL6yIn6exkJOVUyAT9llgnrvnzbgbCeQoCb+9H gPGEGORzeNus252RnLtVOdE4SP+2WTv9aDhHOFfi+TNfln1X4xY6CGmyq5WgVHZa8fr5 2IfKDAyY4KnS7OAdUG9KEvENb8sRi/hKChc3m9+xlFt6tq/qh8F0y3/BApz2bL0i5AUe MZr2P/qhboBm958SnqdksrICUqUcjI0A0P5G/eqZPoduxAaO4WYigbVx1EB6GocMyx3g SnlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oS+6W66HcoQuB/oLBDJ9kgSSWP/V+pYyYvcxM3pyL4w=; b=bPx37hv/sjfnAfdbAqEHL1unZFBUtTPZ+ckttHlbhPN0txGioLHoYOGHp0QgZRVTbG Tx5oU3ZY+oe8DkJy+jQzUlUbNwXBhZMEXZpknSW6na+XOzxNtKTJYDsX4AXMQsh+4C95 +U1zxkpqeAOY86a3FYWoml1HfG1Xlz7d+t9UFAL89dhHgun8dcTD5hlfv0W+YTw+6jBb CAr7gzSARE5XgPKLQbRUKb2H8mkWSAnAC8C2msJs57vGlureyJoQ6ME2Pl6lZ3pksyNn PUQ+WieGQIo2Ui9fGVHTTZWRlpJFufNrE59f+6+gl8OcuU5ZEgXcmq2xAD7BVUE1s4VY geQA== X-Gm-Message-State: AOAM531lfWhJK43YZs1TuyocA/S6cECdJ9MTLgHRusDlUq26o3wxQ9s6 uHkc7NZhrJ9fXbvmFObwrko= X-Google-Smtp-Source: ABdhPJwdXM0wfecEdfafaCrV+r+3eyaS2htDHRe01epxm8fYRXfCewHaGDEctDqZPdRjbuOrIW/ivQ== X-Received: by 2002:a17:907:37b:: with SMTP id rs27mr34856143ejb.287.1622037356952; Wed, 26 May 2021 06:55:56 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.55.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:55:56 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot Subject: [RFC PATCH v2 linux-next 05/14] net: dsa: sja1105: add a PHY interface type compatibility matrix Date: Wed, 26 May 2021 16:55:26 +0300 Message-Id: <20210526135535.2515123-6-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC On the SJA1105, all ports support the parallel "xMII" protocols (MII, RMII, RGMII) except for port 4 on SJA1105R/S which supports only SGMII. This was relatively easy to model, by special-casing the SGMII port. On the SJA1110, certain ports can be pinmuxed between SGMII and xMII, or between SGMII and an internal 100base-TX PHY. This creates problems, because the driver's assumption so far was that if a port supports SGMII, it uses SGMII. We allow the device tree to tell us how the port pinmuxing is done, and check that against a PHY interface type compatibility matrix for plausibility. The other big change is that instead of doing SGMII configuration based on what the port supports, we do it based on what is the configured phy_mode of the port. The 2500base-x support added in this patch is not complete. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- drivers/net/dsa/sja1105/sja1105.h | 5 +++ drivers/net/dsa/sja1105/sja1105_main.c | 59 +++++++++++++------------- drivers/net/dsa/sja1105/sja1105_spi.c | 20 +++++++++ 3 files changed, 55 insertions(+), 29 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index d5c0217b1f65..a27841642693 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -111,6 +111,11 @@ struct sja1105_info { enum packing_op op); int (*clocking_setup)(struct sja1105_private *priv); const char *name; + bool supports_mii[SJA1105_MAX_NUM_PORTS]; + bool supports_rmii[SJA1105_MAX_NUM_PORTS]; + bool supports_rgmii[SJA1105_MAX_NUM_PORTS]; + bool supports_sgmii[SJA1105_MAX_NUM_PORTS]; + bool supports_2500basex[SJA1105_MAX_NUM_PORTS]; }; enum sja1105_key_type { diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index f33c23074bb5..8a07373e3cf3 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -143,21 +143,6 @@ static int sja1105_init_mac_settings(struct sja1105_private *priv) return 0; } -static bool sja1105_supports_sgmii(struct sja1105_private *priv, int port) -{ - if (priv->info->part_no != SJA1105R_PART_NO && - priv->info->part_no != SJA1105S_PART_NO) - return false; - - if (port != SJA1105_SGMII_PORT) - return false; - - if (dsa_is_unused_port(priv->ds, port)) - return false; - - return true; -} - static int sja1105_init_mii_settings(struct sja1105_private *priv, struct sja1105_dt_port *ports) { @@ -191,25 +176,42 @@ static int sja1105_init_mii_settings(struct sja1105_private *priv, switch (ports[i].phy_mode) { case PHY_INTERFACE_MODE_MII: + if (!priv->info->supports_mii[i]) + goto unsupported; + mii->xmii_mode[i] = XMII_MODE_MII; break; case PHY_INTERFACE_MODE_RMII: + if (!priv->info->supports_rmii[i]) + goto unsupported; + mii->xmii_mode[i] = XMII_MODE_RMII; break; case PHY_INTERFACE_MODE_RGMII: case PHY_INTERFACE_MODE_RGMII_ID: case PHY_INTERFACE_MODE_RGMII_RXID: case PHY_INTERFACE_MODE_RGMII_TXID: + if (!priv->info->supports_rgmii[i]) + goto unsupported; + mii->xmii_mode[i] = XMII_MODE_RGMII; break; case PHY_INTERFACE_MODE_SGMII: - if (!sja1105_supports_sgmii(priv, i)) - return -EINVAL; + if (!priv->info->supports_sgmii[i]) + goto unsupported; + + mii->xmii_mode[i] = XMII_MODE_SGMII; + break; + case PHY_INTERFACE_MODE_2500BASEX: + if (!priv->info->supports_2500basex[i]) + goto unsupported; + mii->xmii_mode[i] = XMII_MODE_SGMII; break; +unsupported: default: - dev_err(dev, "Unsupported PHY mode %s!\n", - phy_modes(ports[i].phy_mode)); + dev_err(dev, "Unsupported PHY mode %s on port %d!\n", + phy_modes(ports[i].phy_mode), i); return -EINVAL; } @@ -999,10 +1001,8 @@ static int sja1105_speed[] = { static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, int speed_mbps) { - struct sja1105_xmii_params_entry *mii; struct sja1105_mac_config_entry *mac; struct device *dev = priv->ds->dev; - sja1105_phy_interface_t phy_mode; sja1105_speed_t speed; int rc; @@ -1013,7 +1013,6 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, * reasonable approximation for both E/T and P/Q/R/S. */ mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; - mii = priv->static_config.tables[BLK_IDX_XMII_PARAMS].entries; switch (speed_mbps) { case SPEED_UNKNOWN: @@ -1047,7 +1046,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, * Actually for the SGMII port, the MAC is fixed at 1 Gbps and * we need to configure the PCS only (if even that). */ - if (sja1105_supports_sgmii(priv, port)) + if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII) mac[port].speed = SJA1105_SPEED_1000MBPS; else mac[port].speed = speed; @@ -1066,8 +1065,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, * the clock setup does interrupt the clock signal for a certain time * which causes trouble for all PHYs relying on this signal. */ - phy_mode = mii->xmii_mode[port]; - if (phy_mode != XMII_MODE_RGMII) + if (!phy_interface_mode_is_rgmii(priv->phy_mode[port])) return 0; return sja1105_clocking_setup_port(priv, port); @@ -1091,7 +1089,9 @@ static void sja1105_mac_config(struct dsa_switch *ds, int port, const struct phylink_link_state *state) { struct sja1105_private *priv = ds->priv; - bool is_sgmii = sja1105_supports_sgmii(priv, port); + bool is_sgmii; + + is_sgmii = (state->interface == PHY_INTERFACE_MODE_SGMII); if (sja1105_phy_mode_mismatch(priv, port, state->interface)) { dev_err(ds->dev, "Changing PHY mode to %s not supported!\n", @@ -1128,7 +1128,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port, sja1105_adjust_port_config(priv, port, speed); - if (sja1105_supports_sgmii(priv, port) && !phylink_autoneg_inband(mode)) + if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII && + !phylink_autoneg_inband(mode)) sja1105_sgmii_pcs_force_speed(priv, port, speed); sja1105_inhibit_tx(priv, BIT(port), false); @@ -1885,7 +1886,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv, speed_mbps[i] = sja1105_speed[mac[i].speed]; mac[i].speed = SJA1105_SPEED_AUTO; - if (sja1105_supports_sgmii(priv, i)) + if (priv->phy_mode[i] == PHY_INTERFACE_MODE_SGMII) bmcr[i] = sja1105_sgmii_read(priv, i, MDIO_MMD_VEND2, MDIO_CTRL1); @@ -1942,7 +1943,7 @@ int sja1105_static_config_reload(struct sja1105_private *priv, if (rc < 0) goto out; - if (!sja1105_supports_sgmii(priv, i)) + if (priv->phy_mode[i] != PHY_INTERFACE_MODE_SGMII) continue; an_enabled = !!(bmcr[i] & BMCR_ANENABLE); diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 615e0906b1fa..565b594efa7d 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -482,6 +482,9 @@ const struct sja1105_info sja1105e_info = { .ptp_cmd_packing = sja1105et_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105et_regs, + .supports_mii = {true, true, true, true, true}, + .supports_rmii = {true, true, true, true, true}, + .supports_rgmii = {true, true, true, true, true}, .name = "SJA1105E", }; @@ -502,6 +505,9 @@ const struct sja1105_info sja1105t_info = { .ptp_cmd_packing = sja1105et_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105et_regs, + .supports_mii = {true, true, true, true, true}, + .supports_rmii = {true, true, true, true, true}, + .supports_rgmii = {true, true, true, true, true}, .name = "SJA1105T", }; @@ -523,6 +529,9 @@ const struct sja1105_info sja1105p_info = { .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105pqrs_regs, + .supports_mii = {true, true, true, true, true}, + .supports_rmii = {true, true, true, true, true}, + .supports_rgmii = {true, true, true, true, true}, .name = "SJA1105P", }; @@ -544,6 +553,9 @@ const struct sja1105_info sja1105q_info = { .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105pqrs_regs, + .supports_mii = {true, true, true, true, true}, + .supports_rmii = {true, true, true, true, true}, + .supports_rgmii = {true, true, true, true, true}, .name = "SJA1105Q", }; @@ -565,6 +577,10 @@ const struct sja1105_info sja1105r_info = { .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105pqrs_regs, + .supports_mii = {true, true, true, true, true}, + .supports_rmii = {true, true, true, true, true}, + .supports_rgmii = {true, true, true, true, true}, + .supports_sgmii = {false, false, false, false, true}, .name = "SJA1105R", }; @@ -586,5 +602,9 @@ const struct sja1105_info sja1105s_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, + .supports_mii = {true, true, true, true, true}, + .supports_rmii = {true, true, true, true, true}, + .supports_rgmii = {true, true, true, true, true}, + .supports_sgmii = {false, false, false, false, true}, .name = "SJA1105S", }; From patchwork Wed May 26 13:55:27 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281753 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7F9CDC47088 for ; Wed, 26 May 2021 13:56:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 57CC9613D3 for ; Wed, 26 May 2021 13:56:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234593AbhEZN5m (ORCPT ); Wed, 26 May 2021 09:57:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234370AbhEZN5b (ORCPT ); Wed, 26 May 2021 09:57:31 -0400 Received: from mail-ed1-x52c.google.com (mail-ed1-x52c.google.com [IPv6:2a00:1450:4864:20::52c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3C247C061760 for ; Wed, 26 May 2021 06:55:59 -0700 (PDT) Received: by mail-ed1-x52c.google.com with SMTP id i13so1599877edb.9 for ; Wed, 26 May 2021 06:55:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mAPLcBwuCd3g055IKmI9GM/8O52Y4WnH2h3TnK9JHnk=; b=n3X7pDsfWyXBNmxgt9BO+V8nnmON/Sk6NQjORCQ8LlIY1Zy0+LB2KS1Xo+eujKQDIy paI5sw4TWtRMXaZEb4TiyGEVDcMhPMHiaaspiCzWiNul+q8Wl6/TaAlqOcIknFEzeWwQ XmHOtOG4NweqM1RMYM2cVmt7JAuc1G335e1fEXkBXXFHto9GNJOHW5/VchzpL/XZrlDe /iTHLZt7Nr5jqMYK/N6NhFK3TArtHmI1GlB6moOgq/j5RFrucHheqkCEgB0UMKVcJZrf zeANLUFHfrrHuq82ry0gMFGKiliq/ZkxXP1z2ekHWm6QA70O0SY6guuej7WFocNYxO2b uNoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mAPLcBwuCd3g055IKmI9GM/8O52Y4WnH2h3TnK9JHnk=; b=iRJ9FBVdMgZ7g+KiEpFogkMzOBj98bDRfDXya3tqRCPapKdA27ke97X5s1f7C6iObH TUdziRhe8oStNskWkmX9BjFfYQjUBrV0rKp7ckD0WEYP06AuP5Xn0xsrBAnVHDYP/yCP jhY/asgV6TqlQbK2yC/JfOfK3aYHqgUPegRP4nvGIlJ7tJ4KbKpowjPxpBnIPsqOCAWt rqFpiK1PrtB4yk9y6Bwbuq+Y+Ps2MQGeIXo9W9s226bxHyOTBJkRuDxDmgeeIv+euycg WOx+FIdCpoMoR0zXTSusao2emzkANxmoJzD3gk1cgkPTxqsy1fIwR2G1H6g1EuCMWsx8 fxGw== X-Gm-Message-State: AOAM530z0wvHVA/AaKKAmG98lV3YoaFgmzeMtIGJNjcmOB1kFKtrh4E+ PoHf0YYzSPgfaAWdp5M6mAg= X-Google-Smtp-Source: ABdhPJzS5bxUln5jC92P6vjMmyEDzMw+pJwvfCU306QY+yl4QEeWCQp6nnEnQarHZZQYop6q/5loag== X-Received: by 2002:aa7:d758:: with SMTP id a24mr37660190eds.220.1622037357752; Wed, 26 May 2021 06:55:57 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.55.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:55:57 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot Subject: [RFC PATCH v2 linux-next 06/14] net: dsa: sja1105: add a translation table for port speeds Date: Wed, 26 May 2021 16:55:27 +0300 Message-Id: <20210526135535.2515123-7-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC In order to support the new speed of 2500Mbps, the SJA1110 has achieved the great performance of changing the encoding in the MAC Configuration Table for the port speeds of 10, 100, 1000 compared to SJA1105. Because this is a common driver, we need a layer of indirection in order to program the hardware with the right values irrespective of switch generation. Signed-off-by: Vladimir Oltean --- Changes in v2: None. drivers/net/dsa/sja1105/sja1105.h | 17 +++++---- drivers/net/dsa/sja1105/sja1105_clocking.c | 22 +++++------- drivers/net/dsa/sja1105/sja1105_main.c | 38 ++++++++++++-------- drivers/net/dsa/sja1105/sja1105_spi.c | 42 ++++++++++++++++++++++ 4 files changed, 84 insertions(+), 35 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index a27841642693..867cda832e77 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -72,6 +72,15 @@ struct sja1105_regs { u64 stats[__MAX_SJA1105_STATS_AREA][SJA1105_MAX_NUM_PORTS]; }; +enum { + SJA1105_SPEED_AUTO, + SJA1105_SPEED_10MBPS, + SJA1105_SPEED_100MBPS, + SJA1105_SPEED_1000MBPS, + SJA1105_SPEED_2500MBPS, + SJA1105_SPEED_MAX, +}; + struct sja1105_info { u64 device_id; /* Needed for distinction between P and R, and between Q and S @@ -116,6 +125,7 @@ struct sja1105_info { bool supports_rgmii[SJA1105_MAX_NUM_PORTS]; bool supports_sgmii[SJA1105_MAX_NUM_PORTS]; bool supports_2500basex[SJA1105_MAX_NUM_PORTS]; + const u64 port_speed[SJA1105_SPEED_MAX]; }; enum sja1105_key_type { @@ -314,13 +324,6 @@ typedef enum { XMII_MODE_SGMII = 3, } sja1105_phy_interface_t; -typedef enum { - SJA1105_SPEED_10MBPS = 3, - SJA1105_SPEED_100MBPS = 2, - SJA1105_SPEED_1000MBPS = 1, - SJA1105_SPEED_AUTO = 0, -} sja1105_speed_t; - int sja1105pqrs_setup_rgmii_delay(const void *ctx, int port); int sja1105_clocking_setup_port(struct sja1105_private *priv, int port); int sja1105_clocking_setup(struct sja1105_private *priv); diff --git a/drivers/net/dsa/sja1105/sja1105_clocking.c b/drivers/net/dsa/sja1105/sja1105_clocking.c index 4697ac064abc..03173397d950 100644 --- a/drivers/net/dsa/sja1105/sja1105_clocking.c +++ b/drivers/net/dsa/sja1105/sja1105_clocking.c @@ -328,7 +328,7 @@ sja1105_cgu_pll_control_packing(void *buf, struct sja1105_cgu_pll_ctrl *cmd, } static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv, - int port, sja1105_speed_t speed) + int port, u64 speed) { const struct sja1105_regs *regs = priv->info->regs; struct sja1105_cgu_mii_ctrl txc; @@ -338,7 +338,7 @@ static int sja1105_cgu_rgmii_tx_clk_config(struct sja1105_private *priv, if (regs->rgmii_tx_clk[port] == SJA1105_RSV_ADDR) return 0; - if (speed == SJA1105_SPEED_1000MBPS) { + if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) { clksrc = CLKSRC_PLL0; } else { int clk_sources[] = {CLKSRC_IDIV0, CLKSRC_IDIV1, CLKSRC_IDIV2, @@ -524,35 +524,31 @@ static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port, { struct device *dev = priv->ds->dev; struct sja1105_mac_config_entry *mac; - sja1105_speed_t speed; + u64 speed; int rc; mac = priv->static_config.tables[BLK_IDX_MAC_CONFIG].entries; speed = mac[port].speed; - dev_dbg(dev, "Configuring port %d RGMII at speed %dMbps\n", + dev_dbg(dev, "Configuring port %d RGMII at speed %lldMbps\n", port, speed); - switch (speed) { - case SJA1105_SPEED_1000MBPS: + if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) { /* 1000Mbps, IDIV disabled (125 MHz) */ rc = sja1105_cgu_idiv_config(priv, port, false, 1); - break; - case SJA1105_SPEED_100MBPS: + } else if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS]) { /* 100Mbps, IDIV enabled, divide by 1 (25 MHz) */ rc = sja1105_cgu_idiv_config(priv, port, true, 1); - break; - case SJA1105_SPEED_10MBPS: + } else if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS]) { /* 10Mbps, IDIV enabled, divide by 10 (2.5 MHz) */ rc = sja1105_cgu_idiv_config(priv, port, true, 10); - break; - case SJA1105_SPEED_AUTO: + } else if (speed == priv->info->port_speed[SJA1105_SPEED_AUTO]) { /* Skip CGU configuration if there is no speed available * (e.g. link is not established yet) */ dev_dbg(dev, "Speed not available, skipping CGU config\n"); return 0; - default: + } else { rc = -EINVAL; } diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 8a07373e3cf3..d3aa14d3a5c6 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -80,7 +80,7 @@ static int sja1105_init_mac_settings(struct sja1105_private *priv) /* Always put the MAC speed in automatic mode, where it can be * adjusted at runtime by PHYLINK. */ - .speed = SJA1105_SPEED_AUTO, + .speed = priv->info->port_speed[SJA1105_SPEED_AUTO], /* No static correction for 1-step 1588 events */ .tp_delin = 0, .tp_delout = 0, @@ -990,12 +990,19 @@ static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv, } /* Convert link speed from SJA1105 to ethtool encoding */ -static int sja1105_speed[] = { - [SJA1105_SPEED_AUTO] = SPEED_UNKNOWN, - [SJA1105_SPEED_10MBPS] = SPEED_10, - [SJA1105_SPEED_100MBPS] = SPEED_100, - [SJA1105_SPEED_1000MBPS] = SPEED_1000, -}; +static int sja1105_port_speed_to_ethtool(struct sja1105_private *priv, + u64 speed) +{ + if (speed == priv->info->port_speed[SJA1105_SPEED_10MBPS]) + return SPEED_10; + if (speed == priv->info->port_speed[SJA1105_SPEED_100MBPS]) + return SPEED_100; + if (speed == priv->info->port_speed[SJA1105_SPEED_1000MBPS]) + return SPEED_1000; + if (speed == priv->info->port_speed[SJA1105_SPEED_2500MBPS]) + return SPEED_2500; + return SPEED_UNKNOWN; +} /* Set link speed in the MAC configuration for a specific port. */ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, @@ -1003,7 +1010,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, { struct sja1105_mac_config_entry *mac; struct device *dev = priv->ds->dev; - sja1105_speed_t speed; + u64 speed; int rc; /* On P/Q/R/S, one can read from the device via the MAC reconfiguration @@ -1023,16 +1030,16 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, * ok for power consumption in case AN will never complete - * otherwise PHYLINK should come back with a new update. */ - speed = SJA1105_SPEED_AUTO; + speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; break; case SPEED_10: - speed = SJA1105_SPEED_10MBPS; + speed = priv->info->port_speed[SJA1105_SPEED_10MBPS]; break; case SPEED_100: - speed = SJA1105_SPEED_100MBPS; + speed = priv->info->port_speed[SJA1105_SPEED_100MBPS]; break; case SPEED_1000: - speed = SJA1105_SPEED_1000MBPS; + speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; break; default: dev_err(dev, "Invalid speed %iMbps\n", speed_mbps); @@ -1047,7 +1054,7 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, * we need to configure the PCS only (if even that). */ if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII) - mac[port].speed = SJA1105_SPEED_1000MBPS; + mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; else mac[port].speed = speed; @@ -1883,8 +1890,9 @@ int sja1105_static_config_reload(struct sja1105_private *priv, * change it through the dynamic interface later. */ for (i = 0; i < ds->num_ports; i++) { - speed_mbps[i] = sja1105_speed[mac[i].speed]; - mac[i].speed = SJA1105_SPEED_AUTO; + speed_mbps[i] = sja1105_port_speed_to_ethtool(priv, + mac[i].speed); + mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; if (priv->phy_mode[i] == PHY_INTERFACE_MODE_SGMII) bmcr[i] = sja1105_sgmii_read(priv, i, diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 565b594efa7d..786c16a77e46 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -482,6 +482,13 @@ const struct sja1105_info sja1105e_info = { .ptp_cmd_packing = sja1105et_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105et_regs, + .port_speed = { + [SJA1105_SPEED_AUTO] = 0, + [SJA1105_SPEED_10MBPS] = 3, + [SJA1105_SPEED_100MBPS] = 2, + [SJA1105_SPEED_1000MBPS] = 1, + [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */ + }, .supports_mii = {true, true, true, true, true}, .supports_rmii = {true, true, true, true, true}, .supports_rgmii = {true, true, true, true, true}, @@ -505,6 +512,13 @@ const struct sja1105_info sja1105t_info = { .ptp_cmd_packing = sja1105et_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105et_regs, + .port_speed = { + [SJA1105_SPEED_AUTO] = 0, + [SJA1105_SPEED_10MBPS] = 3, + [SJA1105_SPEED_100MBPS] = 2, + [SJA1105_SPEED_1000MBPS] = 1, + [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */ + }, .supports_mii = {true, true, true, true, true}, .supports_rmii = {true, true, true, true, true}, .supports_rgmii = {true, true, true, true, true}, @@ -529,6 +543,13 @@ const struct sja1105_info sja1105p_info = { .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105pqrs_regs, + .port_speed = { + [SJA1105_SPEED_AUTO] = 0, + [SJA1105_SPEED_10MBPS] = 3, + [SJA1105_SPEED_100MBPS] = 2, + [SJA1105_SPEED_1000MBPS] = 1, + [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */ + }, .supports_mii = {true, true, true, true, true}, .supports_rmii = {true, true, true, true, true}, .supports_rgmii = {true, true, true, true, true}, @@ -553,6 +574,13 @@ const struct sja1105_info sja1105q_info = { .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105pqrs_regs, + .port_speed = { + [SJA1105_SPEED_AUTO] = 0, + [SJA1105_SPEED_10MBPS] = 3, + [SJA1105_SPEED_100MBPS] = 2, + [SJA1105_SPEED_1000MBPS] = 1, + [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */ + }, .supports_mii = {true, true, true, true, true}, .supports_rmii = {true, true, true, true, true}, .supports_rgmii = {true, true, true, true, true}, @@ -577,6 +605,13 @@ const struct sja1105_info sja1105r_info = { .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, .regs = &sja1105pqrs_regs, + .port_speed = { + [SJA1105_SPEED_AUTO] = 0, + [SJA1105_SPEED_10MBPS] = 3, + [SJA1105_SPEED_100MBPS] = 2, + [SJA1105_SPEED_1000MBPS] = 1, + [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */ + }, .supports_mii = {true, true, true, true, true}, .supports_rmii = {true, true, true, true, true}, .supports_rgmii = {true, true, true, true, true}, @@ -602,6 +637,13 @@ const struct sja1105_info sja1105s_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, + .port_speed = { + [SJA1105_SPEED_AUTO] = 0, + [SJA1105_SPEED_10MBPS] = 3, + [SJA1105_SPEED_100MBPS] = 2, + [SJA1105_SPEED_1000MBPS] = 1, + [SJA1105_SPEED_2500MBPS] = 0, /* Not supported */ + }, .supports_mii = {true, true, true, true, true}, .supports_rmii = {true, true, true, true, true}, .supports_rgmii = {true, true, true, true, true}, From patchwork Wed May 26 13:55:28 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281755 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8B100C47082 for ; Wed, 26 May 2021 13:56:15 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 741596143F for ; Wed, 26 May 2021 13:56:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234624AbhEZN5o (ORCPT ); Wed, 26 May 2021 09:57:44 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234428AbhEZN5c (ORCPT ); Wed, 26 May 2021 09:57:32 -0400 Received: from mail-ej1-x629.google.com (mail-ej1-x629.google.com [IPv6:2a00:1450:4864:20::629]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 145BCC061574 for ; Wed, 26 May 2021 06:56:00 -0700 (PDT) Received: by mail-ej1-x629.google.com with SMTP id jt22so2606436ejb.7 for ; Wed, 26 May 2021 06:56:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NREUawkbiSlhUvL4cnznGX+NA58sFaz3tm5HmS+R9d0=; b=UvHooha3EZMXP8Da4KEyBZVqB2/Ka+5WB81Qk+bctkA5Gch1dUI+mBX3KhQPchbirM D1wTquyXx0zJPFiu0Z41WfDoUAxo0KKe7QWF1RDp7vGubAzYBXi7wUkWEpnzK0KMiGYu pJnDoIYAFbP42Z3+E5CnVEB7NMvwqylkvnJRabKyIKGeLl3vuAd/QFeFjWgCIDyARSkX Z4kDQIkEGFElIoW2B6mIyS6gROd/MM6Q2gw0ydZj4ZD3J7PBC3b+BeKsEyuoJRJyJYZy rKmylcOb4ocNwE7UpHJM5fZ02FUop4B8+BMPsB2oCHGoqitVNU1h+rrMGc+KrEUiwmSs HD5Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NREUawkbiSlhUvL4cnznGX+NA58sFaz3tm5HmS+R9d0=; b=C8HiRKnc+f3WN9tC2+7KTB3uZbGX5EcmrU6SjZumnAI5snXS01+CeIH6VoVLU7XgQo wYyHtweIUyedn0lWE32Bc1XWlRYAFzK5trnf5Zv+sqhXwwz1l1+TaiQEbiQZwZaflyn4 eSmHUelT2WQz1GBSBY5MDKy3YeZxwwBFd+mSMZPhX1qMB2cjX8FQk2yyNdJmG2UpqBeb O48ulZyW1VVxqHqz90/R88hN2z2SjhBi0L1I6eEl7l3sDF+P+Ft/MWtKVpRpZ4yFvLla wglgw/okzS2rFQIXJ0x68slUi+/glX1SrIxLQ3fnRfTYPhe/cY1aWQWGEVEmE51ejcie cHYA== X-Gm-Message-State: AOAM530EvRVEcspjy7UBGKZDETwIAth437Wiks0hGSqn5Vkw0NswR0CE vPrSdYIsS1NJhllPqowTasE= X-Google-Smtp-Source: ABdhPJwfnqyKZ5VT1B7VIL+EVbm63VrTgZxPT28lhTrhcRspPFP4sZ3tmKPJx7m24MEdm+Zt0+eJBw== X-Received: by 2002:a17:906:6b92:: with SMTP id l18mr34588388ejr.367.1622037358558; Wed, 26 May 2021 06:55:58 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.55.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:55:58 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot Subject: [RFC PATCH v2 linux-next 07/14] net: dsa: sja1105: always keep RGMII ports in the MAC role Date: Wed, 26 May 2021 16:55:28 +0300 Message-Id: <20210526135535.2515123-8-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC In SJA1105, the xMII Mode Parameters Table field called PHY_MAC denotes the 'role' of the port, be it a PHY or a MAC. This makes a difference in the MII and RMII protocols, but RGMII is symmetric, so either PHY or MAC settings result in the same hardware behavior. The SJA1110 is different, and the RGMII ports only work when configured in MAC mode, so keep the port roles in MAC mode unconditionally. Why we had an RGMII port in the PHY role in the first place was because we wanted to have a way in the driver to denote whether RGMII delays should be applied based on the phy-mode property or not. This is already done in sja1105_parse_rgmii_delays() based on an intermediary struct sja1105_dt_port (which contains the port role). So it is a logical fallacy to use the hardware configuration as a scratchpad for driver data, it isn't necessary. We can also remove the gating condition for applying RGMII delays only for ports in the PHY role. The .setup_rgmii_delay() method looks at the priv->rgmii_rx_delay[port] and priv->rgmii_tx_delay[port] properties which are already populated properly (in the case of a port in the MAC role they are false). Removing this condition generates a few more SPI writes for these ports (clearing the RGMII delays) which are perhaps useless for SJA1105P/Q/R/S, where we know that the delays are disabled by default. But for SJA1110, the firmware on the embedded microcontroller might have done something funny, so it's always a good idea to clear the RGMII delays if that's what Linux expects. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- drivers/net/dsa/sja1105/sja1105_clocking.c | 7 +------ drivers/net/dsa/sja1105/sja1105_main.c | 8 +++++++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105_clocking.c b/drivers/net/dsa/sja1105/sja1105_clocking.c index 03173397d950..ae297648611f 100644 --- a/drivers/net/dsa/sja1105/sja1105_clocking.c +++ b/drivers/net/dsa/sja1105/sja1105_clocking.c @@ -566,14 +566,9 @@ static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port, dev_err(dev, "Failed to configure Tx pad registers\n"); return rc; } + if (!priv->info->setup_rgmii_delay) return 0; - /* The role has no hardware effect for RGMII. However we use it as - * a proxy for this interface being a MAC-to-MAC connection, with - * the RGMII internal delays needing to be applied by us. - */ - if (role == XMII_MAC) - return 0; return priv->info->setup_rgmii_delay(priv, port); } diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index d3aa14d3a5c6..04af644bf656 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -218,8 +218,14 @@ static int sja1105_init_mii_settings(struct sja1105_private *priv, /* Even though the SerDes port is able to drive SGMII autoneg * like a PHY would, from the perspective of the XMII tables, * the SGMII port should always be put in MAC mode. + * Similarly, RGMII is a symmetric protocol electrically + * speaking, and the 'RGMII PHY' role does not mean anything to + * hardware. Just keep the 'PHY role' notation relevant to the + * driver to mean 'the switch port should apply RGMII delays', + * but unconditionally put the port in the MAC role. */ - if (ports[i].phy_mode == PHY_INTERFACE_MODE_SGMII) + if (ports[i].phy_mode == PHY_INTERFACE_MODE_SGMII || + phy_interface_mode_is_rgmii(ports[i].phy_mode)) mii->phy_mac[i] = XMII_MAC; else mii->phy_mac[i] = ports[i].role; From patchwork Wed May 26 13:55:29 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281757 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD517C47088 for ; Wed, 26 May 2021 13:56:16 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8A2D0613D3 for ; Wed, 26 May 2021 13:56:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234650AbhEZN5r (ORCPT ); Wed, 26 May 2021 09:57:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53532 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232773AbhEZN5c (ORCPT ); Wed, 26 May 2021 09:57:32 -0400 Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CDBD9C06175F for ; Wed, 26 May 2021 06:56:00 -0700 (PDT) Received: by mail-ej1-x632.google.com with SMTP id s22so2583344ejv.12 for ; Wed, 26 May 2021 06:56:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XhOFN1Z4SAm1vCcLBPoKZJiSnjQphuLxdON2YN9bBGk=; b=QggCQCpzsHlnaM5AsC0KsUGfMkOLeF/nlgU7zl8Z6y1E/gfOc2KHvOqhCfHUQPb0pV dMyQpBTKyP05E6DsriHnzyygl99iP76HLssyY/Jff2O5xW99agvokqurKAD3Og4jXmHG 25xTzwQNvMLXfPKaulem1VnYjiC1ST/YZRtE6rIt1yC00zu2LOUstOjodPhKWXmxbKfc C12QgI/0iAZGDFKjJ6kvf8wE/PijNyw8p1FogKRdAO4RO+bAtZv19ic980qUVJ/0h2yi H6/PtAWYuAZaezZhla/NHV7ni3jd5EK8TAr/8lEwi7UpjANjxjkzdEMvxT0RaXerTVQE QOHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XhOFN1Z4SAm1vCcLBPoKZJiSnjQphuLxdON2YN9bBGk=; b=IprAe/5Q35fjTkpV1ZKBnv+4iHLXegmEwPGCpu6FACjRMUHbIpmSRYxdN6j1TPmSPN 2R2vAqiv9bGrkhCWvNYX/vbRLmdwgwu5nXwKljnDGmnLzVX0rXHrA247XRsysjB1h1z0 9aSwR2/WXBsKNABAM8OGFQCCjWuuCCuR6rmtU0PuFWRs6RJntUA2ZLY5CI9rpGllCFle 5I5Ykoknrnp3EmDh5otjL067qakK5u9gROTlu1XbT+OQ8FYei10oJwomK7nb8Iy4Q0f1 jGqbvgb4qZWKsW92EhvXVRMZjS3Mc8L0by+w5cX1P67V1ispmognhnMX6/ZLUC7yfSdP gODg== X-Gm-Message-State: AOAM533rHwZ24h2PukXnXlJ2Ia09sWvXwMHd1nU67gRBc2keJo/DcYFh U7SRScH/Z50Aj6oum9RJtWE= X-Google-Smtp-Source: ABdhPJxty+DYxsqP+ar3qyelUf0pnvb7fwCwKtyFkDWQKCke/a/q5SJU0hAoV3v/9w+2cWFpmiX10Q== X-Received: by 2002:a17:907:7654:: with SMTP id kj20mr34133359ejc.439.1622037359398; Wed, 26 May 2021 06:55:59 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.55.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:55:59 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot Subject: [RFC PATCH v2 linux-next 08/14] net: dsa: sja1105: some table entries are always present when read dynamically Date: Wed, 26 May 2021 16:55:29 +0300 Message-Id: <20210526135535.2515123-9-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC The SJA1105 has a static configuration comprised of a number of tables with entries. Some of these can be read and modified at runtime as well, through the dynamic configuration interface. As a careful reader can notice from the comments in this file, the software interface for accessing a table entry through the dynamic reconfiguration is a bit of a no man's land, and varies wildly across switch generations and even from one kind of table to another. I have tried my best to come up with a software representation of a 'common denominator' SPI command to access a table entry through the dynamic configuration interface: struct sja1105_dyn_cmd { bool search; u64 valid; /* must be set to 1 */ u64 rdwrset; /* 0 to read, 1 to write */ u64 errors; u64 valident; /* 0 if entry is invalid, 1 if valid */ u64 index; }; Relevant to this patch is the VALIDENT bit, which for READ commands is populated by the switch and lets us know if we're looking at junk or at a real table entry. In SJA1105, the dynamic reconfiguration interface for management routes has notably not implemented the VALIDENT bit, leading to a workaround to ignore this field in sja1105_dynamic_config_read(), as it will be set to zero, but the data is valid nonetheless. In SJA1110, this pattern has sadly been abused to death, and while there are many more tables which can be read back over the dynamic config interface compared to SJA1105, their handling isn't in any way more uniform. Generally speaking, if there is a single possible entry in a given table, and loading that table in the static config is mandatory as per the documentation, then the VALIDENT bit is deemed as redundant and more than likely not implemented. So it is time to make the workaround more official, and add a bit to the flags implemented by dynamic config tables. It will be used by more tables when SJA1110 support arrives. Signed-off-by: Vladimir Oltean --- Changes in v2: None. drivers/net/dsa/sja1105/sja1105_dynamic_config.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c index 12cd04b56803..ff2742f53de3 100644 --- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c +++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c @@ -78,6 +78,9 @@ * on its ENTRY portion, as a result of a SPI write command. * Only the TCAM-based FDB table on SJA1105 P/Q/R/S supports * this. + * OP_VALID_ANYWAY: Reading some tables through the dynamic config + * interface is possible even if the VALIDENT bit is not + * set in the writeback. So don't error out in that case. * - .max_entry_count: The number of entries, counting from zero, that can be * reconfigured through the dynamic interface. If a static * table can be reconfigured at all dynamically, this @@ -651,6 +654,7 @@ static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr, #define OP_WRITE BIT(1) #define OP_DEL BIT(2) #define OP_SEARCH BIT(3) +#define OP_VALID_ANYWAY BIT(4) /* SJA1105E/T: First generation */ const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = { @@ -673,7 +677,7 @@ const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN] = { [BLK_IDX_MGMT_ROUTE] = { .entry_packing = sja1105et_mgmt_route_entry_packing, .cmd_packing = sja1105et_mgmt_route_cmd_packing, - .access = (OP_READ | OP_WRITE), + .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), .max_entry_count = SJA1105_NUM_PORTS, .packed_size = SJA1105ET_SIZE_L2_LOOKUP_DYN_CMD, .addr = 0x20, @@ -757,7 +761,7 @@ const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = { [BLK_IDX_MGMT_ROUTE] = { .entry_packing = sja1105pqrs_mgmt_route_entry_packing, .cmd_packing = sja1105pqrs_mgmt_route_cmd_packing, - .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH), + .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH | OP_VALID_ANYWAY), .max_entry_count = SJA1105_NUM_PORTS, .packed_size = SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD, .addr = 0x24, @@ -911,11 +915,8 @@ int sja1105_dynamic_config_read(struct sja1105_private *priv, cmd = (struct sja1105_dyn_cmd) {0}; ops->cmd_packing(packed_buf, &cmd, UNPACK); - /* UM10944: [valident] will always be found cleared - * during a read access with MGMTROUTE set. - * So don't error out in that case. - */ - if (!cmd.valident && blk_idx != BLK_IDX_MGMT_ROUTE) + + if (!cmd.valident && !(ops->access & OP_VALID_ANYWAY)) return -ENOENT; cpu_relax(); } while (cmd.valid && --retries); From patchwork Wed May 26 13:55:30 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281761 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8291CC47082 for ; Wed, 26 May 2021 13:56:20 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6691A613D3 for ; Wed, 26 May 2021 13:56:20 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234581AbhEZN5u (ORCPT ); Wed, 26 May 2021 09:57:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53546 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234517AbhEZN5f (ORCPT ); Wed, 26 May 2021 09:57:35 -0400 Received: from mail-ej1-x62c.google.com (mail-ej1-x62c.google.com [IPv6:2a00:1450:4864:20::62c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BEB3BC06138C for ; Wed, 26 May 2021 06:56:01 -0700 (PDT) Received: by mail-ej1-x62c.google.com with SMTP id k14so2639039eji.2 for ; Wed, 26 May 2021 06:56:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XrC3ArYNhyLblZEwF0swvO1FRFJKVFZm0HQS4XG/SNI=; b=Fh4V1pL5vWs6UnWik8klHPbZgotCF2TfnHk+OPJBSRWEmoHbJutpdtWWs/ihi2Apr6 RmXNdKG626tEt8vjTjaCLliGpCqx09QWqWAS6b3XknXLydUJMivRIqti/R7LsfVga2WD bfzXIPNvSEUJXU3I7cbjRojK6A1bcKgtsXrQ65dm/KjOxUgYjuQG0prY9ombXtzne25n TbUgfrMrGJ9wPr3N21GXUQ16PKOFpYWrVIRH1KG6sKtmkVlSdQmAmI+wM2d/RbnZtiib 2jD0/0Z/fxyLrLpLHR0iaquNxVJiquUn45CvEqU/8PZFEg7ipKFNGqyeHeZU5AQYJuZG 46wg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XrC3ArYNhyLblZEwF0swvO1FRFJKVFZm0HQS4XG/SNI=; b=JcQK2/UhD+jRcpb2f19lb6chsJVvg4EyuQyREX81y1/RryqFvj/ZvkZapZihPU86l/ XO0FeA0ZC1akPeOFCZ7ua4xozHCgKmLKus08QC/cSaDB3nX9YMZVH8+hyBc1eRnf9sd0 AOSv3A7W+wc0YFUvHqjtiZL2uFZYMHWhhC8fgumBpHmx/rQxwv7WaCr4+UzrFgV9uAO5 Iq0TsQA7AurGuaPTq62Hv4vHC8sXL0eikHKnZbcY4I5gHnAqMQhjRsMPchS7SPoRJUWD /EqgK8WTfJiZoBS/AEFbq0Vosevq28m/y6c/b3MHpmKBhaviAtgpjn2NyBFooiNbWom4 AUFA== X-Gm-Message-State: AOAM531+efKctcEBcxkx2OiSugr2MCsteohzoohEVEQmiei70QOT48B4 GKoChAdob3+gaQXWk8193Wg= X-Google-Smtp-Source: ABdhPJz4/L0qZUbU/14/YcHThNdasTTfuuItZyfc/w4yKCULM5d6DAoqNMUQcPsj2Pz73KmR83Z/OQ== X-Received: by 2002:a17:906:840c:: with SMTP id n12mr33521713ejx.431.1622037360251; Wed, 26 May 2021 06:56:00 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.55.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:55:59 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Rob Herring Subject: [RFC PATCH v2 linux-next 09/14] dt-bindings: net: dsa: sja1105: convert to YAML schema Date: Wed, 26 May 2021 16:55:30 +0300 Message-Id: <20210526135535.2515123-10-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC The following issues exist with the device-specific sja1105,role-mac and sja1105,role-phy: (a) the "sja1105" is not a valid vendor prefix and should probably have been "nxp", but (b) as per the discussion with Florian here: https://lore.kernel.org/netdev/20210201214515.cx6ivvme2tlquge2@skbuf/ more phy-mode values similar to "revmii" can be added which denote that the port is in the role of a PHY (such as "revrmii"), making the sja1105,role-phy redundant. Because there are no upstream users (or any users at all, to my knowledge) of these properties, they could even be removed in a future commit as far as I am concerned. (c) when I force-add sja1105,role-phy to a device tree for testing, the patternProperties matching does not work, it results in the following error: ethernet-switch@2: ethernet-ports:port@1: 'sja1105,role-phy' does not match any of the regexes: 'pinctrl-[0-9]+' From schema: Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml But what's even more interesting is that if I remove the "additionalProperties: true" that dsa.yaml has, I get even more validation errors coming from patternProperties not matching either, from spi-controller.yaml: ethernet-switch@2: 'compatible', 'mdio', 'reg', 'spi-cpol', 'spi-max-frequency' do not match any of the regexes: '^(ethernet-)?ports$', 'pinctrl-[0-9]+' So... it is probably broken. Rob Herring says here: https://lore.kernel.org/linux-spi/20210324181037.GB3320002@robh.at.kernel.org/ I'm aware of the issue, but I don't have a solution for this situation. It's a problem anywhere we have a parent or bus binding defining properties for child nodes. For now, I'd just avoid it in the examples and we'll figure out how to deal with actual dts files later. So that's what I did. Cc: Rob Herring Signed-off-by: Vladimir Oltean --- Changes in v2: Patch is new. .../bindings/net/dsa/nxp,sja1105.yaml | 129 +++++++++++++++ .../devicetree/bindings/net/dsa/sja1105.txt | 156 ------------------ 2 files changed, 129 insertions(+), 156 deletions(-) create mode 100644 Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml delete mode 100644 Documentation/devicetree/bindings/net/dsa/sja1105.txt diff --git a/Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml b/Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml new file mode 100644 index 000000000000..c1f18849a54a --- /dev/null +++ b/Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml @@ -0,0 +1,129 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/net/dsa/nxp,sja1105.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NXP SJA1105 Automotive Ethernet Switch Family Device Tree Bindings + +description: + The SJA1105 SPI interface requires a CS-to-CLK time (t2 in UM10944.pdf) of at + least one half of t_CLK. At an SPI frequency of 1MHz, this means a minimum + cs_sck_delay of 500ns. Ensuring that this SPI timing requirement is observed + depends on the SPI bus master driver. + +allOf: + - $ref: "dsa.yaml#" + +maintainers: + - Vladimir Oltean + +properties: + compatible: + oneOf: + - enum: + - nxp,sja1105e + - nxp,sja1105t + - nxp,sja1105p + - nxp,sja1105q + - nxp,sja1105r + - nxp,sja1105s + + reg: + maxItems: 1 + +patternProperties: + "^(ethernet-)?ports$": + type: object + + patternProperties: + "^(ethernet-)?port@[0-9]+$": + type: object + properties: + + # By default (unless otherwise specified) a port is configured as MAC + # if it is driving a PHY (phy-handle is present) or as PHY if it is + # PHY-less (fixed-link specified, presumably because it is connected + # to a MAC). It is suggested to not use these bindings unless an + # explicit override is necessary (for example, if SJA1105 ports are at + # both ends of a MII/RMII PHY-less setup. In that case, one end would + # need to have sja1105,role-mac, and the other sja1105,role-phy). + sja1105,role-mac: + $ref: /schemas/types.yaml#/definitions/flag + description: + Specifies whether the SJA1105 port is a clock source or sink + for this interface, according to the applicable standard + (applicable for MII and RMII, but not applicable for RGMII + where there are separate TX and RX clocks). In the case of + RGMII it affects the behavior regarding internal delays. + If the port is configured in the role of an RGMII MAC, it will + let the PHY apply internal RGMII delays according to the + phy-mode property, otherwise it will apply the delays itself. + + sja1105,role-phy: + $ref: /schemas/types.yaml#/definitions/flag + description: + See sja1105,role-mac. + +required: + - compatible + - reg + +unevaluatedProperties: false + +examples: + - | + spi { + #address-cells = <1>; + #size-cells = <0>; + + ethernet-switch@1 { + reg = <0x1>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "nxp,sja1105t"; + + ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + phy-handle = <&rgmii_phy6>; + phy-mode = "rgmii-id"; + reg = <0>; + /* Implicit "sja1105,role-mac;" */ + }; + + port@1 { + phy-handle = <&rgmii_phy3>; + phy-mode = "rgmii-id"; + reg = <1>; + /* Implicit "sja1105,role-mac;" */ + }; + + port@2 { + phy-handle = <&rgmii_phy4>; + phy-mode = "rgmii-id"; + reg = <2>; + /* Implicit "sja1105,role-mac;" */ + }; + + port@3 { + phy-mode = "rgmii-id"; + reg = <3>; + }; + + port@4 { + ethernet = <&enet2>; + phy-mode = "rgmii"; + reg = <4>; + /* Implicit "sja1105,role-phy;" */ + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; + }; diff --git a/Documentation/devicetree/bindings/net/dsa/sja1105.txt b/Documentation/devicetree/bindings/net/dsa/sja1105.txt deleted file mode 100644 index 13fd21074d48..000000000000 --- a/Documentation/devicetree/bindings/net/dsa/sja1105.txt +++ /dev/null @@ -1,156 +0,0 @@ -NXP SJA1105 switch driver -========================= - -Required properties: - -- compatible: - Must be one of: - - "nxp,sja1105e" - - "nxp,sja1105t" - - "nxp,sja1105p" - - "nxp,sja1105q" - - "nxp,sja1105r" - - "nxp,sja1105s" - - Although the device ID could be detected at runtime, explicit bindings - are required in order to be able to statically check their validity. - For example, SGMII can only be specified on port 4 of R and S devices, - and the non-SGMII devices, while pin-compatible, are not equal in terms - of support for RGMII internal delays (supported on P/Q/R/S, but not on - E/T). - -Optional properties: - -- sja1105,role-mac: -- sja1105,role-phy: - Boolean properties that can be assigned under each port node. By - default (unless otherwise specified) a port is configured as MAC if it - is driving a PHY (phy-handle is present) or as PHY if it is PHY-less - (fixed-link specified, presumably because it is connected to a MAC). - The effect of this property (in either its implicit or explicit form) - is: - - In the case of MII or RMII it specifies whether the SJA1105 port is a - clock source or sink for this interface (not applicable for RGMII - where there is a Tx and an Rx clock). - - In the case of RGMII it affects the behavior regarding internal - delays: - 1. If sja1105,role-mac is specified, and the phy-mode property is one - of "rgmii-id", "rgmii-txid" or "rgmii-rxid", then the entity - designated to apply the delay/clock skew necessary for RGMII - is the PHY. The SJA1105 MAC does not apply any internal delays. - 2. If sja1105,role-phy is specified, and the phy-mode property is one - of the above, the designated entity to apply the internal delays - is the SJA1105 MAC (if hardware-supported). This is only supported - by the second-generation (P/Q/R/S) hardware. On a first-generation - E or T device, it is an error to specify an RGMII phy-mode other - than "rgmii" for a port that is in fixed-link mode. In that case, - the clock skew must either be added by the MAC at the other end of - the fixed-link, or by PCB serpentine traces on the board. - These properties are required, for example, in the case where SJA1105 - ports are at both ends of a MII/RMII PHY-less setup. One end would need - to have sja1105,role-mac, while the other sja1105,role-phy. - -See Documentation/devicetree/bindings/net/dsa/dsa.txt for the list of standard -DSA required and optional properties. - -Other observations ------------------- - -The SJA1105 SPI interface requires a CS-to-CLK time (t2 in UM10944) of at least -one half of t_CLK. At an SPI frequency of 1MHz, this means a minimum -cs_sck_delay of 500ns. Ensuring that this SPI timing requirement is observed -depends on the SPI bus master driver. - -Example -------- - -Ethernet switch connected via SPI to the host, CPU port wired to enet2: - -arch/arm/boot/dts/ls1021a-tsn.dts: - -/* SPI controller of the LS1021 */ -&dspi0 { - sja1105@1 { - reg = <0x1>; - #address-cells = <1>; - #size-cells = <0>; - compatible = "nxp,sja1105t"; - spi-max-frequency = <4000000>; - fsl,spi-cs-sck-delay = <1000>; - fsl,spi-sck-cs-delay = <1000>; - ports { - #address-cells = <1>; - #size-cells = <0>; - port@0 { - /* ETH5 written on chassis */ - label = "swp5"; - phy-handle = <&rgmii_phy6>; - phy-mode = "rgmii-id"; - reg = <0>; - /* Implicit "sja1105,role-mac;" */ - }; - port@1 { - /* ETH2 written on chassis */ - label = "swp2"; - phy-handle = <&rgmii_phy3>; - phy-mode = "rgmii-id"; - reg = <1>; - /* Implicit "sja1105,role-mac;" */ - }; - port@2 { - /* ETH3 written on chassis */ - label = "swp3"; - phy-handle = <&rgmii_phy4>; - phy-mode = "rgmii-id"; - reg = <2>; - /* Implicit "sja1105,role-mac;" */ - }; - port@3 { - /* ETH4 written on chassis */ - phy-handle = <&rgmii_phy5>; - label = "swp4"; - phy-mode = "rgmii-id"; - reg = <3>; - /* Implicit "sja1105,role-mac;" */ - }; - port@4 { - /* Internal port connected to eth2 */ - ethernet = <&enet2>; - phy-mode = "rgmii"; - reg = <4>; - /* Implicit "sja1105,role-phy;" */ - fixed-link { - speed = <1000>; - full-duplex; - }; - }; - }; - }; -}; - -/* MDIO controller of the LS1021 */ -&mdio0 { - /* BCM5464 */ - rgmii_phy3: ethernet-phy@3 { - reg = <0x3>; - }; - rgmii_phy4: ethernet-phy@4 { - reg = <0x4>; - }; - rgmii_phy5: ethernet-phy@5 { - reg = <0x5>; - }; - rgmii_phy6: ethernet-phy@6 { - reg = <0x6>; - }; -}; - -/* Ethernet master port of the LS1021 */ -&enet2 { - phy-connection-type = "rgmii"; - status = "ok"; - fixed-link { - speed = <1000>; - full-duplex; - }; -}; From patchwork Wed May 26 13:55:31 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281759 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3709AC47089 for ; Wed, 26 May 2021 13:56:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1AD67611C9 for ; Wed, 26 May 2021 13:56:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234678AbhEZN5s (ORCPT ); Wed, 26 May 2021 09:57:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234502AbhEZN5e (ORCPT ); Wed, 26 May 2021 09:57:34 -0400 Received: from mail-ej1-x632.google.com (mail-ej1-x632.google.com [IPv6:2a00:1450:4864:20::632]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B20AC06138D for ; Wed, 26 May 2021 06:56:02 -0700 (PDT) Received: by mail-ej1-x632.google.com with SMTP id c20so2628027ejm.3 for ; Wed, 26 May 2021 06:56:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=o0MVqFruU6aPtwc2tbsO0idX94GaaF33HpLypJmzPKQ=; b=IkWH6+a81QAFnTAJl7aAF468bg+9AMNfuDagYkmAEPYE/YJWxTloB5NNGdALVyTInO Y/WPoHHnJAOngaOWYNr/SM9w61bebz2l1x9hCL3CZNlchQG4XigIkt6OmjTQLnfkDrZi raqYYKhLQY4Qo9ftRjxa3v7h5U10XyOBXDsKwCGTjbTmVxZ4A/eXwjxgFV5K8Nl73YJ7 FCmlZPqOs5F5++Ps2XJCXsnMEPiUVt5AY2/Hxs/Vc37HkCI44TfAhiC08u6s80j4vuwP Fw38oRcj+cCqYmqdpEgz73FwNvL1Xu3sO9iViEoT7Rh7r57g+ldA6/OkzT7Dybjvqyu2 A5nA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=o0MVqFruU6aPtwc2tbsO0idX94GaaF33HpLypJmzPKQ=; b=CrHaEx/jmSbrUstWxKNp+IR2drPjTLibF8eaYe0e3zESLk3dY6ExEs7Z3ufIROjQnV T81227peGWsAk33+JHp41mztfhuC+cMpdKvT6w+NHPIgHwPtAXT0FRFUTRrQxj2bcmjr 9BpyqlLM2JEZqgD26ztx75w3QFM8MRrJgZ3Nvhz/YRkfrqctXHKy/D5oNfPSOo0MtCHt ESl8sDmQNOBLr0m8JlVN8tBc/+kOcQ/Vcfpqs+NI85Ql7LUw8VZZsitt1rwc3m0qEnHb SLySsvYPzvGGz7ken7Zx6YCplskoVp+wJweb1DLOpx7NjQMCzUegF4p48tliZYNiCq6N WvDg== X-Gm-Message-State: AOAM533kIck9c3uqp+C5Y8fWQBqAKhZNv5ht4oT3YXhNT/oRcpqrJt8Q 5+RGqRNox4Z2Wl/omGxMedI= X-Google-Smtp-Source: ABdhPJxPXrPpgDNs49bM+uMKjudVqSc0WsvBrUkVKeiVSue46nx0EyuTUB4t2iZ+LpyYvRfQWLyjJg== X-Received: by 2002:a17:906:fa93:: with SMTP id lt19mr33874630ejb.14.1622037361251; Wed, 26 May 2021 06:56:01 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.56.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:56:00 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Rob Herring Subject: [RFC PATCH v2 linux-next 10/14] dt-bindings: net: dsa: sja1105: add SJA1110 bindings Date: Wed, 26 May 2021 16:55:31 +0300 Message-Id: <20210526135535.2515123-11-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC There are 4 variations of the SJA1110 switch which have a different set of MII protocols supported per port. Document the compatible strings. Also, the SJA1110 optionally supports 2 internal MDIO buses for 2 different types of Ethernet PHYs. Document a container node called "mdios" which has 2 subnodes "mdio@0" and "mdio@1", identifiable via compatible string, under which the driver finds the internal PHYs. Cc: Rob Herring Signed-off-by: Vladimir Oltean --- Changes in v2: Patch is new. .../bindings/net/dsa/nxp,sja1105.yaml | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml b/Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml index c1f18849a54a..640da65b0f59 100644 --- a/Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml +++ b/Documentation/devicetree/bindings/net/dsa/nxp,sja1105.yaml @@ -28,10 +28,53 @@ properties: - nxp,sja1105q - nxp,sja1105r - nxp,sja1105s + - nxp,sja1110a + - nxp,sja1110b + - nxp,sja1110c + - nxp,sja1110d reg: maxItems: 1 + # Optional container node for the 2 internal MDIO buses of the SJA1110 + # (one for the internal 100base-T1 PHYs and the other for the single + # 100base-TX PHY). The "reg" property does not have physical significance. + # The PHY addresses to port correspondence is as follows: for 100base-T1, + # port 5 has PHY 1, port 6 has PHY 2 etc, while for 100base-TX, port 1 has + # PHY 1. + mdios: + type: object + + properties: + '#address-cells': + const: 1 + '#size-cells': + const: 0 + + patternProperties: + "^mdio@[0-1]$": + type: object + + allOf: + - $ref: "http://devicetree.org/schemas/net/mdio.yaml#" + + properties: + compatible: + oneOf: + - enum: + - nxp,sja1110-base-t1-mdio + - nxp,sja1110-base-tx-mdio + + reg: + oneOf: + - enum: + - 0 + - 1 + + required: + - compatible + - reg + patternProperties: "^(ethernet-)?ports$": type: object From patchwork Wed May 26 13:55:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281763 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E60BAC47082 for ; Wed, 26 May 2021 13:56:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B8D95613D3 for ; Wed, 26 May 2021 13:56:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234714AbhEZN5z (ORCPT ); Wed, 26 May 2021 09:57:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53520 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234096AbhEZN5g (ORCPT ); Wed, 26 May 2021 09:57:36 -0400 Received: from mail-ed1-x533.google.com (mail-ed1-x533.google.com [IPv6:2a00:1450:4864:20::533]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 21A94C061756 for ; Wed, 26 May 2021 06:56:04 -0700 (PDT) Received: by mail-ed1-x533.google.com with SMTP id h16so1618984edr.6 for ; Wed, 26 May 2021 06:56:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1WazJaW3yUqBduwaZ6g9b034ysTaCm3Bdh3Dfvp6sHk=; b=kjCGUbfKHJPp7dNiXuz3QDoU9SVa8iyHIGX18o/6UE0Lcz6ZQL9by2XKDkFLlwBcpv tJKAsyjepQuFoU0AExYRGmKwS25Vr+KPwCNEEfJ/MedBJESjnq59oMtxKvHBUAANCE+6 M2mB43mlNLxQf921D3pRz6j33o/oNYTzrrrDmsIqzL0uCcGKlvU+ABAQIu+QFuqBPKq9 lnPrvC+OCN9+7QyJ444/MvyQq46Tt7+SaMyC4sJy3dE+3NL/q8KBNMOdOQH9ykhPa8lg Zd8TniDBmCBtJjdhO8wZ4MMbDr77NcVEAanxXKmr/JqZ8Uo3S1EgI54HncYabQC1J731 TIWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1WazJaW3yUqBduwaZ6g9b034ysTaCm3Bdh3Dfvp6sHk=; b=qRFPX0lt+hL3Y2N4LAOyOv5RmEwpAtfyQJbAYg6hgoNvXxhulQvzaA93oUQFdvhWaJ ViawfJGdxdsDNQh3uMx+lTGW/BxqyrypHpTSzKeGXok9KFUF20MnI6l8ZeEqexOlulwg VkrcgdUS0p+aRqbzTwX3Rmd3KDmtls3PlWuHDW7834v0aOTUHUhnNKapR64oWDTLIy2v Cr8mkhsu1aPbVbMAANSAB27tjPNL/ZBCsUWeMCgaClLbuE6JzQT3OKzKSECuSXUU33IM gXxfGa89onJuEDg+072P/9J5sVO+rl0Gc+McZvtRaiqFWW50LplQhbdBFAlZHWQPCR2B ANuQ== X-Gm-Message-State: AOAM530HGXaG49YKdY6MeKY5n6eTOUSMuI8PJis/jiWimRWYsbLbrvQR GWtD18G+BEEURn6wCV6GP+Pulh17uQg= X-Google-Smtp-Source: ABdhPJwlmqZOYtjmHMcR7foFED2igU7TSwVy2Q2d/KyCsV1ruR4XasCD+NGSNQ6M+huJBb64lm3cUQ== X-Received: by 2002:a05:6402:14d2:: with SMTP id f18mr1079502edx.259.1622037362298; Wed, 26 May 2021 06:56:02 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.56.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:56:01 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot Subject: [RFC PATCH v2 linux-next 11/14] net: dsa: sja1105: add support for the SJA1110 switch family Date: Wed, 26 May 2021 16:55:32 +0300 Message-Id: <20210526135535.2515123-12-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC The SJA1110 is basically an SJA1105 with more ports, some integrated PHYs (100base-T1 and 100base-TX) and an embedded microcontroller which can be disabled, and the switch core can be controlled by a host running Linux, over SPI. This patch contains: - the static and dynamic config packing functions, for the tables that are common with SJA1105 - one more static config tables which is "unique" to the SJA1110 (actually it is a rehash of stuff that was placed somewhere else in SJA1105): the PCP Remapping Table - a reset and clock configuration procedure for the SJA1110 switch. This resets just the switch subsystem, and gates off the clock which powers on the embedded microcontroller. - an RGMII delay configuration procedure for SJA1110, which is very similar to SJA1105, but different enough for us to be unable to reuse it (this is a pattern that repeats itself) - some adaptations to dynamic config table entries which are no longer programmed in the same way. For example, to delete a VLAN, you used to write an entry through the dynamic reconfiguration interface with the desired VLAN ID, and with the VALIDENT bit set to false. Now, the VLAN table entries contain a TYPE_ENTRY field, which must be set to zero (in a backwards-incompatible way) in order for the entry to be deleted, or to some other entry for the VLAN to match "inner tagged" or "outer tagged" packets. - a similar thing for the static config: the xMII Mode Parameters Table encoding for SGMII and MII (the latter just when attached to a 100base-TX PHY) just isn't what it used to be in SJA1105. They are identical, except there is an extra "special" bit which needs to be set. Set it. Signed-off-by: Vladimir Oltean --- Changes in v2: None. drivers/net/dsa/sja1105/sja1105.h | 24 +- drivers/net/dsa/sja1105/sja1105_clocking.c | 91 ++++ .../net/dsa/sja1105/sja1105_dynamic_config.c | 321 +++++++++++- .../net/dsa/sja1105/sja1105_dynamic_config.h | 1 + drivers/net/dsa/sja1105/sja1105_main.c | 55 +- drivers/net/dsa/sja1105/sja1105_spi.c | 252 +++++++++ .../net/dsa/sja1105/sja1105_static_config.c | 483 ++++++++++++++++++ .../net/dsa/sja1105/sja1105_static_config.h | 98 +++- 8 files changed, 1313 insertions(+), 12 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 867cda832e77..8bfda8c7bc1f 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -13,15 +13,12 @@ #include #include "sja1105_static_config.h" -#define SJA1105_NUM_PORTS 5 -#define SJA1105_MAX_NUM_PORTS SJA1105_NUM_PORTS -#define SJA1105_NUM_TC 8 #define SJA1105ET_FDB_BIN_SIZE 4 /* The hardware value is in multiples of 10 ms. * The passed parameter is in multiples of 1 ms. */ #define SJA1105_AGEING_TIME_MS(ms) ((ms) / 10) -#define SJA1105_NUM_L2_POLICERS 45 +#define SJA1105_NUM_L2_POLICERS SJA1110_MAX_L2_POLICING_COUNT typedef enum { SPI_READ = 0, @@ -99,6 +96,7 @@ struct sja1105_info { int ptpegr_ts_bytes; int num_cbs_shapers; int max_frame_mem; + int num_ports; const struct sja1105_dynamic_table_ops *dyn_ops; const struct sja1105_table_ops *static_ops; const struct sja1105_regs *regs; @@ -309,6 +307,10 @@ extern const struct sja1105_info sja1105p_info; extern const struct sja1105_info sja1105q_info; extern const struct sja1105_info sja1105r_info; extern const struct sja1105_info sja1105s_info; +extern const struct sja1105_info sja1110a_info; +extern const struct sja1105_info sja1110b_info; +extern const struct sja1105_info sja1110c_info; +extern const struct sja1105_info sja1110d_info; /* From sja1105_clocking.c */ @@ -325,8 +327,10 @@ typedef enum { } sja1105_phy_interface_t; int sja1105pqrs_setup_rgmii_delay(const void *ctx, int port); +int sja1110_setup_rgmii_delay(const void *ctx, int port); int sja1105_clocking_setup_port(struct sja1105_private *priv, int port); int sja1105_clocking_setup(struct sja1105_private *priv); +int sja1110_clocking_setup(struct sja1105_private *priv); /* From sja1105_ethtool.c */ void sja1105_get_ethtool_stats(struct dsa_switch *ds, int port, u64 *data); @@ -347,6 +351,18 @@ enum sja1105_iotag { SJA1105_S_TAG = 1, /* Outer VLAN header */ }; +enum sja1110_vlan_type { + SJA1110_VLAN_INVALID = 0, + SJA1110_VLAN_C_TAG = 1, /* Single inner VLAN tag */ + SJA1110_VLAN_S_TAG = 2, /* Single outer VLAN tag */ + SJA1110_VLAN_D_TAG = 3, /* Double tagged, use outer tag for lookup */ +}; + +enum sja1110_shaper_type { + SJA1110_LEAKY_BUCKET_SHAPER = 0, + SJA1110_CBS_SHAPER = 1, +}; + u8 sja1105et_fdb_hash(struct sja1105_private *priv, const u8 *addr, u16 vid); int sja1105et_fdb_add(struct dsa_switch *ds, int port, const unsigned char *addr, u16 vid); diff --git a/drivers/net/dsa/sja1105/sja1105_clocking.c b/drivers/net/dsa/sja1105/sja1105_clocking.c index ae297648611f..645edea5a81f 100644 --- a/drivers/net/dsa/sja1105/sja1105_clocking.c +++ b/drivers/net/dsa/sja1105/sja1105_clocking.c @@ -6,6 +6,7 @@ #include "sja1105.h" #define SJA1105_SIZE_CGU_CMD 4 +#define SJA1110_BASE_TIMER_CLK SJA1110_CGU_ADDR(0x74) /* Common structure for CFG_PAD_MIIx_RX and CFG_PAD_MIIx_TX */ struct sja1105_cfg_pad_mii { @@ -61,6 +62,12 @@ struct sja1105_cgu_pll_ctrl { u64 pd; }; +struct sja1110_cgu_outclk { + u64 clksrc; + u64 autoblock; + u64 pd; +}; + enum { CLKSRC_MII0_TX_CLK = 0x00, CLKSRC_MII0_RX_CLK = 0x01, @@ -461,6 +468,35 @@ sja1105_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd, sja1105_packing(buf, &cmd->txc_pd, 0, 0, size, op); } +static void +sja1110_cfg_pad_mii_id_packing(void *buf, struct sja1105_cfg_pad_mii_id *cmd, + enum packing_op op) +{ + const int size = SJA1105_SIZE_CGU_CMD; + u64 range = 4; + + /* Fields RXC_RANGE and TXC_RANGE select the input frequency range: + * 0 = 2.5MHz + * 1 = 25MHz + * 2 = 50MHz + * 3 = 125MHz + * 4 = Automatically determined by port speed. + * There's no point in defining a structure different than the one for + * SJA1105, so just hardcode the frequency range to automatic, just as + * before. + */ + sja1105_packing(buf, &cmd->rxc_stable_ovr, 26, 26, size, op); + sja1105_packing(buf, &cmd->rxc_delay, 25, 21, size, op); + sja1105_packing(buf, &range, 20, 18, size, op); + sja1105_packing(buf, &cmd->rxc_bypass, 17, 17, size, op); + sja1105_packing(buf, &cmd->rxc_pd, 16, 16, size, op); + sja1105_packing(buf, &cmd->txc_stable_ovr, 10, 10, size, op); + sja1105_packing(buf, &cmd->txc_delay, 9, 5, size, op); + sja1105_packing(buf, &range, 4, 2, size, op); + sja1105_packing(buf, &cmd->txc_bypass, 1, 1, size, op); + sja1105_packing(buf, &cmd->txc_pd, 0, 0, size, op); +} + /* Valid range in degrees is an integer between 73.8 and 101.7 */ static u64 sja1105_rgmii_delay(u64 phase) { @@ -519,6 +555,35 @@ int sja1105pqrs_setup_rgmii_delay(const void *ctx, int port) packed_buf, SJA1105_SIZE_CGU_CMD); } +int sja1110_setup_rgmii_delay(const void *ctx, int port) +{ + const struct sja1105_private *priv = ctx; + const struct sja1105_regs *regs = priv->info->regs; + struct sja1105_cfg_pad_mii_id pad_mii_id = {0}; + u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0}; + + pad_mii_id.rxc_pd = 1; + pad_mii_id.txc_pd = 1; + + if (priv->rgmii_rx_delay[port]) { + pad_mii_id.rxc_delay = sja1105_rgmii_delay(90); + /* The "BYPASS" bit in SJA1110 is actually a "don't bypass" */ + pad_mii_id.rxc_bypass = 1; + pad_mii_id.rxc_pd = 0; + } + + if (priv->rgmii_tx_delay[port]) { + pad_mii_id.txc_delay = sja1105_rgmii_delay(90); + pad_mii_id.txc_bypass = 1; + pad_mii_id.txc_pd = 0; + } + + sja1110_cfg_pad_mii_id_packing(packed_buf, &pad_mii_id, PACK); + + return sja1105_xfer_buf(priv, SPI_WRITE, regs->pad_mii_id[port], + packed_buf, SJA1105_SIZE_CGU_CMD); +} + static int sja1105_rgmii_clocking_setup(struct sja1105_private *priv, int port, sja1105_mii_role_t role) { @@ -755,3 +820,29 @@ int sja1105_clocking_setup(struct sja1105_private *priv) } return 0; } + +static void +sja1110_cgu_outclk_packing(void *buf, struct sja1110_cgu_outclk *outclk, + enum packing_op op) +{ + const int size = 4; + + sja1105_packing(buf, &outclk->clksrc, 27, 24, size, op); + sja1105_packing(buf, &outclk->autoblock, 11, 11, size, op); + sja1105_packing(buf, &outclk->pd, 0, 0, size, op); +} + +/* Power down the BASE_TIMER_CLK in order to disable the watchdog */ +int sja1110_clocking_setup(struct sja1105_private *priv) +{ + u8 packed_buf[SJA1105_SIZE_CGU_CMD] = {0}; + struct sja1110_cgu_outclk outclk_7_c = { + .clksrc = 0x5, + .pd = true, + }; + + sja1110_cgu_outclk_packing(packed_buf, &outclk_7_c, PACK); + + return sja1105_xfer_buf(priv, SPI_WRITE, SJA1110_BASE_TIMER_CLK, + packed_buf, SJA1105_SIZE_CGU_CMD); +} diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c index ff2742f53de3..031a4a6c76b0 100644 --- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.c +++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.c @@ -106,6 +106,9 @@ #define SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD \ (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_VL_LOOKUP_ENTRY) +#define SJA1110_SIZE_VL_POLICING_DYN_CMD \ + (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_VL_POLICING_ENTRY) + #define SJA1105ET_SIZE_MAC_CONFIG_DYN_ENTRY \ SJA1105_SIZE_DYN_CMD @@ -115,9 +118,15 @@ #define SJA1105PQRS_SIZE_L2_LOOKUP_DYN_CMD \ (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY) +#define SJA1110_SIZE_L2_LOOKUP_DYN_CMD \ + (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_L2_LOOKUP_ENTRY) + #define SJA1105_SIZE_VLAN_LOOKUP_DYN_CMD \ (SJA1105_SIZE_DYN_CMD + 4 + SJA1105_SIZE_VLAN_LOOKUP_ENTRY) +#define SJA1110_SIZE_VLAN_LOOKUP_DYN_CMD \ + (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_VLAN_LOOKUP_ENTRY) + #define SJA1105_SIZE_L2_FORWARDING_DYN_CMD \ (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_L2_FORWARDING_ENTRY) @@ -133,12 +142,18 @@ #define SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_DYN_CMD \ (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY) +#define SJA1110_SIZE_L2_LOOKUP_PARAMS_DYN_CMD \ + (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY) + #define SJA1105ET_SIZE_GENERAL_PARAMS_DYN_CMD \ SJA1105_SIZE_DYN_CMD #define SJA1105PQRS_SIZE_GENERAL_PARAMS_DYN_CMD \ (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY) +#define SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD \ + (SJA1105_SIZE_DYN_CMD + SJA1110_SIZE_GENERAL_PARAMS_ENTRY) + #define SJA1105PQRS_SIZE_AVB_PARAMS_DYN_CMD \ (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY) @@ -151,8 +166,17 @@ #define SJA1105PQRS_SIZE_CBS_DYN_CMD \ (SJA1105_SIZE_DYN_CMD + SJA1105PQRS_SIZE_CBS_ENTRY) +#define SJA1110_SIZE_XMII_PARAMS_DYN_CMD \ + SJA1110_SIZE_XMII_PARAMS_ENTRY + +#define SJA1110_SIZE_L2_POLICING_DYN_CMD \ + (SJA1105_SIZE_DYN_CMD + SJA1105_SIZE_L2_POLICING_ENTRY) + +#define SJA1110_SIZE_L2_FORWARDING_PARAMS_DYN_CMD \ + SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY + #define SJA1105_MAX_DYN_CMD_SIZE \ - SJA1105PQRS_SIZE_GENERAL_PARAMS_DYN_CMD + SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD struct sja1105_dyn_cmd { bool search; @@ -197,6 +221,19 @@ sja1105pqrs_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, sja1105_packing(p, &cmd->index, 9, 0, size, op); } +static void +sja1110_vl_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); + sja1105_packing(p, &cmd->errors, 29, 29, size, op); + sja1105_packing(p, &cmd->index, 11, 0, size, op); +} + static size_t sja1105et_vl_lookup_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -208,6 +245,18 @@ static size_t sja1105et_vl_lookup_entry_packing(void *buf, void *entry_ptr, return size; } +static void +sja1110_vl_policing_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1105_SIZE_VL_LOOKUP_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); + sja1105_packing(p, &cmd->index, 11, 0, size, op); +} + static void sja1105pqrs_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, enum packing_op op) @@ -326,6 +375,18 @@ sja1105pqrs_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr, return sja1105pqrs_l2_lookup_entry_packing(buf, entry_ptr, op); } +static size_t sja1110_dyn_l2_lookup_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_l2_lookup_entry *entry = entry_ptr; + u8 *cmd = buf + SJA1110_SIZE_L2_LOOKUP_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(cmd, &entry->lockeds, 28, 28, size, op); + + return sja1110_l2_lookup_entry_packing(buf, entry_ptr, op); +} + static void sja1105et_l2_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, enum packing_op op) @@ -437,6 +498,39 @@ sja1105_vlan_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, SJA1105_SIZE_VLAN_LOOKUP_ENTRY, op); } +/* In SJA1110 there is no gap between the command and the data, yay... */ +static void +sja1110_vlan_lookup_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1110_SIZE_VLAN_LOOKUP_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + u64 type_entry = 0; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); + sja1105_packing(p, &cmd->errors, 29, 29, size, op); + /* Hack: treat 'vlanid' field of struct sja1105_vlan_lookup_entry as + * cmd->index. + */ + sja1105_packing(buf, &cmd->index, 38, 27, + SJA1110_SIZE_VLAN_LOOKUP_ENTRY, op); + + /* But the VALIDENT bit has disappeared, now we are supposed to + * invalidate an entry through the TYPE_ENTRY field of the entry.. + * This is a hack to transform the non-zero quality of the TYPE_ENTRY + * field into a VALIDENT bit. + */ + if (op == PACK && !cmd->valident) { + sja1105_packing(buf, &type_entry, 40, 39, + SJA1110_SIZE_VLAN_LOOKUP_ENTRY, PACK); + } else if (op == UNPACK) { + sja1105_packing(buf, &type_entry, 40, 39, + SJA1110_SIZE_VLAN_LOOKUP_ENTRY, UNPACK); + cmd->valident = !!type_entry; + } +} + static void sja1105_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, enum packing_op op) @@ -450,6 +544,19 @@ sja1105_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, sja1105_packing(p, &cmd->index, 4, 0, size, op); } +static void +sja1110_l2_forwarding_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1105_SIZE_L2_FORWARDING_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); + sja1105_packing(p, &cmd->errors, 29, 29, size, op); + sja1105_packing(p, &cmd->index, 4, 0, size, op); +} + static void sja1105et_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, enum packing_op op) @@ -504,6 +611,19 @@ sja1105pqrs_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, sja1105_packing(p, &cmd->index, 2, 0, size, op); } +static void +sja1110_mac_config_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); + sja1105_packing(p, &cmd->errors, 29, 29, size, op); + sja1105_packing(p, &cmd->index, 3, 0, size, op); +} + static void sja1105et_l2_lookup_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, enum packing_op op) @@ -536,6 +656,18 @@ sja1105pqrs_l2_lookup_params_cmd_packing(void *buf, sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); } +static void +sja1110_l2_lookup_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); + sja1105_packing(p, &cmd->errors, 29, 29, size, op); +} + static void sja1105et_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, enum packing_op op) @@ -570,6 +702,18 @@ sja1105pqrs_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, sja1105_packing(p, &cmd->rdwrset, 28, 28, size, op); } +static void +sja1110_general_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1110_SIZE_GENERAL_PARAMS_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); + sja1105_packing(p, &cmd->errors, 29, 29, size, op); +} + static void sja1105pqrs_avb_params_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, enum packing_op op) @@ -596,6 +740,20 @@ sja1105_retagging_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, sja1105_packing(p, &cmd->index, 5, 0, size, op); } +static void +sja1110_retagging_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1105_SIZE_RETAGGING_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); + sja1105_packing(p, &cmd->errors, 29, 29, size, op); + sja1105_packing(p, &cmd->valident, 28, 28, size, op); + sja1105_packing(p, &cmd->index, 4, 0, size, op); +} + static void sja1105et_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, enum packing_op op) { @@ -635,6 +793,18 @@ static void sja1105pqrs_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, sja1105_packing(p, &cmd->index, 3, 0, size, op); } +static void sja1110_cbs_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1105PQRS_SIZE_CBS_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); + sja1105_packing(p, &cmd->errors, 29, 29, size, op); + sja1105_packing(p, &cmd->index, 7, 0, size, op); +} + static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -650,6 +820,39 @@ static size_t sja1105pqrs_cbs_entry_packing(void *buf, void *entry_ptr, return size; } +static size_t sja1110_cbs_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + const size_t size = SJA1105PQRS_SIZE_CBS_ENTRY; + struct sja1105_cbs_entry *entry = entry_ptr; + u64 entry_type = SJA1110_CBS_SHAPER; + + sja1105_packing(buf, &entry_type, 159, 159, size, op); + sja1105_packing(buf, &entry->credit_lo, 151, 120, size, op); + sja1105_packing(buf, &entry->credit_hi, 119, 88, size, op); + sja1105_packing(buf, &entry->send_slope, 87, 56, size, op); + sja1105_packing(buf, &entry->idle_slope, 55, 24, size, op); + return size; +} + +static void sja1110_dummy_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ +} + +static void +sja1110_l2_policing_cmd_packing(void *buf, struct sja1105_dyn_cmd *cmd, + enum packing_op op) +{ + u8 *p = buf + SJA1105_SIZE_L2_POLICING_ENTRY; + const int size = SJA1105_SIZE_DYN_CMD; + + sja1105_packing(p, &cmd->valid, 31, 31, size, op); + sja1105_packing(p, &cmd->rdwrset, 30, 30, size, op); + sja1105_packing(p, &cmd->errors, 29, 29, size, op); + sja1105_packing(p, &cmd->index, 6, 0, size, op); +} + #define OP_READ BIT(0) #define OP_WRITE BIT(1) #define OP_DEL BIT(2) @@ -832,6 +1035,122 @@ const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN] = { }, }; +/* SJA1110: Third generation */ +const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN] = { + [BLK_IDX_VL_LOOKUP] = { + .entry_packing = sja1110_vl_lookup_entry_packing, + .cmd_packing = sja1110_vl_lookup_cmd_packing, + .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), + .max_entry_count = SJA1110_MAX_VL_LOOKUP_COUNT, + .packed_size = SJA1105PQRS_SIZE_VL_LOOKUP_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0x124), + }, + [BLK_IDX_VL_POLICING] = { + .entry_packing = sja1110_vl_policing_entry_packing, + .cmd_packing = sja1110_vl_policing_cmd_packing, + .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), + .max_entry_count = SJA1110_MAX_VL_POLICING_COUNT, + .packed_size = SJA1110_SIZE_VL_POLICING_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0x310), + }, + [BLK_IDX_L2_LOOKUP] = { + .entry_packing = sja1110_dyn_l2_lookup_entry_packing, + .cmd_packing = sja1105pqrs_l2_lookup_cmd_packing, + .access = (OP_READ | OP_WRITE | OP_DEL | OP_SEARCH), + .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, + .packed_size = SJA1110_SIZE_L2_LOOKUP_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0x8c), + }, + [BLK_IDX_VLAN_LOOKUP] = { + .entry_packing = sja1110_vlan_lookup_entry_packing, + .cmd_packing = sja1110_vlan_lookup_cmd_packing, + .access = (OP_READ | OP_WRITE | OP_DEL), + .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, + .packed_size = SJA1110_SIZE_VLAN_LOOKUP_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0xb4), + }, + [BLK_IDX_L2_FORWARDING] = { + .entry_packing = sja1110_l2_forwarding_entry_packing, + .cmd_packing = sja1110_l2_forwarding_cmd_packing, + .max_entry_count = SJA1110_MAX_L2_FORWARDING_COUNT, + .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), + .packed_size = SJA1105_SIZE_L2_FORWARDING_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0xa8), + }, + [BLK_IDX_MAC_CONFIG] = { + .entry_packing = sja1110_mac_config_entry_packing, + .cmd_packing = sja1110_mac_config_cmd_packing, + .max_entry_count = SJA1110_MAX_MAC_CONFIG_COUNT, + .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), + .packed_size = SJA1105PQRS_SIZE_MAC_CONFIG_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0x134), + }, + [BLK_IDX_L2_LOOKUP_PARAMS] = { + .entry_packing = sja1110_l2_lookup_params_entry_packing, + .cmd_packing = sja1110_l2_lookup_params_cmd_packing, + .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, + .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), + .packed_size = SJA1110_SIZE_L2_LOOKUP_PARAMS_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0x158), + }, + [BLK_IDX_AVB_PARAMS] = { + .entry_packing = sja1105pqrs_avb_params_entry_packing, + .cmd_packing = sja1105pqrs_avb_params_cmd_packing, + .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, + .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), + .packed_size = SJA1105PQRS_SIZE_AVB_PARAMS_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0x2000C), + }, + [BLK_IDX_GENERAL_PARAMS] = { + .entry_packing = sja1110_general_params_entry_packing, + .cmd_packing = sja1110_general_params_cmd_packing, + .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, + .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), + .packed_size = SJA1110_SIZE_GENERAL_PARAMS_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0xe8), + }, + [BLK_IDX_RETAGGING] = { + .entry_packing = sja1110_retagging_entry_packing, + .cmd_packing = sja1110_retagging_cmd_packing, + .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, + .access = (OP_READ | OP_WRITE | OP_DEL), + .packed_size = SJA1105_SIZE_RETAGGING_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0xdc0), + }, + [BLK_IDX_CBS] = { + .entry_packing = sja1110_cbs_entry_packing, + .cmd_packing = sja1110_cbs_cmd_packing, + .max_entry_count = SJA1110_MAX_CBS_COUNT, + .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), + .packed_size = SJA1105PQRS_SIZE_CBS_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0xc4), + }, + [BLK_IDX_XMII_PARAMS] = { + .entry_packing = sja1110_xmii_params_entry_packing, + .cmd_packing = sja1110_dummy_cmd_packing, + .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, + .access = (OP_READ | OP_VALID_ANYWAY), + .packed_size = SJA1110_SIZE_XMII_PARAMS_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0x3c), + }, + [BLK_IDX_L2_POLICING] = { + .entry_packing = sja1110_l2_policing_entry_packing, + .cmd_packing = sja1110_l2_policing_cmd_packing, + .max_entry_count = SJA1110_MAX_L2_POLICING_COUNT, + .access = (OP_READ | OP_WRITE | OP_VALID_ANYWAY), + .packed_size = SJA1110_SIZE_L2_POLICING_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0x2fc), + }, + [BLK_IDX_L2_FORWARDING_PARAMS] = { + .entry_packing = sja1110_l2_forwarding_params_entry_packing, + .cmd_packing = sja1110_dummy_cmd_packing, + .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, + .access = (OP_READ | OP_VALID_ANYWAY), + .packed_size = SJA1110_SIZE_L2_FORWARDING_PARAMS_DYN_CMD, + .addr = SJA1110_SPI_ADDR(0x20000), + }, +}; + /* Provides read access to the settings through the dynamic interface * of the switch. * @blk_idx is used as key to select from the sja1105_dynamic_table_ops. diff --git a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h index 28d4eb5efb8b..a1472f80a059 100644 --- a/drivers/net/dsa/sja1105/sja1105_dynamic_config.h +++ b/drivers/net/dsa/sja1105/sja1105_dynamic_config.h @@ -36,5 +36,6 @@ struct sja1105_mgmt_entry { extern const struct sja1105_dynamic_table_ops sja1105et_dyn_ops[BLK_IDX_MAX_DYN]; extern const struct sja1105_dynamic_table_ops sja1105pqrs_dyn_ops[BLK_IDX_MAX_DYN]; +extern const struct sja1105_dynamic_table_ops sja1110_dyn_ops[BLK_IDX_MAX_DYN]; #endif diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 04af644bf656..5e208ca78c4f 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -357,6 +357,7 @@ static int sja1105_init_static_vlan(struct sja1105_private *priv) { struct sja1105_table *table; struct sja1105_vlan_lookup_entry pvid = { + .type_entry = SJA1110_VLAN_C_TAG, .ving_mirr = 0, .vegr_mirr = 0, .vmemb_port = 0, @@ -469,6 +470,47 @@ static int sja1105_init_l2_forwarding(struct sja1105_private *priv) l2fwd[ds->num_ports + i].vlan_pmap[j] = i; } + + l2fwd[ds->num_ports + i].type_egrpcp2outputq = true; + } + + return 0; +} + +static int sja1110_init_pcp_remapping(struct sja1105_private *priv) +{ + struct sja1110_pcp_remapping_entry *pcp_remap; + struct dsa_switch *ds = priv->ds; + struct sja1105_table *table; + int port, tc; + + table = &priv->static_config.tables[BLK_IDX_PCP_REMAPPING]; + + /* Nothing to do for SJA1105 */ + if (!table->ops->max_entry_count) + return 0; + + if (table->entry_count) { + kfree(table->entries); + table->entry_count = 0; + } + + table->entries = kcalloc(table->ops->max_entry_count, + table->ops->unpacked_entry_size, GFP_KERNEL); + if (!table->entries) + return -ENOMEM; + + table->entry_count = table->ops->max_entry_count; + + pcp_remap = table->entries; + + /* Repeat the configuration done for vlan_pmap */ + for (port = 0; port < ds->num_ports; port++) { + if (dsa_is_unused_port(ds, port)) + continue; + + for (tc = 0; tc < SJA1105_NUM_TC; tc++) + pcp_remap[port].egrpcp[tc] = tc; } return 0; @@ -792,6 +834,9 @@ static int sja1105_static_config_load(struct sja1105_private *priv, if (rc < 0) return rc; rc = sja1105_init_avb_params(priv); + if (rc < 0) + return rc; + rc = sja1110_init_pcp_remapping(priv); if (rc < 0) return rc; @@ -2322,6 +2367,7 @@ sja1105_build_bridge_vlans(struct sja1105_private *priv, new_vlan[match].vlan_bc |= BIT(v->port); if (!v->untagged) new_vlan[match].tag_port |= BIT(v->port); + new_vlan[match].type_entry = SJA1110_VLAN_C_TAG; } return 0; @@ -2344,6 +2390,7 @@ sja1105_build_dsa_8021q_vlans(struct sja1105_private *priv, new_vlan[match].vlan_bc |= BIT(v->port); if (!v->untagged) new_vlan[match].tag_port |= BIT(v->port); + new_vlan[match].type_entry = SJA1110_VLAN_C_TAG; } return 0; @@ -2404,6 +2451,7 @@ static int sja1105_build_subvlans(struct sja1105_private *priv, new_vlan[match].tag_port |= BIT(v->port); /* But it's always tagged towards the CPU */ new_vlan[match].tag_port |= BIT(upstream); + new_vlan[match].type_entry = SJA1110_VLAN_C_TAG; /* The Retagging Table generates packet *clones* with * the new VLAN. This is a very odd hardware quirk @@ -2571,6 +2619,7 @@ sja1105_build_crosschip_subvlans(struct sja1105_private *priv, if (!tmp->untagged) new_vlan[match].tag_port |= BIT(tmp->port); new_vlan[match].tag_port |= BIT(upstream); + new_vlan[match].type_entry = SJA1110_VLAN_C_TAG; /* Deny egress of @rx_vid towards our front-panel port. * This will force the switch to drop it, and we'll see * only the re-retagged packets (having the original, @@ -3712,7 +3761,7 @@ static int sja1105_probe(struct spi_device *spi) return -ENOMEM; ds->dev = dev; - ds->num_ports = SJA1105_MAX_NUM_PORTS; + ds->num_ports = priv->info->num_ports; ds->ops = &sja1105_switch_ops; ds->priv = priv; priv->ds = ds; @@ -3816,6 +3865,10 @@ static const struct of_device_id sja1105_dt_ids[] = { { .compatible = "nxp,sja1105q", .data = &sja1105q_info }, { .compatible = "nxp,sja1105r", .data = &sja1105r_info }, { .compatible = "nxp,sja1105s", .data = &sja1105s_info }, + { .compatible = "nxp,sja1110a", .data = &sja1110a_info }, + { .compatible = "nxp,sja1110b", .data = &sja1110b_info }, + { .compatible = "nxp,sja1110c", .data = &sja1110c_info }, + { .compatible = "nxp,sja1110d", .data = &sja1110d_info }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, sja1105_dt_ids); diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 786c16a77e46..187c9fbbd397 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -193,6 +193,16 @@ static int sja1105pqrs_reset_cmd(struct dsa_switch *ds) return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &cold_reset, NULL); } +static int sja1110_reset_cmd(struct dsa_switch *ds) +{ + struct sja1105_private *priv = ds->priv; + const struct sja1105_regs *regs = priv->info->regs; + u32 switch_reset = BIT(20); + + /* Switch core reset */ + return sja1105_xfer_u32(priv, SPI_WRITE, regs->rgu, &switch_reset, NULL); +} + int sja1105_inhibit_tx(const struct sja1105_private *priv, unsigned long port_bitmap, bool tx_inhibited) { @@ -465,6 +475,88 @@ static struct sja1105_regs sja1105pqrs_regs = { .ptpsyncts = 0x1F, }; +static struct sja1105_regs sja1110_regs = { + .device_id = SJA1110_SPI_ADDR(0x0), + .prod_id = SJA1110_ACU_ADDR(0xf00), + .status = SJA1110_SPI_ADDR(0x4), + .port_control = SJA1110_SPI_ADDR(0x50), /* actually INHIB_TX */ + .vl_status = 0x10000, + .config = 0x020000, + .rgu = SJA1110_RGU_ADDR(0x100), /* Reset Control Register 0 */ + /* Ports 2 and 3 are capable of xMII, but there isn't anything to + * configure in the CGU/ACU for them. + */ + .pad_mii_tx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR}, + .pad_mii_rx = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR}, + .pad_mii_id = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1110_ACU_ADDR(0x18), SJA1110_ACU_ADDR(0x28), + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR}, + .rmii_pll1 = SJA1105_RSV_ADDR, + .cgu_idiv = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, + .stats[MAC] = {0x200, 0x202, 0x204, 0x206, 0x208, 0x20a, + 0x20c, 0x20e, 0x210, 0x212, 0x214}, + .stats[HL1] = {0x400, 0x410, 0x420, 0x430, 0x440, 0x450, + 0x460, 0x470, 0x480, 0x490, 0x4a0}, + .stats[HL2] = {0x600, 0x610, 0x620, 0x630, 0x640, 0x650, + 0x660, 0x670, 0x680, 0x690, 0x6a0}, + .stats[ETHER] = {0x1400, 0x1418, 0x1430, 0x1448, 0x1460, 0x1478, + 0x1490, 0x14a8, 0x14c0, 0x14d8, 0x14f0}, + .mii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, + .mii_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, + .mii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, + .mii_ext_rx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, + .rgmii_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, + .rmii_ref_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, + .rmii_ext_tx_clk = {SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR}, + .ptpschtm = SJA1110_SPI_ADDR(0x54), + .ptppinst = SJA1110_SPI_ADDR(0x5c), + .ptppindur = SJA1110_SPI_ADDR(0x64), + .ptp_control = SJA1110_SPI_ADDR(0x68), + .ptpclkval = SJA1110_SPI_ADDR(0x6c), + .ptpclkrate = SJA1110_SPI_ADDR(0x74), + .ptpclkcorp = SJA1110_SPI_ADDR(0x80), + .ptpsyncts = SJA1110_SPI_ADDR(0x84), +}; + const struct sja1105_info sja1105e_info = { .device_id = SJA1105E_DEVICE_ID, .part_no = SJA1105ET_PART_NO, @@ -475,6 +567,7 @@ const struct sja1105_info sja1105e_info = { .ptp_ts_bits = 24, .ptpegr_ts_bytes = 4, .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, + .num_ports = SJA1105_NUM_PORTS, .num_cbs_shapers = SJA1105ET_MAX_CBS_COUNT, .reset_cmd = sja1105et_reset_cmd, .fdb_add_cmd = sja1105et_fdb_add, @@ -505,6 +598,7 @@ const struct sja1105_info sja1105t_info = { .ptp_ts_bits = 24, .ptpegr_ts_bytes = 4, .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, + .num_ports = SJA1105_NUM_PORTS, .num_cbs_shapers = SJA1105ET_MAX_CBS_COUNT, .reset_cmd = sja1105et_reset_cmd, .fdb_add_cmd = sja1105et_fdb_add, @@ -535,6 +629,7 @@ const struct sja1105_info sja1105p_info = { .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, + .num_ports = SJA1105_NUM_PORTS, .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, .reset_cmd = sja1105pqrs_reset_cmd, @@ -566,6 +661,7 @@ const struct sja1105_info sja1105q_info = { .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, + .num_ports = SJA1105_NUM_PORTS, .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, .reset_cmd = sja1105pqrs_reset_cmd, @@ -597,6 +693,7 @@ const struct sja1105_info sja1105r_info = { .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, + .num_ports = SJA1105_NUM_PORTS, .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, .reset_cmd = sja1105pqrs_reset_cmd, @@ -630,6 +727,7 @@ const struct sja1105_info sja1105s_info = { .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1105_MAX_FRAME_MEMORY, + .num_ports = SJA1105_NUM_PORTS, .num_cbs_shapers = SJA1105PQRS_MAX_CBS_COUNT, .setup_rgmii_delay = sja1105pqrs_setup_rgmii_delay, .reset_cmd = sja1105pqrs_reset_cmd, @@ -650,3 +748,157 @@ const struct sja1105_info sja1105s_info = { .supports_sgmii = {false, false, false, false, true}, .name = "SJA1105S", }; + +const struct sja1105_info sja1110a_info = { + .device_id = SJA1110_DEVICE_ID, + .part_no = SJA1110A_PART_NO, + .static_ops = sja1110_table_ops, + .dyn_ops = sja1110_dyn_ops, + .regs = &sja1110_regs, + .qinq_tpid = ETH_P_8021AD, + .can_limit_mcast_flood = true, + .ptp_ts_bits = 32, + .ptpegr_ts_bytes = 8, + .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, + .num_ports = SJA1110_NUM_PORTS, + .num_cbs_shapers = SJA1110_MAX_CBS_COUNT, + .setup_rgmii_delay = sja1110_setup_rgmii_delay, + .reset_cmd = sja1110_reset_cmd, + .fdb_add_cmd = sja1105pqrs_fdb_add, + .fdb_del_cmd = sja1105pqrs_fdb_del, + .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .clocking_setup = sja1110_clocking_setup, + .port_speed = { + [SJA1105_SPEED_AUTO] = 0, + [SJA1105_SPEED_10MBPS] = 4, + [SJA1105_SPEED_100MBPS] = 3, + [SJA1105_SPEED_1000MBPS] = 2, + [SJA1105_SPEED_2500MBPS] = 1, + }, + .supports_mii = {true, true, true, true, false, + true, true, true, true, true, true}, + .supports_rmii = {false, false, true, true, false, + false, false, false, false, false, false}, + .supports_rgmii = {false, false, true, true, false, + false, false, false, false, false, false}, + .supports_sgmii = {false, true, true, true, true, + false, false, false, false, false, false}, + .supports_2500basex = {false, false, false, true, true, + false, false, false, false, false, false}, + .name = "SJA1110A", +}; + +const struct sja1105_info sja1110b_info = { + .device_id = SJA1110_DEVICE_ID, + .part_no = SJA1110B_PART_NO, + .static_ops = sja1110_table_ops, + .dyn_ops = sja1110_dyn_ops, + .regs = &sja1110_regs, + .qinq_tpid = ETH_P_8021AD, + .can_limit_mcast_flood = true, + .ptp_ts_bits = 32, + .ptpegr_ts_bytes = 8, + .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, + .num_ports = SJA1110_NUM_PORTS, + .num_cbs_shapers = SJA1110_MAX_CBS_COUNT, + .setup_rgmii_delay = sja1110_setup_rgmii_delay, + .reset_cmd = sja1110_reset_cmd, + .fdb_add_cmd = sja1105pqrs_fdb_add, + .fdb_del_cmd = sja1105pqrs_fdb_del, + .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .clocking_setup = sja1110_clocking_setup, + .port_speed = { + [SJA1105_SPEED_AUTO] = 0, + [SJA1105_SPEED_10MBPS] = 4, + [SJA1105_SPEED_100MBPS] = 3, + [SJA1105_SPEED_1000MBPS] = 2, + [SJA1105_SPEED_2500MBPS] = 1, + }, + .supports_mii = {true, true, true, true, false, + true, true, true, true, true, false}, + .supports_rmii = {false, false, true, true, false, + false, false, false, false, false, false}, + .supports_rgmii = {false, false, true, true, false, + false, false, false, false, false, false}, + .supports_sgmii = {false, false, false, true, true, + false, false, false, false, false, false}, + .supports_2500basex = {false, false, false, true, true, + false, false, false, false, false, false}, + .name = "SJA1110B", +}; + +const struct sja1105_info sja1110c_info = { + .device_id = SJA1110_DEVICE_ID, + .part_no = SJA1110C_PART_NO, + .static_ops = sja1110_table_ops, + .dyn_ops = sja1110_dyn_ops, + .regs = &sja1110_regs, + .qinq_tpid = ETH_P_8021AD, + .can_limit_mcast_flood = true, + .ptp_ts_bits = 32, + .ptpegr_ts_bytes = 8, + .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, + .num_ports = SJA1110_NUM_PORTS, + .num_cbs_shapers = SJA1110_MAX_CBS_COUNT, + .setup_rgmii_delay = sja1110_setup_rgmii_delay, + .reset_cmd = sja1110_reset_cmd, + .fdb_add_cmd = sja1105pqrs_fdb_add, + .fdb_del_cmd = sja1105pqrs_fdb_del, + .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .clocking_setup = sja1110_clocking_setup, + .port_speed = { + [SJA1105_SPEED_AUTO] = 0, + [SJA1105_SPEED_10MBPS] = 4, + [SJA1105_SPEED_100MBPS] = 3, + [SJA1105_SPEED_1000MBPS] = 2, + [SJA1105_SPEED_2500MBPS] = 1, + }, + .supports_mii = {true, true, true, true, false, + true, true, true, false, false, false}, + .supports_rmii = {false, false, true, true, false, + false, false, false, false, false, false}, + .supports_rgmii = {false, false, true, true, false, + false, false, false, false, false, false}, + .supports_sgmii = {false, false, false, false, true, + false, false, false, false, false, false}, + .supports_2500basex = {false, false, false, false, true, + false, false, false, false, false, false}, + .name = "SJA1110C", +}; + +const struct sja1105_info sja1110d_info = { + .device_id = SJA1110_DEVICE_ID, + .part_no = SJA1110D_PART_NO, + .static_ops = sja1110_table_ops, + .dyn_ops = sja1110_dyn_ops, + .regs = &sja1110_regs, + .qinq_tpid = ETH_P_8021AD, + .can_limit_mcast_flood = true, + .ptp_ts_bits = 32, + .ptpegr_ts_bytes = 8, + .max_frame_mem = SJA1110_MAX_FRAME_MEMORY, + .num_ports = SJA1110_NUM_PORTS, + .num_cbs_shapers = SJA1110_MAX_CBS_COUNT, + .setup_rgmii_delay = sja1110_setup_rgmii_delay, + .reset_cmd = sja1110_reset_cmd, + .fdb_add_cmd = sja1105pqrs_fdb_add, + .fdb_del_cmd = sja1105pqrs_fdb_del, + .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, + .clocking_setup = sja1110_clocking_setup, + .port_speed = { + [SJA1105_SPEED_AUTO] = 0, + [SJA1105_SPEED_10MBPS] = 4, + [SJA1105_SPEED_100MBPS] = 3, + [SJA1105_SPEED_1000MBPS] = 2, + [SJA1105_SPEED_2500MBPS] = 1, + }, + .supports_mii = {true, false, true, false, false, + true, true, true, false, false, false}, + .supports_rmii = {false, false, true, false, false, + false, false, false, false, false, false}, + .supports_rgmii = {false, false, true, false, false, + false, false, false, false, false, false}, + .supports_sgmii = {false, true, true, true, true, + false, false, false, false, false, false}, + .name = "SJA1110D", +}; diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.c b/drivers/net/dsa/sja1105/sja1105_static_config.c index 33f91ecbe07b..48ad984d2367 100644 --- a/drivers/net/dsa/sja1105/sja1105_static_config.c +++ b/drivers/net/dsa/sja1105/sja1105_static_config.c @@ -180,6 +180,41 @@ size_t sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_general_params_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_general_params_entry *entry = entry_ptr; + const size_t size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY; + + sja1105_packing(buf, &entry->vllupformat, 447, 447, size, op); + sja1105_packing(buf, &entry->mirr_ptacu, 446, 446, size, op); + sja1105_packing(buf, &entry->switchid, 445, 442, size, op); + sja1105_packing(buf, &entry->hostprio, 441, 439, size, op); + sja1105_packing(buf, &entry->mac_fltres1, 438, 391, size, op); + sja1105_packing(buf, &entry->mac_fltres0, 390, 343, size, op); + sja1105_packing(buf, &entry->mac_flt1, 342, 295, size, op); + sja1105_packing(buf, &entry->mac_flt0, 294, 247, size, op); + sja1105_packing(buf, &entry->incl_srcpt1, 246, 246, size, op); + sja1105_packing(buf, &entry->incl_srcpt0, 245, 245, size, op); + sja1105_packing(buf, &entry->send_meta1, 244, 244, size, op); + sja1105_packing(buf, &entry->send_meta0, 243, 243, size, op); + sja1105_packing(buf, &entry->casc_port, 242, 232, size, op); + sja1105_packing(buf, &entry->host_port, 231, 228, size, op); + sja1105_packing(buf, &entry->mirr_port, 227, 224, size, op); + sja1105_packing(buf, &entry->vlmarker, 223, 192, size, op); + sja1105_packing(buf, &entry->vlmask, 191, 160, size, op); + sja1105_packing(buf, &entry->tpid2, 159, 144, size, op); + sja1105_packing(buf, &entry->ignore2stf, 143, 143, size, op); + sja1105_packing(buf, &entry->tpid, 142, 127, size, op); + sja1105_packing(buf, &entry->queue_ts, 126, 126, size, op); + sja1105_packing(buf, &entry->egrmirrvid, 125, 114, size, op); + sja1105_packing(buf, &entry->egrmirrpcp, 113, 111, size, op); + sja1105_packing(buf, &entry->egrmirrdei, 110, 110, size, op); + sja1105_packing(buf, &entry->replay_port, 109, 106, size, op); + sja1105_packing(buf, &entry->tte_en, 16, 16, size, op); + return size; +} + static size_t sja1105_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr, enum packing_op op) @@ -195,6 +230,20 @@ sja1105_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_l2_forwarding_params_entry *entry = entry_ptr; + const size_t size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY; + int offset, i; + + sja1105_packing(buf, &entry->max_dynp, 95, 93, size, op); + for (i = 0, offset = 5; i < 8; i++, offset += 11) + sja1105_packing(buf, &entry->part_spc[i], + offset + 10, offset + 0, size, op); + return size; +} + size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -211,6 +260,27 @@ size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_l2_forwarding_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_l2_forwarding_entry *entry = entry_ptr; + const size_t size = SJA1105_SIZE_L2_FORWARDING_ENTRY; + int offset, i; + + if (entry->type_egrpcp2outputq) { + for (i = 0, offset = 31; i < SJA1110_NUM_PORTS; + i++, offset += 3) { + sja1105_packing(buf, &entry->vlan_pmap[i], + offset + 2, offset + 0, size, op); + } + } else { + sja1105_packing(buf, &entry->bc_domain, 63, 53, size, op); + sja1105_packing(buf, &entry->reach_port, 52, 42, size, op); + sja1105_packing(buf, &entry->fl_domain, 41, 31, size, op); + } + return size; +} + static size_t sja1105et_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, enum packing_op op) @@ -249,6 +319,28 @@ size_t sja1105pqrs_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_l2_lookup_params_entry *entry = entry_ptr; + const size_t size = SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY; + int offset, i; + + for (i = 0, offset = 70; i < SJA1110_NUM_PORTS; i++, offset += 11) + sja1105_packing(buf, &entry->maxaddrp[i], + offset + 10, offset + 0, size, op); + sja1105_packing(buf, &entry->maxage, 69, 55, size, op); + sja1105_packing(buf, &entry->start_dynspc, 54, 45, size, op); + sja1105_packing(buf, &entry->drpnolearn, 44, 34, size, op); + sja1105_packing(buf, &entry->shared_learn, 33, 33, size, op); + sja1105_packing(buf, &entry->no_enf_hostprt, 32, 32, size, op); + sja1105_packing(buf, &entry->no_mgmt_learn, 31, 31, size, op); + sja1105_packing(buf, &entry->use_static, 30, 30, size, op); + sja1105_packing(buf, &entry->owr_dyn, 29, 29, size, op); + sja1105_packing(buf, &entry->learn_once, 28, 28, size, op); + return size; +} + size_t sja1105et_l2_lookup_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -291,6 +383,36 @@ size_t sja1105pqrs_l2_lookup_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_l2_lookup_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + const size_t size = SJA1110_SIZE_L2_LOOKUP_ENTRY; + struct sja1105_l2_lookup_entry *entry = entry_ptr; + + if (entry->lockeds) { + sja1105_packing(buf, &entry->trap, 168, 168, size, op); + sja1105_packing(buf, &entry->mirrvlan, 167, 156, size, op); + sja1105_packing(buf, &entry->takets, 155, 155, size, op); + sja1105_packing(buf, &entry->mirr, 154, 154, size, op); + sja1105_packing(buf, &entry->retag, 153, 153, size, op); + } else { + sja1105_packing(buf, &entry->touched, 168, 168, size, op); + sja1105_packing(buf, &entry->age, 167, 153, size, op); + } + sja1105_packing(buf, &entry->mask_iotag, 152, 152, size, op); + sja1105_packing(buf, &entry->mask_vlanid, 151, 140, size, op); + sja1105_packing(buf, &entry->mask_macaddr, 139, 92, size, op); + sja1105_packing(buf, &entry->mask_srcport, 91, 88, size, op); + sja1105_packing(buf, &entry->iotag, 87, 87, size, op); + sja1105_packing(buf, &entry->vlanid, 86, 75, size, op); + sja1105_packing(buf, &entry->macaddr, 74, 27, size, op); + sja1105_packing(buf, &entry->srcport, 26, 23, size, op); + sja1105_packing(buf, &entry->destports, 22, 12, size, op); + sja1105_packing(buf, &entry->enfport, 11, 11, size, op); + sja1105_packing(buf, &entry->index, 10, 1, size, op); + return size; +} + static size_t sja1105_l2_policing_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -305,6 +427,20 @@ static size_t sja1105_l2_policing_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_l2_policing_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_l2_policing_entry *entry = entry_ptr; + const size_t size = SJA1105_SIZE_L2_POLICING_ENTRY; + + sja1105_packing(buf, &entry->sharindx, 63, 57, size, op); + sja1105_packing(buf, &entry->smax, 56, 39, size, op); + sja1105_packing(buf, &entry->rate, 38, 21, size, op); + sja1105_packing(buf, &entry->maxlen, 20, 10, size, op); + sja1105_packing(buf, &entry->partition, 9, 7, size, op); + return size; +} + static size_t sja1105et_mac_config_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -373,6 +509,40 @@ size_t sja1105pqrs_mac_config_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_mac_config_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + const size_t size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY; + struct sja1105_mac_config_entry *entry = entry_ptr; + int offset, i; + + for (i = 0, offset = 104; i < 8; i++, offset += 19) { + sja1105_packing(buf, &entry->enabled[i], + offset + 0, offset + 0, size, op); + sja1105_packing(buf, &entry->base[i], + offset + 9, offset + 1, size, op); + sja1105_packing(buf, &entry->top[i], + offset + 18, offset + 10, size, op); + } + sja1105_packing(buf, &entry->speed, 98, 96, size, op); + sja1105_packing(buf, &entry->tp_delin, 95, 80, size, op); + sja1105_packing(buf, &entry->tp_delout, 79, 64, size, op); + sja1105_packing(buf, &entry->maxage, 63, 56, size, op); + sja1105_packing(buf, &entry->vlanprio, 55, 53, size, op); + sja1105_packing(buf, &entry->vlanid, 52, 41, size, op); + sja1105_packing(buf, &entry->ing_mirr, 40, 40, size, op); + sja1105_packing(buf, &entry->egr_mirr, 39, 39, size, op); + sja1105_packing(buf, &entry->drpnona664, 38, 38, size, op); + sja1105_packing(buf, &entry->drpdtag, 37, 37, size, op); + sja1105_packing(buf, &entry->drpuntag, 34, 34, size, op); + sja1105_packing(buf, &entry->retag, 33, 33, size, op); + sja1105_packing(buf, &entry->dyn_learn, 32, 32, size, op); + sja1105_packing(buf, &entry->egress, 31, 31, size, op); + sja1105_packing(buf, &entry->ingress, 30, 30, size, op); + sja1105_packing(buf, &entry->ifg, 10, 5, size, op); + return size; +} + static size_t sja1105_schedule_entry_points_params_entry_packing(void *buf, void *entry_ptr, enum packing_op op) @@ -398,6 +568,19 @@ sja1105_schedule_entry_points_entry_packing(void *buf, void *entry_ptr, return size; } +static size_t +sja1110_schedule_entry_points_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_schedule_entry_points_entry *entry = entry_ptr; + const size_t size = SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY; + + sja1105_packing(buf, &entry->subschindx, 63, 61, size, op); + sja1105_packing(buf, &entry->delta, 60, 43, size, op); + sja1105_packing(buf, &entry->address, 42, 31, size, op); + return size; +} + static size_t sja1105_schedule_params_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -411,6 +594,19 @@ static size_t sja1105_schedule_params_entry_packing(void *buf, void *entry_ptr, return size; } +static size_t sja1110_schedule_params_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_schedule_params_entry *entry = entry_ptr; + const size_t size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY; + int offset, i; + + for (i = 0, offset = 0; i < 8; i++, offset += 12) + sja1105_packing(buf, &entry->subscheind[i], + offset + 11, offset + 0, size, op); + return size; +} + static size_t sja1105_schedule_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -430,6 +626,25 @@ static size_t sja1105_schedule_entry_packing(void *buf, void *entry_ptr, return size; } +static size_t sja1110_schedule_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + const size_t size = SJA1110_SIZE_SCHEDULE_ENTRY; + struct sja1105_schedule_entry *entry = entry_ptr; + + sja1105_packing(buf, &entry->winstindex, 95, 84, size, op); + sja1105_packing(buf, &entry->winend, 83, 83, size, op); + sja1105_packing(buf, &entry->winst, 82, 82, size, op); + sja1105_packing(buf, &entry->destports, 81, 71, size, op); + sja1105_packing(buf, &entry->setvalid, 70, 70, size, op); + sja1105_packing(buf, &entry->txen, 69, 69, size, op); + sja1105_packing(buf, &entry->resmedia_en, 68, 68, size, op); + sja1105_packing(buf, &entry->resmedia, 67, 60, size, op); + sja1105_packing(buf, &entry->vlindex, 59, 48, size, op); + sja1105_packing(buf, &entry->delta, 47, 30, size, op); + return size; +} + static size_t sja1105_vl_forwarding_params_entry_packing(void *buf, void *entry_ptr, enum packing_op op) @@ -445,6 +660,21 @@ sja1105_vl_forwarding_params_entry_packing(void *buf, void *entry_ptr, return size; } +static size_t +sja1110_vl_forwarding_params_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_vl_forwarding_params_entry *entry = entry_ptr; + const size_t size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY; + int offset, i; + + for (i = 0, offset = 8; i < 8; i++, offset += 11) + sja1105_packing(buf, &entry->partspc[i], + offset + 10, offset + 0, size, op); + sja1105_packing(buf, &entry->debugen, 7, 7, size, op); + return size; +} + static size_t sja1105_vl_forwarding_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -458,6 +688,19 @@ static size_t sja1105_vl_forwarding_entry_packing(void *buf, void *entry_ptr, return size; } +static size_t sja1110_vl_forwarding_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_vl_forwarding_entry *entry = entry_ptr; + const size_t size = SJA1105_SIZE_VL_FORWARDING_ENTRY; + + sja1105_packing(buf, &entry->type, 31, 31, size, op); + sja1105_packing(buf, &entry->priority, 30, 28, size, op); + sja1105_packing(buf, &entry->partition, 27, 25, size, op); + sja1105_packing(buf, &entry->destports, 24, 14, size, op); + return size; +} + size_t sja1105_vl_lookup_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -492,6 +735,41 @@ size_t sja1105_vl_lookup_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_vl_lookup_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_vl_lookup_entry *entry = entry_ptr; + const size_t size = SJA1105_SIZE_VL_LOOKUP_ENTRY; + + if (entry->format == SJA1105_VL_FORMAT_PSFP) { + /* Interpreting vllupformat as 0 */ + /* XXX: vl_police ? */ + sja1105_packing(buf, &entry->destports, + 94, 84, size, op); + sja1105_packing(buf, &entry->iscritical, + 83, 83, size, op); + sja1105_packing(buf, &entry->macaddr, + 82, 35, size, op); + sja1105_packing(buf, &entry->vlanid, + 34, 23, size, op); + sja1105_packing(buf, &entry->port, + 22, 19, size, op); + sja1105_packing(buf, &entry->vlanprior, + 18, 16, size, op); + } else { + /* Interpreting vllupformat as 1 */ + sja1105_packing(buf, &entry->egrmirr, + 94, 84, size, op); + sja1105_packing(buf, &entry->ingrmirr, + 83, 83, size, op); + sja1105_packing(buf, &entry->vlid, + 50, 35, size, op); + sja1105_packing(buf, &entry->port, + 22, 19, size, op); + } + return size; +} + static size_t sja1105_vl_policing_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -508,6 +786,22 @@ static size_t sja1105_vl_policing_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_vl_policing_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_vl_policing_entry *entry = entry_ptr; + const size_t size = SJA1105_SIZE_VL_POLICING_ENTRY; + + sja1105_packing(buf, &entry->type, 63, 63, size, op); + sja1105_packing(buf, &entry->maxlen, 62, 52, size, op); + sja1105_packing(buf, &entry->sharindx, 51, 40, size, op); + if (entry->type == 0) { + sja1105_packing(buf, &entry->bag, 41, 28, size, op); + sja1105_packing(buf, &entry->jitter, 27, 18, size, op); + } + return size; +} + size_t sja1105_vlan_lookup_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -523,6 +817,22 @@ size_t sja1105_vlan_lookup_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_vlan_lookup_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_vlan_lookup_entry *entry = entry_ptr; + const size_t size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY; + + sja1105_packing(buf, &entry->ving_mirr, 95, 85, size, op); + sja1105_packing(buf, &entry->vegr_mirr, 84, 74, size, op); + sja1105_packing(buf, &entry->vmemb_port, 73, 63, size, op); + sja1105_packing(buf, &entry->vlan_bc, 62, 52, size, op); + sja1105_packing(buf, &entry->tag_port, 51, 41, size, op); + sja1105_packing(buf, &entry->type_entry, 40, 39, size, op); + sja1105_packing(buf, &entry->vlanid, 38, 27, size, op); + return size; +} + static size_t sja1105_xmii_params_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -539,6 +849,24 @@ static size_t sja1105_xmii_params_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_xmii_params_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + const size_t size = SJA1110_SIZE_XMII_PARAMS_ENTRY; + struct sja1105_xmii_params_entry *entry = entry_ptr; + int offset, i; + + for (i = 0, offset = 20; i < SJA1110_NUM_PORTS; i++, offset += 4) { + sja1105_packing(buf, &entry->xmii_mode[i], + offset + 1, offset + 0, size, op); + sja1105_packing(buf, &entry->phy_mac[i], + offset + 2, offset + 2, size, op); + sja1105_packing(buf, &entry->special[i], + offset + 3, offset + 3, size, op); + } + return size; +} + size_t sja1105_retagging_entry_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -555,6 +883,36 @@ size_t sja1105_retagging_entry_packing(void *buf, void *entry_ptr, return size; } +size_t sja1110_retagging_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1105_retagging_entry *entry = entry_ptr; + const size_t size = SJA1105_SIZE_RETAGGING_ENTRY; + + sja1105_packing(buf, &entry->egr_port, 63, 53, size, op); + sja1105_packing(buf, &entry->ing_port, 52, 42, size, op); + sja1105_packing(buf, &entry->vlan_ing, 41, 30, size, op); + sja1105_packing(buf, &entry->vlan_egr, 29, 18, size, op); + sja1105_packing(buf, &entry->do_not_learn, 17, 17, size, op); + sja1105_packing(buf, &entry->use_dest_ports, 16, 16, size, op); + sja1105_packing(buf, &entry->destports, 15, 5, size, op); + return size; +} + +static size_t sja1110_pcp_remapping_entry_packing(void *buf, void *entry_ptr, + enum packing_op op) +{ + struct sja1110_pcp_remapping_entry *entry = entry_ptr; + const size_t size = SJA1110_SIZE_PCP_REMAPPING_ENTRY; + int offset, i; + + for (i = 0, offset = 8; i < SJA1105_NUM_TC; i++, offset += 3) + sja1105_packing(buf, &entry->egrpcp[i], + offset + 2, offset + 0, size, op); + + return size; +} + size_t sja1105_table_header_packing(void *buf, void *entry_ptr, enum packing_op op) { @@ -619,6 +977,7 @@ static u64 blk_id_map[BLK_IDX_MAX] = { [BLK_IDX_GENERAL_PARAMS] = BLKID_GENERAL_PARAMS, [BLK_IDX_RETAGGING] = BLKID_RETAGGING, [BLK_IDX_XMII_PARAMS] = BLKID_XMII_PARAMS, + [BLK_IDX_PCP_REMAPPING] = BLKID_PCP_REMAPPING, }; const char *sja1105_static_config_error_msg[] = { @@ -1400,6 +1759,130 @@ const struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX] = { }, }; +/* SJA1110A: Third generation */ +const struct sja1105_table_ops sja1110_table_ops[BLK_IDX_MAX] = { + [BLK_IDX_SCHEDULE] = { + .packing = sja1110_schedule_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_schedule_entry), + .packed_entry_size = SJA1110_SIZE_SCHEDULE_ENTRY, + .max_entry_count = SJA1110_MAX_SCHEDULE_COUNT, + }, + [BLK_IDX_SCHEDULE_ENTRY_POINTS] = { + .packing = sja1110_schedule_entry_points_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_entry), + .packed_entry_size = SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY, + .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT, + }, + [BLK_IDX_VL_LOOKUP] = { + .packing = sja1110_vl_lookup_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_vl_lookup_entry), + .packed_entry_size = SJA1105_SIZE_VL_LOOKUP_ENTRY, + .max_entry_count = SJA1110_MAX_VL_LOOKUP_COUNT, + }, + [BLK_IDX_VL_POLICING] = { + .packing = sja1110_vl_policing_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_vl_policing_entry), + .packed_entry_size = SJA1105_SIZE_VL_POLICING_ENTRY, + .max_entry_count = SJA1110_MAX_VL_POLICING_COUNT, + }, + [BLK_IDX_VL_FORWARDING] = { + .packing = sja1110_vl_forwarding_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_entry), + .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_ENTRY, + .max_entry_count = SJA1110_MAX_VL_FORWARDING_COUNT, + }, + [BLK_IDX_L2_LOOKUP] = { + .packing = sja1110_l2_lookup_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_entry), + .packed_entry_size = SJA1110_SIZE_L2_LOOKUP_ENTRY, + .max_entry_count = SJA1105_MAX_L2_LOOKUP_COUNT, + }, + [BLK_IDX_L2_POLICING] = { + .packing = sja1110_l2_policing_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_l2_policing_entry), + .packed_entry_size = SJA1105_SIZE_L2_POLICING_ENTRY, + .max_entry_count = SJA1110_MAX_L2_POLICING_COUNT, + }, + [BLK_IDX_VLAN_LOOKUP] = { + .packing = sja1110_vlan_lookup_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_vlan_lookup_entry), + .packed_entry_size = SJA1110_SIZE_VLAN_LOOKUP_ENTRY, + .max_entry_count = SJA1105_MAX_VLAN_LOOKUP_COUNT, + }, + [BLK_IDX_L2_FORWARDING] = { + .packing = sja1110_l2_forwarding_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_entry), + .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_ENTRY, + .max_entry_count = SJA1110_MAX_L2_FORWARDING_COUNT, + }, + [BLK_IDX_MAC_CONFIG] = { + .packing = sja1110_mac_config_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_mac_config_entry), + .packed_entry_size = SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY, + .max_entry_count = SJA1110_MAX_MAC_CONFIG_COUNT, + }, + [BLK_IDX_SCHEDULE_PARAMS] = { + .packing = sja1110_schedule_params_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_schedule_params_entry), + .packed_entry_size = SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY, + .max_entry_count = SJA1105_MAX_SCHEDULE_PARAMS_COUNT, + }, + [BLK_IDX_SCHEDULE_ENTRY_POINTS_PARAMS] = { + .packing = sja1105_schedule_entry_points_params_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_schedule_entry_points_params_entry), + .packed_entry_size = SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY, + .max_entry_count = SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT, + }, + [BLK_IDX_VL_FORWARDING_PARAMS] = { + .packing = sja1110_vl_forwarding_params_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_vl_forwarding_params_entry), + .packed_entry_size = SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY, + .max_entry_count = SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT, + }, + [BLK_IDX_L2_LOOKUP_PARAMS] = { + .packing = sja1110_l2_lookup_params_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_l2_lookup_params_entry), + .packed_entry_size = SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY, + .max_entry_count = SJA1105_MAX_L2_LOOKUP_PARAMS_COUNT, + }, + [BLK_IDX_L2_FORWARDING_PARAMS] = { + .packing = sja1110_l2_forwarding_params_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_l2_forwarding_params_entry), + .packed_entry_size = SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY, + .max_entry_count = SJA1105_MAX_L2_FORWARDING_PARAMS_COUNT, + }, + [BLK_IDX_AVB_PARAMS] = { + .packing = sja1105pqrs_avb_params_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_avb_params_entry), + .packed_entry_size = SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY, + .max_entry_count = SJA1105_MAX_AVB_PARAMS_COUNT, + }, + [BLK_IDX_GENERAL_PARAMS] = { + .packing = sja1110_general_params_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_general_params_entry), + .packed_entry_size = SJA1110_SIZE_GENERAL_PARAMS_ENTRY, + .max_entry_count = SJA1105_MAX_GENERAL_PARAMS_COUNT, + }, + [BLK_IDX_RETAGGING] = { + .packing = sja1110_retagging_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_retagging_entry), + .packed_entry_size = SJA1105_SIZE_RETAGGING_ENTRY, + .max_entry_count = SJA1105_MAX_RETAGGING_COUNT, + }, + [BLK_IDX_XMII_PARAMS] = { + .packing = sja1110_xmii_params_entry_packing, + .unpacked_entry_size = sizeof(struct sja1105_xmii_params_entry), + .packed_entry_size = SJA1110_SIZE_XMII_PARAMS_ENTRY, + .max_entry_count = SJA1105_MAX_XMII_PARAMS_COUNT, + }, + [BLK_IDX_PCP_REMAPPING] = { + .packing = sja1110_pcp_remapping_entry_packing, + .unpacked_entry_size = sizeof(struct sja1110_pcp_remapping_entry), + .packed_entry_size = SJA1110_SIZE_PCP_REMAPPING_ENTRY, + .max_entry_count = SJA1110_MAX_PCP_REMAPPING_COUNT, + }, +}; + int sja1105_static_config_init(struct sja1105_static_config *config, const struct sja1105_table_ops *static_ops, u64 device_id) diff --git a/drivers/net/dsa/sja1105/sja1105_static_config.h b/drivers/net/dsa/sja1105/sja1105_static_config.h index 4ddb06bd8e92..d24227f78a72 100644 --- a/drivers/net/dsa/sja1105/sja1105_static_config.h +++ b/drivers/net/dsa/sja1105/sja1105_static_config.h @@ -9,21 +9,30 @@ #include #include +#define SJA1105_NUM_PORTS 5 +#define SJA1110_NUM_PORTS 11 +#define SJA1105_MAX_NUM_PORTS SJA1110_NUM_PORTS +#define SJA1105_NUM_TC 8 + #define SJA1105_SIZE_SPI_MSG_HEADER 4 #define SJA1105_SIZE_SPI_MSG_MAXLEN (64 * 4) #define SJA1105_SIZE_DEVICE_ID 4 #define SJA1105_SIZE_TABLE_HEADER 12 #define SJA1105_SIZE_SCHEDULE_ENTRY 8 +#define SJA1110_SIZE_SCHEDULE_ENTRY 12 #define SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY 4 +#define SJA1110_SIZE_SCHEDULE_ENTRY_POINTS_ENTRY 8 #define SJA1105_SIZE_VL_LOOKUP_ENTRY 12 #define SJA1105_SIZE_VL_POLICING_ENTRY 8 #define SJA1105_SIZE_VL_FORWARDING_ENTRY 4 #define SJA1105_SIZE_L2_POLICING_ENTRY 8 #define SJA1105_SIZE_VLAN_LOOKUP_ENTRY 8 +#define SJA1110_SIZE_VLAN_LOOKUP_ENTRY 12 #define SJA1105_SIZE_L2_FORWARDING_ENTRY 8 #define SJA1105_SIZE_L2_FORWARDING_PARAMS_ENTRY 12 #define SJA1105_SIZE_RETAGGING_ENTRY 8 #define SJA1105_SIZE_XMII_PARAMS_ENTRY 4 +#define SJA1110_SIZE_XMII_PARAMS_ENTRY 8 #define SJA1105_SIZE_SCHEDULE_PARAMS_ENTRY 12 #define SJA1105_SIZE_SCHEDULE_ENTRY_POINTS_PARAMS_ENTRY 4 #define SJA1105_SIZE_VL_FORWARDING_PARAMS_ENTRY 12 @@ -34,11 +43,15 @@ #define SJA1105ET_SIZE_AVB_PARAMS_ENTRY 12 #define SJA1105ET_SIZE_CBS_ENTRY 16 #define SJA1105PQRS_SIZE_L2_LOOKUP_ENTRY 20 +#define SJA1110_SIZE_L2_LOOKUP_ENTRY 24 #define SJA1105PQRS_SIZE_MAC_CONFIG_ENTRY 32 #define SJA1105PQRS_SIZE_L2_LOOKUP_PARAMS_ENTRY 16 +#define SJA1110_SIZE_L2_LOOKUP_PARAMS_ENTRY 28 #define SJA1105PQRS_SIZE_GENERAL_PARAMS_ENTRY 44 +#define SJA1110_SIZE_GENERAL_PARAMS_ENTRY 56 #define SJA1105PQRS_SIZE_AVB_PARAMS_ENTRY 16 #define SJA1105PQRS_SIZE_CBS_ENTRY 20 +#define SJA1110_SIZE_PCP_REMAPPING_ENTRY 4 /* UM10944.pdf Page 11, Table 2. Configuration Blocks */ enum { @@ -61,6 +74,7 @@ enum { BLKID_GENERAL_PARAMS = 0x11, BLKID_RETAGGING = 0x12, BLKID_CBS = 0x13, + BLKID_PCP_REMAPPING = 0x1C, BLKID_XMII_PARAMS = 0x4E, }; @@ -85,6 +99,7 @@ enum sja1105_blk_idx { BLK_IDX_RETAGGING, BLK_IDX_CBS, BLK_IDX_XMII_PARAMS, + BLK_IDX_PCP_REMAPPING, BLK_IDX_MAX, /* Fake block indices that are only valid for dynamic access */ BLK_IDX_MGMT_ROUTE, @@ -93,15 +108,22 @@ enum sja1105_blk_idx { }; #define SJA1105_MAX_SCHEDULE_COUNT 1024 +#define SJA1110_MAX_SCHEDULE_COUNT 4096 #define SJA1105_MAX_SCHEDULE_ENTRY_POINTS_COUNT 2048 #define SJA1105_MAX_VL_LOOKUP_COUNT 1024 +#define SJA1110_MAX_VL_LOOKUP_COUNT 4096 #define SJA1105_MAX_VL_POLICING_COUNT 1024 +#define SJA1110_MAX_VL_POLICING_COUNT 4096 #define SJA1105_MAX_VL_FORWARDING_COUNT 1024 +#define SJA1110_MAX_VL_FORWARDING_COUNT 4096 #define SJA1105_MAX_L2_LOOKUP_COUNT 1024 #define SJA1105_MAX_L2_POLICING_COUNT 45 +#define SJA1110_MAX_L2_POLICING_COUNT 110 #define SJA1105_MAX_VLAN_LOOKUP_COUNT 4096 #define SJA1105_MAX_L2_FORWARDING_COUNT 13 +#define SJA1110_MAX_L2_FORWARDING_COUNT 19 #define SJA1105_MAX_MAC_CONFIG_COUNT 5 +#define SJA1110_MAX_MAC_CONFIG_COUNT 11 #define SJA1105_MAX_SCHEDULE_PARAMS_COUNT 1 #define SJA1105_MAX_SCHEDULE_ENTRY_POINTS_PARAMS_COUNT 1 #define SJA1105_MAX_VL_FORWARDING_PARAMS_COUNT 1 @@ -113,8 +135,11 @@ enum sja1105_blk_idx { #define SJA1105_MAX_AVB_PARAMS_COUNT 1 #define SJA1105ET_MAX_CBS_COUNT 10 #define SJA1105PQRS_MAX_CBS_COUNT 16 +#define SJA1110_MAX_CBS_COUNT 80 +#define SJA1110_MAX_PCP_REMAPPING_COUNT 11 #define SJA1105_MAX_FRAME_MEMORY 929 +#define SJA1110_MAX_FRAME_MEMORY 1820 #define SJA1105_FRAME_MEMORY_RETAGGING_OVERHEAD 19 #define SJA1105_VL_FRAME_MEMORY 100 @@ -122,12 +147,26 @@ enum sja1105_blk_idx { #define SJA1105T_DEVICE_ID 0x9E00030Eull #define SJA1105PR_DEVICE_ID 0xAF00030Eull #define SJA1105QS_DEVICE_ID 0xAE00030Eull +#define SJA1110_DEVICE_ID 0xB700030Full #define SJA1105ET_PART_NO 0x9A83 #define SJA1105P_PART_NO 0x9A84 #define SJA1105Q_PART_NO 0x9A85 #define SJA1105R_PART_NO 0x9A86 #define SJA1105S_PART_NO 0x9A87 +#define SJA1110A_PART_NO 0x1110 +#define SJA1110B_PART_NO 0x1111 +#define SJA1110C_PART_NO 0x1112 +#define SJA1110D_PART_NO 0x1113 + +#define SJA1110_ACU 0x1c4400 +#define SJA1110_RGU 0x1c6000 +#define SJA1110_CGU 0x1c6400 + +#define SJA1110_SPI_ADDR(x) ((x) / 4) +#define SJA1110_ACU_ADDR(x) (SJA1110_ACU + SJA1110_SPI_ADDR(x)) +#define SJA1110_CGU_ADDR(x) (SJA1110_CGU + SJA1110_SPI_ADDR(x)) +#define SJA1110_RGU_ADDR(x) (SJA1110_RGU + SJA1110_SPI_ADDR(x)) #define SJA1105_RSV_ADDR 0xffffffffffffffffull @@ -175,6 +214,8 @@ struct sja1105_general_params_entry { u64 egrmirrpcp; u64 egrmirrdei; u64 replay_port; + /* SJA1110 only */ + u64 tte_en; }; struct sja1105_schedule_entry_points_entry { @@ -195,6 +236,7 @@ struct sja1105_vlan_lookup_entry { u64 vlan_bc; u64 tag_port; u64 vlanid; + u64 type_entry; /* SJA1110 only */ }; struct sja1105_l2_lookup_entry { @@ -207,11 +249,17 @@ struct sja1105_l2_lookup_entry { u64 mask_iotag; u64 mask_vlanid; u64 mask_macaddr; + u64 mask_srcport; u64 iotag; + u64 srcport; u64 lockeds; union { /* LOCKEDS=1: Static FDB entries */ struct { + /* TSREG is deprecated in SJA1110, TRAP is supported only + * in SJA1110. + */ + u64 trap; u64 tsreg; u64 mirrvlan; u64 takets; @@ -227,7 +275,7 @@ struct sja1105_l2_lookup_entry { }; struct sja1105_l2_lookup_params_entry { - u64 maxaddrp[5]; /* P/Q/R/S only */ + u64 maxaddrp[SJA1105_MAX_NUM_PORTS]; /* P/Q/R/S only */ u64 start_dynspc; /* P/Q/R/S only */ u64 drpnolearn; /* P/Q/R/S only */ u64 use_static; /* P/Q/R/S only */ @@ -245,7 +293,9 @@ struct sja1105_l2_forwarding_entry { u64 bc_domain; u64 reach_port; u64 fl_domain; - u64 vlan_pmap[8]; + /* This is actually max(SJA1105_NUM_TC, SJA1105_MAX_NUM_PORTS) */ + u64 vlan_pmap[SJA1105_MAX_NUM_PORTS]; + bool type_egrpcp2outputq; }; struct sja1105_l2_forwarding_params_entry { @@ -300,8 +350,8 @@ struct sja1105_retagging_entry { }; struct sja1105_cbs_entry { - u64 port; - u64 prio; + u64 port; /* Not used for SJA1110 */ + u64 prio; /* Not used for SJA1110 */ u64 credit_hi; u64 credit_lo; u64 send_slope; @@ -309,8 +359,19 @@ struct sja1105_cbs_entry { }; struct sja1105_xmii_params_entry { - u64 phy_mac[5]; - u64 xmii_mode[5]; + u64 phy_mac[SJA1105_MAX_NUM_PORTS]; + u64 xmii_mode[SJA1105_MAX_NUM_PORTS]; + /* The SJA1110 insists being a snowflake, and requires SGMII, + * 2500base-x and internal MII ports connected to the 100base-TX PHY to + * set this bit. We set it unconditionally from the high-level logic, + * and only sja1110_xmii_params_entry_packing writes it to the static + * config. I have no better name for it than "special". + */ + u64 special[SJA1105_MAX_NUM_PORTS]; +}; + +struct sja1110_pcp_remapping_entry { + u64 egrpcp[SJA1105_NUM_TC]; }; enum { @@ -391,6 +452,7 @@ extern const struct sja1105_table_ops sja1105p_table_ops[BLK_IDX_MAX]; extern const struct sja1105_table_ops sja1105q_table_ops[BLK_IDX_MAX]; extern const struct sja1105_table_ops sja1105r_table_ops[BLK_IDX_MAX]; extern const struct sja1105_table_ops sja1105s_table_ops[BLK_IDX_MAX]; +extern const struct sja1105_table_ops sja1110_table_ops[BLK_IDX_MAX]; size_t sja1105_table_header_packing(void *buf, void *hdr, enum packing_op op); void @@ -438,23 +500,47 @@ void sja1105_packing(void *buf, u64 *val, int start, int end, /* Common implementations for the static and dynamic configs */ size_t sja1105pqrs_general_params_entry_packing(void *buf, void *entry_ptr, enum packing_op op); +size_t sja1110_general_params_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); size_t sja1105pqrs_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, enum packing_op op); +size_t sja1110_l2_lookup_params_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); size_t sja1105_l2_forwarding_entry_packing(void *buf, void *entry_ptr, enum packing_op op); +size_t sja1110_l2_forwarding_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); size_t sja1105pqrs_l2_lookup_entry_packing(void *buf, void *entry_ptr, enum packing_op op); size_t sja1105et_l2_lookup_entry_packing(void *buf, void *entry_ptr, enum packing_op op); +size_t sja1110_l2_lookup_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); size_t sja1105_vlan_lookup_entry_packing(void *buf, void *entry_ptr, enum packing_op op); +size_t sja1110_vlan_lookup_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); size_t sja1105_retagging_entry_packing(void *buf, void *entry_ptr, enum packing_op op); +size_t sja1110_retagging_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); size_t sja1105pqrs_mac_config_entry_packing(void *buf, void *entry_ptr, enum packing_op op); +size_t sja1110_mac_config_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); size_t sja1105pqrs_avb_params_entry_packing(void *buf, void *entry_ptr, enum packing_op op); size_t sja1105_vl_lookup_entry_packing(void *buf, void *entry_ptr, enum packing_op op); +size_t sja1110_vl_lookup_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); +size_t sja1110_vl_policing_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); +size_t sja1110_xmii_params_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); +size_t sja1110_l2_policing_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); +size_t sja1110_l2_forwarding_params_entry_packing(void *buf, void *entry_ptr, + enum packing_op op); #endif From patchwork Wed May 26 13:55:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281765 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9404FC47082 for ; Wed, 26 May 2021 13:56:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 772C960C3D for ; Wed, 26 May 2021 13:56:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233238AbhEZN56 (ORCPT ); Wed, 26 May 2021 09:57:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53526 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234418AbhEZN5h (ORCPT ); Wed, 26 May 2021 09:57:37 -0400 Received: from mail-ed1-x536.google.com (mail-ed1-x536.google.com [IPv6:2a00:1450:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EC67DC061760 for ; Wed, 26 May 2021 06:56:04 -0700 (PDT) Received: by mail-ed1-x536.google.com with SMTP id t3so1613124edc.7 for ; Wed, 26 May 2021 06:56:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NvKXPfJHudA/7MpUC8eb3xPCFwobuco93gUwHQx0PJI=; b=IKKSwCZ6Lj8kBVD0i2rpuXcJWf0lxdn5IeWvduOUjx32P0D/d5JrUZXDPbq9Kxntzx QWicQbsa+/QPuA5d/dY1ysRPCFfcbdM20VF8MYJHWAn7XHRKU6DIVAb7LPX8Oc2uT7rJ qKtXgOSubkJl2NIOHSv5s25bAyxOgfSZ95atq90twjXrBSVEWjVaE1oAnI0W4Sf6aDgY LCAYuVgxBCF5zvNTBu2GSMwruJ4J5oKlXqtLaA3ZkhUU6lSj9P3OJ2loU53ruE9ZqwGe BGwSJeUMfMPlUA9gap+TGq2yJYD+MJ4D3OdOC+aWWO+4poDFzX+NRKCPEtS4N1wcIxet Z3Tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NvKXPfJHudA/7MpUC8eb3xPCFwobuco93gUwHQx0PJI=; b=epgfVOFSvi8BUSk7aCyJMxYzRSsf3gNd6sy2a8Z4U579Zif7yZnx4hKgOSOHaEqXqX o/KNN03X657auL9iIrGAL8QQzZJYx5JsVTm5ikzZ+nm8db9zYIvC64w3T7XZ2l9bGG+/ 0BEEqn1lsE20JJ0HdFvxJwz0/CSICM69q7QmPRDXEynAN8CuirlhitychOGK0OpC8YoQ W4JIs+9cnjwqtCsTJK+B84TLpzjYzCPCQBaSgXqhoc2Yjp7WoMsZ/ph7Wrcpl8wBuT5i +MWCj2mGMBxN3CEFoNx3auRxfWoovVieDqnXeITOi4zNIMzq2XSjBg9h9IJvhtVFkhWR 8bJQ== X-Gm-Message-State: AOAM531eT5nGjPZi40uVzl0O+rRXdjenLZWKV+IDbhZrpA13RfgtzeMk FlB61FZrNelRANcHBz+8iqM= X-Google-Smtp-Source: ABdhPJyzRA57U0ikqNcTnf7NLiP/pQONG6Y0s76lvFeMoF19OiWQ8wTLhqNOyiNVWbXADDS8g8MMfA== X-Received: by 2002:aa7:dc4a:: with SMTP id g10mr38158185edu.316.1622037363429; Wed, 26 May 2021 06:56:03 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.56.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:56:02 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Russell King , Heiner Kallweit , Rob Herring Subject: [RFC PATCH v2 linux-next 12/14] net: dsa: sja1105: register the MDIO buses for 100base-T1 and 100base-TX Date: Wed, 26 May 2021 16:55:33 +0300 Message-Id: <20210526135535.2515123-13-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC The SJA1110 contains two types of integrated PHYs: one 100base-TX PHY and multiple 100base-T1 PHYs. The access procedure for the 100base-T1 PHYs is also different than it is for the 100base-TX one. So we register 2 MDIO buses, one for the base-TX and the other for the base-T1. Each bus has an OF node which is a child of the "mdio" subnode of the switch, and they are recognized by compatible string. Cc: Russell King Cc: Heiner Kallweit Cc: Rob Herring Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Changes in v2: s/"mdio"/"mdios"/ for the name of the container OF node. drivers/net/dsa/sja1105/Makefile | 1 + drivers/net/dsa/sja1105/sja1105.h | 19 ++ drivers/net/dsa/sja1105/sja1105_main.c | 21 +- drivers/net/dsa/sja1105/sja1105_mdio.c | 288 +++++++++++++++++++++++++ drivers/net/dsa/sja1105/sja1105_spi.c | 30 +++ 5 files changed, 358 insertions(+), 1 deletion(-) create mode 100644 drivers/net/dsa/sja1105/sja1105_mdio.c diff --git a/drivers/net/dsa/sja1105/Makefile b/drivers/net/dsa/sja1105/Makefile index a860e3a910be..40d69e6c0bae 100644 --- a/drivers/net/dsa/sja1105/Makefile +++ b/drivers/net/dsa/sja1105/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_NET_DSA_SJA1105) += sja1105.o sja1105-objs := \ sja1105_spi.o \ sja1105_main.o \ + sja1105_mdio.o \ sja1105_flower.o \ sja1105_ethtool.o \ sja1105_devlink.o \ diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 8bfda8c7bc1f..80966d7ce318 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -67,6 +67,12 @@ struct sja1105_regs { u64 rmii_ref_clk[SJA1105_MAX_NUM_PORTS]; u64 rmii_ext_tx_clk[SJA1105_MAX_NUM_PORTS]; u64 stats[__MAX_SJA1105_STATS_AREA][SJA1105_MAX_NUM_PORTS]; + u64 mdio_100base_tx; + u64 mdio_100base_t1; +}; + +struct sja1105_mdio_private { + struct sja1105_private *priv; }; enum { @@ -78,6 +84,12 @@ enum { SJA1105_SPEED_MAX, }; +enum sja1105_internal_phy_t { + SJA1105_NO_PHY = 0, + SJA1105_PHY_BASE_TX, + SJA1105_PHY_BASE_T1, +}; + struct sja1105_info { u64 device_id; /* Needed for distinction between P and R, and between Q and S @@ -123,6 +135,7 @@ struct sja1105_info { bool supports_rgmii[SJA1105_MAX_NUM_PORTS]; bool supports_sgmii[SJA1105_MAX_NUM_PORTS]; bool supports_2500basex[SJA1105_MAX_NUM_PORTS]; + enum sja1105_internal_phy_t internal_phy[SJA1105_MAX_NUM_PORTS]; const u64 port_speed[SJA1105_SPEED_MAX]; }; @@ -245,6 +258,8 @@ struct sja1105_private { enum sja1105_vlan_state vlan_state; struct devlink_region **regions; struct sja1105_cbs_entry *cbs; + struct mii_bus *mdio_base_t1; + struct mii_bus *mdio_base_tx; struct sja1105_tagger_data tagger_data; struct sja1105_ptp_data ptp_data; struct sja1105_tas_data tas_data; @@ -274,6 +289,10 @@ int sja1105_vlan_filtering(struct dsa_switch *ds, int port, bool enabled, struct netlink_ext_ack *extack); void sja1105_frame_memory_partitioning(struct sja1105_private *priv); +/* From sja1105_mdio.c */ +int sja1105_mdiobus_register(struct dsa_switch *ds); +void sja1105_mdiobus_unregister(struct dsa_switch *ds); + /* From sja1105_devlink.c */ int sja1105_devlink_setup(struct dsa_switch *ds); void sja1105_devlink_teardown(struct dsa_switch *ds); diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 5e208ca78c4f..20c5dcd8de8d 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -175,6 +175,15 @@ static int sja1105_init_mii_settings(struct sja1105_private *priv, continue; switch (ports[i].phy_mode) { + case PHY_INTERFACE_MODE_INTERNAL: + if (priv->info->internal_phy[i] == SJA1105_NO_PHY) + goto unsupported; + + mii->xmii_mode[i] = XMII_MODE_MII; + if (priv->info->internal_phy[i] == SJA1105_PHY_BASE_TX) + mii->special[i] = true; + + break; case PHY_INTERFACE_MODE_MII: if (!priv->info->supports_mii[i]) goto unsupported; @@ -3081,11 +3090,19 @@ static int sja1105_setup(struct dsa_switch *ds) dev_err(ds->dev, "Failed to register PTP clock: %d\n", rc); return rc; } + + rc = sja1105_mdiobus_register(ds); + if (rc < 0) { + dev_err(ds->dev, "Failed to register MDIO bus: %pe\n", + ERR_PTR(rc)); + goto out_ptp_clock_unregister; + } + /* Create and send configuration down to device */ rc = sja1105_static_config_load(priv, ports); if (rc < 0) { dev_err(ds->dev, "Failed to load static config: %d\n", rc); - goto out_ptp_clock_unregister; + goto out_mdiobus_unregister; } /* Configure the CGU (PHY link modes and speeds) */ rc = priv->info->clocking_setup(priv); @@ -3128,6 +3145,8 @@ static int sja1105_setup(struct dsa_switch *ds) out_devlink_teardown: sja1105_devlink_teardown(ds); +out_mdiobus_unregister: + sja1105_mdiobus_unregister(ds); out_ptp_clock_unregister: sja1105_ptp_clock_unregister(ds); out_static_config_free: diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c new file mode 100644 index 000000000000..8dfd06318b23 --- /dev/null +++ b/drivers/net/dsa/sja1105/sja1105_mdio.c @@ -0,0 +1,288 @@ +// SPDX-License-Identifier: GPL-2.0 +/* Copyright 2021, NXP Semiconductors + */ +#include +#include "sja1105.h" + +enum sja1105_mdio_opcode { + SJA1105_C45_ADDR = 0, + SJA1105_C22 = 1, + SJA1105_C45_DATA = 2, + SJA1105_C45_DATA_AUTOINC = 3, +}; + +static u64 sja1105_base_t1_encode_addr(struct sja1105_private *priv, + int phy, enum sja1105_mdio_opcode op, + int xad) +{ + const struct sja1105_regs *regs = priv->info->regs; + + return regs->mdio_100base_t1 | (phy << 7) | (op << 5) | (xad << 0); +} + +static int sja1105_base_t1_mdio_read(struct mii_bus *bus, int phy, int reg) +{ + struct sja1105_mdio_private *mdio_priv = bus->priv; + struct sja1105_private *priv = mdio_priv->priv; + u64 addr; + u32 tmp; + int rc; + + if (reg & MII_ADDR_C45) { + u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f; + + addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR, + mmd); + + tmp = reg & MII_REGADDR_C45_MASK; + + rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); + if (rc < 0) + return rc; + + addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA, + mmd); + + rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL); + if (rc < 0) + return rc; + + return tmp & 0xffff; + } + + /* Clause 22 read */ + addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f); + + rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL); + if (rc < 0) + return rc; + + return tmp & 0xffff; +} + +static int sja1105_base_t1_mdio_write(struct mii_bus *bus, int phy, int reg, + u16 val) +{ + struct sja1105_mdio_private *mdio_priv = bus->priv; + struct sja1105_private *priv = mdio_priv->priv; + u64 addr; + u32 tmp; + int rc; + + if (reg & MII_ADDR_C45) { + u16 mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f; + + addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_ADDR, + mmd); + + tmp = reg & MII_REGADDR_C45_MASK; + + rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); + if (rc < 0) + return rc; + + addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C45_DATA, + mmd); + + tmp = val & 0xffff; + + rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); + if (rc < 0) + return rc; + + return 0; + } + + /* Clause 22 write */ + addr = sja1105_base_t1_encode_addr(priv, phy, SJA1105_C22, reg & 0x1f); + + tmp = val & 0xffff; + + return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); +} + +static int sja1105_base_tx_mdio_read(struct mii_bus *bus, int phy, int reg) +{ + struct sja1105_mdio_private *mdio_priv = bus->priv; + struct sja1105_private *priv = mdio_priv->priv; + const struct sja1105_regs *regs = priv->info->regs; + u32 tmp; + int rc; + + rc = sja1105_xfer_u32(priv, SPI_READ, regs->mdio_100base_tx + reg, + &tmp, NULL); + if (rc < 0) + return rc; + + return tmp & 0xffff; +} + +static int sja1105_base_tx_mdio_write(struct mii_bus *bus, int phy, int reg, + u16 val) +{ + struct sja1105_mdio_private *mdio_priv = bus->priv; + struct sja1105_private *priv = mdio_priv->priv; + const struct sja1105_regs *regs = priv->info->regs; + u32 tmp = val; + + return sja1105_xfer_u32(priv, SPI_WRITE, regs->mdio_100base_tx + reg, + &tmp, NULL); +} + +static int sja1105_mdiobus_base_tx_register(struct sja1105_private *priv, + struct device_node *mdio_node) +{ + struct sja1105_mdio_private *mdio_priv; + struct device_node *np; + struct mii_bus *bus; + int rc = 0; + + np = of_find_compatible_node(mdio_node, NULL, + "nxp,sja1110-base-tx-mdio"); + if (!np) + return 0; + + if (!of_device_is_available(np)) + goto out_put_np; + + bus = mdiobus_alloc_size(sizeof(*mdio_priv)); + if (!bus) { + rc = -ENOMEM; + goto out_put_np; + } + + bus->name = "SJA1110 100base-TX MDIO bus"; + snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-tx", + dev_name(priv->ds->dev)); + bus->read = sja1105_base_tx_mdio_read; + bus->write = sja1105_base_tx_mdio_write; + bus->parent = priv->ds->dev; + mdio_priv = bus->priv; + mdio_priv->priv = priv; + + rc = of_mdiobus_register(bus, np); + if (rc) { + mdiobus_free(bus); + goto out_put_np; + } + + priv->mdio_base_tx = bus; + +out_put_np: + of_node_put(np); + + return 0; +} + +static void sja1105_mdiobus_base_tx_unregister(struct sja1105_private *priv) +{ + if (!priv->mdio_base_tx) + return; + + mdiobus_unregister(priv->mdio_base_tx); + mdiobus_free(priv->mdio_base_tx); + priv->mdio_base_tx = NULL; +} + +static int sja1105_mdiobus_base_t1_register(struct sja1105_private *priv, + struct device_node *mdio_node) +{ + struct sja1105_mdio_private *mdio_priv; + struct device_node *np; + struct mii_bus *bus; + int rc = 0; + + np = of_find_compatible_node(mdio_node, NULL, + "nxp,sja1110-base-t1-mdio"); + if (!np) + return 0; + + if (!of_device_is_available(np)) + goto out_put_np; + + bus = mdiobus_alloc_size(sizeof(*mdio_priv)); + if (!bus) { + rc = -ENOMEM; + goto out_put_np; + } + + bus->name = "SJA1110 100base-T1 MDIO bus"; + snprintf(bus->id, MII_BUS_ID_SIZE, "%s-base-t1", + dev_name(priv->ds->dev)); + bus->read = sja1105_base_t1_mdio_read; + bus->write = sja1105_base_t1_mdio_write; + bus->parent = priv->ds->dev; + mdio_priv = bus->priv; + mdio_priv->priv = priv; + + rc = of_mdiobus_register(bus, np); + if (rc) { + mdiobus_free(bus); + goto out_put_np; + } + + priv->mdio_base_t1 = bus; + +out_put_np: + of_node_put(np); + + return rc; +} + +static void sja1105_mdiobus_base_t1_unregister(struct sja1105_private *priv) +{ + if (!priv->mdio_base_t1) + return; + + mdiobus_unregister(priv->mdio_base_t1); + mdiobus_free(priv->mdio_base_t1); + priv->mdio_base_t1 = NULL; +} + +int sja1105_mdiobus_register(struct dsa_switch *ds) +{ + struct sja1105_private *priv = ds->priv; + const struct sja1105_regs *regs = priv->info->regs; + struct device_node *switch_node = ds->dev->of_node; + struct device_node *mdio_node; + int rc; + + mdio_node = of_get_child_by_name(switch_node, "mdios"); + if (!mdio_node) + return 0; + + if (!of_device_is_available(mdio_node)) + goto out_put_mdio_node; + + if (regs->mdio_100base_tx != SJA1105_RSV_ADDR) { + rc = sja1105_mdiobus_base_tx_register(priv, mdio_node); + if (rc) + goto err_put_mdio_node; + } + + if (regs->mdio_100base_t1 != SJA1105_RSV_ADDR) { + rc = sja1105_mdiobus_base_t1_register(priv, mdio_node); + if (rc) + goto err_free_base_tx_mdiobus; + } + +out_put_mdio_node: + of_node_put(mdio_node); + + return 0; + +err_free_base_tx_mdiobus: + sja1105_mdiobus_base_tx_unregister(priv); +err_put_mdio_node: + of_node_put(mdio_node); + + return rc; +} + +void sja1105_mdiobus_unregister(struct dsa_switch *ds) +{ + struct sja1105_private *priv = ds->priv; + + sja1105_mdiobus_base_t1_unregister(priv); + sja1105_mdiobus_base_tx_unregister(priv); +} diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 187c9fbbd397..54ecb5565761 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -436,6 +436,8 @@ static struct sja1105_regs sja1105et_regs = { .ptpclkval = 0x18, /* Spans 0x18 to 0x19 */ .ptpclkrate = 0x1A, .ptpclkcorp = 0x1D, + .mdio_100base_tx = SJA1105_RSV_ADDR, + .mdio_100base_t1 = SJA1105_RSV_ADDR, }; static struct sja1105_regs sja1105pqrs_regs = { @@ -473,6 +475,8 @@ static struct sja1105_regs sja1105pqrs_regs = { .ptpclkrate = 0x1B, .ptpclkcorp = 0x1E, .ptpsyncts = 0x1F, + .mdio_100base_tx = SJA1105_RSV_ADDR, + .mdio_100base_t1 = SJA1105_RSV_ADDR, }; static struct sja1105_regs sja1110_regs = { @@ -555,6 +559,8 @@ static struct sja1105_regs sja1110_regs = { .ptpclkrate = SJA1110_SPI_ADDR(0x74), .ptpclkcorp = SJA1110_SPI_ADDR(0x80), .ptpsyncts = SJA1110_SPI_ADDR(0x84), + .mdio_100base_tx = 0x1c2400, + .mdio_100base_t1 = 0x1c1000, }; const struct sja1105_info sja1105e_info = { @@ -785,6 +791,12 @@ const struct sja1105_info sja1110a_info = { false, false, false, false, false, false}, .supports_2500basex = {false, false, false, true, true, false, false, false, false, false, false}, + .internal_phy = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX, + SJA1105_NO_PHY, SJA1105_NO_PHY, + SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, + SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, + SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, + SJA1105_PHY_BASE_T1}, .name = "SJA1110A", }; @@ -824,6 +836,12 @@ const struct sja1105_info sja1110b_info = { false, false, false, false, false, false}, .supports_2500basex = {false, false, false, true, true, false, false, false, false, false, false}, + .internal_phy = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX, + SJA1105_NO_PHY, SJA1105_NO_PHY, + SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, + SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, + SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, + SJA1105_NO_PHY}, .name = "SJA1110B", }; @@ -863,6 +881,12 @@ const struct sja1105_info sja1110c_info = { false, false, false, false, false, false}, .supports_2500basex = {false, false, false, false, true, false, false, false, false, false, false}, + .internal_phy = {SJA1105_NO_PHY, SJA1105_PHY_BASE_TX, + SJA1105_NO_PHY, SJA1105_NO_PHY, + SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, + SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, + SJA1105_NO_PHY, SJA1105_NO_PHY, + SJA1105_NO_PHY}, .name = "SJA1110C", }; @@ -900,5 +924,11 @@ const struct sja1105_info sja1110d_info = { false, false, false, false, false, false}, .supports_sgmii = {false, true, true, true, true, false, false, false, false, false, false}, + .internal_phy = {SJA1105_NO_PHY, SJA1105_NO_PHY, + SJA1105_NO_PHY, SJA1105_NO_PHY, + SJA1105_NO_PHY, SJA1105_PHY_BASE_T1, + SJA1105_PHY_BASE_T1, SJA1105_PHY_BASE_T1, + SJA1105_NO_PHY, SJA1105_NO_PHY, + SJA1105_NO_PHY}, .name = "SJA1110D", }; From patchwork Wed May 26 13:55:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281767 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 64907C47088 for ; Wed, 26 May 2021 13:56:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3DFAB610A6 for ; Wed, 26 May 2021 13:56:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234528AbhEZN6G (ORCPT ); Wed, 26 May 2021 09:58:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53538 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234235AbhEZN5i (ORCPT ); Wed, 26 May 2021 09:57:38 -0400 Received: from mail-ej1-x633.google.com (mail-ej1-x633.google.com [IPv6:2a00:1450:4864:20::633]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 06B55C061574 for ; Wed, 26 May 2021 06:56:06 -0700 (PDT) Received: by mail-ej1-x633.google.com with SMTP id c20so2628299ejm.3 for ; Wed, 26 May 2021 06:56:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=L3J+3wfaKNI5P7OxxfpW1g/35JERObChqoNpefPvkw4=; b=GHNpdNjB5OMog+EUWfbA/re0ff/UkN9jOzbcatSuX4G6Q+h9DR7AtpYqw3bPvwiy0E Ec42/gvI1EUk53jhnZRsmh177559F9QwzLFBrJGYWJZIlns1DzYWOfcndoKHeUAPO6f3 CxJQrowJdmBpJjyiyS/I/yQJJv8E65St5+nYjXUR4E4elv2mG/UtJvSniYFCCdoZ6wRz gMXrguHzwpRd3aEvt3opn+HMjzw3kGLQIGE+xugN46T7/LvUxk+jOzuqOELjotsnWZ5L I/mwqJhLbZmtzx63oQWo/OuIbpp1kl41z7FrISlVKldc1piw/QPCkqWPpLG3VRslSe/R BWdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=L3J+3wfaKNI5P7OxxfpW1g/35JERObChqoNpefPvkw4=; b=KRFOaeO+JP60Vs8z0q880OM9wxcL08gmLKVtrrMdrxKkFXIQvvk53Kcj4+14S43f0N Z093hGB91+7BHhz/h5EbyDFdHDR6j4hK+O2wo5yk1PSxNMeBMD29vTMl74yhusbYSr3T NP4hITJDebgqSsOUtnfiuJ85kaW9hlIQl+AWlvFRwX3OCFkJRhd5SNiVwsn6nEs22Ba0 Z44JQ8zGVTKry2hmYQQLdEn6fM4KxmBPzg1As9Vk8mkafWx+ErGw+4SmA9itXRxPdUiz z3pTZ8tbGE3WDGk0VwHnHTdvP8NcY9f1FLT2qAWn3uo7/B+rBmlP1OQMNuCxm1GP0NIl +v8w== X-Gm-Message-State: AOAM532mkeFcVYqJRTLsBZMP7iXUgh8nY86AASk76zJORQlCDzFs+u+a PH1luxWOnIEnkZrB0JWJfd4= X-Google-Smtp-Source: ABdhPJydSCHdM87z42Dx+VVMo99bQmXQ6uijyEJmJz6kSt//wOX0RHKRW8mhCRrIhmctWE4dV7jHtw== X-Received: by 2002:a17:907:920e:: with SMTP id ka14mr34083103ejb.193.1622037364406; Wed, 26 May 2021 06:56:04 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.56.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:56:04 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Russell King , Heiner Kallweit Subject: [RFC PATCH v2 linux-next 13/14] net: dsa: sja1105: expose the SGMII PCS as an mdio_device Date: Wed, 26 May 2021 16:55:34 +0300 Message-Id: <20210526135535.2515123-14-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC The SJA1110 has up to 4 PCSes for SGMII/2500base-x, and they have a different access procedure compared to the SJA1105. Since both have a register layout reminiscent of clause 45, the chosen abstraction to hide this difference away was to implement an internal MDIO bus for the PCS, and to use a high-level set of procedures called sja1105_pcs_read and sja1105_pcs_write. Since we touch all PCS accessors again, now it is a good time to check for error codes from the hardware access as well. We can't propagate the errors very far due to phylink returning void for mac_config and mac_link_up, but at least we print them to the console. The SGMII PCS of the SJA1110 is not functional at this point, it needs a different initialization sequence compared to SJA1105. That will be done by the next patch. Cc: Russell King Cc: Heiner Kallweit Signed-off-by: Vladimir Oltean --- Changes in v2: - register this MDIO bus - use mdiobus_c45_addr - move the "offset == 0xff" check later drivers/net/dsa/sja1105/sja1105.h | 12 ++ drivers/net/dsa/sja1105/sja1105_main.c | 93 ++++----- drivers/net/dsa/sja1105/sja1105_mdio.c | 250 ++++++++++++++++++++++++ drivers/net/dsa/sja1105/sja1105_sgmii.h | 2 - drivers/net/dsa/sja1105/sja1105_spi.c | 15 ++ 5 files changed, 319 insertions(+), 53 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 80966d7ce318..be788ddb7259 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -69,6 +69,7 @@ struct sja1105_regs { u64 stats[__MAX_SJA1105_STATS_AREA][SJA1105_MAX_NUM_PORTS]; u64 mdio_100base_tx; u64 mdio_100base_t1; + u64 pcs_base[SJA1105_MAX_NUM_PORTS]; }; struct sja1105_mdio_private { @@ -129,6 +130,8 @@ struct sja1105_info { void (*ptp_cmd_packing)(u8 *buf, struct sja1105_ptp_cmd *cmd, enum packing_op op); int (*clocking_setup)(struct sja1105_private *priv); + int (*pcs_mdio_read)(struct mii_bus *bus, int phy, int reg); + int (*pcs_mdio_write)(struct mii_bus *bus, int phy, int reg, u16 val); const char *name; bool supports_mii[SJA1105_MAX_NUM_PORTS]; bool supports_rmii[SJA1105_MAX_NUM_PORTS]; @@ -260,6 +263,8 @@ struct sja1105_private { struct sja1105_cbs_entry *cbs; struct mii_bus *mdio_base_t1; struct mii_bus *mdio_base_tx; + struct mii_bus *mdio_pcs; + struct mdio_device *pcs[SJA1105_MAX_NUM_PORTS]; struct sja1105_tagger_data tagger_data; struct sja1105_ptp_data ptp_data; struct sja1105_tas_data tas_data; @@ -292,6 +297,13 @@ void sja1105_frame_memory_partitioning(struct sja1105_private *priv); /* From sja1105_mdio.c */ int sja1105_mdiobus_register(struct dsa_switch *ds); void sja1105_mdiobus_unregister(struct dsa_switch *ds); +int sja1105_pcs_mdio_read(struct mii_bus *bus, int phy, int reg); +int sja1105_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val); +int sja1110_pcs_mdio_read(struct mii_bus *bus, int phy, int reg); +int sja1110_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val); +int sja1105_pcs_read(struct sja1105_private *priv, int port, int mmd, int reg); +int sja1105_pcs_write(struct sja1105_private *priv, int port, int mmd, int reg, + u16 val); /* From sja1105_devlink.c */ int sja1105_devlink_setup(struct dsa_switch *ds); diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index 20c5dcd8de8d..d0938daacbae 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -962,74 +962,61 @@ static int sja1105_parse_dt(struct sja1105_private *priv, return rc; } -static int sja1105_sgmii_read(struct sja1105_private *priv, int port, int mmd, - int pcs_reg) -{ - u64 addr = (mmd << 16) | pcs_reg; - u32 val; - int rc; - - if (port != SJA1105_SGMII_PORT) - return -ENODEV; - - rc = sja1105_xfer_u32(priv, SPI_READ, addr, &val, NULL); - if (rc < 0) - return rc; - - return val; -} - -static int sja1105_sgmii_write(struct sja1105_private *priv, int port, int mmd, - int pcs_reg, u16 pcs_val) -{ - u64 addr = (mmd << 16) | pcs_reg; - u32 val = pcs_val; - int rc; - - if (port != SJA1105_SGMII_PORT) - return -ENODEV; - - rc = sja1105_xfer_u32(priv, SPI_WRITE, addr, &val, NULL); - if (rc < 0) - return rc; - - return val; -} - static void sja1105_sgmii_pcs_config(struct sja1105_private *priv, int port, bool an_enabled, bool an_master) { u16 ac = SJA1105_AC_AUTONEG_MODE_SGMII; + int rc; /* DIGITAL_CONTROL_1: Enable vendor-specific MMD1, allow the PHY to * stop the clock during LPI mode, make the MAC reconfigure * autonomously after PCS autoneg is done, flush the internal FIFOs. */ - sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC1, - SJA1105_DC1_EN_VSMMD1 | - SJA1105_DC1_CLOCK_STOP_EN | - SJA1105_DC1_MAC_AUTO_SW | - SJA1105_DC1_INIT); + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC1, + SJA1105_DC1_EN_VSMMD1 | + SJA1105_DC1_CLOCK_STOP_EN | + SJA1105_DC1_MAC_AUTO_SW | + SJA1105_DC1_INIT); + if (rc < 0) + goto out_write_failed; + /* DIGITAL_CONTROL_2: No polarity inversion for TX and RX lanes */ - sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC2, - SJA1105_DC2_TX_POL_INV_DISABLE); + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC2, + SJA1105_DC2_TX_POL_INV_DISABLE); + if (rc < 0) + goto out_write_failed; + /* AUTONEG_CONTROL: Use SGMII autoneg */ if (an_master) ac |= SJA1105_AC_PHY_MODE | SJA1105_AC_SGMII_LINK; - sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, SJA1105_AC, ac); + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_AC, ac); + if (rc < 0) + goto out_write_failed; + /* BASIC_CONTROL: enable in-band AN now, if requested. Otherwise, * sja1105_sgmii_pcs_force_speed must be called later for the link * to become operational. */ - if (an_enabled) - sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1, - BMCR_ANENABLE | BMCR_ANRESTART); + if (an_enabled) { + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1, + BMCR_ANENABLE | BMCR_ANRESTART); + if (rc < 0) + goto out_write_failed; + } + + return; + +out_write_failed: + dev_err(priv->ds->dev, "Failed to write to PCS: %pe\n", + ERR_PTR(rc)); } static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv, int port, int speed) { int pcs_speed; + int rc; switch (speed) { case SPEED_1000: @@ -1045,8 +1032,12 @@ static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv, dev_err(priv->ds->dev, "Invalid speed %d\n", speed); return; } - sja1105_sgmii_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1, - pcs_speed | BMCR_FULLDPLX); + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1, + pcs_speed | BMCR_FULLDPLX); + if (rc < 0) + dev_err(priv->ds->dev, "Failed to write to PCS: %pe\n", + ERR_PTR(rc)); } /* Convert link speed from SJA1105 to ethtool encoding */ @@ -1250,7 +1241,7 @@ static int sja1105_mac_pcs_get_state(struct dsa_switch *ds, int port, int ais; /* Read the vendor-specific AUTONEG_INTR_STATUS register */ - ais = sja1105_sgmii_read(priv, port, MDIO_MMD_VEND2, SJA1105_AIS); + ais = sja1105_pcs_read(priv, port, MDIO_MMD_VEND2, SJA1105_AIS); if (ais < 0) return ais; @@ -1955,9 +1946,9 @@ int sja1105_static_config_reload(struct sja1105_private *priv, mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; if (priv->phy_mode[i] == PHY_INTERFACE_MODE_SGMII) - bmcr[i] = sja1105_sgmii_read(priv, i, - MDIO_MMD_VEND2, - MDIO_CTRL1); + bmcr[i] = sja1105_pcs_read(priv, i, + MDIO_MMD_VEND2, + MDIO_CTRL1); } /* No PTP operations can run right now */ diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c index 8dfd06318b23..bc6c3c1ac7a6 100644 --- a/drivers/net/dsa/sja1105/sja1105_mdio.c +++ b/drivers/net/dsa/sja1105/sja1105_mdio.c @@ -4,6 +4,159 @@ #include #include "sja1105.h" +#define SJA1110_PCS_BANK_REG SJA1110_SPI_ADDR(0x3fc) + +int sja1105_pcs_read(struct sja1105_private *priv, int port, int mmd, int reg) +{ + u32 reg_addr = mdiobus_c45_addr(mmd, reg); + struct mdio_device *pcs = priv->pcs[port]; + + if (!pcs) + return -ENODEV; + + return mdiobus_read(priv->mdio_pcs, port, reg_addr); +} + +int sja1105_pcs_write(struct sja1105_private *priv, int port, int mmd, int reg, + u16 val) +{ + u32 reg_addr = mdiobus_c45_addr(mmd, reg); + struct mdio_device *pcs = priv->pcs[port]; + + if (!pcs) + return -ENODEV; + + return mdiobus_write(priv->mdio_pcs, port, reg_addr, val); +} + +int sja1105_pcs_mdio_read(struct mii_bus *bus, int phy, int reg) +{ + struct sja1105_mdio_private *mdio_priv = bus->priv; + struct sja1105_private *priv = mdio_priv->priv; + u64 addr; + u32 tmp; + u16 mmd; + int rc; + + if (!(reg & MII_ADDR_C45)) + return -EINVAL; + + mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f; + addr = (mmd << 16) | (reg & GENMASK(15, 0)); + + rc = sja1105_xfer_u32(priv, SPI_READ, addr, &tmp, NULL); + if (rc < 0) + return rc; + + return tmp & 0xffff; +} + +int sja1105_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) +{ + struct sja1105_mdio_private *mdio_priv = bus->priv; + struct sja1105_private *priv = mdio_priv->priv; + u64 addr; + u32 tmp; + u16 mmd; + + if (!(reg & MII_ADDR_C45)) + return -EINVAL; + + mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f; + addr = (mmd << 16) | (reg & GENMASK(15, 0)); + tmp = val; + + return sja1105_xfer_u32(priv, SPI_WRITE, addr, &tmp, NULL); +} + +int sja1110_pcs_mdio_read(struct mii_bus *bus, int phy, int reg) +{ + struct sja1105_mdio_private *mdio_priv = bus->priv; + struct sja1105_private *priv = mdio_priv->priv; + const struct sja1105_regs *regs = priv->info->regs; + int offset, bank; + u64 addr; + u32 tmp; + u16 mmd; + int rc; + + if (!(reg & MII_ADDR_C45)) + return -EINVAL; + + if (regs->pcs_base[phy] == SJA1105_RSV_ADDR) + return -ENODEV; + + mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f; + addr = (mmd << 16) | (reg & GENMASK(15, 0)); + + bank = addr >> 8; + offset = addr & GENMASK(7, 0); + + /* This addressing scheme reserves register 0xff for the bank address + * register, so that can never be addressed. + */ + if (WARN_ON(offset == 0xff)) + return -ENODEV; + + tmp = bank; + + rc = sja1105_xfer_u32(priv, SPI_WRITE, + regs->pcs_base[phy] + SJA1110_PCS_BANK_REG, + &tmp, NULL); + if (rc < 0) + return rc; + + rc = sja1105_xfer_u32(priv, SPI_READ, regs->pcs_base[phy] + offset, + &tmp, NULL); + if (rc < 0) + return rc; + + return tmp & 0xffff; +} + +int sja1110_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val) +{ + struct sja1105_mdio_private *mdio_priv = bus->priv; + struct sja1105_private *priv = mdio_priv->priv; + const struct sja1105_regs *regs = priv->info->regs; + int offset, bank; + u64 addr; + u32 tmp; + u16 mmd; + int rc; + + if (!(reg & MII_ADDR_C45)) + return -EINVAL; + + if (regs->pcs_base[phy] == SJA1105_RSV_ADDR) + return -ENODEV; + + mmd = (reg >> MII_DEVADDR_C45_SHIFT) & 0x1f; + addr = (mmd << 16) | (reg & GENMASK(15, 0)); + + bank = addr >> 8; + offset = addr & GENMASK(7, 0); + + /* This addressing scheme reserves register 0xff for the bank address + * register, so that can never be addressed. + */ + if (WARN_ON(offset == 0xff)) + return -ENODEV; + + tmp = bank; + + rc = sja1105_xfer_u32(priv, SPI_WRITE, + regs->pcs_base[phy] + SJA1110_PCS_BANK_REG, + &tmp, NULL); + if (rc < 0) + return rc; + + tmp = val; + + return sja1105_xfer_u32(priv, SPI_WRITE, regs->pcs_base[phy] + offset, + &tmp, NULL); +} + enum sja1105_mdio_opcode { SJA1105_C45_ADDR = 0, SJA1105_C22 = 1, @@ -239,6 +392,97 @@ static void sja1105_mdiobus_base_t1_unregister(struct sja1105_private *priv) priv->mdio_base_t1 = NULL; } +static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv) +{ + struct sja1105_mdio_private *mdio_priv; + struct dsa_switch *ds = priv->ds; + struct mii_bus *bus; + int rc = 0; + int port; + + if (!priv->info->pcs_mdio_read || !priv->info->pcs_mdio_write) + return 0; + + bus = mdiobus_alloc_size(sizeof(*mdio_priv)); + if (!bus) + return -ENOMEM; + + bus->name = "SJA1105 PCS MDIO bus"; + snprintf(bus->id, MII_BUS_ID_SIZE, "%s-pcs", + dev_name(ds->dev)); + bus->read = priv->info->pcs_mdio_read; + bus->write = priv->info->pcs_mdio_write; + bus->parent = ds->dev; + /* There is no PHY on this MDIO bus => mask out all PHY addresses + * from auto probing. + */ + bus->phy_mask = ~0; + mdio_priv = bus->priv; + mdio_priv->priv = priv; + + rc = mdiobus_register(bus); + if (rc) { + mdiobus_free(bus); + return rc; + } + + for (port = 0; port < ds->num_ports; port++) { + struct mdio_device *mdiodev; + + if (dsa_is_unused_port(ds, port)) + continue; + + if (!priv->info->supports_sgmii[port]) + continue; + + mdiodev = mdio_device_create(bus, port); + if (IS_ERR(mdiodev)) { + rc = PTR_ERR(mdiodev); + goto out_pcs_free; + } + + priv->pcs[port] = mdiodev; + } + + priv->mdio_pcs = bus; + + return 0; + +out_pcs_free: + for (port = 0; port < ds->num_ports; port++) { + if (!priv->pcs[port]) + continue; + + mdio_device_free(priv->pcs[port]); + priv->pcs[port] = NULL; + } + + mdiobus_free(bus); + + return rc; +} + +static void sja1105_mdiobus_pcs_unregister(struct sja1105_private *priv) +{ + struct dsa_switch *ds = priv->ds; + int port; + + if (!priv->mdio_pcs) + return; + + for (port = 0; port < ds->num_ports; port++) { + if (!priv->pcs[port]) + continue; + + mdio_device_free(priv->pcs[port]); + priv->pcs[port] = NULL; + } + + mdiobus_unregister(priv->mdio_pcs); + mdiobus_free(priv->mdio_pcs); + priv->mdio_pcs = NULL; +} + int sja1105_mdiobus_register(struct dsa_switch *ds) { struct sja1105_private *priv = ds->priv; @@ -247,6 +491,10 @@ int sja1105_mdiobus_register(struct dsa_switch *ds) struct device_node *mdio_node; int rc; + rc = sja1105_mdiobus_pcs_register(priv); + if (rc) + return rc; + mdio_node = of_get_child_by_name(switch_node, "mdios"); if (!mdio_node) return 0; @@ -275,6 +523,7 @@ int sja1105_mdiobus_register(struct dsa_switch *ds) sja1105_mdiobus_base_tx_unregister(priv); err_put_mdio_node: of_node_put(mdio_node); + sja1105_mdiobus_pcs_unregister(priv); return rc; } @@ -285,4 +534,5 @@ void sja1105_mdiobus_unregister(struct dsa_switch *ds) sja1105_mdiobus_base_t1_unregister(priv); sja1105_mdiobus_base_tx_unregister(priv); + sja1105_mdiobus_pcs_unregister(priv); } diff --git a/drivers/net/dsa/sja1105/sja1105_sgmii.h b/drivers/net/dsa/sja1105/sja1105_sgmii.h index 24d9bc046e70..dc067b876758 100644 --- a/drivers/net/dsa/sja1105/sja1105_sgmii.h +++ b/drivers/net/dsa/sja1105/sja1105_sgmii.h @@ -4,8 +4,6 @@ #ifndef _SJA1105_SGMII_H #define _SJA1105_SGMII_H -#define SJA1105_SGMII_PORT 4 - /* DIGITAL_CONTROL_1 (address 1f8000h) */ #define SJA1105_DC1 0x8000 #define SJA1105_DC1_VS_RESET BIT(15) diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index 54ecb5565761..e6c2cb68fcc4 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -561,6 +561,9 @@ static struct sja1105_regs sja1110_regs = { .ptpsyncts = SJA1110_SPI_ADDR(0x84), .mdio_100base_tx = 0x1c2400, .mdio_100base_t1 = 0x1c1000, + .pcs_base = {SJA1105_RSV_ADDR, 0x1c1400, 0x1c1800, 0x1c1c00, 0x1c2000, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, + SJA1105_RSV_ADDR, SJA1105_RSV_ADDR, SJA1105_RSV_ADDR}, }; const struct sja1105_info sja1105e_info = { @@ -707,6 +710,8 @@ const struct sja1105_info sja1105r_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, + .pcs_mdio_read = sja1105_pcs_mdio_read, + .pcs_mdio_write = sja1105_pcs_mdio_write, .regs = &sja1105pqrs_regs, .port_speed = { [SJA1105_SPEED_AUTO] = 0, @@ -741,6 +746,8 @@ const struct sja1105_info sja1105s_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1105_clocking_setup, + .pcs_mdio_read = sja1105_pcs_mdio_read, + .pcs_mdio_write = sja1105_pcs_mdio_write, .port_speed = { [SJA1105_SPEED_AUTO] = 0, [SJA1105_SPEED_10MBPS] = 3, @@ -774,6 +781,8 @@ const struct sja1105_info sja1110a_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1110_clocking_setup, + .pcs_mdio_read = sja1110_pcs_mdio_read, + .pcs_mdio_write = sja1110_pcs_mdio_write, .port_speed = { [SJA1105_SPEED_AUTO] = 0, [SJA1105_SPEED_10MBPS] = 4, @@ -819,6 +828,8 @@ const struct sja1105_info sja1110b_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1110_clocking_setup, + .pcs_mdio_read = sja1110_pcs_mdio_read, + .pcs_mdio_write = sja1110_pcs_mdio_write, .port_speed = { [SJA1105_SPEED_AUTO] = 0, [SJA1105_SPEED_10MBPS] = 4, @@ -864,6 +875,8 @@ const struct sja1105_info sja1110c_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1110_clocking_setup, + .pcs_mdio_read = sja1110_pcs_mdio_read, + .pcs_mdio_write = sja1110_pcs_mdio_write, .port_speed = { [SJA1105_SPEED_AUTO] = 0, [SJA1105_SPEED_10MBPS] = 4, @@ -909,6 +922,8 @@ const struct sja1105_info sja1110d_info = { .fdb_del_cmd = sja1105pqrs_fdb_del, .ptp_cmd_packing = sja1105pqrs_ptp_cmd_packing, .clocking_setup = sja1110_clocking_setup, + .pcs_mdio_read = sja1110_pcs_mdio_read, + .pcs_mdio_write = sja1110_pcs_mdio_write, .port_speed = { [SJA1105_SPEED_AUTO] = 0, [SJA1105_SPEED_10MBPS] = 4, From patchwork Wed May 26 13:55:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 12281769 X-Patchwork-Delegate: kuba@kernel.org Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E4D5C47089 for ; Wed, 26 May 2021 13:56:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 46A606101E for ; Wed, 26 May 2021 13:56:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234640AbhEZN6J (ORCPT ); Wed, 26 May 2021 09:58:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53564 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234553AbhEZN5i (ORCPT ); Wed, 26 May 2021 09:57:38 -0400 Received: from mail-ej1-x62a.google.com (mail-ej1-x62a.google.com [IPv6:2a00:1450:4864:20::62a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E0D0AC06175F for ; Wed, 26 May 2021 06:56:06 -0700 (PDT) Received: by mail-ej1-x62a.google.com with SMTP id k14so2639469eji.2 for ; Wed, 26 May 2021 06:56:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=oqUoU6rHfW0PLI4QpYCajuab8//yEteqkwgtUVbNRUE=; b=bnv0wwU+9EfZOEvXk5qhDAhtuVmCWORajr8KXE7lGZgHMaU+RIoyZI6h2zhK1qJG0M OhyS4BbQjuM07LgwJItzfB19xkoEGBnca1+VUnn5VBylL+sHCfmMMp0Hpf5uCHPTJAPO S9Yqztya8PnuF6ygtNEXO0Gg+lxMXoytOA88IxgVsdw4dwu5FB1cFndaPaeGJBfj/LJq OP+Q9aKUGw8g35FuVQTMrh6I3hYEuA7fb0QtRIadClo4pjOCOY5a/mGbV+ChaPAXyDO6 HKqEfeYP2FU5n7mPVlRi22mgiIWFxire+suSSTGilbdcaVPGPAxQLm5NzjgeZ8LM9Vfi XWWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=oqUoU6rHfW0PLI4QpYCajuab8//yEteqkwgtUVbNRUE=; b=pIbvmvzorn4YILiD4GUuCXYCfbiJkgatRy2DuUBD02oEzWZUYF68BLtR9ZsZ5PfLv+ Xn2Y9x+kpZHhegzagr7RnKGk5tQJtOvVVnJxsZmkw7GsXpTieQxsjivzPuWpq6KX9cnt K5J3RgNIDGVMJXIUzV28EaiSyRPeTyZVpTAfc2cDj1Itv5cwn4RMa4FXi7M17gFss3EQ AvgNYLmfhOuzI6RnifWZX+0WO4ggLA1EiYdZTqATAgNtz/cYcvP26uDGuLQ2Za8l/bGr m6XmwzQhNFR9brDJC+4oJkiTDyyIgRDakrOgfJAk33w65oPlB/GFG0cvSqNaMCyD0945 qIyw== X-Gm-Message-State: AOAM532nJUCsx6sB/+51e+VqtCvWjxGPjRi08RPN6c/v6J6phwnxnNfd Q5JkLyk7sSnG0DfzRjYrARU= X-Google-Smtp-Source: ABdhPJzWexR6bnDlUdvmZNwBsWh+IdpQsZq9B291zc4BJjwCyMnGk/wa3+EsBu6SxrHjfvtK1FSQ9A== X-Received: by 2002:a17:906:2854:: with SMTP id s20mr33613192ejc.335.1622037365315; Wed, 26 May 2021 06:56:05 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id k11sm10508476ejc.94.2021.05.26.06.56.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 May 2021 06:56:05 -0700 (PDT) From: Vladimir Oltean X-Google-Original-From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Russell King , Heiner Kallweit Subject: [RFC PATCH v2 linux-next 14/14] net: dsa: sja1105: add support for the SJA1110 SGMII/2500base-x PCS Date: Wed, 26 May 2021 16:55:35 +0300 Message-Id: <20210526135535.2515123-15-vladimir.oltean@nxp.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210526135535.2515123-1-vladimir.oltean@nxp.com> References: <20210526135535.2515123-1-vladimir.oltean@nxp.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org X-Patchwork-Delegate: kuba@kernel.org X-Patchwork-State: RFC Configure the Synopsys PCS for 10/100/1000 SGMII in autoneg on/off modes, or for fixed 2500base-x. The portion of PCS configuration that forces the speed is common, but the portion that initializes the PCS and enables/disables autoneg is different, so a new .pcs_config() method was introduced in struct sja1105_info to hide away the differences. For the xMII Mode Parameters Table to be properly configured for SGMII mode on SJA1110, we need to set the "special" bit, since SGMII is officially bitwise coded as 0b0011 in SJA1105 (decimal 3, equal to XMII_MODE_SGMII), and as 0b1011 in SJA1110 (decimal 11). Cc: Russell King Cc: Heiner Kallweit Signed-off-by: Vladimir Oltean --- Changes in v2: None. drivers/net/dsa/sja1105/sja1105.h | 9 + drivers/net/dsa/sja1105/sja1105_main.c | 224 ++++++++++++++++++++++-- drivers/net/dsa/sja1105/sja1105_mdio.c | 3 +- drivers/net/dsa/sja1105/sja1105_sgmii.h | 61 +++++++ drivers/net/dsa/sja1105/sja1105_spi.c | 8 + 5 files changed, 293 insertions(+), 12 deletions(-) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index be788ddb7259..617d139a627f 100644 --- a/drivers/net/dsa/sja1105/sja1105.h +++ b/drivers/net/dsa/sja1105/sja1105.h @@ -132,6 +132,9 @@ struct sja1105_info { int (*clocking_setup)(struct sja1105_private *priv); int (*pcs_mdio_read)(struct mii_bus *bus, int phy, int reg); int (*pcs_mdio_write)(struct mii_bus *bus, int phy, int reg, u16 val); + void (*pcs_config)(struct sja1105_private *priv, int port, + bool an_enabled, bool an_master, + phy_interface_t interface); const char *name; bool supports_mii[SJA1105_MAX_NUM_PORTS]; bool supports_rmii[SJA1105_MAX_NUM_PORTS]; @@ -304,6 +307,12 @@ int sja1110_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 val); int sja1105_pcs_read(struct sja1105_private *priv, int port, int mmd, int reg); int sja1105_pcs_write(struct sja1105_private *priv, int port, int mmd, int reg, u16 val); +void sja1105_pcs_config(struct sja1105_private *priv, int port, + bool an_enabled, bool an_master, + phy_interface_t interface); +void sja1110_pcs_config(struct sja1105_private *priv, int port, + bool an_enabled, bool an_master, + phy_interface_t interface); /* From sja1105_devlink.c */ int sja1105_devlink_setup(struct dsa_switch *ds); diff --git a/drivers/net/dsa/sja1105/sja1105_main.c b/drivers/net/dsa/sja1105/sja1105_main.c index d0938daacbae..2ef23c8f725b 100644 --- a/drivers/net/dsa/sja1105/sja1105_main.c +++ b/drivers/net/dsa/sja1105/sja1105_main.c @@ -210,12 +210,14 @@ static int sja1105_init_mii_settings(struct sja1105_private *priv, goto unsupported; mii->xmii_mode[i] = XMII_MODE_SGMII; + mii->special[i] = true; break; case PHY_INTERFACE_MODE_2500BASEX: if (!priv->info->supports_2500basex[i]) goto unsupported; mii->xmii_mode[i] = XMII_MODE_SGMII; + mii->special[i] = true; break; unsupported: default: @@ -234,6 +236,7 @@ static int sja1105_init_mii_settings(struct sja1105_private *priv, * but unconditionally put the port in the MAC role. */ if (ports[i].phy_mode == PHY_INTERFACE_MODE_SGMII || + ports[i].phy_mode == PHY_INTERFACE_MODE_2500BASEX || phy_interface_mode_is_rgmii(ports[i].phy_mode)) mii->phy_mac[i] = XMII_MAC; else @@ -962,8 +965,9 @@ static int sja1105_parse_dt(struct sja1105_private *priv, return rc; } -static void sja1105_sgmii_pcs_config(struct sja1105_private *priv, int port, - bool an_enabled, bool an_master) +void sja1105_pcs_config(struct sja1105_private *priv, int port, + bool an_enabled, bool an_master, + phy_interface_t interface) { u16 ac = SJA1105_AC_AUTONEG_MODE_SGMII; int rc; @@ -1012,6 +1016,188 @@ static void sja1105_sgmii_pcs_config(struct sja1105_private *priv, int port, ERR_PTR(rc)); } +void sja1110_pcs_config(struct sja1105_private *priv, int port, + bool an_enabled, bool an_master, + phy_interface_t interface) +{ + const int timeout_us = 1000; + u16 val; + int rc; + + /* Soft-reset the PCS */ + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1, + MDIO_CTRL1_RESET); + if (rc < 0) + goto out_write_failed; + + rc = read_poll_timeout(sja1105_pcs_read, val, + !(val & MDIO_CTRL1_RESET), + 0, timeout_us, false, + priv, port, MDIO_MMD_VEND2, MDIO_CTRL1); + if (rc || val < 0) { + dev_err(priv->ds->dev, "port %d PCS reset failed: %pe\n", + port, ERR_PTR(rc)); + return; + } + + val = SJA1105_DC1_EN_VSMMD1; + if (interface == PHY_INTERFACE_MODE_2500BASEX) + val |= SJA1105_DC1_ENA_2500_MODE; + if (an_master) + val |= SJA1105_DC1_MAC_AUTO_SW; + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_DC1, val); + if (rc < 0) + goto out_write_failed; + + /* Program TX PLL feedback divider and reference divider settings for + * correct oscillation frequency. + */ + if (interface == PHY_INTERFACE_MODE_2500BASEX) + val = SJA1105_TXPLL_FBDIV(0x7d); + else + val = SJA1105_TXPLL_FBDIV(0x19); + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_TXPLL_CTRL0, + val); + if (rc < 0) + goto out_write_failed; + + if (interface == PHY_INTERFACE_MODE_2500BASEX) + val = SJA1105_TXPLL_REFDIV(0x2); + else + val = SJA1105_TXPLL_REFDIV(0x1); + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_TXPLL_CTRL1, + val); + if (rc < 0) + goto out_write_failed; + + /* Program transmitter amplitude and disable amplitude trimming */ + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, + SJA1105_LANE_DRIVER1_0, + SJA1105_TXDRV(0x5)); + if (rc < 0) + goto out_write_failed; + + val = SJA1105_TXDRVTRIM_LSB(0xffffffull); + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, + SJA1105_LANE_DRIVER2_0, val); + if (rc < 0) + goto out_write_failed; + + val = SJA1105_TXDRVTRIM_MSB(0xffffffull) | SJA1105_LANE_DRIVER2_1_RSV; + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, + SJA1105_LANE_DRIVER2_1, val); + if (rc < 0) + goto out_write_failed; + + /* Enable input and output resistor terminations for low BER. */ + val = SJA1105_ACCOUPLE_RXVCM_EN | SJA1105_CDR_GAIN | + SJA1105_RXRTRIM(4) | SJA1105_RXTEN | SJA1105_TXPLL_BWSEL | + SJA1105_TXRTRIM(3) | SJA1105_TXTEN; + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_LANE_TRIM, + val); + if (rc < 0) + goto out_write_failed; + + /* Select PCS as transmitter data source. */ + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, + SJA1105_LANE_DATAPATH_1, 0); + if (rc < 0) + goto out_write_failed; + + /* Program RX PLL feedback divider and reference divider for correct + * oscillation frequency. + */ + if (interface == PHY_INTERFACE_MODE_2500BASEX) + val = SJA1105_RXPLL_FBDIV(0x7d); + else + val = SJA1105_RXPLL_FBDIV(0x19); + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_RXPLL_CTRL0, + val); + if (rc < 0) + goto out_write_failed; + + if (interface == PHY_INTERFACE_MODE_2500BASEX) + val = SJA1105_RXPLL_REFDIV(0x2); + else + val = SJA1105_RXPLL_REFDIV(0x1); + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_RXPLL_CTRL1, + val); + if (rc < 0) + goto out_write_failed; + + /* Program threshold for receiver signal detector. + * Enable control of RXPLL by receiver signal detector to disable RXPLL + * when an input signal is not present. + */ + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, + SJA1105_RX_DATA_DETECT, 0x0005); + if (rc < 0) + goto out_write_failed; + + /* Enable TX and RX PLLs and circuits. + * Release reset of PMA to enable data flow to/from PCS. + */ + val = sja1105_pcs_read(priv, port, MDIO_MMD_VEND2, + SJA1105_POWERDOWN_ENABLE); + if (val < 0) { + dev_err(priv->ds->dev, "failed to read PCS: %pe\n", + ERR_PTR(val)); + return; + } + + val &= ~(SJA1105_TXPLL_PD | SJA1105_TXPD | SJA1105_RXCH_PD | + SJA1105_RXBIAS_PD | SJA1105_RESET_SER_EN | + SJA1105_RESET_SER | SJA1105_RESET_DES); + val |= SJA1105_RXPKDETEN | SJA1105_RCVEN; + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, + SJA1105_POWERDOWN_ENABLE, val); + if (rc < 0) + goto out_write_failed; + + /* Program continuous-time linear equalizer (CTLE) settings. */ + if (interface == PHY_INTERFACE_MODE_2500BASEX) + val = 0x732a; + else + val = 0x212a; + + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_RX_CDR_CTLE, + val); + if (rc < 0) + goto out_write_failed; + + /* AUTONEG_CONTROL: Use SGMII autoneg in MAC mode */ + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, SJA1105_AC, + SJA1105_AC_AUTONEG_MODE_SGMII); + if (rc < 0) + goto out_write_failed; + + /* BASIC_CONTROL: enable in-band AN now, if requested. Otherwise, + * sja1105_sgmii_pcs_force_speed must be called later for the link + * to become operational. + */ + if (an_enabled) { + rc = sja1105_pcs_write(priv, port, MDIO_MMD_VEND2, MDIO_CTRL1, + BMCR_ANENABLE | BMCR_ANRESTART); + if (rc < 0) + goto out_write_failed; + } + + return; + +out_write_failed: + dev_err(priv->ds->dev, "Failed to write to PCS: %pe\n", + ERR_PTR(rc)); +} + static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv, int port, int speed) { @@ -1019,6 +1205,7 @@ static void sja1105_sgmii_pcs_force_speed(struct sja1105_private *priv, int rc; switch (speed) { + case SPEED_2500: case SPEED_1000: pcs_speed = BMCR_SPEED1000; break; @@ -1092,6 +1279,9 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, case SPEED_1000: speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; break; + case SPEED_2500: + speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; + break; default: dev_err(dev, "Invalid speed %iMbps\n", speed_mbps); return -EINVAL; @@ -1106,6 +1296,8 @@ static int sja1105_adjust_port_config(struct sja1105_private *priv, int port, */ if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII) mac[port].speed = priv->info->port_speed[SJA1105_SPEED_1000MBPS]; + else if (priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX) + mac[port].speed = priv->info->port_speed[SJA1105_SPEED_2500MBPS]; else mac[port].speed = speed; @@ -1162,10 +1354,10 @@ static void sja1105_mac_config(struct dsa_switch *ds, int port, return; } - if (is_sgmii) - sja1105_sgmii_pcs_config(priv, port, - phylink_autoneg_inband(mode), - false); + if (state->interface == PHY_INTERFACE_MODE_SGMII || + state->interface == PHY_INTERFACE_MODE_2500BASEX) + priv->info->pcs_config(priv, port, phylink_autoneg_inband(mode), + false, state->interface); } static void sja1105_mac_link_down(struct dsa_switch *ds, int port, @@ -1186,7 +1378,8 @@ static void sja1105_mac_link_up(struct dsa_switch *ds, int port, sja1105_adjust_port_config(priv, port, speed); - if (priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII && + if ((priv->phy_mode[port] == PHY_INTERFACE_MODE_SGMII || + priv->phy_mode[port] == PHY_INTERFACE_MODE_2500BASEX) && !phylink_autoneg_inband(mode)) sja1105_sgmii_pcs_force_speed(priv, port, speed); @@ -1228,6 +1421,10 @@ static void sja1105_phylink_validate(struct dsa_switch *ds, int port, if (mii->xmii_mode[port] == XMII_MODE_RGMII || mii->xmii_mode[port] == XMII_MODE_SGMII) phylink_set(mask, 1000baseT_Full); + if (priv->info->supports_2500basex[port]) { + phylink_set(mask, 2500baseT_Full); + phylink_set(mask, 2500baseX_Full); + } bitmap_and(supported, supported, mask, __ETHTOOL_LINK_MODE_MASK_NBITS); bitmap_and(state->advertising, state->advertising, mask, @@ -1945,7 +2142,8 @@ int sja1105_static_config_reload(struct sja1105_private *priv, mac[i].speed); mac[i].speed = priv->info->port_speed[SJA1105_SPEED_AUTO]; - if (priv->phy_mode[i] == PHY_INTERFACE_MODE_SGMII) + if (priv->phy_mode[i] == PHY_INTERFACE_MODE_SGMII || + priv->phy_mode[i] == PHY_INTERFACE_MODE_2500BASEX) bmcr[i] = sja1105_pcs_read(priv, i, MDIO_MMD_VEND2, MDIO_CTRL1); @@ -2002,17 +2200,21 @@ int sja1105_static_config_reload(struct sja1105_private *priv, if (rc < 0) goto out; - if (priv->phy_mode[i] != PHY_INTERFACE_MODE_SGMII) + if (priv->phy_mode[i] != PHY_INTERFACE_MODE_SGMII && + priv->phy_mode[i] != PHY_INTERFACE_MODE_2500BASEX) continue; an_enabled = !!(bmcr[i] & BMCR_ANENABLE); - sja1105_sgmii_pcs_config(priv, i, an_enabled, false); + priv->info->pcs_config(priv, i, an_enabled, false, + priv->phy_mode[i]); if (!an_enabled) { int speed = SPEED_UNKNOWN; - if (bmcr[i] & BMCR_SPEED1000) + if (priv->phy_mode[i] == PHY_INTERFACE_MODE_2500BASEX) + speed = SPEED_2500; + else if (bmcr[i] & BMCR_SPEED1000) speed = SPEED_1000; else if (bmcr[i] & BMCR_SPEED100) speed = SPEED_100; diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c index bc6c3c1ac7a6..26c2bf8ed1f0 100644 --- a/drivers/net/dsa/sja1105/sja1105_mdio.c +++ b/drivers/net/dsa/sja1105/sja1105_mdio.c @@ -432,7 +432,8 @@ static int sja1105_mdiobus_pcs_register(struct sja1105_private *priv) if (dsa_is_unused_port(ds, port)) continue; - if (!priv->info->supports_sgmii[port]) + if (!priv->info->supports_sgmii[port] && + !priv->info->supports_2500basex[port]) continue; mdiodev = mdio_device_create(bus, port); diff --git a/drivers/net/dsa/sja1105/sja1105_sgmii.h b/drivers/net/dsa/sja1105/sja1105_sgmii.h index dc067b876758..b2d117f68417 100644 --- a/drivers/net/dsa/sja1105/sja1105_sgmii.h +++ b/drivers/net/dsa/sja1105/sja1105_sgmii.h @@ -15,6 +15,7 @@ #define SJA1105_DC1_INIT BIT(8) #define SJA1105_DC1_TX_DISABLE BIT(4) #define SJA1105_DC1_AUTONEG_TIMER_OVRR BIT(3) +#define SJA1105_DC1_ENA_2500_MODE BIT(2) #define SJA1105_DC1_BYP_POWERUP BIT(1) #define SJA1105_DC1_PHY_MODE_CONTROL BIT(0) @@ -48,4 +49,64 @@ #define SJA1105_DC_SUPPRESS_LOS BIT(4) #define SJA1105_DC_RESTART_SYNC BIT(0) +/* LANE_DRIVER1_0 register (address 0x1f8038) */ +#define SJA1105_LANE_DRIVER1_0 0x8038 +#define SJA1105_TXDRV(x) (((x) << 12) & GENMASK(14, 12)) + +/* LANE_DRIVER2_0 register (address 0x1f803a) */ +#define SJA1105_LANE_DRIVER2_0 0x803a +#define SJA1105_TXDRVTRIM_LSB(x) ((x) & GENMASK_ULL(15, 0)) + +/* LANE_DRIVER2_1 register (address 0x1f803b) */ +#define SJA1105_LANE_DRIVER2_1 0x803b +#define SJA1105_LANE_DRIVER2_1_RSV BIT(9) +#define SJA1105_TXDRVTRIM_MSB(x) (((x) & GENMASK_ULL(23, 16)) >> 16) + +/* LANE_TRIM register (address 0x1f8040) */ +#define SJA1105_LANE_TRIM 0x8040 +#define SJA1105_TXTEN BIT(11) +#define SJA1105_TXRTRIM(x) (((x) << 8) & GENMASK(10, 8)) +#define SJA1105_TXPLL_BWSEL BIT(7) +#define SJA1105_RXTEN BIT(6) +#define SJA1105_RXRTRIM(x) (((x) << 3) & GENMASK(5, 3)) +#define SJA1105_CDR_GAIN BIT(2) +#define SJA1105_ACCOUPLE_RXVCM_EN BIT(0) + +/* LANE_DATAPATH_1 register (address 0x1f8037) */ +#define SJA1105_LANE_DATAPATH_1 0x8037 + +/* POWERDOWN_ENABLE register (address 0x1f8041) */ +#define SJA1105_POWERDOWN_ENABLE 0x8041 +#define SJA1105_TXPLL_PD BIT(12) +#define SJA1105_TXPD BIT(11) +#define SJA1105_RXPKDETEN BIT(10) +#define SJA1105_RXCH_PD BIT(9) +#define SJA1105_RXBIAS_PD BIT(8) +#define SJA1105_RESET_SER_EN BIT(7) +#define SJA1105_RESET_SER BIT(6) +#define SJA1105_RESET_DES BIT(5) +#define SJA1105_RCVEN BIT(4) + +/* RXPLL_CTRL0 register (address 0x1f8065) */ +#define SJA1105_RXPLL_CTRL0 0x8065 +#define SJA1105_RXPLL_FBDIV(x) (((x) << 2) & GENMASK(9, 2)) + +/* RXPLL_CTRL1 register (address 0x1f8066) */ +#define SJA1105_RXPLL_CTRL1 0x8066 +#define SJA1105_RXPLL_REFDIV(x) ((x) & GENMASK(4, 0)) + +/* TXPLL_CTRL0 register (address 0x1f806d) */ +#define SJA1105_TXPLL_CTRL0 0x806d +#define SJA1105_TXPLL_FBDIV(x) ((x) & GENMASK(11, 0)) + +/* TXPLL_CTRL1 register (address 0x1f806e) */ +#define SJA1105_TXPLL_CTRL1 0x806e +#define SJA1105_TXPLL_REFDIV(x) ((x) & GENMASK(5, 0)) + +/* RX_DATA_DETECT register (address 0x1f8045) */ +#define SJA1105_RX_DATA_DETECT 0x8045 + +/* RX_CDR_CTLE register (address 0x1f8042) */ +#define SJA1105_RX_CDR_CTLE 0x8042 + #endif diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index e6c2cb68fcc4..c776a08e5e77 100644 --- a/drivers/net/dsa/sja1105/sja1105_spi.c +++ b/drivers/net/dsa/sja1105/sja1105_spi.c @@ -712,6 +712,7 @@ const struct sja1105_info sja1105r_info = { .clocking_setup = sja1105_clocking_setup, .pcs_mdio_read = sja1105_pcs_mdio_read, .pcs_mdio_write = sja1105_pcs_mdio_write, + .pcs_config = sja1105_pcs_config, .regs = &sja1105pqrs_regs, .port_speed = { [SJA1105_SPEED_AUTO] = 0, @@ -748,6 +749,7 @@ const struct sja1105_info sja1105s_info = { .clocking_setup = sja1105_clocking_setup, .pcs_mdio_read = sja1105_pcs_mdio_read, .pcs_mdio_write = sja1105_pcs_mdio_write, + .pcs_config = sja1105_pcs_config, .port_speed = { [SJA1105_SPEED_AUTO] = 0, [SJA1105_SPEED_10MBPS] = 3, @@ -783,6 +785,7 @@ const struct sja1105_info sja1110a_info = { .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, + .pcs_config = sja1110_pcs_config, .port_speed = { [SJA1105_SPEED_AUTO] = 0, [SJA1105_SPEED_10MBPS] = 4, @@ -830,6 +833,7 @@ const struct sja1105_info sja1110b_info = { .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, + .pcs_config = sja1110_pcs_config, .port_speed = { [SJA1105_SPEED_AUTO] = 0, [SJA1105_SPEED_10MBPS] = 4, @@ -877,6 +881,7 @@ const struct sja1105_info sja1110c_info = { .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, + .pcs_config = sja1110_pcs_config, .port_speed = { [SJA1105_SPEED_AUTO] = 0, [SJA1105_SPEED_10MBPS] = 4, @@ -924,6 +929,7 @@ const struct sja1105_info sja1110d_info = { .clocking_setup = sja1110_clocking_setup, .pcs_mdio_read = sja1110_pcs_mdio_read, .pcs_mdio_write = sja1110_pcs_mdio_write, + .pcs_config = sja1110_pcs_config, .port_speed = { [SJA1105_SPEED_AUTO] = 0, [SJA1105_SPEED_10MBPS] = 4, @@ -939,6 +945,8 @@ const struct sja1105_info sja1110d_info = { false, false, false, false, false, false}, .supports_sgmii = {false, true, true, true, true, false, false, false, false, false, false}, + .supports_2500basex = {false, false, false, true, true, + false, false, false, false, false, false}, .internal_phy = {SJA1105_NO_PHY, SJA1105_NO_PHY, SJA1105_NO_PHY, SJA1105_NO_PHY, SJA1105_NO_PHY, SJA1105_PHY_BASE_T1,