aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.16-sparse/arch
diff options
context:
space:
mode:
authorakw27@boulderdash.cl.cam.ac.uk <akw27@boulderdash.cl.cam.ac.uk>2003-02-14 14:27:45 +0000
committerakw27@boulderdash.cl.cam.ac.uk <akw27@boulderdash.cl.cam.ac.uk>2003-02-14 14:27:45 +0000
commited220108094cf8e5c3f70a7421182cdbcb59f3d3 (patch)
tree22722275b0a231a057b08d99825b24d551545396 /xenolinux-2.4.16-sparse/arch
parentce62d9e7f6d76422b025939279a2a51b5262a06d (diff)
parent77cf55f0b8964f4d82d7119bfe59db8fddf4b320 (diff)
downloadxen-ed220108094cf8e5c3f70a7421182cdbcb59f3d3.tar.gz
xen-ed220108094cf8e5c3f70a7421182cdbcb59f3d3.tar.bz2
xen-ed220108094cf8e5c3f70a7421182cdbcb59f3d3.zip
bitkeeper revision 1.34 (3e4cfce1Ot4YJzJ4jwNjDthlFrZV5w)
conflict resolution.
Diffstat (limited to 'xenolinux-2.4.16-sparse/arch')
-rw-r--r--xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c127
1 files changed, 101 insertions, 26 deletions
diff --git a/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c b/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c
index b018e29e49..87b1a97fdc 100644
--- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c
+++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c
@@ -21,14 +21,12 @@
#include <linux/skbuff.h>
#include <linux/init.h>
+#include <asm/io.h>
#include <net/sock.h>
#define NET_TX_IRQ _EVENT_NET_TX
#define NET_RX_IRQ _EVENT_NET_RX
-#define NET_TX_IRQ_FOR_VIF(x) _EVENT_NET_TX_FOR_VIF(x)
-#define NET_RX_IRQ_FOR_VIF(x) _EVENT_NET_RX_FOR_VIF(x)
-
#define TX_MAX_ENTRIES (TX_RING_SIZE - 2)
#define RX_MAX_ENTRIES (RX_RING_SIZE - 2)
@@ -37,7 +35,7 @@
#define TX_RING_ADD(_i,_j) (((_i)+(_j)) & (TX_RING_SIZE-1))
#define RX_RING_ADD(_i,_j) (((_i)+(_j)) & (RX_RING_SIZE-1))
-#define RX_BUF_SIZE 1600 /* Ethernet MTU + plenty of slack! */
+#define RX_BUF_SIZE 2049 /* (was 1600) Ethernet MTU + plenty of slack! */
static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs);
static void network_tx_int(int irq, void *dev_id, struct pt_regs *ptregs);
@@ -48,6 +46,8 @@ static void cleanup_module(void);
static struct list_head dev_list;
+static unsigned int net_countx;
+
/*
* RX RING: RX_IDX <= rx_cons <= rx_prod
* TX RING: TX_IDX <= tx_cons <= tx_prod
@@ -72,16 +72,8 @@ struct net_private
static int network_open(struct net_device *dev)
{
struct net_private *np = dev->priv;
- int error;
- char *rxlabel, *txlabel;
-
- // This is inevitably not the right way to allocate a couple of static strings.
- rxlabel = kmalloc(sizeof("net-rx- "), GFP_KERNEL);
- txlabel = kmalloc(sizeof("net-tx- "), GFP_KERNEL);
- if ((rxlabel == NULL) || (txlabel == NULL)) goto fail;
- sprintf(rxlabel, "net-rx-%d", np->id);
- sprintf(txlabel, "net-tx-%d", np->id);
-
+ int error = 0;
+
np->rx_idx = np->tx_idx = np->tx_full = 0;
memset(&np->stats, 0, sizeof(np->stats));
@@ -113,8 +105,8 @@ static int network_open(struct net_device *dev)
network_alloc_rx_buffers(dev);
- error = request_irq(NET_RX_IRQ_FOR_VIF(np->id), network_rx_int, 0,
- rxlabel, dev);
+ error = request_irq(NET_RX_IRQ, network_rx_int, 0,
+ "net-rx", dev);
if ( error )
{
printk(KERN_WARNING "%s: Could not allocate receive interrupt\n",
@@ -122,13 +114,13 @@ static int network_open(struct net_device *dev)
goto fail;
}
- error = request_irq(NET_TX_IRQ_FOR_VIF(np->id), network_tx_int, 0,
- txlabel, dev);
+ error = request_irq(NET_TX_IRQ, network_tx_int, 0,
+ "net-tx", dev);
if ( error )
{
printk(KERN_WARNING "%s: Could not allocate transmit interrupt\n",
dev->name);
- free_irq(NET_RX_IRQ_FOR_VIF(np->id), dev);
+ free_irq(NET_RX_IRQ, dev);
goto fail;
}
@@ -141,8 +133,6 @@ static int network_open(struct net_device *dev)
return 0;
fail:
- if ( rxlabel ) kfree(rxlabel);
- if ( txlabel ) kfree(txlabel);
if ( np->net_ring->rx_ring ) kfree(np->net_ring->rx_ring);
if ( np->net_ring->tx_ring ) kfree(np->net_ring->tx_ring);
if ( np->rx_skb_ring ) kfree(np->rx_skb_ring);
@@ -179,13 +169,59 @@ static void network_tx_buf_gc(struct net_device *dev)
spin_unlock_irqrestore(&np->tx_lock, flags);
}
+inline unsigned long get_ppte(unsigned long addr)
+{
+ unsigned long ppte = 0xdeadbeef;
+ pgd_t *pgd; pmd_t *pmd; pte_t *ptep;
+ pgd = pgd_offset_k(addr);
+
+ if (pgd_none(*pgd) || pgd_bad(*pgd)) BUG();
+
+ pmd = pmd_offset(pgd, addr);
+ if (pmd_none(*pmd)) BUG();
+ if (pmd_bad(*pmd)) BUG();
+
+ ptep = pte_offset(pmd, addr);
+ ppte = (unsigned long)phys_to_machine(virt_to_phys(ptep));
+
+ return ppte;
+}
+/*
+static void validate_free_list(void)
+{
+ unsigned long addr, ppfn, mpfn, mpfn2, flags;
+ struct list_head *i;
+ struct net_page_info *np;
+
+ printk(KERN_ALERT "Walking free pages:\n");
+
+ spin_lock_irqsave(&net_page_list_lock, flags);
+
+ list_for_each(i, &net_page_list)
+ {
+ np = list_entry(i, struct net_page_info, list);
+ addr = np->virt_addr;
+ ppfn = virt_to_phys(addr) >> PAGE_SHIFT;
+ mpfn = get_ppte(addr);
+ mpfn2 = phys_to_machine_mapping[ppfn];
+
+ mpfn = (*(unsigned long *)phys_to_virt(machine_to_phys(mpfn))) >> PAGE_SHIFT;
+ if (mpfn != mpfn2) printk(KERN_ALERT "mpfn %lu != %lu\n", mpfn, mpfn2);
+ if (machine_to_phys_mapping[mpfn] != ppfn) printk(KERN_ALERT "ppfn %lu != %lu\n", machine_to_phys_mapping[mpfn], ppfn);
+ }
+
+ spin_unlock_irqrestore(&net_page_list_lock, flags);
+
+}
+*/
static void network_alloc_rx_buffers(struct net_device *dev)
{
unsigned int i;
struct net_private *np = dev->priv;
struct sk_buff *skb;
unsigned int end = RX_RING_ADD(np->rx_idx, RX_MAX_ENTRIES);
+
for ( i = np->net_ring->rx_prod; i != end; i = RX_RING_INC(i) )
{
@@ -194,8 +230,9 @@ static void network_alloc_rx_buffers(struct net_device *dev)
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 = (unsigned long)skb->data;
+ np->net_ring->rx_ring[i].addr = get_ppte(skb->head);
np->net_ring->rx_ring[i].size = RX_BUF_SIZE - 16; /* arbitrary */
+//printk(KERN_ALERT "[%p]\n", phys_to_machine(virt_to_phys(skb->page_ptr)));
}
np->net_ring->rx_prod = i;
@@ -219,6 +256,14 @@ static void network_free_rx_buffers(struct net_device *dev)
}
}
+void print_range(u8 *start, unsigned int len)
+{
+ int i = 0;
+
+ while (i++ < len)
+ printk("%x:", start[i]);
+ printk("\n");
+}
static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
@@ -231,10 +276,23 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
netif_stop_queue(dev);
return -ENOBUFS;
}
-
+//print_range(skb->data, ETH_HLEN + 8);
+//print_range(skb->data + ETH_HLEN + 8, 20);
+//printk("skb->len is %u in guestOS (expected fraglen: %u).\n", skb->len, skb->len - (ETH_HLEN + 8));
i = np->net_ring->tx_prod;
+
+ if ( (((unsigned long)skb->data & ~PAGE_MASK) + skb->len) >= PAGE_SIZE )
+ {
+ struct sk_buff *new_skb = alloc_skb(RX_BUF_SIZE, GFP_KERNEL);
+ skb_put(new_skb, skb->len);
+ memcpy(new_skb->data, skb->data, skb->len);
+ kfree_skb(skb);
+ skb = new_skb;
+ }
+
np->tx_skb_ring[i] = skb;
- np->net_ring->tx_ring[i].addr = (unsigned long)skb->data;
+ np->net_ring->tx_ring[i].addr
+ = (unsigned long)phys_to_machine(virt_to_phys(skb->data));
np->net_ring->tx_ring[i].size = skb->len;
np->net_ring->tx_prod = TX_RING_INC(i);
atomic_inc(&np->tx_entries);
@@ -273,13 +331,30 @@ static void network_rx_int(int irq, void *dev_id, struct pt_regs *ptregs)
struct net_private *np = dev->priv;
struct sk_buff *skb;
+ /*if (net_countx++ % 100 == 0) validate_free_list();*/
+
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)
+ {
+ printk("bad buffer on RX ring!(%d)\n",
+ np->net_ring->rx_ring[i].status);
+ continue;
+ }
skb = np->rx_skb_ring[i];
+
+//printk(KERN_ALERT "[%u]: ptmm[%lx] old:(%lx) new:(%lx)\n", i , virt_to_phys(skb->head) >> PAGE_SHIFT, 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);
+
+ 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);
np->stats.rx_packets++;
+
np->stats.rx_bytes += np->net_ring->rx_ring[i].size;
netif_rx(skb);
dev->last_rx = jiffies;
@@ -309,8 +384,8 @@ int network_close(struct net_device *dev)
struct net_private *np = dev->priv;
netif_stop_queue(dev);
- free_irq(NET_RX_IRQ_FOR_VIF(np->id), dev);
- free_irq(NET_TX_IRQ_FOR_VIF(np->id), dev);
+ free_irq(NET_RX_IRQ, dev);
+ free_irq(NET_TX_IRQ, dev);
network_free_rx_buffers(dev);
kfree(np->net_ring->rx_ring);
kfree(np->net_ring->tx_ring);