From patchwork Fri Oct 4 16:13:53 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Claudiu Manoil X-Patchwork-Id: 280664 X-Patchwork-Delegate: joe.hershberger@gmail.com 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 AC25C2C009A for ; Sat, 5 Oct 2013 02:18:56 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B1E954A0C2; Fri, 4 Oct 2013 18:18:52 +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 x+HzCZ5kJGVo; Fri, 4 Oct 2013 18:18:52 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2FA4B4A0C3; Fri, 4 Oct 2013 18:18:46 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id BA0114A0B8 for ; Fri, 4 Oct 2013 18:18: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 YfI8T4u7VtbJ for ; Fri, 4 Oct 2013 18:18: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 db9outboundpool.messaging.microsoft.com (mail-db9lp0250.outbound.messaging.microsoft.com [213.199.154.250]) by theia.denx.de (Postfix) with ESMTPS id 653B24A0A1 for ; Fri, 4 Oct 2013 18:18:27 +0200 (CEST) Received: from mail26-db9-R.bigfish.com (10.174.16.241) by DB9EHSOBE002.bigfish.com (10.174.14.65) with Microsoft SMTP Server id 14.1.225.22; Fri, 4 Oct 2013 16:18:24 +0000 Received: from mail26-db9 (localhost [127.0.0.1]) by mail26-db9-R.bigfish.com (Postfix) with ESMTP id E35AD2E02A3 for ; Fri, 4 Oct 2013 16:18:24 +0000 (UTC) X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPV:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-SpamScore: 0 X-BigFish: VS0(zzzz1f42h208ch1ee6h1de0h1fdah2073h1202h1e76h1d1ah1d2ah1fc6hzz1de098h1de097h8275bhz2dh2a8h839hd24he5bhf0ah107ah1288h12a5h12a9h12bdh12e5h137ah139eh13b6h1441h1504h1537h162dh1631h1758h1898h18e1h1946h19b5h1ad9h1b0ah1b2fh1fb3h1d0ch1d2eh1d3fh1dfeh1dffh1e1dh1e23h1fe8h1ff5h1155h) Received: from mail26-db9 (localhost.localdomain [127.0.0.1]) by mail26-db9 (MessageSwitch) id 1380903503167102_18622; Fri, 4 Oct 2013 16:18:23 +0000 (UTC) Received: from DB9EHSMHS027.bigfish.com (unknown [10.174.16.247]) by mail26-db9.bigfish.com (Postfix) with ESMTP id 1A7EB2A0069 for ; Fri, 4 Oct 2013 16:18:23 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by DB9EHSMHS027.bigfish.com (10.174.14.37) with Microsoft SMTP Server (TLS) id 14.16.227.3; Fri, 4 Oct 2013 16:18:22 +0000 Received: from az84smr01.freescale.net (10.64.34.197) by 039-SN1MMR1-004.039d.mgd.msft.net (10.84.1.14) with Microsoft SMTP Server (TLS) id 14.3.158.2; Fri, 4 Oct 2013 16:18:20 +0000 Received: from fsr-fed1764-016.ea.freescale.net (fsr-fed1764-016.ea.freescale.net [10.171.81.161]) by az84smr01.freescale.net (8.14.3/8.14.0) with ESMTP id r94GIJEM023932; Fri, 4 Oct 2013 09:18:20 -0700 Received: (from b08782@localhost) by fsr-fed1764-016.ea.freescale.net (8.14.5/8.14.5/Submit) id r94GDtoF002908; Fri, 4 Oct 2013 19:13:55 +0300 From: Claudiu Manoil To: Date: Fri, 4 Oct 2013 19:13:53 +0300 Message-ID: <1380903233-2876-1-git-send-email-claudiu.manoil@freescale.com> X-Mailer: git-send-email 1.7.11.7 In-Reply-To: <1380901846.7979.2.camel@snotra.buserror.net> References: <1380901846.7979.2.camel@snotra.buserror.net> MIME-Version: 1.0 X-OriginatorOrg: freescale.net X-FOPE-CONNECTOR: Id%0$Dn%*$RO%0$TLS%0$FQDN%$TlsDn% Cc: Scott Wood , York Sun Subject: [U-Boot] [PATCH 7/9][v3] net: tsec: Use portable types and accessors for BDs 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: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Currently, the buffer descriptor (BD) fields cannot be correctly accessed by a little endian processor. This patch fixes the issue by making the access of BDs to be portable among different cpu architectures. Use portable data types for the Rx/Tx buffer descriptor fields. Use portable I/O accessors to insure that the big endian BDs are correctly accessed by little endian cpus too, and to insure proper sync with the H/W. Removed the redundant RTXBD "volatile" type, as proper synchronization around BD data accesses is provided by the I/O accessors now. The "sparse" tool was also used to verify the correctness of these changes. Cc: Scott Wood Signed-off-by: Claudiu Manoil --- v2: * used portable I/O accessors (in_be/out_be) * replaced macro usage * retested on p1020 (ping, tftp) v3: * txbd, rxbd declared as __iomem to avoid casting drivers/net/tsec.c | 88 ++++++++++++++++++++++++++++-------------------------- include/tsec.h | 22 +++++++------- 2 files changed, 56 insertions(+), 54 deletions(-) diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 289229a..e354fad 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -28,13 +28,10 @@ DECLARE_GLOBAL_DATA_PTR; static uint rx_idx; /* index of the current RX buffer */ static uint tx_idx; /* index of the current TX buffer */ -typedef volatile struct rtxbd { - txbd8_t txbd[TX_BUF_CNT]; - rxbd8_t rxbd[PKTBUFSRX]; -} RTXBD; - #ifdef __GNUC__ -static RTXBD rtx __attribute__ ((aligned(8))); +static struct txbd8 __iomem txbd[TX_BUF_CNT] __aligned(8); +static struct rxbd8 __iomem rxbd[PKTBUFSRX] __aligned(8); + #else #error "rtx must be 64-bit aligned" #endif @@ -275,10 +272,11 @@ void redundant_init(struct eth_device *dev) clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); do { + uint16_t status; tsec_send(dev, (void *)pkt, sizeof(pkt)); /* Wait for buffer to be received */ - for (t = 0; rtx.rxbd[rx_idx].status & RXBD_EMPTY; t++) { + for (t = 0; in_be16(&rxbd[rx_idx].status) & RXBD_EMPTY; t++) { if (t >= 10 * TOUT_LOOP) { printf("%s: tsec: rx error\n", dev->name); break; @@ -288,9 +286,11 @@ void redundant_init(struct eth_device *dev) if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt))) fail = 0; - rtx.rxbd[rx_idx].length = 0; - rtx.rxbd[rx_idx].status = - RXBD_EMPTY | (((rx_idx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); + out_be16(&rxbd[rx_idx].length, 0); + status = RXBD_EMPTY; + if ((rx_idx + 1) == PKTBUFSRX) + status |= RXBD_WRAP; + out_be16(&rxbd[rx_idx].status, status); rx_idx = (rx_idx + 1) % PKTBUFSRX; if (in_be32(®s->ievent) & IEVENT_BSY) { @@ -319,9 +319,10 @@ void redundant_init(struct eth_device *dev) */ static void startup_tsec(struct eth_device *dev) { - int i; struct tsec_private *priv = (struct tsec_private *)dev->priv; struct tsec __iomem *regs = priv->regs; + uint16_t status; + int i; /* reset the indices to zero */ rx_idx = 0; @@ -331,24 +332,26 @@ static void startup_tsec(struct eth_device *dev) #endif /* Point to the buffer descriptors */ - out_be32(®s->tbase, (unsigned int)(&rtx.txbd[tx_idx])); - out_be32(®s->rbase, (unsigned int)(&rtx.rxbd[rx_idx])); + out_be32(®s->tbase, (u32)&txbd[0]); + out_be32(®s->rbase, (u32)&rxbd[0]); /* Initialize the Rx Buffer descriptors */ for (i = 0; i < PKTBUFSRX; i++) { - rtx.rxbd[i].status = RXBD_EMPTY; - rtx.rxbd[i].length = 0; - rtx.rxbd[i].bufptr = (uint) NetRxPackets[i]; + out_be16(&rxbd[i].status, RXBD_EMPTY); + out_be16(&rxbd[i].length, 0); + out_be32(&rxbd[i].bufptr, (u32)NetRxPackets[i]); } - rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP; + status = in_be16(&rxbd[PKTBUFSRX - 1].status); + out_be16(&rxbd[PKTBUFSRX - 1].status, status | RXBD_WRAP); /* Initialize the TX Buffer Descriptors */ for (i = 0; i < TX_BUF_CNT; i++) { - rtx.txbd[i].status = 0; - rtx.txbd[i].length = 0; - rtx.txbd[i].bufptr = 0; + out_be16(&txbd[i].status, 0); + out_be16(&txbd[i].length, 0); + out_be32(&txbd[i].bufptr, 0); } - rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP; + status = in_be16(&txbd[TX_BUF_CNT - 1].status); + out_be16(&txbd[TX_BUF_CNT - 1].status, status | TXBD_WRAP); #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 svr = get_svr(); @@ -372,29 +375,31 @@ static void startup_tsec(struct eth_device *dev) */ static int tsec_send(struct eth_device *dev, void *packet, int length) { - int i; - int result = 0; struct tsec_private *priv = (struct tsec_private *)dev->priv; struct tsec __iomem *regs = priv->regs; + uint16_t status; + int result = 0; + int i; /* Find an empty buffer descriptor */ - for (i = 0; rtx.txbd[tx_idx].status & TXBD_READY; i++) { + for (i = 0; in_be16(&txbd[tx_idx].status) & TXBD_READY; i++) { if (i >= TOUT_LOOP) { debug("%s: tsec: tx buffers full\n", dev->name); return result; } } - rtx.txbd[tx_idx].bufptr = (uint) packet; - rtx.txbd[tx_idx].length = length; - rtx.txbd[tx_idx].status |= - (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT); + out_be32(&txbd[tx_idx].bufptr, (u32)packet); + out_be16(&txbd[tx_idx].length, length); + status = in_be16(&txbd[tx_idx].status); + out_be16(&txbd[tx_idx].status, status | + (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT)); /* Tell the DMA to go */ out_be32(®s->tstat, TSTAT_CLEAR_THALT); /* Wait for buffer to be transmitted */ - for (i = 0; rtx.txbd[tx_idx].status & TXBD_READY; i++) { + for (i = 0; in_be16(&txbd[tx_idx].status) & TXBD_READY; i++) { if (i >= TOUT_LOOP) { debug("%s: tsec: tx error\n", dev->name); return result; @@ -402,34 +407,33 @@ static int tsec_send(struct eth_device *dev, void *packet, int length) } tx_idx = (tx_idx + 1) % TX_BUF_CNT; - result = rtx.txbd[tx_idx].status & TXBD_STATS; + result = in_be16(&txbd[tx_idx].status) & TXBD_STATS; return result; } static int tsec_recv(struct eth_device *dev) { - int length; struct tsec_private *priv = (struct tsec_private *)dev->priv; struct tsec __iomem *regs = priv->regs; - while (!(rtx.rxbd[rx_idx].status & RXBD_EMPTY)) { - - length = rtx.rxbd[rx_idx].length; + while (!(in_be16(&rxbd[rx_idx].status) & RXBD_EMPTY)) { + int length = in_be16(&rxbd[rx_idx].length); + uint16_t status = in_be16(&rxbd[rx_idx].status); /* Send the packet up if there were no errors */ - if (!(rtx.rxbd[rx_idx].status & RXBD_STATS)) { + if (!(status & RXBD_STATS)) NetReceive(NetRxPackets[rx_idx], length - 4); - } else { - printf("Got error %x\n", - (rtx.rxbd[rx_idx].status & RXBD_STATS)); - } + else + printf("Got error %x\n", (status & RXBD_STATS)); - rtx.rxbd[rx_idx].length = 0; + out_be16(&rxbd[rx_idx].length, 0); + status = RXBD_EMPTY; /* Set the wrap bit if this is the last element in the list */ - rtx.rxbd[rx_idx].status = - RXBD_EMPTY | (((rx_idx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); + if ((rx_idx + 1) == PKTBUFSRX) + status |= RXBD_WRAP; + out_be16(&rxbd[rx_idx].status, status); rx_idx = (rx_idx + 1) % PKTBUFSRX; } diff --git a/include/tsec.h b/include/tsec.h index 6bc43ef..95054be 100644 --- a/include/tsec.h +++ b/include/tsec.h @@ -198,19 +198,17 @@ #define RXBD_TRUNCATED 0x0001 #define RXBD_STATS 0x003f -typedef struct txbd8 -{ - ushort status; /* Status Fields */ - ushort length; /* Buffer length */ - uint bufptr; /* Buffer Pointer */ -} txbd8_t; +struct txbd8 { + uint16_t status; /* Status Fields */ + uint16_t length; /* Buffer length */ + uint32_t bufptr; /* Buffer Pointer */ +}; -typedef struct rxbd8 -{ - ushort status; /* Status Fields */ - ushort length; /* Buffer Length */ - uint bufptr; /* Buffer Pointer */ -} rxbd8_t; +struct rxbd8 { + uint16_t status; /* Status Fields */ + uint16_t length; /* Buffer Length */ + uint32_t bufptr; /* Buffer Pointer */ +}; typedef struct rmon_mib {