From patchwork Mon Mar 25 16:43:34 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Ruehl X-Patchwork-Id: 230759 X-Patchwork-Delegate: trini@ti.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 71DF52C009A for ; Tue, 26 Mar 2013 04:15:44 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id EDE204A088; Mon, 25 Mar 2013 18:15:40 +0100 (CET) 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 UHFsMnqrA2BV; Mon, 25 Mar 2013 18:15:40 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 55B7C4A04A; Mon, 25 Mar 2013 18:15:37 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id B1C674A04A for ; Mon, 25 Mar 2013 17:43:41 +0100 (CET) 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 amlQwmVDg7MN for ; Mon, 25 Mar 2013 17:43:40 +0100 (CET) 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 fpa01n0.fpasia.hk (mail.fpasia.hk [202.130.89.98]) by theia.denx.de (Postfix) with ESMTP id 5D83D4A049 for ; Mon, 25 Mar 2013 17:43:37 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by fpa01n0.fpasia.hk (Postfix) with ESMTP id 62D79CFA743 for ; Tue, 26 Mar 2013 00:43:36 +0800 (HKT) X-Virus-Scanned: FPASIA amavisd-new at fpasia.hk Received: from fpa01n0.fpasia.hk ([127.0.0.1]) by localhost (fpa01n0.office.fpa.com.hk [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id fwG1n7lcu9jS for ; Tue, 26 Mar 2013 00:43:35 +0800 (HKT) Received: from s01.gtsys.com.hk (gtsnode.office.fpasia.hk [10.10.37.40]) by fpa01n0.fpasia.hk (Postfix) with ESMTP id 1F77FCFA742 for ; Tue, 26 Mar 2013 00:43:35 +0800 (HKT) Received: from [10.128.2.32] (n219077082246.netvigator.com [219.77.82.246]) by s01.gtsys.com.hk (Postfix) with ESMTPSA id ADF2FC019E7 for ; Tue, 26 Mar 2013 00:43:32 +0800 (HKT) Message-ID: <51507EB6.1040900@gtsys.com.hk> Date: Tue, 26 Mar 2013 00:43:34 +0800 From: Chris Ruehl User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.16) Gecko/20121215 Icedove/3.0.11 ThunderBrowse/3.8 MIME-Version: 1.0 To: u-boot@lists.denx.de X-Mailman-Approved-At: Mon, 25 Mar 2013 18:15:34 +0100 Subject: [U-Boot] dm9000 patch tftp, nfs fixes. 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 Hi, I start a project on a freescale imx27 using the dm9000a for network. I learned that the tftp , nfs and other network related working more less very unstable. I start compare the dm9000.c code with the upstream kernel v3.8.4 and fix some issues. issues tftp with many bad checksums and timeouts nfs with not working at all when upload a 38Mbyte rootfs.jffs2 After the patch its works much better for me. please find my patch attached and consider to merge it the the head branch. cheers Chris diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index b8ad98d..ce2d97a 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -58,6 +58,7 @@ #define DM9000_ID 0x90000A46 #define DM9000_PKT_MAX 1536 /* Received packet max size */ #define DM9000_PKT_RDY 0x01 /* Packet ready to receive */ +#define DM9000_PKT_ERR 0x02 #define DM9000_NCR 0x00 #define DM9000_NSR 0x01 @@ -163,6 +164,7 @@ #define IMR_ROM (1<<2) #define IMR_PTM (1<<1) #define IMR_PRM (1<<0) +#define IMR_LNKCHNG (1<<5) struct dm9000_priv { unsigned long iobase; @@ -351,75 +353,82 @@ static int dm9000_eth_rx (struct eth_device *edev) u32 tmplen, i; u32 tmpdata; + udelay(2500); // we called in a loop to quick .. give me some time + /* Check packet ready or not */ DM9000_ior(priv, DM9000_MRCMDX); /* Dummy read */ + udelay(100); rxbyte = readb(priv->iodata); /* Got most updated data */ - if (rxbyte == 0) - return 0; /* Status check: this byte must be 0 or 1 */ - if (rxbyte > 1) { - DM9000_iow(priv, DM9000_RCR, 0x00); /* Stop Device */ - DM9000_iow(priv, DM9000_ISR, 0x80); /* Stop INT request */ - debug("rx status check: %d\n", rxbyte); + if (rxbyte & DM9000_PKT_ERR) { + debug("rx status check failed: %d\n", rxbyte); + DM9000_iow(priv, DM9000_RCR, 0x00); /* Stop Device */ + DM9000_iow(priv, DM9000_ISR, IMR_PAR); /* Stop INT request */ + dm9000_reset(priv); + /* re-enable the interupt, rx */ + DM9000_iow(priv, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); + DM9000_iow(priv, DM9000_ISR, 0x0f); } - debug("receiving packet\n"); - - /* A packet ready now & Get status/length */ - writeb(DM9000_MRCMD, priv->iobase); - - /* Move data from DM9000 */ - /* Read received packet from RX SRAM */ - switch (priv->buswidth) { - case DM9000_WIDTH_8: - RxStatus = readb(priv->iodata) + (readb(priv->iodata) << 8); - RxLen = readb(priv->iodata) + (readb(priv->iodata) << 8); - for (i = 0; i < RxLen; i++) - rdptr[i] = readb(priv->iodata); - break; - case DM9000_WIDTH_16: - RxStatus = readw(priv->iodata); - RxLen = readw(priv->iodata); - tmplen = (RxLen + 1) / 2; - for (i = 0; i < tmplen; i++) - ((u16 *) rdptr)[i] = readw(priv->iodata); - break; - case DM9000_WIDTH_32: - tmpdata = readl(priv->iodata); - RxStatus = tmpdata; - RxLen = tmpdata >> 16; - tmplen = (RxLen + 3) / 4; - for (i = 0; i < tmplen; i++) - ((u32 *) rdptr)[i] = readl(priv->iodata); - break; - default: - /* dm9000_probe makes sure this cannot happen */ - return -EINVAL; - } - - if ((RxStatus & 0xbf00) || (RxLen < 0x40) - || (RxLen > DM9000_PKT_MAX)) { - if (RxStatus & 0x100) { - printf("rx fifo error\n"); - } - if (RxStatus & 0x200) { - printf("rx crc error\n"); + else if ((rxbyte & DM9000_PKT_RDY)) { + debug("receiving packet\n"); + + /* A packet ready now & Get status/length */ + writeb(DM9000_MRCMD, priv->iobase); + udelay(100); + + /* Move data from DM9000 */ + /* Read received packet from RX SRAM */ + switch (priv->buswidth) { + case DM9000_WIDTH_8: + RxStatus = readb(priv->iodata) + (readb(priv->iodata) << 8); + RxLen = readb(priv->iodata) + (readb(priv->iodata) << 8); + for (i = 0; i < RxLen; i++) + rdptr[i] = readb(priv->iodata); + break; + case DM9000_WIDTH_16: + RxStatus = readw(priv->iodata); + RxLen = readw(priv->iodata); + tmplen = (RxLen + 1) / 2; + for (i = 0; i < tmplen; i++) + ((u16 *) rdptr)[i] = readw(priv->iodata); + break; + case DM9000_WIDTH_32: + tmpdata = readl(priv->iodata); + RxStatus = tmpdata; + RxLen = tmpdata >> 16; + tmplen = (RxLen + 3) / 4; + for (i = 0; i < tmplen; i++) + ((u32 *) rdptr)[i] = readl(priv->iodata); + break; + default: + /* dm9000_probe makes sure this cannot happen */ + return -EINVAL; + } + + if ((RxStatus & 0xbf00) || (RxLen < 0x40) + || (RxLen > DM9000_PKT_MAX)) { + if (RxStatus & 0x100) { + printf("rx fifo error\n"); + } + if (RxStatus & 0x200) { + printf("rx crc error\n"); + } + if (RxStatus & 0x8000) { + printf("rx length error\n"); + } + if (RxLen > DM9000_PKT_MAX) { + printf("rx length too big\n"); + } + dm9000_reset(priv); + RxLen = 0; + } else { + /* Pass to upper layer */ + debug("passing packet to upper layer\n"); + NetReceive(NetRxPackets[0], RxLen); + } } - if (RxStatus & 0x8000) { - printf("rx length error\n"); - } - if (RxLen > DM9000_PKT_MAX) { - printf("rx length too big\n"); - dm9000_reset(priv); - } - } else { - - /* Pass to upper layer */ - debug("passing packet to upper layer\n"); - NetReceive(NetRxPackets[0], RxLen); - return RxLen; - } - return 0; + return RxLen; } static u16 read_srom_word(struct dm9000_priv *priv, int offset) @@ -511,7 +520,7 @@ static int dm9000_probe(struct device_d *dev) DM9000_iow(priv, DM9000_TCR, 0); /* TX Polling clear */ DM9000_iow(priv, DM9000_BPTR, 0x3f); /* Less 3Kb, 200us */ DM9000_iow(priv, DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); /* Flow Control : High/Low Water */ - DM9000_iow(priv, DM9000_FCR, 0x0); /* SH FIXME: This looks strange! Flow Control */ + DM9000_iow(priv, DM9000_FCR, 0xFF); /* Flow Control */ DM9000_iow(priv, DM9000_SMCR, 0); /* Special Mode */ DM9000_iow(priv, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* clear TX status */ DM9000_iow(priv, DM9000_ISR, 0x0f); /* Clear interrupt status */ @@ -520,7 +529,7 @@ static int dm9000_probe(struct device_d *dev) DM9000_iow(priv, DM9000_GPCR, 0x01); /* Let GPIO0 output */ DM9000_iow(priv, DM9000_GPR, 0x00); /* Enable PHY */ DM9000_iow(priv, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); /* RX enable */ - DM9000_iow(priv, DM9000_IMR, IMR_PAR); /* Enable TX/RX interrupt mask */ + DM9000_iow(priv, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM | IMR_LNKCHNG ); /* Enable TX/RX interrupt mask */ priv->miiphy.read = dm9000_phy_read; priv->miiphy.write = dm9000_phy_write;