aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sky2.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r--drivers/net/sky2.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index f5d697c0c031..996275245144 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -75,6 +75,7 @@
75#define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le)) 75#define RX_LE_BYTES (RX_LE_SIZE*sizeof(struct sky2_rx_le))
76#define RX_MAX_PENDING (RX_LE_SIZE/2 - 2) 76#define RX_MAX_PENDING (RX_LE_SIZE/2 - 2)
77#define RX_DEF_PENDING RX_MAX_PENDING 77#define RX_DEF_PENDING RX_MAX_PENDING
78#define RX_SKB_ALIGN 8
78 79
79#define TX_RING_SIZE 512 80#define TX_RING_SIZE 512
80#define TX_DEF_PENDING (TX_RING_SIZE - 1) 81#define TX_DEF_PENDING (TX_RING_SIZE - 1)
@@ -905,15 +906,30 @@ static void sky2_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid)
905#endif 906#endif
906 907
907/* 908/*
909 * It appears the hardware has a bug in the FIFO logic that
910 * cause it to hang if the FIFO gets overrun and the receive buffer
911 * is not aligned. ALso alloc_skb() won't align properly if slab
912 * debugging is enabled.
913 */
914static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask)
915{
916 struct sk_buff *skb;
917
918 skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask);
919 if (likely(skb)) {
920 unsigned long p = (unsigned long) skb->data;
921 skb_reserve(skb,
922 ((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p);
923 }
924
925 return skb;
926}
927
928/*
908 * Allocate and setup receiver buffer pool. 929 * Allocate and setup receiver buffer pool.
909 * In case of 64 bit dma, there are 2X as many list elements 930 * In case of 64 bit dma, there are 2X as many list elements
910 * available as ring entries 931 * available as ring entries
911 * and need to reserve one list element so we don't wrap around. 932 * and need to reserve one list element so we don't wrap around.
912 *
913 * It appears the hardware has a bug in the FIFO logic that
914 * cause it to hang if the FIFO gets overrun and the receive buffer
915 * is not aligned. This means we can't use skb_reserve to align
916 * the IP header.
917 */ 933 */
918static int sky2_rx_start(struct sky2_port *sky2) 934static int sky2_rx_start(struct sky2_port *sky2)
919{ 935{
@@ -929,7 +945,7 @@ static int sky2_rx_start(struct sky2_port *sky2)
929 for (i = 0; i < sky2->rx_pending; i++) { 945 for (i = 0; i < sky2->rx_pending; i++) {
930 struct ring_info *re = sky2->rx_ring + i; 946 struct ring_info *re = sky2->rx_ring + i;
931 947
932 re->skb = dev_alloc_skb(sky2->rx_bufsize); 948 re->skb = sky2_alloc_skb(sky2->rx_bufsize, GFP_KERNEL);
933 if (!re->skb) 949 if (!re->skb)
934 goto nomem; 950 goto nomem;
935 951
@@ -1713,7 +1729,7 @@ static struct sk_buff *sky2_receive(struct sky2_port *sky2,
1713 } else { 1729 } else {
1714 struct sk_buff *nskb; 1730 struct sk_buff *nskb;
1715 1731
1716 nskb = dev_alloc_skb(sky2->rx_bufsize); 1732 nskb = sky2_alloc_skb(sky2->rx_bufsize, GFP_ATOMIC);
1717 if (!nskb) 1733 if (!nskb)
1718 goto resubmit; 1734 goto resubmit;
1719 1735