diff options
Diffstat (limited to 'drivers/net/mv643xx_eth.c')
-rw-r--r-- | drivers/net/mv643xx_eth.c | 80 |
1 files changed, 28 insertions, 52 deletions
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 58c1c1b0aa5..0e4babbe37a 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c @@ -443,74 +443,50 @@ static unsigned int mv643xx_eth_port_disable_tx(struct mv643xx_eth_private *mp) /* rx ***********************************************************************/ static void mv643xx_eth_free_completed_tx_descs(struct net_device *dev); -static FUNC_RET_STATUS rx_return_buff(struct mv643xx_eth_private *mp, - struct pkt_info *pkt_info) +static void mv643xx_eth_rx_refill_descs(struct net_device *dev) { - int used_rx_desc; /* Where to return Rx resource */ - volatile struct rx_desc *rx_desc; + struct mv643xx_eth_private *mp = netdev_priv(dev); unsigned long flags; spin_lock_irqsave(&mp->lock, flags); - /* Get 'used' Rx descriptor */ - used_rx_desc = mp->rx_used_desc; - rx_desc = &mp->rx_desc_area[used_rx_desc]; - - rx_desc->buf_ptr = pkt_info->buf_ptr; - rx_desc->buf_size = pkt_info->byte_cnt; - mp->rx_skb[used_rx_desc] = pkt_info->return_info; - - /* Flush the write pipe */ - - /* Return the descriptor to DMA ownership */ - wmb(); - rx_desc->cmd_sts = BUFFER_OWNED_BY_DMA | RX_ENABLE_INTERRUPT; - wmb(); - - /* Move the used descriptor pointer to the next descriptor */ - mp->rx_used_desc = (used_rx_desc + 1) % mp->rx_ring_size; - - spin_unlock_irqrestore(&mp->lock, flags); - - return ETH_OK; -} - -static void mv643xx_eth_rx_refill_descs(struct net_device *dev) -{ - struct mv643xx_eth_private *mp = netdev_priv(dev); - struct pkt_info pkt_info; - struct sk_buff *skb; - int unaligned; - while (mp->rx_desc_count < mp->rx_ring_size) { + struct sk_buff *skb; + int unaligned; + int rx; + skb = dev_alloc_skb(ETH_RX_SKB_SIZE + dma_get_cache_alignment()); - if (!skb) + if (skb == NULL) break; - mp->rx_desc_count++; + unaligned = (u32)skb->data & (dma_get_cache_alignment() - 1); if (unaligned) skb_reserve(skb, dma_get_cache_alignment() - unaligned); - pkt_info.cmd_sts = RX_ENABLE_INTERRUPT; - pkt_info.byte_cnt = ETH_RX_SKB_SIZE; - pkt_info.buf_ptr = dma_map_single(NULL, skb->data, - ETH_RX_SKB_SIZE, DMA_FROM_DEVICE); - pkt_info.return_info = skb; - if (rx_return_buff(mp, &pkt_info) != ETH_OK) { - printk(KERN_ERR - "%s: Error allocating RX Ring\n", dev->name); - break; - } + + mp->rx_desc_count++; + rx = mp->rx_used_desc; + mp->rx_used_desc = (rx + 1) % mp->rx_ring_size; + + mp->rx_desc_area[rx].buf_ptr = dma_map_single(NULL, + skb->data, + ETH_RX_SKB_SIZE, + DMA_FROM_DEVICE); + mp->rx_desc_area[rx].buf_size = ETH_RX_SKB_SIZE; + mp->rx_skb[rx] = skb; + wmb(); + mp->rx_desc_area[rx].cmd_sts = BUFFER_OWNED_BY_DMA | + RX_ENABLE_INTERRUPT; + wmb(); + skb_reserve(skb, ETH_HW_IP_ALIGN); } - /* - * If RX ring is empty of SKB, set a timer to try allocating - * again at a later time. - */ + if (mp->rx_desc_count == 0) { - printk(KERN_INFO "%s: Rx ring is empty\n", dev->name); - mp->timeout.expires = jiffies + (HZ / 10); /* 100 mSec */ + mp->timeout.expires = jiffies + (HZ / 10); add_timer(&mp->timeout); } + + spin_unlock_irqrestore(&mp->lock, flags); } static inline void mv643xx_eth_rx_refill_descs_timer_wrapper(unsigned long data) |