--- drivers/net/gianfar.c | 52 +++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 25 deletions(-) --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1568,6 +1568,15 @@ schedule_work(&priv->reset_task); } +static void gfar_align_skb(struct sk_buff *skb) +{ + /* We need the data buffer to be aligned properly. We will reserve + * as many bytes as needed to align the data properly + */ + skb_reserve(skb, RXBUF_ALIGNMENT - + (((unsigned long) skb->data) & (RXBUF_ALIGNMENT - 1))); +} + /* Interrupt Handler for Transmit complete */ static int gfar_clean_tx_ring(struct net_device *dev) { @@ -1620,9 +1629,10 @@ */ if (skb_queue_len(&priv->rx_recycle) < priv->rx_ring_size && skb_recycle_check(skb, priv->rx_buffer_size + - RXBUF_ALIGNMENT)) + RXBUF_ALIGNMENT)) { + gfar_align_skb(skb); __skb_queue_head(&priv->rx_recycle, skb); - else + } else dev_kfree_skb_any(skb); priv->tx_skbuff[skb_dirtytx] = NULL; @@ -1696,28 +1706,29 @@ bdp->lstatus = lstatus; } +static struct sk_buff * gfar_alloc_skb(struct net_device *dev) +{ + struct gfar_private *priv = netdev_priv(dev); + struct sk_buff *skb = NULL; + + skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT); + if (!skb) + return NULL; + + gfar_align_skb(skb); + + return skb; +} struct sk_buff * gfar_new_skb(struct net_device *dev) { - unsigned int alignamount; struct gfar_private *priv = netdev_priv(dev); struct sk_buff *skb = NULL; skb = __skb_dequeue(&priv->rx_recycle); - if (!skb) - skb = netdev_alloc_skb(dev, - priv->rx_buffer_size + RXBUF_ALIGNMENT); if (!skb) - return NULL; - - alignamount = RXBUF_ALIGNMENT - - (((unsigned long) skb->data) & (RXBUF_ALIGNMENT - 1)); - - /* We need the data buffer to be aligned properly. We will reserve - * as many bytes as needed to align the data properly - */ - skb_reserve(skb, alignamount); + skb = gfar_alloc_skb(dev); return skb; } @@ -1853,17 +1864,8 @@ if (unlikely(!newskb)) newskb = skb; - else if (skb) { - /* - * We need to reset ->data to what it - * was before gfar_new_skb() re-aligned - * it to an RXBUF_ALIGNMENT boundary - * before we put the skb back on the - * recycle list. - */ - skb->data = skb->head + NET_SKB_PAD; + else if (skb) __skb_queue_head(&priv->rx_recycle, skb); - } } else { /* Increment the number of packets */ dev->stats.rx_packets++;