From patchwork Fri Jun 11 20:05: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: 12316571 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.7 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_SIGNED,DKIM_VALID,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=unavailable 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 13F92C48BE0 for ; Fri, 11 Jun 2021 20:54:55 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D4296610A5 for ; Fri, 11 Jun 2021 20:54:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D4296610A5 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=7XcJLotO9pIUVag+wMyiKsk+QuCqIRusD6ETKk7I7tE=; b=lVWuievkzVvQMs Au+TbIq53bfk03aLdbbeASDLdtr35cgUIDRlVyfV+Aa069obiqvMxWsn3tQj4ub5MtlcXvlAGfdcB +VDDkCzloN2MNgzifd1bdwqr9SkzJ6ontE2HUOng1bcsjy8HJn+40ppNvD2pGYYizCt+PJmAinLup jD7mJF4jFYQZJbD2PMuJUc6CJxdEsm7TJtrPlIKmGsBSHR8gyxKk8j7JhwfWRUwft7IwMwxt0fM+R huCPPG225unvyOSIX3nUzbbrbjQ3mU8YO8mM33TQQMESG2zrtRioeHNO3AzLycFROpZMJIomy75qK T+ZwXtWIqHfFzwDD6U4Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1lro8L-0072AY-Ll; Fri, 11 Jun 2021 20:52:06 +0000 Received: from mail-ej1-f52.google.com ([209.85.218.52]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1lrnQm-006p2I-Of for linux-arm-kernel@lists.infradead.org; Fri, 11 Jun 2021 20:07:06 +0000 Received: by mail-ej1-f52.google.com with SMTP id k25so6231263eja.9 for ; Fri, 11 Jun 2021 13:07:03 -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=8M2/RG6z50uoGEAbutNKpp3O5Lsinip7wy73szfV7/4=; b=UdhYP+zgu8SCmEGnawvk/W2dCMlOrWtvS3AcYzMooSlRWzdcH5HuGCqyQMm63KGCra HtakFCBGNZxHmSgRjp8Z6+r9E+mzgbPaV6Ro9c1W/hr5cMzi7BdXDzQDRIrbKmgWFkDm eOuUp8FmRxGWRF1nQm2tls8QJgeIT4G8mbcsUNye7+4Yb4SSNiGEDOW+XqUkjh82yynJ xT+DMCaiU18EgoWeNtZE01AhyoMpbIZ0bgdl3T/w9ZHgO4pHwTgbRo02o3KNKp+45PcL OXzxYIPp9zSdAMOzHSt6orkKEavWH0uBoOubDO8Xyvmykcz6bWidgYHyQC5koZ/z79Go juAw== 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=8M2/RG6z50uoGEAbutNKpp3O5Lsinip7wy73szfV7/4=; b=AFGXSnsYHPw6GHVcU7V+LlPCpHXUEDQG8xKNes5r2zIhnEnXHDsJ/A7rRrFrKcNfDR FOxPhb065gJE3oN5Byug2PncGZcRrCYTp6mHQ1r4wnYm+gqwI0/PtVhKE12feF5Oy/gc krlPlEv/ZJQMte5rvQSSgqUn9PBNU31L9EsxUqPGl6IbPRBE7gisMxw2V0jsZDF9BRhZ OErG0n1Vd61NMD9bs4DOIoQyvTKWFGRYT1ywAC4lYylNdqpvdS+CiAvecHuHx4/l+GJb YDJWCEBwKjr4J8qxgASzVm++as16CFXoh78dFtrYWYv2qN4siz7eZGB3wYkKga3pSwRb xCYA== X-Gm-Message-State: AOAM531+zYZFtm8d15zWBdbiP6C7OKe3gGhhHkQD3ziaYHE4tj+LjJPu 3iwkhPNQKFqEc+mKd+7DlAM= X-Google-Smtp-Source: ABdhPJzss3xS6cHiAMQgMY9qgSZlaYgbX55pLD2zWX6gZiMBcP10zo9CENesUUnL+7A0FbGbNte4kA== X-Received: by 2002:a17:906:161b:: with SMTP id m27mr5137165ejd.89.1623441962734; Fri, 11 Jun 2021 13:06:02 -0700 (PDT) Received: from localhost.localdomain ([188.26.52.84]) by smtp.gmail.com with ESMTPSA id w2sm2392084ejn.118.2021.06.11.13.06.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 11 Jun 2021 13:06:02 -0700 (PDT) From: Vladimir Oltean To: Jakub Kicinski , "David S. Miller" , netdev@vger.kernel.org Cc: Wong Vee Khee , Ong Boon Leong , Michael Sit Wei Hong , Giuseppe Cavallaro , Alexandre Torgue , Jose Abreu , Jose Abreu , Maxime Coquelin , Heiner Kallweit , Russell King - ARM Linux admin , Florian Fainelli , Andrew Lunn , Vivien Didelot , linux-arm-kernel@lists.infradead.org, linux-stm32@st-md-mailman.stormreply.com, Vladimir Oltean Subject: [PATCH v3 net-next 11/13] net: dsa: sja1105: register the PCS MDIO bus for SJA1110 Date: Fri, 11 Jun 2021 23:05:29 +0300 Message-Id: <20210611200531.2384819-12-olteanv@gmail.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210611200531.2384819-1-olteanv@gmail.com> References: <20210611200531.2384819-1-olteanv@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210611_130704_849608_CA18F46C X-CRM114-Status: GOOD ( 20.98 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org From: Vladimir Oltean On the SJA1110, the PCS of each SERDES-capable port is accessed through a different memory window which is 0x100 bytes in size, denoted by "pcs_base". In each PCS register access window, the XPCS MMDs are accessed in an indirect way: in pages/banks of up to 0x100 addresses each. Changing the page/bank is done by writing to a special register at the end of the access window. The MDIO register map accessed indirectly through the indirect banked method described above is similar to what SJA1105 has: upper 5 bits are the MMD, lower 16 bits are the MDIO address within that MMD. Since the PHY ID reported by the XPCS inside SJA1110 is also all zeroes (like SJA1105), we need to trap those reads and return a fake PHY ID so that the xpcs driver can apply some specific fixups for our integration. Signed-off-by: Vladimir Oltean --- v2->v3: none v1->v2: none drivers/net/dsa/sja1105/sja1105.h | 3 + drivers/net/dsa/sja1105/sja1105_mdio.c | 95 ++++++++++++++++++++++++++ drivers/net/dsa/sja1105/sja1105_spi.c | 11 +++ 3 files changed, 109 insertions(+) diff --git a/drivers/net/dsa/sja1105/sja1105.h b/drivers/net/dsa/sja1105/sja1105.h index 82450921059a..39124726bdd9 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 { @@ -303,6 +304,8 @@ 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); /* From sja1105_devlink.c */ int sja1105_devlink_setup(struct dsa_switch *ds); diff --git a/drivers/net/dsa/sja1105/sja1105_mdio.c b/drivers/net/dsa/sja1105/sja1105_mdio.c index 5185471e9b7c..41468e51a38e 100644 --- a/drivers/net/dsa/sja1105/sja1105_mdio.c +++ b/drivers/net/dsa/sja1105/sja1105_mdio.c @@ -5,6 +5,8 @@ #include #include "sja1105.h" +#define SJA1110_PCS_BANK_REG SJA1110_SPI_ADDR(0x3fc) + int sja1105_pcs_mdio_read(struct mii_bus *bus, int phy, int reg) { struct sja1105_mdio_private *mdio_priv = bus->priv; @@ -56,6 +58,99 @@ int sja1105_pcs_mdio_write(struct mii_bus *bus, int phy, int reg, u16 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)); + + if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID1) + return NXP_SJA1110_XPCS_ID >> 16; + if (mmd == MDIO_MMD_VEND2 && (reg & GENMASK(15, 0)) == MII_PHYSID2) + return NXP_SJA1110_XPCS_ID & 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, diff --git a/drivers/net/dsa/sja1105/sja1105_spi.c b/drivers/net/dsa/sja1105/sja1105_spi.c index c1c54b7ff0e4..96768af4c6a8 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 = { @@ -794,6 +797,8 @@ const struct sja1105_info sja1110a_info = { .rxtstamp = sja1110_rxtstamp, .txtstamp = sja1110_txtstamp, .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, @@ -843,6 +848,8 @@ const struct sja1105_info sja1110b_info = { .rxtstamp = sja1110_rxtstamp, .txtstamp = sja1110_txtstamp, .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, @@ -892,6 +899,8 @@ const struct sja1105_info sja1110c_info = { .rxtstamp = sja1110_rxtstamp, .txtstamp = sja1110_txtstamp, .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, @@ -941,6 +950,8 @@ const struct sja1105_info sja1110d_info = { .rxtstamp = sja1110_rxtstamp, .txtstamp = sja1110_txtstamp, .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,