From patchwork Sat Apr 18 00:03:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Lunn X-Patchwork-Id: 221067 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=-9.5 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,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 A823DC2BB1D for ; Sat, 18 Apr 2020 00:04:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 73A6D214D8 for ; Sat, 18 Apr 2020 00:04:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=lunn.ch header.i=@lunn.ch header.b="oLeSzJXL" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726152AbgDRAEM (ORCPT ); Fri, 17 Apr 2020 20:04:12 -0400 Received: from vps0.lunn.ch ([185.16.172.187]:45534 "EHLO vps0.lunn.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726036AbgDRAEM (ORCPT ); Fri, 17 Apr 2020 20:04:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lunn.ch; s=20171124; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=9UOdLcGHgTkoBjr0ZJ79fpliXOKASifALXPlwpfztbI=; b=oLeSzJXLC9I5NiAnQIS3Q1BgpX 5SjDScXll1QjsSUSu4AFf7x+w7z8Hk2XdhE2zw1NDegqjWgMEJQsRrbiPldbVveCb+0zHptbuWuUm ZIwjq1QocuXzwwIZsAWp/by6UHgnVj1egxzhT3QIFr6Y7IabYcVoOvtJA9u+kkK1gf/w=; Received: from andrew by vps0.lunn.ch with local (Exim 4.93) (envelope-from ) id 1jPaxs-003NKW-Q6; Sat, 18 Apr 2020 02:04:08 +0200 From: Andrew Lunn To: David Miller Cc: netdev , Florian Fainelli , Heiner Kallweit , fugang.duan@nxp.com, Andrew Lunn , Chris Heally Subject: [PATCH net-next v2 1/3] net: ethernet: fec: Replace interrupt driven MDIO with polled IO Date: Sat, 18 Apr 2020 02:03:53 +0200 Message-Id: <20200418000355.804617-2-andrew@lunn.ch> X-Mailer: git-send-email 2.26.0.rc2 In-Reply-To: <20200418000355.804617-1-andrew@lunn.ch> References: <20200418000355.804617-1-andrew@lunn.ch> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Measurements of the MDIO bus have shown that driving the MDIO bus using interrupts is slow. Back to back MDIO transactions take about 90uS, with 25uS spent performing the transaction, and the remainder of the time the bus is idle. Replacing the completion interrupt with polled IO results in back to back transactions of 40uS. The polling loop waiting for the hardware to complete the transaction takes around 27uS. Which suggests interrupt handling has an overhead of 50uS, and polled IO nearly halves this overhead, and doubles the MDIO performance. Suggested-by: Chris Heally Signed-off-by: Andrew Lunn --- drivers/net/ethernet/freescale/fec.h | 4 +- drivers/net/ethernet/freescale/fec_main.c | 67 ++++++++++++----------- 2 files changed, 35 insertions(+), 36 deletions(-) diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h index e74dd1f86bba..a6cdd5b61921 100644 --- a/drivers/net/ethernet/freescale/fec.h +++ b/drivers/net/ethernet/freescale/fec.h @@ -376,8 +376,7 @@ struct bufdesc_ex { #define FEC_ENET_TS_AVAIL ((uint)0x00010000) #define FEC_ENET_TS_TIMER ((uint)0x00008000) -#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII) -#define FEC_NAPI_IMASK FEC_ENET_MII +#define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF) #define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF)) /* ENET interrupt coalescing macro define */ @@ -543,7 +542,6 @@ struct fec_enet_private { int link; int full_duplex; int speed; - struct completion mdio_done; int irq[FEC_IRQ_NUM]; bool bufdesc_ex; int pause_flag; diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index dc6f8763a5d4..6530829632b1 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -976,8 +976,8 @@ fec_restart(struct net_device *ndev) writel((__force u32)cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH); - /* Clear any outstanding interrupt. */ - writel(0xffffffff, fep->hwp + FEC_IEVENT); + /* Clear any outstanding interrupt, except MDIO. */ + writel((0xffffffff & ~FEC_ENET_MII), fep->hwp + FEC_IEVENT); fec_enet_bd_init(ndev); @@ -1123,7 +1123,7 @@ fec_restart(struct net_device *ndev) if (fep->link) writel(FEC_DEFAULT_IMASK, fep->hwp + FEC_IMASK); else - writel(FEC_ENET_MII, fep->hwp + FEC_IMASK); + writel(0, fep->hwp + FEC_IMASK); /* Init the interrupt coalescing */ fec_enet_itr_coal_init(ndev); @@ -1652,6 +1652,10 @@ fec_enet_interrupt(int irq, void *dev_id) irqreturn_t ret = IRQ_NONE; int_events = readl(fep->hwp + FEC_IEVENT); + + /* Don't clear MDIO events, we poll for those */ + int_events &= ~FEC_ENET_MII; + writel(int_events, fep->hwp + FEC_IEVENT); fec_enet_collect_events(fep, int_events); @@ -1659,16 +1663,12 @@ fec_enet_interrupt(int irq, void *dev_id) ret = IRQ_HANDLED; if (napi_schedule_prep(&fep->napi)) { - /* Disable the NAPI interrupts */ - writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK); + /* Disable interrupts */ + writel(0, fep->hwp + FEC_IMASK); __napi_schedule(&fep->napi); } } - if (int_events & FEC_ENET_MII) { - ret = IRQ_HANDLED; - complete(&fep->mdio_done); - } return ret; } @@ -1818,11 +1818,24 @@ static void fec_enet_adjust_link(struct net_device *ndev) phy_print_status(phy_dev); } +static int fec_enet_mdio_wait(struct fec_enet_private *fep) +{ + uint ievent; + int ret; + + ret = readl_poll_timeout(fep->hwp + FEC_IEVENT, ievent, + ievent & FEC_ENET_MII, 0, 30000); + + if (!ret) + writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); + + return ret; +} + static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) { struct fec_enet_private *fep = bus->priv; struct device *dev = &fep->pdev->dev; - unsigned long time_left; int ret = 0, frame_start, frame_addr, frame_op; bool is_c45 = !!(regnum & MII_ADDR_C45); @@ -1830,8 +1843,6 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) if (ret < 0) return ret; - reinit_completion(&fep->mdio_done); - if (is_c45) { frame_start = FEC_MMFR_ST_C45; @@ -1843,11 +1854,9 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) fep->hwp + FEC_MII_DATA); /* wait for end of transfer */ - time_left = wait_for_completion_timeout(&fep->mdio_done, - usecs_to_jiffies(FEC_MII_TIMEOUT)); - if (time_left == 0) { + ret = fec_enet_mdio_wait(fep); + if (ret) { netdev_err(fep->netdev, "MDIO address write timeout\n"); - ret = -ETIMEDOUT; goto out; } @@ -1866,11 +1875,9 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) FEC_MMFR_TA, fep->hwp + FEC_MII_DATA); /* wait for end of transfer */ - time_left = wait_for_completion_timeout(&fep->mdio_done, - usecs_to_jiffies(FEC_MII_TIMEOUT)); - if (time_left == 0) { + ret = fec_enet_mdio_wait(fep); + if (ret) { netdev_err(fep->netdev, "MDIO read timeout\n"); - ret = -ETIMEDOUT; goto out; } @@ -1888,7 +1895,6 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, { struct fec_enet_private *fep = bus->priv; struct device *dev = &fep->pdev->dev; - unsigned long time_left; int ret, frame_start, frame_addr; bool is_c45 = !!(regnum & MII_ADDR_C45); @@ -1898,8 +1904,6 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, else ret = 0; - reinit_completion(&fep->mdio_done); - if (is_c45) { frame_start = FEC_MMFR_ST_C45; @@ -1911,11 +1915,9 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, fep->hwp + FEC_MII_DATA); /* wait for end of transfer */ - time_left = wait_for_completion_timeout(&fep->mdio_done, - usecs_to_jiffies(FEC_MII_TIMEOUT)); - if (time_left == 0) { + ret = fec_enet_mdio_wait(fep); + if (ret) { netdev_err(fep->netdev, "MDIO address write timeout\n"); - ret = -ETIMEDOUT; goto out; } } else { @@ -1931,12 +1933,9 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, fep->hwp + FEC_MII_DATA); /* wait for end of transfer */ - time_left = wait_for_completion_timeout(&fep->mdio_done, - usecs_to_jiffies(FEC_MII_TIMEOUT)); - if (time_left == 0) { + ret = fec_enet_mdio_wait(fep); + if (ret) netdev_err(fep->netdev, "MDIO write timeout\n"); - ret = -ETIMEDOUT; - } out: pm_runtime_mark_last_busy(dev); @@ -2132,6 +2131,9 @@ static int fec_enet_mii_init(struct platform_device *pdev) writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); + /* Clear any pending transaction complete indication */ + writel(FEC_ENET_MII, fep->hwp + FEC_IEVENT); + fep->mii_bus = mdiobus_alloc(); if (fep->mii_bus == NULL) { err = -ENOMEM; @@ -3674,7 +3676,6 @@ fec_probe(struct platform_device *pdev) fep->irq[i] = irq; } - init_completion(&fep->mdio_done); ret = fec_enet_mii_init(pdev); if (ret) goto failed_mii_init; From patchwork Sat Apr 18 00:03:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Lunn X-Patchwork-Id: 221066 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=-9.5 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,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 84496C352BE for ; Sat, 18 Apr 2020 00:04:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6490C221EA for ; Sat, 18 Apr 2020 00:04:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=lunn.ch header.i=@lunn.ch header.b="07QCHlzQ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726414AbgDRAE2 (ORCPT ); Fri, 17 Apr 2020 20:04:28 -0400 Received: from vps0.lunn.ch ([185.16.172.187]:45560 "EHLO vps0.lunn.ch" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726036AbgDRAE1 (ORCPT ); Fri, 17 Apr 2020 20:04:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lunn.ch; s=20171124; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=uF2w8pHsSMCHxvg8n1ReKtpYE6xeN6VRn3oRropG0uU=; b=07QCHlzQHfkgAgVRYtLTh+Sp6V JL6wgvALyWyvDhH6IUwKn/H9TRR+TYy7GBIjKwQ0NQM3RlShlPfCNG3aMlslsMxrfQHOMHIhDGYG9 +CXXFwpvm+EKdaYUFajYBk3rl8bukCB0tR/h2Whlj1JQqPm8cvjchuphBaRc1NpELuPk=; Received: from andrew by vps0.lunn.ch with local (Exim 4.93) (envelope-from ) id 1jPaxs-003NKf-SC; Sat, 18 Apr 2020 02:04:08 +0200 From: Andrew Lunn To: David Miller Cc: netdev , Florian Fainelli , Heiner Kallweit , fugang.duan@nxp.com, Andrew Lunn , Chris Healy Subject: [PATCH net-next v2 3/3] net: ethernet: fec: Allow the MDIO preamble to be disabled Date: Sat, 18 Apr 2020 02:03:55 +0200 Message-Id: <20200418000355.804617-4-andrew@lunn.ch> X-Mailer: git-send-email 2.26.0.rc2 In-Reply-To: <20200418000355.804617-1-andrew@lunn.ch> References: <20200418000355.804617-1-andrew@lunn.ch> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org An MDIO transaction normally starts with 32 1s as a preamble. However not all devices requires such a preamble. Add a device tree property which allows the preamble to be suppressed. This will half the size of the MDIO transaction, allowing faster transactions. Suggested-by: Chris Healy Signed-off-by: Andrew Lunn --- Documentation/devicetree/bindings/net/mdio.yaml | 4 ++++ drivers/net/ethernet/freescale/fec_main.c | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/net/mdio.yaml b/Documentation/devicetree/bindings/net/mdio.yaml index bcd457c54cd7..41ed4019f8ca 100644 --- a/Documentation/devicetree/bindings/net/mdio.yaml +++ b/Documentation/devicetree/bindings/net/mdio.yaml @@ -43,6 +43,10 @@ properties: description: Desired MDIO bus clock frequency in Hz. + suppress-preamble: + description: The 32 bit preamble should be suppressed. + type: boolean + patternProperties: "^ethernet-phy@[0-9a-f]+$": type: object diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index 28ef0abfa660..3404e085c657 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -2064,6 +2064,7 @@ static int fec_enet_mii_init(struct platform_device *pdev) static struct mii_bus *fec0_mii_bus; struct net_device *ndev = platform_get_drvdata(pdev); struct fec_enet_private *fep = netdev_priv(ndev); + bool suppress_preamble = false; struct device_node *node; int err = -ENXIO; u32 mii_speed, holdtime; @@ -2097,8 +2098,11 @@ static int fec_enet_mii_init(struct platform_device *pdev) bus_freq = 2500000; /* 2.5MHz by default */ node = of_get_child_by_name(pdev->dev.of_node, "mdio"); - if (node) + if (node) { of_property_read_u32(node, "clock-frequency", &bus_freq); + suppress_preamble = of_property_read_bool(node, + "suppress-preamble"); + } /* * Set MII speed (= clk_get_rate() / 2 * phy_speed) @@ -2135,6 +2139,9 @@ static int fec_enet_mii_init(struct platform_device *pdev) fep->phy_speed = mii_speed << 1 | holdtime << 8; + if (suppress_preamble) + fep->phy_speed |= BIT(7); + writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED); /* Clear any pending transaction complete indication */