From 27860b33901a0df2e95cdfdeb2bc9aba1a13e82d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Wed, 28 Nov 2007 14:27:03 -0800 Subject: [PATCH] --- yaml --- r: 78968 b: refs/heads/master c: f03b865491c2f30f2a4d77cdafc69c978ceb38a0 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/net/sky2.c | 33 ++++++++++++++++++++------------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/[refs] b/[refs] index 0fd2c21569cf..7c361e692da8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 5ac5d616327bdbdf632bdf4dc9ae09477f79b6b3 +refs/heads/master: f03b865491c2f30f2a4d77cdafc69c978ceb38a0 diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index bc15940ce1bc..30e567a2d5a1 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -64,7 +64,6 @@ #define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le)) #define RX_MAX_PENDING (RX_LE_SIZE/6 - 2) #define RX_DEF_PENDING RX_MAX_PENDING -#define RX_SKB_ALIGN 8 #define TX_RING_SIZE 512 #define TX_DEF_PENDING (TX_RING_SIZE - 1) @@ -1174,24 +1173,32 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp /* * Allocate an skb for receiving. If the MTU is large enough * make the skb non-linear with a fragment list of pages. - * - * It appears the hardware has a bug in the FIFO logic that - * cause it to hang if the FIFO gets overrun and the receive buffer - * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is - * aligned except if slab debugging is enabled. */ static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2) { struct sk_buff *skb; - unsigned long p; int i; - skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + RX_SKB_ALIGN); - if (!skb) - goto nomem; - - p = (unsigned long) skb->data; - skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); + if (sky2->hw->flags & SKY2_HW_FIFO_HANG_CHECK) { + unsigned char *start; + /* + * Workaround for a bug in FIFO that cause hang + * if the FIFO if the receive buffer is not 64 byte aligned. + * The buffer returned from netdev_alloc_skb is + * aligned except if slab debugging is enabled. + */ + skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + 8); + if (!skb) + goto nomem; + start = PTR_ALIGN(skb->data, 8); + skb_reserve(skb, start - skb->data); + } else { + skb = netdev_alloc_skb(sky2->netdev, + sky2->rx_data_size + NET_IP_ALIGN); + if (!skb) + goto nomem; + skb_reserve(skb, NET_IP_ALIGN); + } for (i = 0; i < sky2->rx_nfrags; i++) { struct page *page = alloc_page(GFP_ATOMIC);