A few things:
- skb_reserve two bytes to longword-align the L3
part of incoming packets. Thanks to Philip Blundell
for pointing this out.
- Removed a delay loop in dma_rx() which snuck
through in my previous patch...
- Replace an occurence of 100 with HZ
- Remove some outmoded fiddling with skbuff internals.
- Fix initialisation of dev->priv's spinlock in
non-module mode.
- Added 'cs89x0_dma=N' __setup() option so
DMA Rx mode can be used when the driver is linked
in. (Yes, the __setup functions does return 1!).
- Updated documentation for the above.
Patch against 2.3.99-pre1 is attached.
--
-akpm---- linux-2.3.99-pre1/Documentation/networking/cs89x0.txt Tue Mar 14
21:20:31 2000
+++ linux.akpm/Documentation/networking/cs89x0.txt Fri Mar 24 01:13:21 2000
@@ -308,6 +308,30 @@
l) If during DMA operation you find erratic behavior or network data
corruption you should use your PC's BIOS to slow the EISA bus clock.
+m) If the cs89x0 driver is compiled directly into the kernel
+ (non-modular) then its I/O address is automatically determined by
+ ISA bus probing. The IRQ number, media options, etc are determined
+ from the card's EEPROM.
+
+n) If the cs89x0 driver is compiled directly into the kernel, DMA
+ mode may be selected by providing the kernel with a boot option
+ 'cs89x0_dma=N' where 'N' is the desired DMA channel number (5, 6 or
+ 7).
+
+ Kernel boot options may be provided on the LILO command line:
+
+ LILO boot: linux cs89x0_dma=5
+
+ or they may be placed in /etc/lilo.conf:
+
+ image=/boot/bzImage-2.3.48
+ append="cs89x0_dma=5"
+ label=linux
+ root=/dev/hda5
+ read-only
+
+ The DMA Rx buffer size is hardwared to 16 kbytes in this mode.
+ (64k mode is not available).
4.0 COMPILING THE DRIVER
===============================================================================
--- linux-2.3.99-pre1/drivers/net/cs89x0.c Tue Mar 14 21:20:37 2000
+++ linux.akpm/drivers/net/cs89x0.c Fri Mar 24 01:15:28 2000
@@ -48,10 +48,18 @@
: Don't call netif_wake_queue() in net_send_packet()
: Fixed an out-of-mem bug in dma_rx()
: Updated Documentation/cs89x0.txt
+
+ Andrew Morton : andrewm@xxxxxxxxxx / Kernel 2.3.99-pre1
+ : Use skb_reserve to longword align IP header (two places)
+ : Remove a delay loop from dma_rx()
+ : Replace '100' with HZ
+ : Clean up a couple of skb API abuses
+ : Added 'cs89x0_dma=N' kernel boot option
+ : Correctly initialise lp->lock in non-module compile
*/
static char *version =
-"cs89x0.c: (kernel 2.3.48) Russell Nelson <nelson@xxxxxxxxxx>, Andrew Morton
<andrewm@xxxxxxxxxx>\n";
+"cs89x0.c: v2.3.99-pre1-2 Russell Nelson <nelson@xxxxxxxxxx>, Andrew Morton
<andrewm@xxxxxxxxxx>\n";
/* ======================= end of configuration ======================= */
@@ -121,7 +129,7 @@
{ 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0,
0x2c0, 0x2e0, 0};
#if DEBUGGING
-static unsigned int net_debug = 5;
+static unsigned int net_debug = DEBUGGING;
#else
#define net_debug 0 /* gcc will remove all the debug code for us */
#endif
@@ -190,6 +198,21 @@
/* Example routines you must write ;->. */
#define tx_done(dev) 1
+/*
+ * Permit 'cs89x0_dma=N' in the kernel boot environment
+ */
+#if !defined(MODULE) && (ALLOW_DMA != 0)
+static int g_cs89x0_dma;
+
+static int __init dma_fn(char *str)
+{
+ g_cs89x0_dma = simple_strtol(str,NULL,0);
+ return 1;
+}
+
+__setup("cs89x0_dma=", dma_fn);
+#endif /* !defined(MODULE) && (ALLOW_DMA != 0) */
+
/* Check for a network adaptor of this type, and return '0' iff one exists.
If dev->base_addr == 0, probe all likely locations.
@@ -318,7 +341,17 @@
retval = ENOMEM;
goto out;
}
- memset(dev->priv, 0, sizeof(struct net_local));
+ lp = (struct net_local *)dev->priv;
+ memset(lp, 0, sizeof(*lp));
+ spin_lock_init(&lp->lock);
+#if !defined(MODULE) && (ALLOW_DMA != 0)
+ if (g_cs89x0_dma)
+ {
+ lp->use_dma = 1;
+ lp->dma = g_cs89x0_dma;
+ lp->dmasize = 16; /* Could make this an option...
*/
+ }
+#endif
}
lp = (struct net_local *)dev->priv;
@@ -612,12 +645,6 @@
int status, length;
unsigned char *bp = lp->rx_dma_ptr;
- {
- int i;
- for (i = 0; i < 1000; i++)
- ;
- }
-
status = bp[0] + (bp[1]<<8);
length = bp[2] + (bp[3]<<8);
bp += 4;
@@ -632,7 +659,7 @@
}
/* Malloc up new buffer. */
- skb = alloc_skb(length, GFP_ATOMIC);
+ skb = dev_alloc_skb(length + 2);
if (skb == NULL) {
if (net_debug) /* I don't think we want to do this to a
stressed system */
printk("%s: Memory squeeze, dropping packet.\n",
dev->name);
@@ -645,8 +672,7 @@
lp->rx_dma_ptr = bp;
return;
}
-
- skb->len = length;
+ skb_reserve(skb, 2); /* longword align L3 header */
skb->dev = dev;
if (bp + length > lp->end_dma_buff) {
@@ -720,7 +746,7 @@
writereg(dev, PP_SelfCTL, selfcontrol);
/* Wait for the DC/DC converter to power up - 500ms */
- while (jiffies - timenow < 100)
+ while (jiffies - timenow < HZ)
;
}
@@ -1317,7 +1343,7 @@
}
/* Malloc up new buffer. */
- skb = alloc_skb(length, GFP_ATOMIC);
+ skb = dev_alloc_skb(length + 2);
if (skb == NULL) {
#if 0 /* Again, this seems a cruel thing to do */
printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n",
dev->name);
@@ -1325,10 +1351,10 @@
lp->stats.rx_dropped++;
return;
}
- skb->len = length;
+ skb_reserve(skb, 2); /* longword align L3 header */
skb->dev = dev;
- insw(ioaddr + RX_FRAME_PORT, skb->data, length >> 1);
+ insw(ioaddr + RX_FRAME_PORT, skb_put(skb, length), length >> 1);
if (length & 1)
skb->data[length-1] = inw(ioaddr + RX_FRAME_PORT);
|