I managed to bring up the lance driver with a PCnetPCI card on
a Noname. I append the patch file to this mail. I'm not sure,
wether the patched lance driver is still running on an Intel
CPU and at the moment I'm not able to test this. So anyone
who is willing to test the patch on a Intel platform is welcome.
Please mail me any problems.
While doing this port, I noticed, that there is no support for
ISA busmaster cards (hopefully nobody will use them) for the Noname,
probably it's the same for the Cabriolet. David, do you have any
plans to change this ?
Another question: Has anyone brought up a 1.3.57 on a Noname ?
Mine crashes when the NCR looks for SCSI devices. Later I will
redo the NCR changes between 1.3.56 and 1.3.57, to check if
it's related to the last changes.
And one final thing I have no answer for: milo-1.3.52 booted
from floppy works without problem. But when I flash it, my
Noname won't come up. No sign of any activity. Any hint ?
Thomas.
PS: The patch is relative to 1.3.57, but only tested with 1.3.53.
--- lance.c-1.3.57 Sun Jan 14 22:26:32 1996
+++ linux/drivers/net/lance.c Tue Jan 16 22:04:45 1996
@@ -137,6 +137,30 @@
*/
+/*
+ * Changes:
+ * Thomas Bogendoerfer (tsbogend@bigbug.franken.de):
+ * - added support for Linux/Alpha
+ *
+ * At the moment only the PCnet PCI chip is supported for Linux/Alpha.
+ *
+ * I've started implementing the 32bit mode for the PCnet PCI, because
+ * especially on an Alpha with more than 16MByte ram, nearly every packet
+ * is copied to the bounce buffers:-(
+ */
+
+#ifdef __alpha__
+#if defined(CONFIG_ALPHA_LCA)
+#define DMA_WIN_BASE LCA_DMA_WIN_BASE
+#elif defined(CONFIG_ALPHA_APECS)
+#define DMA_WIN_BASE APECS_DMA_WIN_BASE
+#else
+#error Unknown PCI<->CPU address space mapping
+#endif
+#else /* __alpha__ */
+#define DMA_WIN_BASE 0x00000000L
+#endif
+
/* Set the number of Tx and Rx buffers, using Log_2(# buffers).
Reasonable default values are 4 Tx buffers, and 16 Rx buffers.
That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4). */
@@ -164,25 +188,25 @@
/* The LANCE Rx and Tx ring descriptors. */
struct lance_rx_head {
- int base;
- short buf_length; /* This length is 2s complement (negative)! */
- short msg_length; /* This length is "normal". */
+ s32 base;
+ s16 buf_length; /* This length is 2s complement (negative)! */
+ s16 msg_length; /* This length is "normal". */
};
struct lance_tx_head {
- int base;
- short length; /* Length is 2s complement (negative)! */
- short misc;
+ s32 base;
+ s16 length; /* Length is 2s complement (negative)! */
+ s16 misc;
};
/* The LANCE initialization block, described in databook. */
struct lance_init_block {
- unsigned short mode; /* Pre-set mode (reg. 15) */
- unsigned char phys_addr[6]; /* Physical ethernet address */
- unsigned filter[2]; /* Multicast filter (unused). */
+ u16 mode; /* Pre-set mode (reg. 15) */
+ u8 phys_addr[6]; /* Physical ethernet address */
+ u32 filter[2]; /* Multicast filter (unused). */
/* Receive and transmit ring base, along with extra bits. */
- unsigned rx_ring; /* Tx and Rx ring base pointers */
- unsigned tx_ring;
+ u32 rx_ring; /* Tx and Rx ring base pointers */
+ u32 tx_ring;
};
struct lance_private {
@@ -203,7 +227,7 @@
struct enet_statistics stats;
unsigned char chip_version; /* See lance_chip_type. */
char tx_full;
- char lock;
+ unsigned long lock;
};
#define LANCE_MUST_PAD 0x00000001
@@ -313,6 +337,8 @@
}
#endif /* defined(CONFIG_PCI) */
+/* On the Alpha don't look for PCnet chips on the ISA bus */
+#ifndef __alpha__
for (port = lance_portlist; *port; port++) {
int ioaddr = *port;
@@ -326,6 +352,7 @@
lance_probe1(ioaddr);
}
}
+#endif
return 0;
}
@@ -342,6 +369,7 @@
int hp_builtin = 0; /* HP on-board ethernet. */
static int did_version = 0; /* Already printed version info. */
+#ifndef __alpha__
/* First we look for special cases.
Check for HP's on-board ethernet by looking for 'HP' in the BIOS.
There are two HP versions, check the BIOS for the configuration port.
@@ -358,6 +386,7 @@
/* We also recognize the HP Vectra on-board here, but check below. */
hpJ2405A = (inb(ioaddr) == 0x08 && inb(ioaddr+1) == 0x00
&& inb(ioaddr+2) == 0x09);
+#endif
/* Reset the LANCE. */
reset_val = inw(ioaddr+LANCE_RESET); /* Reset the LANCE */
@@ -419,15 +448,15 @@
lp->init_block.phys_addr[i] = dev->dev_addr[i];
lp->init_block.filter[0] = 0x00000000;
lp->init_block.filter[1] = 0x00000000;
- lp->init_block.rx_ring = (int)lp->rx_ring | RX_RING_LEN_BITS;
- lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;
+ lp->init_block.rx_ring = ((u32)virt_to_bus(lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
+ lp->init_block.tx_ring = ((u32)virt_to_bus(lp->tx_ring) & 0xffffff) | TX_RING_LEN_BITS;
outw(0x0001, ioaddr+LANCE_ADDR);
inw(ioaddr+LANCE_ADDR);
- outw((short) (int) &lp->init_block, ioaddr+LANCE_DATA);
+ outw((short) (u32) virt_to_bus(&lp->init_block), ioaddr+LANCE_DATA);
outw(0x0002, ioaddr+LANCE_ADDR);
inw(ioaddr+LANCE_ADDR);
- outw(((int)&lp->init_block) >> 16, ioaddr+LANCE_DATA);
+ outw(((u32)virt_to_bus(&lp->init_block)) >> 16, ioaddr+LANCE_DATA);
outw(0x0000, ioaddr+LANCE_ADDR);
inw(ioaddr+LANCE_ADDR);
@@ -594,15 +623,17 @@
if (lance_debug > 1)
printk("%s: lance_open() irq %d dma %d tx/rx rings %#x/%#x init %#x.\n",
- dev->name, dev->irq, dev->dma, (int) lp->tx_ring, (int) lp->rx_ring,
- (int) &lp->init_block);
+ dev->name, dev->irq, dev->dma,
+ (u32) virt_to_bus(lp->tx_ring),
+ (u32) virt_to_bus(lp->rx_ring),
+ (u32) virt_to_bus(&lp->init_block));
lance_init_ring(dev);
/* Re-initialize the LANCE, and start it when done. */
outw(0x0001, ioaddr+LANCE_ADDR);
- outw((short) (int) &lp->init_block, ioaddr+LANCE_DATA);
+ outw((short) (u32) virt_to_bus(&lp->init_block), ioaddr+LANCE_DATA);
outw(0x0002, ioaddr+LANCE_ADDR);
- outw(((int)&lp->init_block) >> 16, ioaddr+LANCE_DATA);
+ outw(((u32)virt_to_bus(&lp->init_block)) >> 16, ioaddr+LANCE_DATA);
outw(0x0004, ioaddr+LANCE_ADDR);
outw(0x0915, ioaddr+LANCE_DATA);
@@ -625,7 +656,7 @@
if (lance_debug > 2)
printk("%s: LANCE open after %d ticks, init block %#x csr0 %4.4x.\n",
- dev->name, i, (int) &lp->init_block, inw(ioaddr+LANCE_DATA));
+ dev->name, i, (u32) virt_to_bus(&lp->init_block), inw(ioaddr+LANCE_DATA));
return 0; /* Always succeed */
}
@@ -683,8 +714,8 @@
lp->init_block.phys_addr[i] = dev->dev_addr[i];
lp->init_block.filter[0] = 0x00000000;
lp->init_block.filter[1] = 0x00000000;
- lp->init_block.rx_ring = (int)lp->rx_ring | RX_RING_LEN_BITS;
- lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;
+ lp->init_block.rx_ring = ((u32)virt_to_bus(lp->rx_ring) & 0xffffff) | RX_RING_LEN_BITS;
+ lp->init_block.tx_ring = ((u32)virt_to_bus(lp->tx_ring) & 0xffffff) | TX_RING_LEN_BITS;
}
static void
@@ -792,17 +823,17 @@
/* If any part of this buffer is >16M we must copy it to a low-memory
buffer. */
- if ((int)(skb->data) + skb->len > 0x01000000) {
+ if ((u32)virt_to_bus(skb->data) + skb->len > (0x01000000+DMA_WIN_BASE)) {
if (lance_debug > 5)
printk("%s: bouncing a high-memory packet (%#x).\n",
- dev->name, (int)(skb->data));
+ dev->name, (u32)virt_to_bus(skb->data));
memcpy(&lp->tx_bounce_buffs[entry], skb->data, skb->len);
lp->tx_ring[entry].base =
- (int)(lp->tx_bounce_buffs + entry) | 0x83000000;
+ ((u32)virt_to_bus((lp->tx_bounce_buffs + entry)) & 0xffffff) | 0x83000000;
dev_kfree_skb (skb, FREE_WRITE);
} else {
lp->tx_skbuff[entry] = skb;
- lp->tx_ring[entry].base = (int)(skb->data) | 0x83000000;
+ lp->tx_ring[entry].base = ((u32)virt_to_bus(skb->data) & 0xffffff) | 0x83000000;
}
lp->cur_tx++;
@@ -1010,7 +1041,7 @@
skb_reserve(skb,2); /* 16 byte align */
skb_put(skb,pkt_len); /* Make room */
eth_copy_and_sum(skb,
- (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
+ (unsigned char *)bus_to_virt((lp->rx_ring[entry].base & 0x00ffffff) + DMA_WIN_BASE),
pkt_len,0);
skb->protocol=eth_type_trans(skb,dev);
netif_rx(skb);