From patchwork Wed Mar 19 05:32:40 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Byungho An X-Patchwork-Id: 26534 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-ie0-f200.google.com (mail-ie0-f200.google.com [209.85.223.200]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 07B5C203C3 for ; Wed, 19 Mar 2014 05:33:36 +0000 (UTC) Received: by mail-ie0-f200.google.com with SMTP id lx4sf28925575iec.7 for ; Tue, 18 Mar 2014 22:33:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:cc:subject:date:message-id :mime-version:thread-index:dlp-filter:sender:precedence:list-id :x-original-sender:x-original-authentication-results:mailing-list :list-post:list-help:list-archive:list-unsubscribe:content-type :content-transfer-encoding:content-language; bh=XNVmaIgwsaXQRka2NuNVwYnjURDyswsZsjmjBgGdp78=; b=Tqa60EmIbPeJhI6G/naC4XDyifG3ip/13RlvvlV45dYdZtakqn9KLEuwwXz2tq0lc0 2A2uLzcb6sb0oTVaZ42yPER1iDpvEUUWNZp21deq0aS7YUWOEjEmTs32ytEJs2Hc05oU rUetKhHhQ2ZoPRoQt6Rzd1STmM+PjQd51L3FspooUYkPlObiEVf9G/jskg0AiV7r2pwo sxuAM6CVvRjlsoX81avIKNuuKcCah9raE1PIVaSFWducc9AqAznGXxuKzeHO01GbQJY8 +8uIGc8qj2eFaD7rGL1Yw70CCgvbJwieqAFD/4FyY9ySB7jamQCaYagiXXCCC/Zm5kSU o2aA== X-Gm-Message-State: ALoCoQkDNkYWaYh9DTt7jrlybNn154TvjetKgbxbdRpHoj2PgzvXp+sSpdG0+2tetUa6A038u8Hf X-Received: by 10.43.18.133 with SMTP id qg5mr12176327icb.13.1395207216487; Tue, 18 Mar 2014 22:33:36 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.140.87.33 with SMTP id q30ls2311410qgd.99.gmail; Tue, 18 Mar 2014 22:33:36 -0700 (PDT) X-Received: by 10.53.1.69 with SMTP id be5mr9469229vdd.27.1395207216318; Tue, 18 Mar 2014 22:33:36 -0700 (PDT) Received: from mail-vc0-f181.google.com (mail-vc0-f181.google.com [209.85.220.181]) by mx.google.com with ESMTPS id gq1si4195146vec.77.2014.03.18.22.33.36 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Tue, 18 Mar 2014 22:33:36 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.220.181 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) client-ip=209.85.220.181; Received: by mail-vc0-f181.google.com with SMTP id id10so8354433vcb.26 for ; Tue, 18 Mar 2014 22:33:36 -0700 (PDT) X-Received: by 10.58.122.164 with SMTP id lt4mr28328319veb.2.1395207216089; Tue, 18 Mar 2014 22:33:36 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.220.78.9 with SMTP id i9csp270805vck; Tue, 18 Mar 2014 22:33:35 -0700 (PDT) X-Received: by 10.68.34.197 with SMTP id b5mr37360478pbj.16.1395207214982; Tue, 18 Mar 2014 22:33:34 -0700 (PDT) Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id zt8si12474739pbc.135.2014.03.18.22.33.34; Tue, 18 Mar 2014 22:33:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of devicetree-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752406AbaCSFdc (ORCPT + 9 others); Wed, 19 Mar 2014 01:33:32 -0400 Received: from mailout4.samsung.com ([203.254.224.34]:55635 "EHLO mailout4.samsung.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752223AbaCSFc4 (ORCPT ); Wed, 19 Mar 2014 01:32:56 -0400 Received: from epcpsbgr1.samsung.com (u141.gpu120.samsung.co.kr [203.254.230.141]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0N2O00B7V4QVED80@mailout4.samsung.com>; Wed, 19 Mar 2014 14:32:55 +0900 (KST) Received: from epcpsbgm2.samsung.com ( [203.254.230.48]) by epcpsbgr1.samsung.com (EPCPMTA) with SMTP id D2.F3.12635.50C29235; Wed, 19 Mar 2014 14:32:53 +0900 (KST) X-AuditID: cbfee68d-b7fcd6d00000315b-0b-53292c0506ff Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 71.2E.28157.50C29235; Wed, 19 Mar 2014 14:32:53 +0900 (KST) Received: from VISITOR1LAB ([105.128.19.10]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01 (7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0N2O00EQR4QBA710@mmp1.samsung.com>; Wed, 19 Mar 2014 14:32:53 +0900 (KST) From: Byungho An To: 'netdev' , linux-samsung-soc@vger.kernel.org, devicetree@vger.kernel.org Cc: 'David Miller' , "'ks.giri'" , "'siva.kallam'" , "'vipul.pandya'" , "'ilho215.lee'" Subject: [PATCH V6 6/8] net: sxgbe: add WOL(Wakeup-On-Lan)support for Samsung sxgbe Date: Tue, 18 Mar 2014 22:32:40 -0700 Message-id: <006401cf4334$ab308d80$0191a880$@samsung.com> MIME-version: 1.0 X-Mailer: Microsoft Outlook 14.0 Thread-index: Ac9DNCPEsLc9dpvLQ9qufq28A0+1VQ== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrKIsWRmVeSWpSXmKPExsVy+t8zA11WHc1gg7d7NSzmnG9hsZh/5Byr xdF/Cxkt5h/dwWQx4/w+JotjC8QsVjRtZbTYtuACswOHx5aVN5k8+rasYvT4vEkugDmKyyYl NSezLLVI3y6BK+Pcrh9sBQvTK9ZM/cHSwHglrIuRg0NCwESi7wuQyQlkiklcuLeerYuRi0NI YBmjRMu8rSwQCROJDzePMEIkFjFKNJ7pYodw/jBKHDh8nRmkik1ATaJ55mU2EFtEIE1i96U9 zCBFzAJXGCVWnp4AViQsECpxedZLsCIWAVWJebe2MIHYvAKWEpee7meGsAUlfky+B7aaWUBL Yv3O40wQtrzE5jVvmSFOUpDYcfY1I8QyPYnnp1exQtSIS0x68BDsOgmBU+wS33puM0MsE5D4 NvkQC8TPshKbDkDNkZQ4uOIGywRGsVlIVs9CsnoWktWzkKxYwMiyilE0tSC5oDgpvchQrzgx t7g0L10vOT93EyMkCnt3MN4+YH2IMRlo/URmKdHkfGAU55XEGxqbGVmYmpgaG5lbmpEmrCTO m/QwKUhIID2xJDU7NbUgtSi+qDQntfgQIxMHp1QDowSz83K1+gdxp9XYXQ9IP2lUU30Qc2zX 3a1nvnTO2u9Q/1o+mO3688MdfOuY9uhVHui48X7mz28P5q6xdmfyM7vSr6NQqP9NIZLrYI34 BK5/q+KfPiq8GsHCFFCt2KmUctH106y/t/49vs/m1H7P/nZ4s1/gt28/Hl3g+vEx+M2bxLQb 7XwFy5RYijMSDbWYi4oTAXw4jinYAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrMKsWRmVeSWpSXmKPExsVy+t9jAV1WHc1gg09HFC3mnG9hsZh/5Byr xdF/Cxkt5h/dwWQx4/w+JotjC8QsVjRtZbTYtuACswOHx5aVN5k8+rasYvT4vEkugDmqgdEm IzUxJbVIITUvOT8lMy/dVsk7ON453tTMwFDX0NLCXEkhLzE31VbJxSdA1y0zB+gCJYWyxJxS oFBAYnGxkr4dpgmhIW66FjCNEbq+IUFwPUYGaCBhHWPGuV0/2AoWplesmfqDpYHxSlgXIyeH hICJxIebRxghbDGJC/fWs3UxcnEICSxilGg808UO4fxhlDhw+DozSBWbgJpE88zLbCC2iECa xO5Le5hBipgFrjBKrDw9AaxIWCBU4vKsl2BFLAKqEvNubWECsXkFLCUuPd3PDGELSvyYfI8F xGYW0JJYv/M4E4QtL7F5zVtmiJMUJHacfc0IsUxP4vnpVawQNeISkx48ZJ/AKDALyahZSEbN QjJqFpKWBYwsqxhFUwuSC4qT0nON9IoTc4tL89L1kvNzNzGCo/yZ9A7GVQ0WhxgFOBiVeHgP RGkEC7EmlhVX5h5ilOBgVhLhFb4LFOJNSaysSi3Kjy8qzUktPsSYDPTpRGYp0eR8YALKK4k3 NDYxM7I0MrMwMjE3J01YSZz3YKt1oJBAemJJanZqakFqEcwWJg5OqQbGaMaT2yN2yNsfaHrx RbbU7L3Qt4s2x74mvpA+tPioz/xHryqzD7CkajDaZe0rjdsYs29ZrHlUBHc81x6Pe/emlHy2 Ydf9x2OePiFnbd2h786rt3hvCrvL+71sw1ErRgbP/jdGLzhiLZ6s0A7WnG9ZJ8sa+jDpgcvr eOOSU4neXIU6Ci6xj2cqsRRnJBpqMRcVJwIA8HI6qDYDAAA= DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-CFilter-Loop: Reflected Sender: devicetree-owner@vger.kernel.org Precedence: list List-ID: X-Mailing-List: devicetree@vger.kernel.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: bh74.an@samsung.com X-Original-Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.220.181 is neither permitted nor denied by best guess record for domain of patch+caf_=patchwork-forward=linaro.org@linaro.org) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Post: , List-Help: , List-Archive: List-Unsubscribe: , Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7bit Content-language: en-us From: Girish K S This patch adds support for wake up on magic frame arrival. Also remote wake up on all other packets (unicast, multicast broadcast) is supported. Signed-off-by: Girish K S Neatening-by: Joe Perches Signed-off-by: Byungho An --- drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h | 15 +++++ drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c | 29 ++++++++ drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c | 47 +++++++++++++ drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 71 ++++++++++++++++++++ drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.c | 43 +++++++++++- drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.h | 4 ++ .../net/ethernet/samsung/sxgbe/sxgbe_platform.c | 4 ++ drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h | 3 + 8 files changed, 215 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h index 7937493..30adc81 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h @@ -121,9 +121,18 @@ struct sxgbe_mtl_ops; #define RX_ENTRY_LPI_MODE 0x40 #define RX_EXIT_LPI_MODE 0x80 +/* PMT mode bits */ +#define PMT_PWRDWN BIT(0) +#define PMT_MGPKT_EN BIT(1) +#define PMT_RWKPKT_EN BIT(2) +#define PMT_GUCAST_EN BIT(9) + /* EEE-LPI Interrupt status flag */ #define LPI_INT_STATUS BIT(5) +/* PMT Interrupt status */ +#define PMT_INT_STATUS BIT(4) + /* EEE-LPI Default timer values */ #define LPI_LINK_STATUS_TIMER 0x3E8 #define LPI_MAC_WAIT_TIMER 0x00 @@ -225,6 +234,7 @@ struct sxgbe_extra_stats { unsigned long rx_desc_access_err; unsigned long rx_buffer_access_err; unsigned long rx_data_transfer_err; + unsigned long pmt_irq_event_n; /* EEE-LPI stats */ unsigned long tx_lpi_entry_n; @@ -489,6 +499,11 @@ struct sxgbe_priv_data { int eee_enabled; int eee_active; int tx_lpi_timer; + + /* PM-WOL specific members */ + int wolopts; + int wolenabled; + int wol_irq; }; /* Function prototypes */ diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c index 5885fd6..334d196 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c @@ -78,12 +78,41 @@ static int sxgbe_core_host_irq_status(void __iomem *ioaddr, if (unlikely(irq_status & LPI_INT_STATUS)) status |= sxgbe_get_lpi_status(ioaddr, irq_status); + if (unlikely(irq_status & PMT_INT_STATUS)) { + /* clear the PMT bits 5 and 6 by reading the PMT status reg */ + readl(ioaddr + SXGBE_CORE_PMT_CTL_STATUS_REG); + x->pmt_irq_event_n++; + } + return status; } /* Set power management mode (e.g. magic frame) */ static void sxgbe_core_pmt(void __iomem *ioaddr, unsigned long mode) { + unsigned int pmt = 0; + + if (mode & WAKE_MAGIC) { + pr_debug("WOL Magic frame\n"); + pmt |= PMT_MGPKT_EN; + } + if (mode & WAKE_UCAST) { + pr_debug("WOL on global unicast\n"); + pmt |= PMT_GUCAST_EN; + } + if (mode & (WAKE_MCAST | WAKE_BCAST)) { + pr_debug("WOL on any other packet\n"); + pmt |= PMT_RWKPKT_EN; + } + + writel(pmt, ioaddr + SXGBE_CORE_PMT_CTL_STATUS_REG); + + /* Enable power down bit if any of the requested mode is enabled */ + if (pmt) { + writel(SXGBE_RX_ENABLE, ioaddr + SXGBE_CORE_RX_CONFIG_REG); + pmt |= PMT_PWRDWN; + writel(pmt, ioaddr + SXGBE_CORE_PMT_CTL_STATUS_REG); + } } /* Set/Get Unicast MAC addresses */ diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c index 9083300..89b1450 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_ethtool.c @@ -12,6 +12,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include #include #include #include @@ -37,6 +38,7 @@ static const struct sxgbe_stats sxgbe_gstrings_stats[] = { SXGBE_STAT(rx_lpi_entry_n), SXGBE_STAT(rx_lpi_exit_n), SXGBE_STAT(eee_wakeup_error_n), + SXGBE_STAT(pmt_irq_event_n), }; #define SXGBE_STATS_LEN ARRAY_SIZE(sxgbe_gstrings_stats) @@ -80,9 +82,54 @@ static int sxgbe_ethtool_set_eee(struct net_device *dev, return phy_ethtool_set_eee(priv->phydev, edata); } +static void sxgbe_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct sxgbe_priv_data *priv = netdev_priv(dev); + + wol->wolopts = 0; + if (!device_can_wakeup(priv->device)) { + dev_err(priv->device, "cannot wakeup device\n"); + return; + } + + if (priv->hw_cap.pmt_magic_frame) + wol->supported |= WAKE_MAGIC; + + if (priv->hw_cap.pmt_remote_wake_up) + wol->supported |= (WAKE_UCAST | WAKE_MCAST | WAKE_BCAST); + + wol->wolopts = priv->wolopts; +} + +static int sxgbe_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol) +{ + struct sxgbe_priv_data *priv = netdev_priv(dev); + + if (wol->wolopts & (WAKE_PHY | WAKE_ARP | WAKE_MAGICSECURE)) + return -EOPNOTSUPP; + + if (!device_can_wakeup(priv->device)) + return -EOPNOTSUPP; + + if (wol->wolopts) { + netdev_info(dev, "wakeup enable\n"); + device_set_wakeup_enable(priv->device, true); + enable_irq_wake(priv->wol_irq); + } else { + device_set_wakeup_enable(priv->device, false); + disable_irq_wake(priv->wol_irq); + } + + priv->wolopts = wol->wolopts; + + return 0; +} + static const struct ethtool_ops sxgbe_ethtool_ops = { .get_eee = sxgbe_ethtool_get_eee, .set_eee = sxgbe_ethtool_set_eee, + .get_wol = sxgbe_get_wol, + .set_wol = sxgbe_set_wol, }; void sxgbe_set_ethtool_ops(struct net_device *netdev) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index f0ee143..86a3f6d 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c @@ -1089,6 +1089,18 @@ static int sxgbe_open(struct net_device *dev) goto init_error; } + /* Request the Wake IRQ in case of another line is used for WoL */ + if (priv->wol_irq != dev->irq) { + ret = devm_request_irq(priv->device, priv->wol_irq, + sxgbe_common_interrupt, IRQF_SHARED, + dev->name, dev); + if (unlikely(ret < 0)) { + netdev_err(dev, "%s: ERROR: allocating the WoL IRQ %d (%d)\n", + __func__, priv->wol_irq, ret); + goto init_error; + } + } + /* If the LPI irq is different from the mac irq * register a dedicated handler */ @@ -2056,6 +2068,27 @@ static int sxgbe_hw_init(struct sxgbe_priv_data * const priv) return 0; } +static void sxgbe_set_pmt_capabilities(struct sxgbe_priv_data *priv) +{ + u32 ctrl; + + priv->wolopts = 0; + + ctrl = readl(priv->ioaddr + SXGBE_CORE_PMT_CTL_STATUS_REG); + /* Enable maagic packet reception */ + if (priv->hw_cap.pmt_magic_frame) { + priv->wolopts |= WAKE_MAGIC; + ctrl |= PMT_MGPKT_EN; + } + if (priv->hw_cap.pmt_remote_wake_up) { + priv->wolopts |= WAKE_UCAST | WAKE_MCAST | WAKE_BCAST; + ctrl |= (PMT_RWKPKT_EN | PMT_GUCAST_EN); + } + writel(ctrl, priv->ioaddr + SXGBE_CORE_PMT_CTL_STATUS_REG); + + device_init_wakeup(priv->device, true); +} + /** * sxgbe_dvr_probe * @device: device pointer @@ -2178,6 +2211,7 @@ struct sxgbe_priv_data *sxgbe_dvr_probe(struct device *device, goto error_netdev_register; } + sxgbe_set_pmt_capabilities(priv); sxgbe_check_ether_addr(priv); return priv; @@ -2226,11 +2260,48 @@ int sxgbe_dvr_remove(struct net_device *ndev) #ifdef CONFIG_PM int sxgbe_suspend(struct net_device *ndev) { + struct sxgbe_priv_data *priv = netdev_priv(ndev); + struct netdev_hw_addr *ha; + int queue_num = 0, reg = 0; + + /* Disable TX and wait till all frames flushed out */ + priv->hw->mac->enable_tx(priv->ioaddr, false); + sxgbe_tx_all_clean(priv); + SXGBE_FOR_EACH_QUEUE(SXGBE_TX_QUEUES, queue_num) + priv->hw->mtl->mtl_flush_txqueue(priv->ioaddr, queue_num); + + /* Disable RX and wait till all frames read into memory */ + priv->hw->mac->enable_rx(priv->ioaddr, false); + SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) + priv->hw->mtl->mtl_readout_rxqueue(priv->ioaddr, queue_num); + + /* Enable Power down mode by programming the PMT regs */ + if (device_may_wakeup(priv->device)) { + priv->hw->mac->pmt(priv->ioaddr, priv->wolopts); + } else { + netdev_for_each_uc_addr(ha, ndev) + priv->hw->mac->set_umac_addr(priv->ioaddr, ha->addr, + reg++); + /* Disable clock in case of PWM is off */ + clk_disable_unprepare(priv->sxgbe_clk); + } + return 0; } int sxgbe_resume(struct net_device *ndev) { + struct sxgbe_priv_data *priv = netdev_priv(ndev); + + if (device_may_wakeup(priv->device)) + priv->hw->mac->pmt(priv->ioaddr, 0); + else + /* enable the clk prevously disabled */ + clk_prepare_enable(priv->sxgbe_clk); + + priv->hw->mac->enable_rx(priv->ioaddr, true); + priv->hw->mac->enable_tx(priv->ioaddr, true); + return 0; } diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.c index d3ec6eb..6f6202c 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.c @@ -174,6 +174,45 @@ static void sxgbe_mtl_fup_disable(void __iomem *ioaddr, int queue_num) writel(reg_val, ioaddr + SXGBE_MTL_RXQ_OPMODE_REG(queue_num)); } +static int sxgbe_mtl_flush_txqueue(void __iomem *ioaddr, int queue_num) +{ + unsigned long timeout; + u32 reg_val; + + timeout = jiffies + msecs_to_jiffies(5); + + reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num)); + while ((reg_val & + (SXGBE_MTL_TXQ_EMPTY_STAT | SXGBE_MTL_TXQ_WRITE_STAT))) { + if (time_after(jiffies, timeout)) { + pr_err("cannot flush tx queue - timeout\n"); + return -ETIMEDOUT; + } + reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num)); + } + + return 0; +} + +static int sxgbe_mtl_readout_rxqueue(void __iomem *ioaddr, int queue_num) +{ + unsigned long timeout; + u32 reg_val; + + timeout = jiffies + msecs_to_jiffies(5); + + reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num)); + while ((reg_val & + (SXGBE_MTL_TXQ_EMPTY_STAT | SXGBE_MTL_TXQ_WRITE_STAT))) { + if (time_after(jiffies, timeout)) { + pr_err("cannot flush tx queue - timeout\n"); + return -ETIMEDOUT; + } + reg_val = readl(ioaddr + SXGBE_MTL_TXQ_OPMODE_REG(queue_num)); + } + + return 0; +} static void sxgbe_set_tx_mtl_mode(void __iomem *ioaddr, int queue_num, int tx_mode) @@ -243,7 +282,9 @@ static const struct sxgbe_mtl_ops mtl_ops = { .mtl_fep_enable = sxgbe_mtl_fep_enable, .mtl_fep_disable = sxgbe_mtl_fep_disable, .mtl_fup_enable = sxgbe_mtl_fup_enable, - .mtl_fup_disable = sxgbe_mtl_fup_disable + .mtl_fup_disable = sxgbe_mtl_fup_disable, + .mtl_flush_txqueue = sxgbe_mtl_flush_txqueue, + .mtl_readout_rxqueue = sxgbe_mtl_readout_rxqueue }; const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(void) diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.h index 7e4810c..b2f3f10 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mtl.h @@ -97,6 +97,10 @@ struct sxgbe_mtl_ops { void (*mtl_fup_enable)(void __iomem *ioaddr, int queue_num); void (*mtl_fup_disable)(void __iomem *ioaddr, int queue_num); + + int (*mtl_flush_txqueue)(void __iomem *ioaddr, int queue_num); + + int (*mtl_readout_rxqueue)(void __iomem *ioaddr, int queue_num); }; const struct sxgbe_mtl_ops *sxgbe_get_mtl_ops(void); diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c index b23ec57..482a6e4 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_platform.c @@ -164,6 +164,10 @@ static int sxgbe_platform_probe(struct platform_device *pdev) if (priv->lpi_irq == -ENXIO) priv->lpi_irq = priv->dev->irq; + priv->wol_irq = irq_of_parse_and_map(dev->of_node, loop++); + if (priv->wol_irq == -ENXIO) + priv->wol_irq = priv->dev->irq; + platform_set_drvdata(pdev, priv->dev); pr_debug("platform driver registration completed\n"); diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h index 85a7b31..bd85923 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h @@ -257,6 +257,9 @@ #define SXGBE_MTL_SFMODE BIT(1) #define SXGBE_MTL_FIFO_LSHIFT 16 #define SXGBE_MTL_ENABLE_QUEUE 0x00000008 +#define SXGBE_MTL_TXQ_EMPTY_STAT BIT(4) +#define SXGBE_MTL_TXQ_WRITE_STAT BIT(3) + #define SXGBE_MTL_TXQ_UNDERFLOW_REG(qnum) \ (SXGBE_MTL_TC_TXBASE_REG + (qnum * 0x80) + 0x04) #define SXGBE_MTL_TXQ_DEBUG_REG(qnum) \