aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2007-11-28 17:27:03 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:04:18 -0500
commitf03b865491c2f30f2a4d77cdafc69c978ceb38a0 (patch)
tree2d66c0e238b2770ef198a0acfd6d704566bcade1 /drivers
parent5ac5d616327bdbdf632bdf4dc9ae09477f79b6b3 (diff)
sky2: align IP header on Rx if possible
The sky2 driver was not aligning the IP header on receive buffers. This workaround is only needed on hardware with broken FIFO, newer chips without FIFO can just DMA to unaligned address. Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/sky2.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index bc15940ce1bc..30e567a2d5a1 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -64,7 +64,6 @@
64#define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le)) 64#define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le))
65#define RX_MAX_PENDING (RX_LE_SIZE/6 - 2) 65#define RX_MAX_PENDING (RX_LE_SIZE/6 - 2)
66#define RX_DEF_PENDING RX_MAX_PENDING 66#define RX_DEF_PENDING RX_MAX_PENDING
67#define RX_SKB_ALIGN 8
68 67
69#define TX_RING_SIZE 512 68#define TX_RING_SIZE 512
70#define TX_DEF_PENDING (TX_RING_SIZE - 1) 69#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
1174/* 1173/*
1175 * Allocate an skb for receiving. If the MTU is large enough 1174 * Allocate an skb for receiving. If the MTU is large enough
1176 * make the skb non-linear with a fragment list of pages. 1175 * make the skb non-linear with a fragment list of pages.
1177 *
1178 * It appears the hardware has a bug in the FIFO logic that
1179 * cause it to hang if the FIFO gets overrun and the receive buffer
1180 * is not 64 byte aligned. The buffer returned from netdev_alloc_skb is
1181 * aligned except if slab debugging is enabled.
1182 */ 1176 */
1183static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2) 1177static struct sk_buff *sky2_rx_alloc(struct sky2_port *sky2)
1184{ 1178{
1185 struct sk_buff *skb; 1179 struct sk_buff *skb;
1186 unsigned long p;
1187 int i; 1180 int i;
1188 1181
1189 skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + RX_SKB_ALIGN); 1182 if (sky2->hw->flags & SKY2_HW_FIFO_HANG_CHECK) {
1190 if (!skb) 1183 unsigned char *start;
1191 goto nomem; 1184 /*
1192 1185 * Workaround for a bug in FIFO that cause hang
1193 p = (unsigned long) skb->data; 1186 * if the FIFO if the receive buffer is not 64 byte aligned.
1194 skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); 1187 * The buffer returned from netdev_alloc_skb is
1188 * aligned except if slab debugging is enabled.
1189 */
1190 skb = netdev_alloc_skb(sky2->netdev, sky2->rx_data_size + 8);
1191 if (!skb)
1192 goto nomem;
1193 start = PTR_ALIGN(skb->data, 8);
1194 skb_reserve(skb, start - skb->data);
1195 } else {
1196 skb = netdev_alloc_skb(sky2->netdev,
1197 sky2->rx_data_size + NET_IP_ALIGN);
1198 if (!skb)
1199 goto nomem;
1200 skb_reserve(skb, NET_IP_ALIGN);
1201 }
1195 1202
1196 for (i = 0; i < sky2->rx_nfrags; i++) { 1203 for (i = 0; i < sky2->rx_nfrags; i++) {
1197 struct page *page = alloc_page(GFP_ATOMIC); 1204 struct page *page = alloc_page(GFP_ATOMIC);