--- zzzz-none-000/linux-2.6.19.2/drivers/net/arm/ep93xx_eth.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5505/linux-2.6.19.2/drivers/net/arm/ep93xx_eth.c 2007-01-11 07:38:19.000000000 +0000 @@ -193,9 +193,12 @@ static int ep93xx_rx(struct net_device *dev, int *budget) { struct ep93xx_priv *ep = netdev_priv(dev); + int tail_offset; int rx_done; int processed; + tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr; + rx_done = 0; processed = 0; while (*budget > 0) { @@ -208,28 +211,36 @@ entry = ep->rx_pointer; rstat = ep->descs->rstat + entry; - - rstat0 = rstat->rstat0; - rstat1 = rstat->rstat1; - if (!(rstat0 & RSTAT0_RFP) || !(rstat1 & RSTAT1_RFP)) { + if ((void *)rstat - (void *)ep->descs == tail_offset) { rx_done = 1; break; } + rstat0 = rstat->rstat0; + rstat1 = rstat->rstat1; rstat->rstat0 = 0; rstat->rstat1 = 0; + if (!(rstat0 & RSTAT0_RFP)) + printk(KERN_CRIT "ep93xx_rx: buffer not done " + " %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_EOF)) printk(KERN_CRIT "ep93xx_rx: not end-of-frame " " %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_EOB)) printk(KERN_CRIT "ep93xx_rx: not end-of-buffer " " %.8x %.8x\n", rstat0, rstat1); + if (!(rstat1 & RSTAT1_RFP)) + printk(KERN_CRIT "ep93xx_rx: buffer1 not done " + " %.8x %.8x\n", rstat0, rstat1); if ((rstat1 & RSTAT1_BUFFER_INDEX) >> 16 != entry) printk(KERN_CRIT "ep93xx_rx: entry mismatch " " %.8x %.8x\n", rstat0, rstat1); if (!(rstat0 & RSTAT0_RWE)) { + printk(KERN_NOTICE "ep93xx_rx: receive error " + " %.8x %.8x\n", rstat0, rstat1); + ep->stats.rx_errors++; if (rstat0 & RSTAT0_OE) ep->stats.rx_fifo_errors++; @@ -290,8 +301,13 @@ static int ep93xx_have_more_rx(struct ep93xx_priv *ep) { - struct ep93xx_rstat *rstat = ep->descs->rstat + ep->rx_pointer; - return !!((rstat->rstat0 & RSTAT0_RFP) && (rstat->rstat1 & RSTAT1_RFP)); + struct ep93xx_rstat *rstat; + int tail_offset; + + rstat = ep->descs->rstat + ep->rx_pointer; + tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr; + + return !((void *)rstat - (void *)ep->descs == tail_offset); } static int ep93xx_poll(struct net_device *dev, int *budget) @@ -331,7 +347,7 @@ struct ep93xx_priv *ep = netdev_priv(dev); int entry; - if (unlikely(skb->len > MAX_PKT_SIZE)) { + if (unlikely(skb->len) > MAX_PKT_SIZE) { ep->stats.tx_dropped++; dev_kfree_skb(skb); return NETDEV_TX_OK; @@ -363,8 +379,10 @@ static void ep93xx_tx_complete(struct net_device *dev) { struct ep93xx_priv *ep = netdev_priv(dev); + int tail_offset; int wake; + tail_offset = rdl(ep, REG_TXSTSQCURADD) - ep->descs_dma_addr; wake = 0; spin_lock(&ep->tx_pending_lock); @@ -375,13 +393,15 @@ entry = ep->tx_clean_pointer; tstat = ep->descs->tstat + entry; - - tstat0 = tstat->tstat0; - if (!(tstat0 & TSTAT0_TXFP)) + if ((void *)tstat - (void *)ep->descs == tail_offset) break; + tstat0 = tstat->tstat0; tstat->tstat0 = 0; + if (!(tstat0 & TSTAT0_TXFP)) + printk(KERN_CRIT "ep93xx_tx_complete: buffer not done " + " %.8x\n", tstat0); if (tstat0 & TSTAT0_FA) printk(KERN_CRIT "ep93xx_tx_complete: frame aborted " " %.8x\n", tstat0);