From patchwork Fri Apr 1 12:41:47 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sven Eckelmann X-Patchwork-Id: 604782 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from arrakis.dune.hu (caladan.dune.hu [78.24.191.180]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3qc1H84WjXz9sBG for ; Fri, 1 Apr 2016 23:42:12 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=open-mesh-com.20150623.gappssmtp.com header.i=@open-mesh-com.20150623.gappssmtp.com header.b=X+Swyedj; dkim-atps=neutral Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id 79B1FB80966; Fri, 1 Apr 2016 14:42:02 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on arrakis.dune.hu X-Spam-Level: ** X-Spam-Status: No, score=2.4 required=5.0 tests=RDNS_NONE,T_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.1 Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP; Fri, 1 Apr 2016 14:42:02 +0200 (CEST) Received: from arrakis.dune.hu (localhost [127.0.0.1]) by arrakis.dune.hu (Postfix) with ESMTP id B8061B80949 for ; Fri, 1 Apr 2016 14:42:00 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 CL_IP_EQ_HELO_IP=-2 (check from: .open-mesh. - helo: .mail-wm0-f44.google. - helo-domain: .google.) FROM/MX_MATCHES_HELO(DOMAIN)=-2; rate: -7 Received: from mail-wm0-f44.google.com (unknown [74.125.82.44]) by arrakis.dune.hu (Postfix) with ESMTPS for ; Fri, 1 Apr 2016 14:41:59 +0200 (CEST) Received: by mail-wm0-f44.google.com with SMTP id 127so18686814wmu.1 for ; Fri, 01 Apr 2016 05:41:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=open-mesh-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id; bh=SNnsbW6sjqPt0MWHE7+LRnB/Vm6WhYJCZ7iizb6d4xw=; b=X+Swyedj4icTp9t/cVOb55sFEODP2GPxvoVARe/Gm2C6lYdw/Z6JJ8/IWNc1EzUP1A SaUIBGy5CwB/jxHSkQkLpXZWtwjGezn6IcKjgW+BxtswJ0E14LjnqsN+Y04ljkdfcFOV yaVXoRN2mtcMYH2d9dcUKBtr+z5/uohl/gWPrLxx3cvS6Up7T3Vs4rjizIf5N1XYKbAZ IunFQXA3KgBD6Et3noWECdy/rrrBzNFJzQBWdXwcEu/Fo+jc+C8W+D5sJWOqwB6D9mZ8 Dr2pP7Ey1Du6ydJ/vs4qCg5yIlXsJOzCa8a4heBPjhKI/YK+2tM5qrna+E/OVz3xc+q8 6tMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=SNnsbW6sjqPt0MWHE7+LRnB/Vm6WhYJCZ7iizb6d4xw=; b=VkAytow+XNO+Lhti1KDo8NPt4lE2a2bzPMjf047/fPuUjZUEdD5MqRdvIMo3KlH1x2 OApe9W6t9/abHaEqG2x8f/M0HfdHuSbwKUA4GydmYkK+gqJbbDbco93/aYaUkwxhS7mc 1DWzVPYnPeCemq77+E8iGrsN9Fq310/e4t3OZ/tYJ1XHbWx6fRHJ8sf6+4i93HZSeEru jZYyjFXvZwlXQgdhE/2ezLlYVOVJVmLvkiNVrtShoiwDC6YmmHsdPlV+LTZ56F4+jkIQ NVvBDtr/vGELeK/aHM8pS0uSsh1c9nTron1HvFKfTfX7oIwNUTrNDUWCL3TnjlBuFdEY 7uAA== X-Gm-Message-State: AD7BkJKGp9r9prViGZptyPkX2bB6gTM0BddSFqYOPWw5TR/0X/hMweQw/pLMt39sytQ52ZLG X-Received: by 10.194.248.135 with SMTP id ym7mr2158521wjc.174.1459514518931; Fri, 01 Apr 2016 05:41:58 -0700 (PDT) Received: from sven-desktop.home.narfation.org (xd9ba8664.dyn.telefonica.de. [217.186.134.100]) by smtp.gmail.com with ESMTPSA id s66sm29822837wmb.6.2016.04.01.05.41.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 01 Apr 2016 05:41:58 -0700 (PDT) From: Sven Eckelmann X-Google-Original-From: Sven Eckelmann To: openwrt-devel@lists.openwrt.org Date: Fri, 1 Apr 2016 14:41:47 +0200 Message-Id: <1459514507-20044-1-git-send-email-sven@open-mesh.com> X-Mailer: git-send-email 2.8.0.rc3 Subject: [OpenWrt-Devel] [RFC] ar71xx: Reset QCA955x SGMII link on speed change X-BeenThere: openwrt-devel@lists.openwrt.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: OpenWrt Development List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Sven Eckelmann MIME-Version: 1.0 Errors-To: openwrt-devel-bounces@lists.openwrt.org Sender: "openwrt-devel" From: Sven Eckelmann The SGMII link of the QCA955x seems to be unstable when the PHY changes the link speed. Reseting the SGMII and the PHY management control seems to resolve this problem. This was observed with an AR8033 and QCA9558 The code of this RFC is not meant to be an actual patch. It should show what the u-boot for QCA955x does and what seemed to work(tm) in my limited tests. It would be interesting to know whether this was also noticed by other people and how they fixed it (when they fixed it). If it is already known than it would maybe good to find a better way to integrate it with ag71xx. Right now it just uses the set_speed callback to start the reset. Signed-off-by: Sven Eckelmann --- .../linux/ar71xx/files/arch/mips/ath79/dev-eth.c | 110 +++++++++++++++++++++ .../601-MIPS-ath79-add-more-register-defines.patch | 2 +- .../601-MIPS-ath79-add-more-register-defines.patch | 2 +- 3 files changed, 112 insertions(+), 2 deletions(-) diff --git a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c index b43c80a..01c25b2 100644 --- a/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c +++ b/target/linux/ar71xx/files/arch/mips/ath79/dev-eth.c @@ -373,6 +373,20 @@ static void ar934x_set_speed_ge0(int speed) iounmap(base); } +#define QCA955X_GMAC_REG_SGMII_RESET 0x14 +#define QCA955X_GMAC_REG_MR_AN_CONTROL 0x1C +#define QCA955X_GMAC_REG_SGMII_DEBUG 0x58 +#define SGMII_LINK_WAR_MAX_TRY 20 + +#define QCA955X_GMAC_REG_MR_AN_CONTROL_AN_ENABLE BIT(12) +#define QCA955X_GMAC_REG_MR_AN_CONTROL_PHY_RESET BIT(15) + +#define QCA955X_GMAC_REG_SGMII_RESET_HW_RX_125M_N BIT(4) +#define QCA955X_GMAC_REG_SGMII_RESET_TX_125M_N BIT(3) +#define QCA955X_GMAC_REG_SGMII_RESET_RX_125M_N BIT(2) +#define QCA955X_GMAC_REG_SGMII_RESET_TX_CLK_N BIT(1) +#define QCA955X_GMAC_REG_SGMII_RESET_RX_CLK_N BIT(0) + static void qca955x_set_speed_xmii(int speed) { void __iomem *base; @@ -381,6 +395,100 @@ static void qca955x_set_speed_xmii(int speed) base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); __raw_writel(val, base + QCA955X_PLL_ETH_XMII_CONTROL_REG); iounmap(base); + + // TODO: find out if something like qca955x_reset_xmii(); is needed +} + +static void qca955x_reset_sgmii(void) +{ + void __iomem *base; + int count = 0; + u32 status; + u32 t; + + base = ioremap(QCA955X_GMAC_BASE, QCA955X_GMAC_SIZE); + + /* WARNING ugly PoC code ahead */ + printk("Resetting SGMII link\n"); + + t = QCA955X_GMAC_REG_MR_AN_CONTROL_AN_ENABLE | + QCA955X_GMAC_REG_MR_AN_CONTROL_PHY_RESET; + __raw_writel(t, base + QCA955X_GMAC_REG_MR_AN_CONTROL); + udelay(10); + + t = QCA955X_GMAC_REG_MR_AN_CONTROL_AN_ENABLE; + __raw_writel(t, base + QCA955X_GMAC_REG_MR_AN_CONTROL); + + t = 0; + __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET); + udelay(10); + + t = QCA955X_GMAC_REG_SGMII_RESET_HW_RX_125M_N; + __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET); + udelay(10); + + t = QCA955X_GMAC_REG_SGMII_RESET_HW_RX_125M_N | + QCA955X_GMAC_REG_SGMII_RESET_RX_125M_N; + __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET); + udelay(10); + + t = QCA955X_GMAC_REG_SGMII_RESET_HW_RX_125M_N | + QCA955X_GMAC_REG_SGMII_RESET_TX_125M_N | + QCA955X_GMAC_REG_SGMII_RESET_RX_125M_N; + __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET); + udelay(10); + + t = QCA955X_GMAC_REG_SGMII_RESET_HW_RX_125M_N | + QCA955X_GMAC_REG_SGMII_RESET_TX_125M_N | + QCA955X_GMAC_REG_SGMII_RESET_RX_125M_N | + QCA955X_GMAC_REG_SGMII_RESET_RX_CLK_N; + __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET); + udelay(10); + + t = QCA955X_GMAC_REG_SGMII_RESET_HW_RX_125M_N | + QCA955X_GMAC_REG_SGMII_RESET_TX_125M_N | + QCA955X_GMAC_REG_SGMII_RESET_RX_125M_N | + QCA955X_GMAC_REG_SGMII_RESET_RX_CLK_N | + QCA955X_GMAC_REG_SGMII_RESET_TX_CLK_N; + __raw_writel(t, base + QCA955X_GMAC_REG_SGMII_RESET); + udelay(10); + + /* TODO this should be an rmw */ + t = __raw_readl(base + QCA955X_GMAC_REG_MR_AN_CONTROL); + t &= ~QCA955X_GMAC_REG_MR_AN_CONTROL_PHY_RESET; + __raw_writel(t, base + QCA955X_GMAC_REG_MR_AN_CONTROL); + udelay(100); + + status = __raw_readl(base + QCA955X_GMAC_REG_SGMII_DEBUG); + status &= 0xff; + while (status != 0xf && status != 0x10) { + printk("state %#02x\n", status); + /* TODO this should be an rmw */ + t = __raw_readl(base + QCA955X_GMAC_REG_MR_AN_CONTROL); + t |= QCA955X_GMAC_REG_MR_AN_CONTROL_PHY_RESET; + __raw_writel(t, base + QCA955X_GMAC_REG_MR_AN_CONTROL); + + udelay(100); + + /* TODO this should be an rmw */ + t = __raw_readl(base + QCA955X_GMAC_REG_MR_AN_CONTROL); + t &= ~QCA955X_GMAC_REG_MR_AN_CONTROL_PHY_RESET; + __raw_writel(t, base + QCA955X_GMAC_REG_MR_AN_CONTROL); + + if (count++ >= SGMII_LINK_WAR_MAX_TRY) { + printk("Max resets limit reached exiting...\n"); + break; + } + + mdelay(10); + + status = __raw_readl(base + QCA955X_GMAC_REG_SGMII_DEBUG); + status &= 0xff; + } + + printk("Reached count %d\n", count); + + iounmap(base); } static void qca955x_set_speed_sgmii(int speed) @@ -401,6 +509,8 @@ static void qca956x_set_speed_sgmii(int speed) base = ioremap_nocache(AR71XX_PLL_BASE, AR71XX_PLL_SIZE); __raw_writel(val, base + QCA955X_PLL_ETH_SGMII_CONTROL_REG); iounmap(base); + + qca955x_reset_sgmii(); } static void ath79_set_speed_dummy(int speed) diff --git a/target/linux/ar71xx/patches-4.1/601-MIPS-ath79-add-more-register-defines.patch b/target/linux/ar71xx/patches-4.1/601-MIPS-ath79-add-more-register-defines.patch index 0126f6a..2da1048 100644 --- a/target/linux/ar71xx/patches-4.1/601-MIPS-ath79-add-more-register-defines.patch +++ b/target/linux/ar71xx/patches-4.1/601-MIPS-ath79-add-more-register-defines.patch @@ -47,7 +47,7 @@ #define QCA955X_PCI_CTRL_SIZE 0x100 +#define QCA955X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -+#define QCA955X_GMAC_SIZE 0x40 ++#define QCA955X_GMAC_SIZE 0x64 #define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) #define QCA955X_WMAC_SIZE 0x20000 #define QCA955X_EHCI0_BASE 0x1b000000 diff --git a/target/linux/ar71xx/patches-4.4/601-MIPS-ath79-add-more-register-defines.patch b/target/linux/ar71xx/patches-4.4/601-MIPS-ath79-add-more-register-defines.patch index 0126f6a..2da1048 100644 --- a/target/linux/ar71xx/patches-4.4/601-MIPS-ath79-add-more-register-defines.patch +++ b/target/linux/ar71xx/patches-4.4/601-MIPS-ath79-add-more-register-defines.patch @@ -47,7 +47,7 @@ #define QCA955X_PCI_CTRL_SIZE 0x100 +#define QCA955X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000) -+#define QCA955X_GMAC_SIZE 0x40 ++#define QCA955X_GMAC_SIZE 0x64 #define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) #define QCA955X_WMAC_SIZE 0x20000 #define QCA955X_EHCI0_BASE 0x1b000000