aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.21-pre4-sparse
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-03-21 11:01:27 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-03-21 11:01:27 +0000
commit90a2fdc8c67f15155721f3b0853c3fa283680828 (patch)
treec36c789c8c23c3a54e8cc5247fc97250534d2992 /xenolinux-2.4.21-pre4-sparse
parent9448593a8ace5d7866ccc678052fc3877ae501ff (diff)
downloadxen-90a2fdc8c67f15155721f3b0853c3fa283680828.tar.gz
xen-90a2fdc8c67f15155721f3b0853c3fa283680828.tar.bz2
xen-90a2fdc8c67f15155721f3b0853c3fa283680828.zip
bitkeeper revision 1.154 (3e7af107VaUd3AaItgryI3J0mrJQ1Q)
network.c, dev.c, vif.h, network.h, tg3.c: Allow reecive of net packets at arbitrary offset in a page. We can now properly support broken NICs which cannot do unaligned receives.
Diffstat (limited to 'xenolinux-2.4.21-pre4-sparse')
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c
index 86bbeb921a..01e81e0cf0 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c
@@ -230,7 +230,6 @@ static void network_alloc_rx_buffers(struct net_device *dev)
skb = dev_alloc_skb(RX_BUF_SIZE);
if ( skb == NULL ) break;
skb->dev = dev;
- skb_reserve(skb, 2); /* word align the IP header */
np->rx_skb_ring[i] = skb;
np->net_ring->rx_ring[i].addr = get_ppte((unsigned long)skb->head);
np->net_ring->rx_ring[i].size = RX_BUF_SIZE - 16; /* arbitrary */
@@ -317,25 +316,20 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
struct net_device *dev = (struct net_device *)dev_id;
struct net_private *np = dev->priv;
struct sk_buff *skb;
+ rx_entry_t *rx;
again:
for ( i = np->rx_idx; i != np->net_ring->rx_cons; i = RX_RING_INC(i) )
{
- if (np->net_ring->rx_ring[i].status != RING_STATUS_OK)
+ rx = &np->net_ring->rx_ring[i];
+ skb = np->rx_skb_ring[i];
+
+ if ( rx->status != RING_STATUS_OK )
{
- printk(KERN_ALERT "bad buffer on RX ring!(%d)\n",
- np->net_ring->rx_ring[i].status);
+ printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
+ dev_kfree_skb_any(skb);
continue;
}
- skb = np->rx_skb_ring[i];
-
- phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT] =
- (*(unsigned long *)phys_to_virt(
- machine_to_phys(np->net_ring->rx_ring[i].addr))
- ) >> PAGE_SHIFT;
-
- skb_put(skb, np->net_ring->rx_ring[i].size);
- skb->protocol = eth_type_trans(skb, dev);
/*
* Set up shinfo -- from alloc_skb This was particularily nasty: the
@@ -346,6 +340,22 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
skb_shinfo(skb)->nr_frags = 0;
skb_shinfo(skb)->frag_list = NULL;
+ phys_to_machine_mapping[virt_to_phys(skb->head) >> PAGE_SHIFT] =
+ (*(unsigned long *)phys_to_virt(machine_to_phys(rx->addr))
+ ) >> PAGE_SHIFT;
+
+ if ( rx->offset < 16 )
+ {
+ printk(KERN_ALERT "need pkt offset >= 16 (got %d)\n", rx->offset);
+ dev_kfree_skb_any(skb);
+ continue;
+ }
+
+ skb_reserve(skb, rx->offset - 16);
+
+ skb_put(skb, np->net_ring->rx_ring[i].size);
+ skb->protocol = eth_type_trans(skb, dev);
+
np->stats.rx_packets++;
np->stats.rx_bytes += np->net_ring->rx_ring[i].size;