From patchwork Mon Jun 17 12:06:52 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kuo-Jung Su X-Patchwork-Id: 251824 X-Patchwork-Delegate: albert.aribaud@free.fr Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id F2EE62C00A0 for ; Mon, 17 Jun 2013 22:08:26 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id A1C444A1B5; Mon, 17 Jun 2013 14:08:24 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id REuuX1gCImBw; Mon, 17 Jun 2013 14:08:24 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B4D1C4A1CA; Mon, 17 Jun 2013 14:07:48 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 0D09F4A199 for ; Mon, 17 Jun 2013 14:07:39 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id b+H263nNht9c for ; Mon, 17 Jun 2013 14:07:33 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-pa0-f43.google.com (mail-pa0-f43.google.com [209.85.220.43]) by theia.denx.de (Postfix) with ESMTPS id 2F0014A170 for ; Mon, 17 Jun 2013 14:07:26 +0200 (CEST) Received: by mail-pa0-f43.google.com with SMTP id hz11so2808710pad.30 for ; Mon, 17 Jun 2013 05:07:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :in-reply-to:references; bh=4DswteaJlmrNxbbYK2iUSbAWGUZdn0I6u68BfQCxT4g=; b=oj2XAC6Y/45/pWLfpptWLiyukH7qfZZDNYr+L7ZUmxBCElw3GkV8ADyH01O8Dje0fx SAsUCzzn/RsxLzzUZL+3qUoMAktIWWf4z+4Pp/qfSfUaJ5ERsiGUfEMeI4ffUoKBsJhY WD2cBVQ2Fr/AeT7gkmyN+uq40j3n0xeiObmtgUG61b9Ndi1vljpCbKAgZyj8urYbExCE hegWl/kQBIuZeUKU9dzf53fJU662YGUkiSpnvQQQsMbCDZthvP2noC2s2m7M4FbRZvWp evXUKp+mu9KaNq+7OKDgWwJjlOiCS5+WtIyuP4wkQVNwqMqXWXX60l9Wpbr5kgoOUXq9 I46A== X-Received: by 10.68.134.40 with SMTP id ph8mr12578686pbb.177.1371470844738; Mon, 17 Jun 2013 05:07:24 -0700 (PDT) Received: from localhost.localdomain (114-35-170-161.HINET-IP.hinet.net. [114.35.170.161]) by mx.google.com with ESMTPSA id wt5sm13621839pbc.38.2013.06.17.05.07.22 for (version=TLSv1 cipher=DES-CBC3-SHA bits=168/168); Mon, 17 Jun 2013 05:07:24 -0700 (PDT) From: Kuo-Jung Su To: u-boot@lists.denx.de Date: Mon, 17 Jun 2013 20:06:52 +0800 Message-Id: <1371470824-3228-3-git-send-email-dantesu@gmail.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1371470824-3228-1-git-send-email-dantesu@gmail.com> References: <1371470824-3228-1-git-send-email-dantesu@gmail.com> In-Reply-To: <1364540788-13943-1-git-send-email-dantesu@gmail.com> References: <1364540788-13943-1-git-send-email-dantesu@gmail.com> Cc: Tom Rini , Kuo-Jung Su Subject: [U-Boot] [PATCH v5 02/14] net: ftgmac100: add MMU/D-cache support X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.11 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de From: Kuo-Jung Su 1. Dynamically allocate the tx/rx descriptors through dma_alloc_coherent(), instead of allocating at compile/link time. 2. Do not block on ftgmac100_send(), the packet has been copied to a safe buffer. Although it's a little bit slower, but the tx performance is never critical. 3. No matter if MMU/D-cache is on or off, this patch always depends on previous patch: arm: dma_alloc_coherent: malloc() -> memalign(). Because the FTGMAC100 expects the tx/rx descriptors are always be aligned to 16-bytes boundary. Signed-off-by: Kuo-Jung Su CC: Albert ARIBAUD CC: Joe Hershberger CC: Tom Rini --- Changes for v5: - Chain it back to Faraday A360/A369 patch series, because this strongly depends on patch to dma_alloc_coherent() at the Faraday A360/A369 patch series. Changes for v4: - Make it a separate patch, rather then a part of Faraday A36x patch series Changes for v3: - Coding Style cleanup Changes for v2: - Coding Style cleanup - Cleanup (Drop cosmetic patch) drivers/net/ftgmac100.c | 70 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 21 deletions(-) -- 1.7.9.5 diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c index 69ba57d..2dbb328 100644 --- a/drivers/net/ftgmac100.c +++ b/drivers/net/ftgmac100.c @@ -27,11 +27,13 @@ #include #include #include +#include #include #include "ftgmac100.h" #define ETH_ZLEN 60 +#define CFG_XBUF_SIZE 1536 /* RBSR - hw default init value is also 0x640 */ #define RBSR_DEFAULT_VALUE 0x640 @@ -40,8 +42,10 @@ #define PKTBUFSTX 4 /* must be power of 2 */ struct ftgmac100_data { - struct ftgmac100_txdes txdes[PKTBUFSTX]; - struct ftgmac100_rxdes rxdes[PKTBUFSRX]; + ulong txdes_dma; + struct ftgmac100_txdes *txdes; + ulong rxdes_dma; + struct ftgmac100_rxdes *rxdes; int tx_index; int rx_index; int phy_addr; @@ -375,13 +379,34 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd) { struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; struct ftgmac100_data *priv = dev->priv; - struct ftgmac100_txdes *txdes = priv->txdes; - struct ftgmac100_rxdes *rxdes = priv->rxdes; + struct ftgmac100_txdes *txdes; + struct ftgmac100_rxdes *rxdes; unsigned int maccr; + void *buf; int i; debug("%s()\n", __func__); + if (!priv->txdes) { + txdes = dma_alloc_coherent( + sizeof(*txdes) * PKTBUFSTX, &priv->txdes_dma); + if (!txdes) + panic("ftgmac100: out of memory\n"); + memset(txdes, 0, sizeof(*txdes) * PKTBUFSTX); + priv->txdes = txdes; + } + txdes = priv->txdes; + + if (!priv->rxdes) { + rxdes = dma_alloc_coherent( + sizeof(*rxdes) * PKTBUFSRX, &priv->rxdes_dma); + if (!rxdes) + panic("ftgmac100: out of memory\n"); + memset(rxdes, 0, sizeof(*rxdes) * PKTBUFSRX); + priv->rxdes = rxdes; + } + rxdes = priv->rxdes; + /* set the ethernet address */ ftgmac100_set_mac_from_env(dev); @@ -397,21 +422,31 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd) for (i = 0; i < PKTBUFSTX; i++) { /* TXBUF_BADR */ - txdes[i].txdes3 = 0; + if (!txdes[i].txdes2) { + buf = memalign(ARCH_DMA_MINALIGN, CFG_XBUF_SIZE); + if (!buf) + panic("ftgmac100: out of memory\n"); + txdes[i].txdes3 = virt_to_phys(buf); + txdes[i].txdes2 = (uint)buf; + } txdes[i].txdes1 = 0; } for (i = 0; i < PKTBUFSRX; i++) { /* RXBUF_BADR */ - rxdes[i].rxdes3 = (unsigned int)NetRxPackets[i]; + if (!rxdes[i].rxdes2) { + buf = NetRxPackets[i]; + rxdes[i].rxdes3 = virt_to_phys(buf); + rxdes[i].rxdes2 = (uint)buf; + } rxdes[i].rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY; } /* transmit ring */ - writel((unsigned int)txdes, &ftgmac100->txr_badr); + writel(priv->txdes_dma, &ftgmac100->txr_badr); /* receive ring */ - writel((unsigned int)rxdes, &ftgmac100->rxr_badr); + writel(priv->rxdes_dma, &ftgmac100->rxr_badr); /* poll receive descriptor automatically */ writel(FTGMAC100_APTC_RXPOLL_CNT(1), &ftgmac100->aptc); @@ -466,8 +501,11 @@ static int ftgmac100_recv(struct eth_device *dev) debug("%s(): RX buffer %d, %x received\n", __func__, priv->rx_index, rxlen); + /* invalidate d-cache */ + dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE); + /* pass the packet up to the protocol layers. */ - NetReceive((void *)curr_des->rxdes3, rxlen); + NetReceive((void *)curr_des->rxdes2, rxlen); /* release buffer to DMA */ curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY; @@ -485,7 +523,6 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length) struct ftgmac100 *ftgmac100 = (struct ftgmac100 *)dev->iobase; struct ftgmac100_data *priv = dev->priv; struct ftgmac100_txdes *curr_des = &priv->txdes[priv->tx_index]; - int start; if (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) { debug("%s(): no TX descriptor available\n", __func__); @@ -496,8 +533,8 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length) length = (length < ETH_ZLEN) ? ETH_ZLEN : length; - /* initiate a transmit sequence */ - curr_des->txdes3 = (unsigned int)packet; /* TXBUF_BADR */ + memcpy((void *)curr_des->txdes2, (void *)packet, length); + dma_map_single((void *)curr_des->txdes2, length, DMA_TO_DEVICE); /* only one descriptor on TXBUF */ curr_des->txdes0 &= FTGMAC100_TXDES0_EDOTR; @@ -509,15 +546,6 @@ static int ftgmac100_send(struct eth_device *dev, void *packet, int length) /* start transmit */ writel(1, &ftgmac100->txpd); - /* wait for transfer to succeed */ - start = get_timer(0); - while (curr_des->txdes0 & FTGMAC100_TXDES0_TXDMA_OWN) { - if (get_timer(0) >= 5) { - debug("%s(): timed out\n", __func__); - return -1; - } - } - debug("%s(): packet sent\n", __func__); priv->tx_index = (priv->tx_index + 1) % PKTBUFSTX;