From patchwork Mon Jul 24 22:58:20 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcin Wojtas X-Patchwork-Id: 9860781 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 3788860385 for ; Mon, 24 Jul 2017 22:59:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1EE7028565 for ; Mon, 24 Jul 2017 22:59:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 10512285C5; Mon, 24 Jul 2017 22:59:50 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3298C28565 for ; Mon, 24 Jul 2017 22:59:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:To:Subject:Message-ID:Date:From: References:In-Reply-To:MIME-Version:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Hf7OpQyuYclmVfK1Gw+2pgP7MnOD4m3ixr7dXBcK53E=; b=bGjH8gkE+ATGzK mXY0zkBEaFOSdg4LziTaw0zBWkz7OqxEA7O3Qvb2c80nhoBwy0l51EhMcXAfMbFkbnZ1lEBAFyVH+ giBuRHs8jHjNJgAue4iISHg354r/Uyon7TnamQZHqJ+Ejqql539saKUlL2tADDqLw9qOFDp4uSDbh y4JZssOdTPGVLL5SQohZENz1T4HIvPBY1cZLujc4bd5dQVwkreWmd8M+MRMukjju3O1IOQb1D91Lm NTGifwAqx4HoBO37PjyDQwxQYMM0hK7R/qkvEcbVZ1MBfPms8xSGIqCtN9Tcx8BrjD9mrivhMp3bQ 8L2Oa9+o+EqL3xPTCz7A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dZmJL-0008B3-6Z; Mon, 24 Jul 2017 22:58:47 +0000 Received: from mail-io0-x22e.google.com ([2607:f8b0:4001:c06::22e]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dZmJH-0008AG-Vx for linux-arm-kernel@lists.infradead.org; Mon, 24 Jul 2017 22:58:46 +0000 Received: by mail-io0-x22e.google.com with SMTP id j32so28311852iod.0 for ; Mon, 24 Jul 2017 15:58:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=semihalf-com.20150623.gappssmtp.com; s=20150623; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=oOs7bDTFkN9Tv3Uczpv/ataSjuDubTWrtO/pn4SFhzI=; b=XGXuuY82UEMTpLOQUu0K0PNbFEWpkYL7E7kKZGaSNeBWQ4ySRLNw5Lme8MTC6cq5wv ZDWo4BoKfAVGgjgc6vf67huPFqU9cur05V1giwd7wiZZhqKlx03E+iWPoBTPqr2TW/mR eGiPcF8BDmwPFTWVhl/TwUkKQVvCjAQ7RIKtqT9GAzmjyAOCPwRh1LJ3nfU26BMbHHWd 84C/CwXgLIW404D3t9w33vIs/k9I3RQcTJgQzu/ucX/Wy7xW7L0BU7gwW7JLkUO4cDEo ZyHXikge0gPJYIpMbDuLA488g7KjHuUVL9BvgmEHDThWDTTwLFg/NNOgWOzqmEgUw4SI 7+Fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=oOs7bDTFkN9Tv3Uczpv/ataSjuDubTWrtO/pn4SFhzI=; b=q1nRqkGKm1qjWKOBj5Q4rrt7ADB9AFNrQi4LM9Qrx8ZCExil8ePCyr4PLsYLBE750l x7U3vB/Q6iYUaaBPFodUEw6ewKllERAf4J8O+AVDBsvHYGOSRKHxLwMoWrb/l6SfNWwK kuRPjoCrptr/WFF0mams9OWzveJ7fcYeoLlEoW/CtWUxLvCp4PAAaYSEXk6x5DSdbU6V +3wUUuf1bz0hIAUxT/sffvUU1sEhXfmXL16733rB0dHABqGxQ1bRvfbZ5r10S31Tys1o 3F8GTaiQ1hwx2Rqa2f3PiX8LIvseN63LAZ1ZYC+iEqK80mxpNU0PlOwE9XTSixjugPgY pFHA== X-Gm-Message-State: AIVw111a8zjfnD6l+mEWWVQkzgTxe8W+HbWdulqJvokrMmMndNzDfqZ/ 9RtoLgva6x1JlweHqg7VKTAJCjmpgrj7 X-Received: by 10.107.36.136 with SMTP id k130mr16698176iok.7.1500937101447; Mon, 24 Jul 2017 15:58:21 -0700 (PDT) MIME-Version: 1.0 Received: by 10.107.155.198 with HTTP; Mon, 24 Jul 2017 15:58:20 -0700 (PDT) In-Reply-To: <20170724134848.19330-11-antoine.tenart@free-electrons.com> References: <20170724134848.19330-1-antoine.tenart@free-electrons.com> <20170724134848.19330-11-antoine.tenart@free-electrons.com> From: Marcin Wojtas Date: Tue, 25 Jul 2017 00:58:20 +0200 Message-ID: Subject: Re: [PATCH net-next 10/18] net: mvpp2: use the GoP interrupt for link status changes To: Antoine Tenart X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170724_155844_157240_FD14CFAD X-CRM114-Status: GOOD ( 24.24 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Thomas Petazzoni , Andrew Lunn , Jason Cooper , netdev@vger.kernel.org, Russell King - ARM Linux , nadavh@marvell.com, =?UTF-8?Q?Gregory_Cl=C3=A9ment?= , Stefan Chulski , "David S. Miller" , "linux-arm-kernel@lists.infradead.org" , Sebastian Hesselbarth Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Hi Antoine, This patch requires also: Otherwise a sequence: ifconfig up/down/up results in faults. Best regards, Marcin 2017-07-24 15:48 GMT+02:00 Antoine Tenart : > This patch adds the GoP link interrupt support for when a port isn't > connected to a PHY. Because of this the phylib callback is never called > and the link status management isn't done. This patch use the GoP link > interrupt in such cases to still have a minimal link management. Without > this patch ports not connected to a PHY cannot work. > > Signed-off-by: Antoine Tenart > --- > drivers/net/ethernet/marvell/mvpp2.c | 157 ++++++++++++++++++++++++++++++++++- > 1 file changed, 154 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c > index 77eef2cc40a1..33a7eb834855 100644 > --- a/drivers/net/ethernet/marvell/mvpp2.c > +++ b/drivers/net/ethernet/marvell/mvpp2.c > @@ -339,16 +339,24 @@ > #define MVPP2_GMAC_FLOW_CTRL_AUTONEG BIT(11) > #define MVPP2_GMAC_CONFIG_FULL_DUPLEX BIT(12) > #define MVPP2_GMAC_AN_DUPLEX_EN BIT(13) > +#define MVPP2_GMAC_STATUS0 0x10 > +#define MVPP2_GMAC_STATUS0_LINK_UP BIT(0) > #define MVPP2_GMAC_PORT_FIFO_CFG_1_REG 0x1c > #define MVPP2_GMAC_TX_FIFO_MIN_TH_OFFS 6 > #define MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK 0x1fc0 > #define MVPP2_GMAC_TX_FIFO_MIN_TH_MASK(v) (((v) << 6) & \ > MVPP2_GMAC_TX_FIFO_MIN_TH_ALL_MASK) > +#define MVPP22_GMAC_INT_STAT 0x20 > +#define MVPP22_GMAC_INT_STAT_LINK BIT(1) > +#define MVPP22_GMAC_INT_MASK 0x24 > +#define MVPP22_GMAC_INT_MASK_LINK_STAT BIT(1) > #define MVPP22_GMAC_CTRL_4_REG 0x90 > #define MVPP22_CTRL4_EXT_PIN_GMII_SEL BIT(0) > #define MVPP22_CTRL4_DP_CLK_SEL BIT(5) > #define MVPP22_CTRL4_SYNC_BYPASS_DIS BIT(6) > #define MVPP22_CTRL4_QSGMII_BYPASS_ACTIVE BIT(7) > +#define MVPP22_GMAC_INT_SUM_MASK 0xa4 > +#define MVPP22_GMAC_INT_SUM_MASK_LINK_STAT BIT(1) > > /* Per-port XGMAC registers. PPv2.2 only, only for GOP port 0, > * relative to port->base. > @@ -358,12 +366,19 @@ > #define MVPP22_XLG_CTRL0_MAC_RESET_DIS BIT(1) > #define MVPP22_XLG_CTRL0_RX_FLOW_CTRL_EN BIT(7) > #define MVPP22_XLG_CTRL0_MIB_CNT_DIS BIT(14) > - > +#define MVPP22_XLG_STATUS 0x10c > +#define MVPP22_XLG_STATUS_LINK_UP BIT(0) > +#define MVPP22_XLG_INT_STAT 0x114 > +#define MVPP22_XLG_INT_STAT_LINK BIT(1) > +#define MVPP22_XLG_INT_MASK 0x118 > +#define MVPP22_XLG_INT_MASK_LINK BIT(1) > #define MVPP22_XLG_CTRL3_REG 0x11c > #define MVPP22_XLG_CTRL3_MACMODESELECT_MASK (7 << 13) > #define MVPP22_XLG_CTRL3_MACMODESELECT_GMAC (0 << 13) > #define MVPP22_XLG_CTRL3_MACMODESELECT_10G (1 << 13) > - > +#define MVPP22_XLG_EXT_INT_MASK 0x15c > +#define MVPP22_XLG_EXT_INT_MASK_XLG BIT(1) > +#define MVPP22_XLG_EXT_INT_MASK_GIG BIT(2) > #define MVPP22_XLG_CTRL4_REG 0x184 > #define MVPP22_XLG_CTRL4_FWD_FC BIT(5) > #define MVPP22_XLG_CTRL4_FWD_PFC BIT(6) > @@ -814,6 +829,7 @@ struct mvpp2_port { > int gop_id; > > int irq; > + int link_irq; > > struct mvpp2 *priv; > > @@ -4330,6 +4346,63 @@ static int mvpp22_gop_init(struct mvpp2_port *port) > return -EINVAL; > } > > +static void mvpp22_gop_unmask_irq(struct mvpp2_port *port) > +{ > + u32 val; > + > + if (port->phy_interface == PHY_INTERFACE_MODE_RGMII || > + port->phy_interface == PHY_INTERFACE_MODE_SGMII) { > + /* Enable the GMAC link status irq for this port */ > + val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK); > + val |= MVPP22_GMAC_INT_SUM_MASK_LINK_STAT; > + writel(val, port->base + MVPP22_GMAC_INT_SUM_MASK); > + } > + > + /* Enable the XLG/GIG irqs for this port */ > + val = readl(port->base + MVPP22_XLG_EXT_INT_MASK); > + if (port->gop_id == 0 && > + port->phy_interface == PHY_INTERFACE_MODE_10GKR) > + val |= MVPP22_XLG_EXT_INT_MASK_XLG; > + else > + val |= MVPP22_XLG_EXT_INT_MASK_GIG; > + writel(val, port->base + MVPP22_XLG_EXT_INT_MASK); > +} > + > +static void mvpp22_gop_mask_irq(struct mvpp2_port *port) > +{ > + u32 val; > + > + val = readl(port->base + MVPP22_XLG_EXT_INT_MASK); > + val &= ~(MVPP22_XLG_EXT_INT_MASK_XLG | > + MVPP22_XLG_EXT_INT_MASK_GIG); > + writel(val, port->base + MVPP22_XLG_EXT_INT_MASK); > + > + if (port->phy_interface == PHY_INTERFACE_MODE_RGMII || > + port->phy_interface == PHY_INTERFACE_MODE_SGMII) { > + val = readl(port->base + MVPP22_GMAC_INT_SUM_MASK); > + val &= ~MVPP22_GMAC_INT_SUM_MASK_LINK_STAT; > + writel(val, port->base + MVPP22_GMAC_INT_SUM_MASK); > + } > +} > + > +static void mvpp22_gop_setup_irq(struct mvpp2_port *port) > +{ > + u32 val; > + > + if (port->phy_interface == PHY_INTERFACE_MODE_RGMII || > + port->phy_interface == PHY_INTERFACE_MODE_SGMII) { > + val = readl(port->base + MVPP22_GMAC_INT_MASK); > + val |= MVPP22_GMAC_INT_MASK_LINK_STAT; > + writel(val, port->base + MVPP22_GMAC_INT_MASK); > + } > + > + val = readl(port->base + MVPP22_XLG_INT_MASK); > + val |= MVPP22_XLG_INT_MASK_LINK; > + writel(val, port->base + MVPP22_XLG_INT_MASK); > + > + mvpp22_gop_unmask_irq(port); > +} > + > static void mvpp2_port_mii_gmac_configure_mode(struct mvpp2_port *port) > { > u32 val; > @@ -5529,6 +5602,60 @@ static irqreturn_t mvpp2_isr(int irq, void *dev_id) > return IRQ_HANDLED; > } > > +/* Per-port interrupt for link status changes */ > +static irqreturn_t mvpp2_link_status_isr(int irq, void *dev_id) > +{ > + struct mvpp2_port *port = (struct mvpp2_port *)dev_id; > + struct net_device *dev = port->dev; > + bool event = false, link = false; > + u32 val; > + > + mvpp22_gop_mask_irq(port); > + > + if (port->gop_id == 0 && > + port->phy_interface == PHY_INTERFACE_MODE_10GKR) { > + val = readl(port->base + MVPP22_XLG_INT_STAT); > + if (val & MVPP22_XLG_INT_STAT_LINK) { > + event = true; > + val = readl(port->base + MVPP22_XLG_STATUS); > + if (val & MVPP22_XLG_STATUS_LINK_UP) > + link = true; > + } > + } else if (port->phy_interface == PHY_INTERFACE_MODE_RGMII || > + port->phy_interface == PHY_INTERFACE_MODE_SGMII) { > + val = readl(port->base + MVPP22_GMAC_INT_STAT); > + if (val & MVPP22_GMAC_INT_STAT_LINK) { > + event = true; > + val = readl(port->base + MVPP2_GMAC_STATUS0); > + if (val & MVPP2_GMAC_STATUS0_LINK_UP) > + link = true; > + } > + } > + > + if (!netif_running(dev) || !event) > + goto handled; > + > + if (link) { > + mvpp2_interrupts_enable(port); > + > + mvpp2_egress_enable(port); > + mvpp2_ingress_enable(port); > + netif_carrier_on(dev); > + netif_tx_wake_all_queues(dev); > + } else { > + netif_tx_stop_all_queues(dev); > + netif_carrier_off(dev); > + mvpp2_ingress_disable(port); > + mvpp2_egress_disable(port); > + > + mvpp2_interrupts_disable(port); > + } > + > +handled: > + mvpp22_gop_unmask_irq(port); > + return IRQ_HANDLED; > +} > + > /* Adjust link */ > static void mvpp2_link_event(struct net_device *dev) > { > @@ -6221,6 +6348,7 @@ static void mvpp2_phy_disconnect(struct mvpp2_port *port) > static int mvpp2_open(struct net_device *dev) > { > struct mvpp2_port *port = netdev_priv(dev); > + struct mvpp2 *priv = port->priv; > unsigned char mac_bcast[ETH_ALEN] = { > 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; > int err; > @@ -6266,12 +6394,24 @@ static int mvpp2_open(struct net_device *dev) > goto err_cleanup_txqs; > } > > + if (priv->hw_version == MVPP22 && !port->phy_node && port->link_irq) { > + err = request_irq(port->link_irq, mvpp2_link_status_isr, 0, > + dev->name, port); > + if (err) { > + netdev_err(port->dev, "cannot request link IRQ %d\n", > + port->link_irq); > + goto err_free_irq; > + } > + > + mvpp22_gop_setup_irq(port); > + } > + > /* In default link is down */ > netif_carrier_off(port->dev); > > err = mvpp2_phy_connect(port); > if (err < 0) > - goto err_free_irq; > + goto err_free_link_irq; > > /* Unmask interrupts on all CPUs */ > on_each_cpu(mvpp2_interrupts_unmask, port, 1); > @@ -6280,6 +6420,8 @@ static int mvpp2_open(struct net_device *dev) > > return 0; > > +err_free_link_irq: > + free_irq(port->link_irq, port); > err_free_irq: > free_irq(port->irq, port); > err_cleanup_txqs: > @@ -6796,6 +6938,15 @@ static int mvpp2_port_probe(struct platform_device *pdev, > -EPROBE_DEFER : -EINVAL; > goto err_free_netdev; > } > + > + port->link_irq = of_irq_get_byname(port_node, "link"); > + if (port->link_irq == -EPROBE_DEFER) { > + err = -EPROBE_DEFER; > + goto err_free_irq; > + } > + if (port->link_irq <= 0) > + /* the link irq is optional */ > + port->link_irq = 0; > } else { > /* kept for dt compatibility */ > port->irq = irq_of_parse_and_map(port_node, 0); > -- > 2.13.3 > diff --git a/drivers/net/ethernet/marvell/mvpp2.c b/drivers/net/ethernet/marvell/mvpp2.c index 4694d4f..369819f 100644 --- a/drivers/net/ethernet/marvell/mvpp2.c +++ b/drivers/net/ethernet/marvell/mvpp2.c @@ -6625,6 +6625,7 @@ static int mvpp2_stop(struct net_device *dev) { struct mvpp2_port *port = netdev_priv(dev); struct mvpp2_port_pcpu *port_pcpu; + struct mvpp2 *priv = port->priv; int cpu; mvpp2_stop_dev(port); @@ -6633,6 +6634,10 @@ static int mvpp2_stop(struct net_device *dev) /* Mask interrupts on all CPUs */ on_each_cpu(mvpp2_interrupts_mask, port, 1); + if (priv->hw_version == MVPP22 && !port->phy_node && port->link_irq) { + free_irq(port->link_irq, port); + } + free_irq(port->irq, port); for_each_present_cpu(cpu) { port_pcpu = per_cpu_ptr(port->pcpu, cpu);