From patchwork Mon Jul 13 10:05:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Ferre X-Patchwork-Id: 11659285 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9B194618 for ; Mon, 13 Jul 2020 10:07:30 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 65B8020758 for ; Mon, 13 Jul 2020 10:07:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="RcD5rQgb"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="pdaD6yei" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 65B8020758 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=microchip.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=sPds1eJ4Z6heC25hmtSAo/j7Rq0Snypo6n8iME3hOSM=; b=RcD5rQgbDiYv9N3sFB3dIrVgF xO9CMYUFGODEjyVcazczLLSIwGyR51wXHipPiPQDDzaA3V+c5xY0B1t9pbL3EhLhKEUoEZwBlHi4T 2jtDurzy//hACHPufRxlbWEi1jtP3sLYQNGlhmBd+CKVPOeEArmWliBpw6b/Ya8dIJFVqOq/LREbL DRQFTPd6YMo2OUPQmuLLAB7zDv0+h+W0uDWOkpB1pPfkCMtj+LXU3QolIi0LpmQP0V8KGPvMIYf+Z ZQVJcQv/4RygL0xb8S8a16JFZ70VCZfJghH8bOIXZchYMzWo1UwSSBJyphsEDwTJnUsyuCINk4l5H FVzbY/LiA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1juvLX-0004vi-VX; Mon, 13 Jul 2020 10:06:04 +0000 Received: from esa6.microchip.iphmx.com ([216.71.154.253]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1juvLN-0004r4-KD for linux-arm-kernel@lists.infradead.org; Mon, 13 Jul 2020 10:05:57 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1594634753; x=1626170753; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=j4fbE/Ra2zunqbefrRtifT/kkezAH7ZZwuMWC07541Y=; b=pdaD6yei1ZOhP5kLFrgIItTxdosJw8Wl1DriU5j9R6S1NKvqIsZFXQ1a hVCEcUeDR1eqncyYFrRpw35gJhyssd1GSSh2Yex0bk2wa2TQlilcN+dfI 9es1bMGN+5gN5Wqu1reDKvr1/dXJYaYnP8VUTlh6I0QpMVDtG4KJOZDVt 34+0R1jY5f1RuW0chPcK9//41ow+Dv1Xu9b3Sxvxog3Zu7CLPY0LGB3sq 1s03s01E1oUFeI6qhV0L9kiUC/6LySuKbaNApfMOdcoW3nCQ3WTx8fqFX M5aQKYoFsgFOoIEhNZqpouwrXjoWy446S54xIenrJQ4jBFXTgYz15xuZY Q==; IronPort-SDR: TfWC43o5Onk8BgX+tKI0ThUZCT8mtd/M6nsD1BxQBqG2ncByKDRTqeM38/X72u+2deAm54zDYE zQ/hr0qDoC67p85s3W1sNF13jgcpkNp3Hg9si4rHsb1m97r1R5Q1fgDAXT20qDI+3b2UMD9OQ8 zs50t174y6wYlRcamsutyzCgGj1dYDWXCAzbz4HLFicB4KVub9mqf4vYZ1/NmJSa0GQ+aSW6QT Frc+VZLZdJiUU0TiPaFeK1WvRekrqgQCqMdKD6Eyr4BOb3aptTkGD8y60LlazkXekyWfC+/+I2 eiI= X-IronPort-AV: E=Sophos;i="5.75,347,1589266800"; d="scan'208";a="18953335" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa6.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Jul 2020 03:05:52 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex03.mchp-main.com (10.10.85.151) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Mon, 13 Jul 2020 03:05:50 -0700 Received: from ness.mchp-main.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Mon, 13 Jul 2020 03:05:16 -0700 From: To: , , , Claudiu Beznea , , Subject: [PATCH v6 1/2] net: macb: WoL support for GEM type of Ethernet controller Date: Mon, 13 Jul 2020 12:05:25 +0200 Message-ID: <1e40c4277d85b2ae23c8baca6f75ad25dbd35446.1594632220.git.nicolas.ferre@microchip.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200713_060553_863888_C522107A X-CRM114-Status: GOOD ( 21.15 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [216.71.154.253 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [216.71.154.253 listed in wl.mailspike.net] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: antoine.tenart@bootlin.com, Alexandre Belloni , linux-kernel@vger.kernel.org, "David S. Miller" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Nicolas Ferre Adapt the Wake-on-Lan feature to the Cadence GEM Ethernet controller. This controller has different register layout and cannot be handled by previous code. We disable completely interrupts on all the queues but the queue 0. Handling of WoL interrupt is done in another interrupt handler positioned depending on the controller version used, just between suspend() and resume() calls. It allows to lower pressure on the generic interrupt hot path by removing the need to handle 2 tests for each IRQ: the first figuring out the controller revision, the second for actually knowing if the WoL bit is set. Queue management in suspend()/resume() functions inspired from RFC patch by Harini Katakam , thanks! Cc: Claudiu Beznea Cc: Harini Katakam Signed-off-by: Nicolas Ferre --- Changes in v6: - Values of registers usrio and scrt2 properly read in any case (WoL or not) during macb_suspend() to be restored during macb_resume() Changes in v3: - In macb_resume(), move to a more in-depth re-configuration of the controller even on the non-WoL path in order to accept deeper sleep states. - this ends up having a phylink_stop()/phylink_start() for each of the WoL/!WoL paths - In macb_resume(), keep setting the MPE bit in NCR register which is needed in case of deep power saving mode used - Tests done in "standby" as well as our deeper Power Management mode: Backup Self-Refresh (BSR) Changes in v2: - Addition of pm_wakeup_event() in WoL IRQ - In macb_resume(), removal of setting the MPE bit in NCR register which is not needed in any case: IP is reset on the usual path and kept alive if WoL is used - In macb_resume(), complete reset of the controller is kept only for non-WoL case. For the WoL case, we only replace the usual IRQ handler. drivers/net/ethernet/cadence/macb.h | 3 + drivers/net/ethernet/cadence/macb_main.c | 151 +++++++++++++++++++---- 2 files changed, 127 insertions(+), 27 deletions(-) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index ab827fb4b6b9..4f1b41569260 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -90,6 +90,7 @@ #define GEM_SA3T 0x009C /* Specific3 Top */ #define GEM_SA4B 0x00A0 /* Specific4 Bottom */ #define GEM_SA4T 0x00A4 /* Specific4 Top */ +#define GEM_WOL 0x00b8 /* Wake on LAN */ #define GEM_EFTSH 0x00e8 /* PTP Event Frame Transmitted Seconds Register 47:32 */ #define GEM_EFRSH 0x00ec /* PTP Event Frame Received Seconds Register 47:32 */ #define GEM_PEFTSH 0x00f0 /* PTP Peer Event Frame Transmitted Seconds Register 47:32 */ @@ -396,6 +397,8 @@ #define MACB_PDRSFT_SIZE 1 #define MACB_SRI_OFFSET 26 /* TSU Seconds Register Increment */ #define MACB_SRI_SIZE 1 +#define GEM_WOL_OFFSET 28 /* Enable wake-on-lan interrupt */ +#define GEM_WOL_SIZE 1 /* Timer increment fields */ #define MACB_TI_CNS_OFFSET 0 diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index e5e37aa81b02..122c54e40f91 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -1517,6 +1517,35 @@ static void macb_tx_restart(struct macb_queue *queue) macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); } +static irqreturn_t gem_wol_interrupt(int irq, void *dev_id) +{ + struct macb_queue *queue = dev_id; + struct macb *bp = queue->bp; + u32 status; + + status = queue_readl(queue, ISR); + + if (unlikely(!status)) + return IRQ_NONE; + + spin_lock(&bp->lock); + + if (status & GEM_BIT(WOL)) { + queue_writel(queue, IDR, GEM_BIT(WOL)); + gem_writel(bp, WOL, 0); + netdev_vdbg(bp->dev, "GEM WoL: queue = %u, isr = 0x%08lx\n", + (unsigned int)(queue - bp->queues), + (unsigned long)status); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, GEM_BIT(WOL)); + pm_wakeup_event(&bp->pdev->dev, 0); + } + + spin_unlock(&bp->lock); + + return IRQ_HANDLED; +} + static irqreturn_t macb_interrupt(int irq, void *dev_id) { struct macb_queue *queue = dev_id; @@ -3316,6 +3345,8 @@ static const struct ethtool_ops macb_ethtool_ops = { static const struct ethtool_ops gem_ethtool_ops = { .get_regs_len = macb_get_regs_len, .get_regs = macb_get_regs, + .get_wol = macb_get_wol, + .set_wol = macb_set_wol, .get_link = ethtool_op_get_link, .get_ts_info = macb_get_ts_info, .get_ethtool_stats = gem_get_ethtool_stats, @@ -4567,33 +4598,67 @@ static int __maybe_unused macb_suspend(struct device *dev) struct macb_queue *queue = bp->queues; unsigned long flags; unsigned int q; + int err; if (!netif_running(netdev)) return 0; if (bp->wol & MACB_WOL_ENABLED) { - macb_writel(bp, IER, MACB_BIT(WOL)); - macb_writel(bp, WOL, MACB_BIT(MAG)); - enable_irq_wake(bp->queues[0].irq); - netif_device_detach(netdev); - } else { - netif_device_detach(netdev); + spin_lock_irqsave(&bp->lock, flags); + /* Flush all status bits */ + macb_writel(bp, TSR, -1); + macb_writel(bp, RSR, -1); for (q = 0, queue = bp->queues; q < bp->num_queues; - ++q, ++queue) - napi_disable(&queue->napi); + ++q, ++queue) { + /* Disable all interrupts */ + queue_writel(queue, IDR, -1); + queue_readl(queue, ISR); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, -1); + } + /* Change interrupt handler and + * Enable WoL IRQ on queue 0 + */ + if (macb_is_gem(bp)) { + devm_free_irq(dev, bp->queues[0].irq, bp->queues); + err = devm_request_irq(dev, bp->queues[0].irq, gem_wol_interrupt, + IRQF_SHARED, netdev->name, bp->queues); + if (err) { + dev_err(dev, + "Unable to request IRQ %d (error %d)\n", + bp->queues[0].irq, err); + return err; + } + queue_writel(bp->queues, IER, GEM_BIT(WOL)); + gem_writel(bp, WOL, MACB_BIT(MAG)); + } else { + queue_writel(bp->queues, IER, MACB_BIT(WOL)); + macb_writel(bp, WOL, MACB_BIT(MAG)); + } + spin_unlock_irqrestore(&bp->lock, flags); + + enable_irq_wake(bp->queues[0].irq); + } + + netif_device_detach(netdev); + for (q = 0, queue = bp->queues; q < bp->num_queues; + ++q, ++queue) + napi_disable(&queue->napi); + + if (!(bp->wol & MACB_WOL_ENABLED)) { rtnl_lock(); phylink_stop(bp->phylink); rtnl_unlock(); spin_lock_irqsave(&bp->lock, flags); macb_reset_hw(bp); spin_unlock_irqrestore(&bp->lock, flags); + } - if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) - bp->pm_data.usrio = macb_or_gem_readl(bp, USRIO); + if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) + bp->pm_data.usrio = macb_or_gem_readl(bp, USRIO); - if (netdev->hw_features & NETIF_F_NTUPLE) - bp->pm_data.scrt2 = gem_readl_n(bp, ETHT, SCRT2_ETHT); - } + if (netdev->hw_features & NETIF_F_NTUPLE) + bp->pm_data.scrt2 = gem_readl_n(bp, ETHT, SCRT2_ETHT); if (bp->ptp_info) bp->ptp_info->ptp_remove(netdev); @@ -4608,7 +4673,9 @@ static int __maybe_unused macb_resume(struct device *dev) struct net_device *netdev = dev_get_drvdata(dev); struct macb *bp = netdev_priv(netdev); struct macb_queue *queue = bp->queues; + unsigned long flags; unsigned int q; + int err; if (!netif_running(netdev)) return 0; @@ -4617,29 +4684,59 @@ static int __maybe_unused macb_resume(struct device *dev) pm_runtime_force_resume(dev); if (bp->wol & MACB_WOL_ENABLED) { - macb_writel(bp, IDR, MACB_BIT(WOL)); - macb_writel(bp, WOL, 0); - disable_irq_wake(bp->queues[0].irq); - } else { - macb_writel(bp, NCR, MACB_BIT(MPE)); - - if (netdev->hw_features & NETIF_F_NTUPLE) - gem_writel_n(bp, ETHT, SCRT2_ETHT, bp->pm_data.scrt2); + spin_lock_irqsave(&bp->lock, flags); + /* Disable WoL */ + if (macb_is_gem(bp)) { + queue_writel(bp->queues, IDR, GEM_BIT(WOL)); + gem_writel(bp, WOL, 0); + } else { + queue_writel(bp->queues, IDR, MACB_BIT(WOL)); + macb_writel(bp, WOL, 0); + } + /* Clear ISR on queue 0 */ + queue_readl(bp->queues, ISR); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(bp->queues, ISR, -1); + /* Replace interrupt handler on queue 0 */ + devm_free_irq(dev, bp->queues[0].irq, bp->queues); + err = devm_request_irq(dev, bp->queues[0].irq, macb_interrupt, + IRQF_SHARED, netdev->name, bp->queues); + if (err) { + dev_err(dev, + "Unable to request IRQ %d (error %d)\n", + bp->queues[0].irq, err); + return err; + } + spin_unlock_irqrestore(&bp->lock, flags); - if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) - macb_or_gem_writel(bp, USRIO, bp->pm_data.usrio); + disable_irq_wake(bp->queues[0].irq); - for (q = 0, queue = bp->queues; q < bp->num_queues; - ++q, ++queue) - napi_enable(&queue->napi); + /* Now make sure we disable phy before moving + * to common restore path + */ rtnl_lock(); - phylink_start(bp->phylink); + phylink_stop(bp->phylink); rtnl_unlock(); } + for (q = 0, queue = bp->queues; q < bp->num_queues; + ++q, ++queue) + napi_enable(&queue->napi); + + if (netdev->hw_features & NETIF_F_NTUPLE) + gem_writel_n(bp, ETHT, SCRT2_ETHT, bp->pm_data.scrt2); + + if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) + macb_or_gem_writel(bp, USRIO, bp->pm_data.usrio); + + macb_writel(bp, NCR, MACB_BIT(MPE)); macb_init_hw(bp); macb_set_rx_mode(netdev); macb_restore_features(bp); + rtnl_lock(); + phylink_start(bp->phylink); + rtnl_unlock(); + netif_device_attach(netdev); if (bp->ptp_info) bp->ptp_info->ptp_init(netdev); From patchwork Mon Jul 13 10:05:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Ferre X-Patchwork-Id: 11659287 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A125214DD for ; Mon, 13 Jul 2020 10:07:36 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (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 7966320758 for ; Mon, 13 Jul 2020 10:07:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="BX9Mhurl"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=microchip.com header.i=@microchip.com header.b="vETzbyst" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7966320758 Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=microchip.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Message-ID:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=/JfiawrHlt0fEsbVKTqR22UMijlw4o88k1g+bpT27+Y=; b=BX9MhurllAmH61YpSnfZA0p1W qid8YrtUGucQH4CVOWyW3dcT0RsT70Wx3XpnYvq6II4EyCMMQ3WZ9aKmBrn32uPXQHFEfvYv26bm4 QKY9IqKdq+f/1+uejbCVmi1Jg34c+vCGFQDWTuULq2rsquKNEQ3nx48TPd1nUTeluGj4wV8ay74sj wbrsX0mQa7GqYoKZxu2qLN9+J2PsZkJxHwiJntkHpv0fMxYlLZdqY+Chvevjwdio8sEVJt8c5NiFp +wH4WejT9vl3CC49nkAX+csP486O4sOwkej86YCSn2FSGfVoFQr5Mf930edVw4p71w3ap9fKOjcVB eeHGKWY0A==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1juvLg-0004yw-Pw; Mon, 13 Jul 2020 10:06:12 +0000 Received: from esa3.microchip.iphmx.com ([68.232.153.233]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1juvLQ-0004rx-4t for linux-arm-kernel@lists.infradead.org; Mon, 13 Jul 2020 10:05:59 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=microchip.com; i=@microchip.com; q=dns/txt; s=mchp; t=1594634756; x=1626170756; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hLiX2KG4+VIakkYAPr8xr4TUGHwNKNbA6nO7XcPJS9U=; b=vETzbyst5AI+y1ouVBEZtA533WRD68sDDaVyOsYnMzBkd6Vya/B2yAWW UE0S0QAaazN953mgqSpjeiz7YnRgDYQPFWMaqtHKkhQXRa6vWoQGZK6/s iyVYAAkFQ2isb45xxqlh3jKavExFiJsou+RLBozx50rOHCkfIUrNTulSc iHqNglvlXlp2XXCl2aI3upq6JKsiahHT8xEguvsjVdyKi9s9XVOSpGlQa mixnMlu/GvmtBW5t6wYl7UpYbDQ6I2WAuwkX/hbafh2Xd4d5AVjFk/BM6 ZtdahdattRVXyOqeYmWqFACZZ0ySgpMAXkrJXlca3FUkjNwZH6bmq5b3S g==; IronPort-SDR: od+NZlvGvnFMjX6RAp905k+qDGMf8/EoN6TT6Ug4+PZIWHyiWn76rCCST3edWqOtQEGDRanGI5 BVs46jt979G0FEj+Z5sIRth8ybil5AjHzR8t3695xaXDkjVgJ5cbss/LbHcnhxL2zzj1Uj0vQh wabW07+f7Hdbj8FL1oRavR4bw4ujZUCKkXOZ5T6h351VU/LDq3ipHeaQKBWX90TaocVBbaUtZg tgZwppTNSMD8gAG5t6Nhl+UY88W+wU1qWaOlo3tVroER4t6yXq+yLEAv4iVhpB1jsiwQaqajIu +GI= X-IronPort-AV: E=Sophos;i="5.75,347,1589266800"; d="scan'208";a="83591191" Received: from smtpout.microchip.com (HELO email.microchip.com) ([198.175.253.82]) by esa3.microchip.iphmx.com with ESMTP/TLS/AES256-SHA256; 13 Jul 2020 03:05:54 -0700 Received: from chn-vm-ex02.mchp-main.com (10.10.85.144) by chn-vm-ex01.mchp-main.com (10.10.85.143) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1979.3; Mon, 13 Jul 2020 03:05:23 -0700 Received: from ness.mchp-main.com (10.10.115.15) by chn-vm-ex02.mchp-main.com (10.10.85.144) with Microsoft SMTP Server id 15.1.1979.3 via Frontend Transport; Mon, 13 Jul 2020 03:05:20 -0700 From: To: , , , Claudiu Beznea , , Subject: [PATCH v6 2/2] net: macb: Add WoL interrupt support for MACB type of Ethernet controller Date: Mon, 13 Jul 2020 12:05:26 +0200 Message-ID: <33ae0b5ae31ae9a97f6fbbebcab23f777937d89d.1594632220.git.nicolas.ferre@microchip.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: References: MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200713_060556_411308_D4BF6515 X-CRM114-Status: GOOD ( 12.76 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.4 on merlin.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [68.232.153.233 listed in list.dnswl.org] -0.0 RCVD_IN_MSPIKE_H4 RBL: Very Good reputation (+4) [68.232.153.233 listed in wl.mailspike.net] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 RCVD_IN_MSPIKE_WL Mailspike good senders X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: antoine.tenart@bootlin.com, Alexandre Belloni , linux-kernel@vger.kernel.org, "David S. Miller" Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org From: Nicolas Ferre Handle the Wake-on-Lan interrupt for the Cadence MACB Ethernet controller. As we do for the GEM version, we handle of WoL interrupt in a specialized interrupt handler for MACB version that is positionned just between suspend() and resume() calls. Cc: Claudiu Beznea Cc: Harini Katakam Signed-off-by: Nicolas Ferre --- Changes in v2: - Addition of pm_wakeup_event() in WoL IRQ drivers/net/ethernet/cadence/macb_main.c | 39 +++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 122c54e40f91..fce5d545ebab 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -1517,6 +1517,35 @@ static void macb_tx_restart(struct macb_queue *queue) macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART)); } +static irqreturn_t macb_wol_interrupt(int irq, void *dev_id) +{ + struct macb_queue *queue = dev_id; + struct macb *bp = queue->bp; + u32 status; + + status = queue_readl(queue, ISR); + + if (unlikely(!status)) + return IRQ_NONE; + + spin_lock(&bp->lock); + + if (status & MACB_BIT(WOL)) { + queue_writel(queue, IDR, MACB_BIT(WOL)); + macb_writel(bp, WOL, 0); + netdev_vdbg(bp->dev, "MACB WoL: queue = %u, isr = 0x%08lx\n", + (unsigned int)(queue - bp->queues), + (unsigned long)status); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, MACB_BIT(WOL)); + pm_wakeup_event(&bp->pdev->dev, 0); + } + + spin_unlock(&bp->lock); + + return IRQ_HANDLED; +} + static irqreturn_t gem_wol_interrupt(int irq, void *dev_id) { struct macb_queue *queue = dev_id; @@ -4619,8 +4648,8 @@ static int __maybe_unused macb_suspend(struct device *dev) /* Change interrupt handler and * Enable WoL IRQ on queue 0 */ + devm_free_irq(dev, bp->queues[0].irq, bp->queues); if (macb_is_gem(bp)) { - devm_free_irq(dev, bp->queues[0].irq, bp->queues); err = devm_request_irq(dev, bp->queues[0].irq, gem_wol_interrupt, IRQF_SHARED, netdev->name, bp->queues); if (err) { @@ -4632,6 +4661,14 @@ static int __maybe_unused macb_suspend(struct device *dev) queue_writel(bp->queues, IER, GEM_BIT(WOL)); gem_writel(bp, WOL, MACB_BIT(MAG)); } else { + err = devm_request_irq(dev, bp->queues[0].irq, macb_wol_interrupt, + IRQF_SHARED, netdev->name, bp->queues); + if (err) { + dev_err(dev, + "Unable to request IRQ %d (error %d)\n", + bp->queues[0].irq, err); + return err; + } queue_writel(bp->queues, IER, MACB_BIT(WOL)); macb_writel(bp, WOL, MACB_BIT(MAG)); }