From patchwork Mon May 24 23:22:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 446793 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 AB148C2B9F8 for ; Mon, 24 May 2021 23:22:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 90E9C6140B for ; Mon, 24 May 2021 23:22:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229898AbhEXXYG (ORCPT ); Mon, 24 May 2021 19:24:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40352 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229643AbhEXXYC (ORCPT ); Mon, 24 May 2021 19:24:02 -0400 Received: from mail-ej1-x62b.google.com (mail-ej1-x62b.google.com [IPv6:2a00:1450:4864:20::62b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7EBB8C061756 for ; Mon, 24 May 2021 16:22:33 -0700 (PDT) Received: by mail-ej1-x62b.google.com with SMTP id l1so44289594ejb.6 for ; Mon, 24 May 2021 16:22:33 -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=/pbiDkMc1xiTTnzJey7JYsMk+HBUbuh5IEY8IdZSCR4=; b=C7seXepgq2gAHzZMJw1pQHL1RbPnq4IS0GQb/R1qIP8cShystNI5BJw/UmgbFboeS1 q6xU2oGqwN7lCnfAvCjQW5tlxfvAyN/pPr8VFUMj7vsYZKCyGMRRyxeWnwYFA4bZmFlD ekOUBlf96CNNZyKbKF/ddBBfhnCmckuGjuPZ9FMorR35OuuFZkayABQVlKST8sW0l03Z LpbqQfjKT8j5dyv+TZd9EBD8BP5r7d4X4k2QEVNcfqb9IRb0Ns1wT91osXqVAfA1/9Sw HcOibdwdCY2KTzQN39j93Oh9IccPSwcGus1MTNXndWXvH5msrDo7uy0OQV7xx7P471Gi /87w== 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=/pbiDkMc1xiTTnzJey7JYsMk+HBUbuh5IEY8IdZSCR4=; b=aDKdq7dLpm/C9xNi7+YYI3OpQMsQ7yorRixcoYtKukDtQsZx2Add9gyOs2TbmXVuCb UFhrNOwk24fseqUgFCID9A+Cent8zM8dKkIZg0oztVanqaEeLSlUCxysfgwyYxu0mVuw GmQstqhY3o762hHxsCcY2gBjiAA3FfbqL4CUlMKBz/Lvyeexeqbo9fyNx2ZYoQ0PFA7g 89QFbTg3b+NxZmOIgljRKQcofcymppHYRZWfkFA60Tib+rOkP5uZLqvbkdqp3zjMSYkV S05EQK5RU1fV313XywsrKfTPwLzahlP06bGAloiMQfCI3viTP+1iH7Nm3cDXW1AUTHwD TWtw== X-Gm-Message-State: AOAM533LgExfB7VDdgv0974+soXA6/7mQF8tUa7NQMCgjpZp7hpaDEUX 7SIs/hDrOBaSjdTs4/i4pJNjim4BQ6s= X-Google-Smtp-Source: ABdhPJx3P3l5TOCRNBaaiKfmqHDvv6Je/JAY1o7O6MfJXzx6R0KiDj58QrsxVlBEe5/8LyY46JBknw== X-Received: by 2002:a17:907:b09:: with SMTP id h9mr24798382ejl.430.1621898552162; Mon, 24 May 2021 16:22:32 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id di7sm9922746edb.34.2021.05.24.16.22.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 May 2021 16:22:31 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Vladimir Oltean Subject: [PATCH net-next 04/13] net: dsa: sja1105: cache the phy-mode port property Date: Tue, 25 May 2021 02:22:05 +0300 Message-Id: <20210524232214.1378937-5-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210524232214.1378937-1-olteanv@gmail.com> References: <20210524232214.1378937-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean 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 --- 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 Mon May 24 23:22:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 446792 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 159DCC2B9F7 for ; Mon, 24 May 2021 23:22:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E92FE6135F for ; Mon, 24 May 2021 23:22:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229922AbhEXXYL (ORCPT ); Mon, 24 May 2021 19:24:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229826AbhEXXYF (ORCPT ); Mon, 24 May 2021 19:24:05 -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 37328C061574 for ; Mon, 24 May 2021 16:22:35 -0700 (PDT) Received: by mail-ej1-x62d.google.com with SMTP id c20so44353586ejm.3 for ; Mon, 24 May 2021 16:22:35 -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=DfWDlnQJnWBbxm0q1Tr+N50vl4DHMxvA1EcJaqgh+IM=; b=DspJuDFNHL93pQBfUgaSrmMxMmx0/P3BxV8AAPfH7NVP9e7aEIjmzC3+5/zwa43P/u PQ4xYvaf2bmniNUFv2NnITT/w13q52nZijsnHlU/Pn/6g7XMrYx5MWyaWtnA2CMR+eP6 7E5EqDBDhOeKj6Figrp4pJAo/sQrpBYB/ixnpPCUAiqdjtjUlahVZD/KCJgGG/MiVdxX nzMFBFWVuUnxKKBqU6rjKS8SbJIAwm5DZgS5JWUvUuDHYThKmSfzKJnKqLuZ8F733xG4 rvEGNby9KxOba4rDtxUwwjQjf9doUg3ddsNHgnmUoHhAHErC2/tb5yDXLShpRN+PFsY1 caaA== 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=DfWDlnQJnWBbxm0q1Tr+N50vl4DHMxvA1EcJaqgh+IM=; b=lCFQS7lRJz5f17V3Gc8q2sfY/eXB9J2JYXhim8F8ZiTGZyqNpzJU/aqnZQbbp3ZPQ/ tBxm+dlIyoUETei9/9sR5Stc4QBCSA9f89U0a9nM/AC1y19wO7yG//clYj4EWMmEiC03 Y/n7ikvJzNJmJ+58XmedJE5lIDKkUHVhqTT+jCMeTZ4QfsBzVtjDKRBIPjJyE1m7iUQ7 TMNzfKI9+oWOKxLfk/mkQJ7LLt+bR25lmKeZU6RVpSI/SQ8pzB03QYVYuSOvEAEsKGiw ScfILNtvdbEQLI7dqVhrLg6WT25fjyxneJ4f/6qgGjL4zjlMPzyb266qdrR+F0oA0vds Mvng== X-Gm-Message-State: AOAM531me/p9UtQsCF07xL6fNTGoNMDnfzp2Qy/d9SeKE7MTnPCiXcRM 7OR9TXK3tvL2Ico9dYWOOqs= X-Google-Smtp-Source: ABdhPJyBttE16USFT0phtRMQzE7UwIEMFBvUwOITzHhz8lOQE5Js8qhwMhj8nWHRfmmAFHqkEzYDPg== X-Received: by 2002:a17:906:814d:: with SMTP id z13mr16357577ejw.195.1621898553833; Mon, 24 May 2021 16:22:33 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id di7sm9922746edb.34.2021.05.24.16.22.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 May 2021 16:22:33 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Vladimir Oltean Subject: [PATCH net-next 06/13] net: dsa: sja1105: add a translation table for port speeds Date: Tue, 25 May 2021 02:22:07 +0300 Message-Id: <20210524232214.1378937-7-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210524232214.1378937-1-olteanv@gmail.com> References: <20210524232214.1378937-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean 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 --- 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 Mon May 24 23:22:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 446791 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 A1307C47085 for ; Mon, 24 May 2021 23:22:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 83DF06140B for ; Mon, 24 May 2021 23:22:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230013AbhEXXYO (ORCPT ); Mon, 24 May 2021 19:24:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229891AbhEXXYG (ORCPT ); Mon, 24 May 2021 19:24:06 -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 C8CE5C06138B for ; Mon, 24 May 2021 16:22:36 -0700 (PDT) Received: by mail-ej1-x62c.google.com with SMTP id f18so14128078ejq.10 for ; Mon, 24 May 2021 16:22:36 -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=p3/uvjoFsLdg1DQX9Am/VgA1o+nsnHsLypQWtoLEHes=; b=EXylfCshv7knwGJZQVAWKM2UFMNqE9g0VR3K3BDxI3DxcaeOje7Uqms9BztnBLnS4A htY4QP8NxWgOj+q8EBtNJUXyzUqIbEUUcazEw2/fdVw3ug3q5Thjeg4YZSyXKMzyys7o LXuZ6ErHagwB0BNLPrgj2MhcWWUMDCzeiBg5roawIr1KehTKEwSsF+kl+0yJ8L2oP+LE MuCP1yECXHtRvDLb8h+1e/rql1rdRbBKzhZ6mWVgYisyqUe4oRZiE0GWkVe6dnW5zkE4 zE9+mUTS5206e84Ypda5LWM17343f3bM8N7wDL9+CzjSQoS460dIKeeL2Ow6nSBL7smv 2d6g== 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=p3/uvjoFsLdg1DQX9Am/VgA1o+nsnHsLypQWtoLEHes=; b=sjjB6FJmUjRzwjY7cvyJjeOH4jc0idfPsN67+Z+kWA3vBfjagJVFfpER+dLhxEk36p TnERb/1T70sdZSLLM/dBCtb0rO1pWDhUKPZGZbcDfDgpA18nvseScd4/Cgg8iFd8c5IS RT/xS7rru+SGp5cdlubp90Lrw9P19ARrtolo8QsL+NMeh6JFvW1Dt2yPVVoS4ZpjjLCU TvLkHfsEQHOJiE2mIlVAkI4cRuYgzp3OTGroJYtIyzBTCDzHsrqZuthOJ/op1sMqEA3u UiPlYEqYwMuaEEky+bBJu+rcXf9evLaHOPnjruqsgzdiPyStKlbuL57IwRKuQaQF+2fX 7BrQ== X-Gm-Message-State: AOAM533DPhSX0ldr8hoZ1REPcr4O9E4W0e1OzeptJ2KnazfqpWz4rX1t rbSWaDGb2dyiXmANoRFUdpfEjIEyQPU= X-Google-Smtp-Source: ABdhPJwJ2K/PlLRdjM9EYBfJgZB6ekUbsZO7G2beIzhZaL3YMZlv/qEgKEb+RNgOLtvNUcXkAxJXmg== X-Received: by 2002:a17:906:2a1b:: with SMTP id j27mr25238514eje.370.1621898555438; Mon, 24 May 2021 16:22:35 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id di7sm9922746edb.34.2021.05.24.16.22.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 May 2021 16:22:35 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Vladimir Oltean Subject: [PATCH net-next 08/13] net: dsa: sja1105: some table entries are always present when read dynamically Date: Tue, 25 May 2021 02:22:09 +0300 Message-Id: <20210524232214.1378937-9-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210524232214.1378937-1-olteanv@gmail.com> References: <20210524232214.1378937-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean 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 --- 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 Mon May 24 23:22:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 446790 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 52EABC2B9F8 for ; Mon, 24 May 2021 23:22:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3522D6135F for ; Mon, 24 May 2021 23:22:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230035AbhEXXYT (ORCPT ); Mon, 24 May 2021 19:24:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40396 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229968AbhEXXYK (ORCPT ); Mon, 24 May 2021 19:24:10 -0400 Received: from mail-ej1-x631.google.com (mail-ej1-x631.google.com [IPv6:2a00:1450:4864:20::631]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7B22DC06138F for ; Mon, 24 May 2021 16:22:37 -0700 (PDT) Received: by mail-ej1-x631.google.com with SMTP id jt22so92580ejb.7 for ; Mon, 24 May 2021 16:22:37 -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=9DYafoQZ8sjJo3dQP1Ut0hCHEoaGM2CgvVGWol/pIgA=; b=mLIQtgdI1/8YSqBCbvNehsGBo+z+9G/8w/6UR3+7nS7NJg8H68mEkKAwYTSfPbmLyr tzJO+8CkgG1mcZMLaU/dWsaJNrWhRgsmjjgO2szNgs7MxM8flHScxgQrF7GVsZwwdjZT ECyVkc/EwK4u5UgnMPOb1gxguswo0NsqKhgGhxDqY7mXughzr/+8DdmpPT8jSMPaqxcc j4jN4aggBvceWhptHphed5M7noZHvK3gPqFaY7Lv2EJZlQhN03i5eeJ1HmicvKi+NRor e0/t9nI+22AHtpdFq5WHaeHeLAoeW9KnXV5GvJyiZ9uBzDAVIkPHBUoxr2w+Fp4P+qM+ RxGg== 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=9DYafoQZ8sjJo3dQP1Ut0hCHEoaGM2CgvVGWol/pIgA=; b=hric9RQ2aVOCduBemkIz1DoS01x6C/5WM7llcCouSCkACt9+ysXhqaKvH3RZgQBmP+ i8WUG6NZ+aYe5VB9OJ2sk2DfK3phyvAGp79F5nHbf1U6jlw97G1ISZmGFISNTaZ14bJJ xKN323OOPG0hvtKwgfvEukk6+QCBF+Ct7YUVLksxvufJcph0V+KhaLuWq+Z+jI5JWXpd JQpcLtKTcRF94lz82xy3tCl27p6QXPlzbWg1JPuPJx5euUasb+vmOIaDZzz+lXG6b2TN 4APBF+FpiPX/XkNuHxk7+qhdYJCCCHNirYSDmDeLXBtIoMcAooKd+qlwuKLOgPA8K02O OGKA== X-Gm-Message-State: AOAM532L/J13njkPWWd2l0ZtS6jCRUpZ5FQiUtlojMXirsitm3UodVB9 KcJVlzAOJSajhcWYKYa7jxg= X-Google-Smtp-Source: ABdhPJyHgHw0TD2L8PLRIyuqW5l8vqkAxeQcIsP1fbVro0ayBdKv3oL5uN5etQVa4zy12dSKp0DB8Q== X-Received: by 2002:a17:907:1002:: with SMTP id ox2mr25087144ejb.337.1621898556164; Mon, 24 May 2021 16:22:36 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id di7sm9922746edb.34.2021.05.24.16.22.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 May 2021 16:22:35 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Vladimir Oltean Subject: [PATCH net-next 09/13] dt-bindings: net: dsa: sja1105: add compatible strings for SJA1110 Date: Tue, 25 May 2021 02:22:10 +0300 Message-Id: <20210524232214.1378937-10-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210524232214.1378937-1-olteanv@gmail.com> References: <20210524232214.1378937-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean There are 4 variations of the SJA1110 switch which have a different set of MII protocols supported per port. Document the compatible strings. Signed-off-by: Vladimir Oltean Reviewed-by: Florian Fainelli --- Documentation/devicetree/bindings/net/dsa/sja1105.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Documentation/devicetree/bindings/net/dsa/sja1105.txt b/Documentation/devicetree/bindings/net/dsa/sja1105.txt index 13fd21074d48..7029ae92daef 100644 --- a/Documentation/devicetree/bindings/net/dsa/sja1105.txt +++ b/Documentation/devicetree/bindings/net/dsa/sja1105.txt @@ -11,6 +11,10 @@ Required properties: - "nxp,sja1105q" - "nxp,sja1105r" - "nxp,sja1105s" + - "nxp,sja1110a" + - "nxp,sja1110b" + - "nxp,sja1110c" + - "nxp,sja1110d" Although the device ID could be detected at runtime, explicit bindings are required in order to be able to statically check their validity. From patchwork Mon May 24 23:22:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 446788 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 040ABC47085 for ; Mon, 24 May 2021 23:23:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DCC176140F for ; Mon, 24 May 2021 23:23:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230029AbhEXXY3 (ORCPT ); Mon, 24 May 2021 19:24:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40416 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229952AbhEXXYM (ORCPT ); Mon, 24 May 2021 19:24:12 -0400 Received: from mail-ej1-x636.google.com (mail-ej1-x636.google.com [IPv6:2a00:1450:4864:20::636]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E1F3C06134A for ; Mon, 24 May 2021 16:22:40 -0700 (PDT) Received: by mail-ej1-x636.google.com with SMTP id lz27so44291351ejb.11 for ; Mon, 24 May 2021 16:22:40 -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=L1jcOcxxMiCPm/pjeOtyhvP7bKvkHUyo6UJm2DwNHBc=; b=tjyVZgro7zVx2/n7iJi7YMpwbn8z5uqchpqpikFROsjv8L39E5S0BUwPsIRioirlS7 j9hrRaOhPnaCXAzJWxVbZMvg6G+yUTyKvAAJTR/rl1pYMJ3YD0kzU2G476Sntds+KC68 c4XNYeTthIIXgI5woZYDYRDIFOyKGksb/x/Sn5BL57TphBQipgsoXsGn7npzctexdKwd CduofTPHMC+y3ehqCCbQG8xJG1Bg1cQ6mlCrrZwhurGc6Jtyl8+z42hotBlHogLv1Hf1 SKb3UY3v10Xry30YWFaVvtNYCpBYKJxIpnP+1SwyaLHByWK6wjYt/SydQY9KiDbJG8Mv HsPA== 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=L1jcOcxxMiCPm/pjeOtyhvP7bKvkHUyo6UJm2DwNHBc=; b=jzvXMWUMhY5FEDFW63xrlPaFaXPpoYTY63ITukiDSjG3myOJ+V2iap6DePPKWwpMJO eujY7OpDqjzaUni2MJ79aXJaCe3SMksQHMZjdx1I4m+04JeVyvFByBo1ySTqg9nafjLd hX2rx+DZNiXkmoAiOinyLwSajb7wyQdR9pAemFUulF6DYAWuLB/wSIRkf28jI20hpI7f 61rEb6z+TZutd9RV02CgddLcmx7ifFLe/Dl38TK6DRpUa/dV5+57DxAp9WKoDao3PEt1 o2+321n1IB7VYJu6f8nyt3pEkfjqG/1TYMieuujxwCzSIVDI53nDcZd19yF5cB+N9IvQ jRcw== X-Gm-Message-State: AOAM531bg0BhdDg1CuDT8EyR7BWP/V2f0vgdllgqtOSCGghZnOMam6YA vYAZXthRv4jJLbMwwAC9LuM= X-Google-Smtp-Source: ABdhPJz4RnLi5ATB/34QYnvXUKgRD0j/rTfn4NytuH1f1uFPFNSqosH/05I/Hk5rDWCzQRHgdnAtfA== X-Received: by 2002:a17:907:248c:: with SMTP id zg12mr25294263ejb.268.1621898558784; Mon, 24 May 2021 16:22:38 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id di7sm9922746edb.34.2021.05.24.16.22.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 May 2021 16:22:38 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Vladimir Oltean , Russell King Subject: [PATCH net-next 12/13] net: dsa: sja1105: expose the SGMII PCS as an mdio_device Date: Tue, 25 May 2021 02:22:13 +0300 Message-Id: <20210524232214.1378937-13-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210524232214.1378937-1-olteanv@gmail.com> References: <20210524232214.1378937-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean 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 Signed-off-by: Vladimir Oltean --- drivers/net/dsa/sja1105/sja1105.h | 12 ++ drivers/net/dsa/sja1105/sja1105_main.c | 93 +++++---- drivers/net/dsa/sja1105/sja1105_mdio.c | 241 ++++++++++++++++++++++++ drivers/net/dsa/sja1105/sja1105_sgmii.h | 2 - drivers/net/dsa/sja1105/sja1105_spi.c | 15 ++ 5 files changed, 310 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 a3fe6b664807..7e83dd0f4f16 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 = MII_ADDR_C45 | mmd << 16 | 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 = MII_ADDR_C45 | mmd << 16 | 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; + + /* This addressing scheme reserves register 0xff for the bank address + * register, so that can never be addressed. + */ + if (WARN_ON(offset == 0xff)) + return -ENODEV; + + 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); + + 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; + + /* This addressing scheme reserves register 0xff for the bank address + * register, so that can never be addressed. + */ + if (WARN_ON(offset == 0xff)) + return -ENODEV; + + 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); + + 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,88 @@ 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; + mdio_priv = bus->priv; + mdio_priv->priv = priv; + + /* We don't register this MDIO bus because there is no PHY on it */ + + 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_free(priv->mdio_pcs); + priv->mdio_pcs = NULL; +} + int sja1105_mdiobus_register(struct dsa_switch *ds) { struct sja1105_private *priv = ds->priv; @@ -247,6 +482,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, "mdio"); if (!mdio_node) return 0; @@ -275,6 +514,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 +525,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 Mon May 24 23:22:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vladimir Oltean X-Patchwork-Id: 446789 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 CAB15C2B9F7 for ; Mon, 24 May 2021 23:22:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AC50C6140B for ; Mon, 24 May 2021 23:22:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229891AbhEXXY1 (ORCPT ); Mon, 24 May 2021 19:24:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40420 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229991AbhEXXYM (ORCPT ); Mon, 24 May 2021 19:24:12 -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 1EE98C06134D for ; Mon, 24 May 2021 16:22:41 -0700 (PDT) Received: by mail-ej1-x62e.google.com with SMTP id p24so43051108ejb.1 for ; Mon, 24 May 2021 16:22:41 -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=P++kPDBbASlBm9PQ4qIA20xYt1hzFoWznezLzuVRG6M=; b=dbJy8ho5TfboScVdc0piA+bg5lOnP2gdKE9dG2XgPkpYRfO/RIPnRQu0VDiguYSTlo DLe21vsEOakEmhI2M7UHku8hRzbL56GnuVoiZnbnv5YRmlUNFmhxgWKgRfsufoCDjfXQ XuQ11Nb+NBRyz5MB0/pu8ExC6bGiGk4ATl1q04NKAQxKrVGlFO6kLttx5xRFhcw2lVPt KtvSd9xMl+XbaPynX6O8fLIjUrDEfdQjOe0S7Fp8SsmsCnL+OrERp/7m7r77B2sq0gE1 XJ1/q7TL0yi/IFasx366HJbwx5xPkOljam7cZc6ojcq7T2TkypIdhitxZQ0aUJzhZ7N/ YjWw== 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=P++kPDBbASlBm9PQ4qIA20xYt1hzFoWznezLzuVRG6M=; b=YoySLj7ZSFA4VCHuBkKFhkWn6KX5/RurFiObLPjzYrQ+jKBvzDASJMZeEuWc/MCa2p /Hvl4xy38CSr4NAP8UyaPQs8NNzZCE7Cw/xlULXvh8cHWPjojxNDyQtHVkx6fisu++Lh ObzFoGLJvmpp6zERTcRTxiZ9iRXjtf/1JwvWgzs9RxdKdJzf/6os/XGxm6y9aUAW9iWj km1QPq1/ip8osRyltOEZEAD4WA0QNy+qIQgWV4c3utnhm6hhz6dQPoUTpgw9KHIM3cSi 0bKtpQcyXx1bkqn3f/sH0zLTwME8wQdhlJP875/Snpo0jHzFzJc00dERuhZgx8ygOdYU 67hw== X-Gm-Message-State: AOAM533JWA+/VJEULzai5ijZvTnEz/qzdb9jmhWLcq+W2uaUjoOeFiID DFIGqObqRdshfq+QauxL2LbKaYvVXTI= X-Google-Smtp-Source: ABdhPJxK6VUIIYdHrZ8TG5PkPK1fBjM4KMxeFs9jLmf2/lUZoyKcn4NlXPiizaWt9Te6EcDwQlq29w== X-Received: by 2002:a17:906:26cb:: with SMTP id u11mr26189873ejc.385.1621898559675; Mon, 24 May 2021 16:22:39 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id di7sm9922746edb.34.2021.05.24.16.22.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 24 May 2021 16:22:39 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Florian Fainelli , Andrew Lunn , Vivien Didelot , Vladimir Oltean , Russell King Subject: [PATCH net-next 13/13] net: dsa: sja1105: add support for the SJA1110 SGMII/2500base-x PCS Date: Tue, 25 May 2021 02:22:14 +0300 Message-Id: <20210524232214.1378937-14-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210524232214.1378937-1-olteanv@gmail.com> References: <20210524232214.1378937-1-olteanv@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Vladimir Oltean 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 Signed-off-by: Vladimir Oltean --- 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 7e83dd0f4f16..722d50665fde 100644 --- a/drivers/net/dsa/sja1105/sja1105_mdio.c +++ b/drivers/net/dsa/sja1105/sja1105_mdio.c @@ -424,7 +424,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,