diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Documentation/Configure.help linux.24rc5/Documentation/Configure.help --- linux.vanilla/Documentation/Configure.help Mon Dec 16 18:19:25 2002 +++ linux.24rc5/Documentation/Configure.help Mon Mar 3 14:58:24 2003 @@ -5712,10 +5712,20 @@ Wireless LAN (non-hamradio) CONFIG_NET_RADIO Support for wireless LANs and everything having to do with radio, - but not with amateur radio. Note that the answer to this question - won't directly affect the kernel: saying N will just cause this - configure script to skip all the questions about radio - interfaces. + but not with amateur radio or FM broadcasting. + + Saying Y here also enables the Wireless Extensions (creates + /proc/net/wireless and enables ifconfig access). The Wireless + Extension is a generic API allowing a driver to expose to the user + space configuration and statistics specific to common Wireless LANs. + The beauty of it is that a single set of tool can support all the + variations of Wireless LANs, regardless of their type (as long as + the driver supports Wireless Extension). Another advantage is that + these parameters may be changed on the fly without restarting the + driver (or Linux). If you wish to use Wireless Extensions with + wireless PCMCIA (PC-) cards, you need to say Y here; you can fetch + the tools from + . Some user-level drivers for scarab devices which don't require special kernel support are available via FTP (user: anonymous) from diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/MAINTAINERS linux.24rc5/MAINTAINERS --- linux.vanilla/MAINTAINERS Wed Sep 18 15:23:16 2002 +++ linux.24rc5/MAINTAINERS Mon Dec 16 18:55:15 2002 @@ -691,19 +691,14 @@ S: Maintained NETWORKING [GENERAL] -P: Networking Teak +P: Networking Team M: netdev@oss.sgi.com L: linux-net@vger.kernel.org -W: http://www.uk.linux.org/NetNews.html (2.0 only) S: Maintained NETWORKING [IPv4/IPv6] -P: David S. Miller -M: davem@redhat.com -P: Andi Kleen -M: ak@muc.de -P: Alexey Kuznetsov -M: kuznet@ms2.inr.ac.ru +P: James Morris +M: jmorris@intercode.com.au L: netdev@oss.sgi.com S: Maintained diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/Makefile linux.24rc5/Makefile --- linux.vanilla/Makefile Mon Dec 16 18:19:26 2002 +++ linux.24rc5/Makefile Wed Feb 19 13:33:37 2003 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 2 -SUBLEVEL = 23 +SUBLEVEL = 24 EXTRAVERSION = ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/arch/i386/kernel/setup.c linux.24rc5/arch/i386/kernel/setup.c --- linux.vanilla/arch/i386/kernel/setup.c Wed Sep 18 15:23:16 2002 +++ linux.24rc5/arch/i386/kernel/setup.c Thu Dec 19 18:52:36 2002 @@ -1378,8 +1378,9 @@ return; case X86_VENDOR_AMD: - init_amd(c); - return; + if(init_amd(c)) + return; + break; case X86_VENDOR_CENTAUR: init_centaur(c); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/n_hdlc.c linux.24rc5/drivers/char/n_hdlc.c --- linux.vanilla/drivers/char/n_hdlc.c Fri Nov 2 16:39:06 2001 +++ linux.24rc5/drivers/char/n_hdlc.c Mon Mar 3 14:52:58 2003 @@ -9,7 +9,7 @@ * Al Longyear , Paul Mackerras * * Original release 01/11/99 - * $Id: n_hdlc.c,v 2.3 2001/05/09 14:42:37 paul Exp $ + * $Id: n_hdlc.c,v 2.4 2002/12/19 18:58:54 paulkf Exp $ * * This code is released under the GNU General Public License (GPL) * @@ -78,7 +78,7 @@ */ #define HDLC_MAGIC 0x239e -#define HDLC_VERSION "$Revision: 2.3 $" +#define HDLC_VERSION "$Revision: 2.4 $" #include #include @@ -184,9 +184,9 @@ /* * HDLC buffer list manipulation functions */ -void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list); -void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf); -N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list); +static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list); +static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf); +static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list); /* Local functions */ @@ -197,10 +197,10 @@ /* debug level can be set by insmod for debugging purposes */ #define DEBUG_LEVEL_INFO 1 -int debuglevel=0; +static int debuglevel=0; /* max frame size for memory allocations */ -ssize_t maxframe=4096; +static ssize_t maxframe=4096; /* TTY callbacks */ @@ -921,7 +921,7 @@ * Arguments: list pointer to buffer list * Return Value: None */ -void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list) +static void n_hdlc_buf_list_init(N_HDLC_BUF_LIST *list) { memset(list,0,sizeof(N_HDLC_BUF_LIST)); spin_lock_init(&list->spinlock); @@ -938,7 +938,7 @@ * * Return Value: None */ -void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf) +static void n_hdlc_buf_put(N_HDLC_BUF_LIST *list,N_HDLC_BUF *buf) { unsigned long flags; spin_lock_irqsave(&list->spinlock,flags); @@ -968,7 +968,7 @@ * * pointer to HDLC buffer if available, otherwise NULL */ -N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list) +static N_HDLC_BUF* n_hdlc_buf_get(N_HDLC_BUF_LIST *list) { unsigned long flags; N_HDLC_BUF *buf; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/pms.c linux.24rc5/drivers/char/pms.c --- linux.vanilla/drivers/char/pms.c Sun Mar 25 17:31:26 2001 +++ linux.24rc5/drivers/char/pms.c Mon Dec 16 19:00:27 2002 @@ -619,7 +619,7 @@ } -static int pms_capture(struct pms_device *dev, char *buf, int rgb555, int count) +static int pms_capture(struct pms_device *dev, char *buf, int rgb555, unsigned long count) { int y; int dw = 2*dev->width; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/char/rtc.c linux.24rc5/drivers/char/rtc.c --- linux.vanilla/drivers/char/rtc.c Fri Aug 30 14:49:09 2002 +++ linux.24rc5/drivers/char/rtc.c Mon Mar 3 14:57:50 2003 @@ -271,22 +271,18 @@ min = alm_tm.tm_min; sec = alm_tm.tm_sec; - if (hrs >= 24) - hrs = 0xff; - - if (min >= 60) - min = 0xff; - - if (sec >= 60) - sec = 0xff; - spin_lock_irqsave(&rtc_lock, flags); if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { - BIN_TO_BCD(sec); - BIN_TO_BCD(min); - BIN_TO_BCD(hrs); + if (sec < 60) BIN_TO_BCD(sec); + else sec = 0xff; + + if (min < 60) BIN_TO_BCD(min); + else min = 0xff; + + if (hrs < 24) BIN_TO_BCD(hrs); + else hrs = 0xff; } CMOS_WRITE(hrs, RTC_HOURS_ALARM); CMOS_WRITE(min, RTC_MINUTES_ALARM); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/3c501.c linux.24rc5/drivers/net/3c501.c --- linux.vanilla/drivers/net/3c501.c Sun Mar 25 17:31:15 2001 +++ linux.24rc5/drivers/net/3c501.c Fri Feb 7 07:04:51 2003 @@ -422,8 +422,15 @@ } else { - int gp_start = 0x800 - (ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN); + int len = skb->len; + int pad = 0; + int gp_start; unsigned char *buf = skb->data; + + if(len < ETH_ZLEN) + pad = ETH_ZLEN - len; + + gp_start = 0x800 - ( len + pad ); load_it_again_sam: lp->tx_pkt_start = gp_start; @@ -451,7 +458,12 @@ outw(0x00, RX_BUF_CLR); /* Set rx packet area to 0. */ outw(gp_start, GP_LOW); /* aim - packet will be loaded into buffer start */ - outsb(DATAPORT,buf,skb->len); /* load buffer (usual thing each byte increments the pointer) */ + outsb(DATAPORT,buf,len); /* load buffer (usual thing each byte increments the pointer) */ + if(pad) + { + while(pad--) /* Zero fill buffer tail */ + outb(0, DATAPORT); + } outw(gp_start, GP_LOW); /* the board reuses the same register */ if(lp->loading==2) /* A receive upset our load, despite our best efforts */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/3c505.c linux.24rc5/drivers/net/3c505.c --- linux.vanilla/drivers/net/3c505.c Fri Nov 2 16:39:07 2001 +++ linux.24rc5/drivers/net/3c505.c Fri Feb 7 07:05:36 2003 @@ -1062,8 +1062,9 @@ adapter->current_dma.direction = 1; adapter->current_dma.start_time = jiffies; - if ((unsigned long)(skb->data + nlen) >= MAX_DMA_ADDRESS) { - memcpy(adapter->dma_buffer, skb->data, nlen); + if ((unsigned long)(skb->data + nlen) >= MAX_DMA_ADDRESS || nlen != skb->len) { + memcpy(adapter->dma_buffer, skb->data, skb->len); + memset(adapter->dma_buffer+skb->len, 0, nlen-skb->len); target = virt_to_bus(adapter->dma_buffer); } else { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/3c507.c linux.24rc5/drivers/net/3c507.c --- linux.vanilla/drivers/net/3c507.c Fri Aug 30 14:49:10 2002 +++ linux.24rc5/drivers/net/3c507.c Fri Feb 7 07:07:43 2003 @@ -290,7 +290,7 @@ static int el16_close(struct device *dev); static struct net_device_stats *el16_get_stats(struct device *dev); -static void hardware_send_packet(struct device *dev, void *buf, short length); +static void hardware_send_packet(struct device *dev, void *buf, short length, short pad); static void init_82586_mem(struct device *dev); @@ -495,10 +495,10 @@ outb(0x80, ioaddr + MISC_CTRL); #ifdef CONFIG_SMP spin_lock_irqsave(&lp->lock, flags); - hardware_send_packet(dev, buf, length); + hardware_send_packet(dev, buf, skb->len, length - skb->len); spin_unlock_irqrestore(&lp->lock, flags); #else - hardware_send_packet(dev, buf, length); + hardware_send_packet(dev, buf, skb->len, length - skb->len); #endif dev->trans_start = jiffies; /* Enable the 82586 interrupt input. */ @@ -758,12 +758,13 @@ return; } -static void hardware_send_packet(struct device *dev, void *buf, short length) +static void hardware_send_packet(struct device *dev, void *buf, short length, short pad) { struct net_local *lp = (struct net_local *)dev->priv; short ioaddr = dev->base_addr; ushort tx_block = lp->tx_head; unsigned long write_ptr = dev->mem_start + tx_block; + static char padding[ETH_ZLEN]; /* Set the write pointer to the Tx block, and put out the header. */ writew(0x0000,write_ptr); /* Tx status */ @@ -772,7 +773,7 @@ writew(tx_block+8,write_ptr+=2); /* Data Buffer offset. */ /* Output the data buffer descriptor. */ - writew(length | 0x8000,write_ptr+=2); /* Byte count parameter. */ + writew((pad + length) | 0x8000,write_ptr+=2); /* Byte count parameter. */ writew(-1,write_ptr+=2); /* No next data buffer. */ writew(tx_block+22+SCB_BASE,write_ptr+=2); /* Buffer follows the NoOp command. */ writew(0x0000,write_ptr+=2); /* Buffer address high bits (always zero). */ @@ -784,6 +785,8 @@ /* Output the packet at the write pointer. */ memcpy_toio(write_ptr+2, buf, length); + if(pad) + memcpy_toio(write_ptr+length+2, padding, pad); /* Set the old command link pointing to this send packet. */ writew(tx_block,dev->mem_start + lp->tx_cmd_link); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/3c523.c linux.24rc5/drivers/net/3c523.c --- linux.vanilla/drivers/net/3c523.c Sun Mar 25 17:31:17 2001 +++ linux.24rc5/drivers/net/3c523.c Thu Feb 13 20:19:02 2003 @@ -1118,8 +1118,10 @@ if (test_and_set_bit(0, (void *) &dev->tbusy) != 0) { printk("%s: Transmitter access conflict.\n", dev->name); } else { - memcpy((char *) p->xmit_cbuffs[p->xmit_count], (char *) (skb->data), skb->len); len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; + if(len != skb->len) + memset((char *) p->xmit_cbuffs[p->xmit_count], 0, ETH_ZLEN); + memcpy((char *) p->xmit_cbuffs[p->xmit_count], (char *) (skb->data), skb->len); #if (NUM_XMIT_BUFFS == 1) #ifdef NO_NOPCOMMANDS diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/3c527.c linux.24rc5/drivers/net/3c527.c --- linux.vanilla/drivers/net/3c527.c Sun Mar 25 17:37:34 2001 +++ linux.24rc5/drivers/net/3c527.c Fri Feb 7 06:38:21 2003 @@ -1087,6 +1087,12 @@ /* We will need this to flush the buffer out */ lp->tx_ring[lp->tx_ring_head].skb=skb; + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + goto out; + } np->length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; np->data = virt_to_bus(skb->data); @@ -1096,6 +1102,7 @@ p->control &= ~CONTROL_EOL; /* Clear EOL on p */ +out: dev->tbusy = 0; /* Keep feeding me */ restore_flags(flags); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/7990.c linux.24rc5/drivers/net/7990.c --- linux.vanilla/drivers/net/7990.c Sun Mar 25 17:31:20 2001 +++ linux.24rc5/drivers/net/7990.c Fri Feb 7 07:09:02 2003 @@ -542,6 +542,8 @@ ib->btx_ring [entry].length = (-len) | 0xf000; ib->btx_ring [entry].misc = 0; + if(skb->len < ETH_ZLEN) + memset((char *)&ib->tx_buf[entry][0], 0, ETH_ZLEN); memcpy ((char *)&ib->tx_buf [entry][0], skb->data, skblen); /* Now, give the packet to the lance */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/8139too.c linux.24rc5/drivers/net/8139too.c --- linux.vanilla/drivers/net/8139too.c Fri Aug 30 14:49:10 2002 +++ linux.24rc5/drivers/net/8139too.c Wed Feb 19 13:28:17 2003 @@ -1840,6 +1840,14 @@ return 0; } } + + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } + mb(); /* Calculate the next Tx descriptor entry. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/82596.c linux.24rc5/drivers/net/82596.c --- linux.vanilla/drivers/net/82596.c Fri Nov 2 16:39:07 2001 +++ linux.24rc5/drivers/net/82596.c Fri Feb 7 06:39:29 2003 @@ -1045,9 +1045,19 @@ if (test_and_set_bit(0, (void *) &dev->tbusy) != 0) printk("%s: Transmitter access conflict.\n", dev->name); else { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + short length = skb->len; dev->trans_start = jiffies; + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + dev->tbusy = 0; + return 0; + } + length = ETH_ZLEN; + } tx_cmd = lp->tx_cmds + lp->next_tx_cmd; tbd = lp->tbds + lp->next_tx_cmd; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/8390.c linux.24rc5/drivers/net/8390.c --- linux.vanilla/drivers/net/8390.c Sun Mar 25 17:31:15 2001 +++ linux.24rc5/drivers/net/8390.c Fri Feb 7 07:11:10 2003 @@ -196,6 +196,7 @@ struct ei_device *ei_local = (struct ei_device *) dev->priv; int length, send_length, output_page; unsigned long flags; + char scratch[ETH_ZLEN]; /* * We normally shouldn't be called if dev->tbusy is set, but the @@ -348,8 +349,16 @@ * isn't already sending. If it is busy, the interrupt handler will * trigger the send later, upon receiving a Tx done interrupt. */ - - ei_block_output(dev, length, skb->data, output_page); + + if(length == send_length) + ei_block_output(dev, length, skb->data, output_page); + else + { + memset(scratch, 0, ETH_ZLEN); + memcpy(scratch, skb->data, skb->len); + ei_block_output(dev, ETH_ZLEN, scratch, output_page); + } + if (! ei_local->txing) { ei_local->txing = 1; @@ -378,7 +387,14 @@ * reasonable hardware if you only use one Tx buffer. */ - ei_block_output(dev, length, skb->data, ei_local->tx_start_page); + if(length == send_length) + ei_block_output(dev, length, skb->data, ei_local->tx_start_page); + else + { + memset(scratch, 0, ETH_ZLEN); + memcpy(scratch, skb->data, skb->len); + ei_block_output(dev, ETH_ZLEN, scratch, ei_local->tx_start_page); + } ei_local->txing = 1; NS8390_trigger_send(dev, send_length, ei_local->tx_start_page); dev->trans_start = jiffies; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/a2065.c linux.24rc5/drivers/net/a2065.c --- linux.vanilla/drivers/net/a2065.c Sun Mar 25 17:31:17 2001 +++ linux.24rc5/drivers/net/a2065.c Fri Feb 7 06:40:20 2003 @@ -594,7 +594,16 @@ } skblen = skb->len; - + len = skblen; + + if(len < ETH_ZLEN) + { + len = ETH_ZLEN; + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } + save_flags(flags); cli(); @@ -615,7 +624,6 @@ } } #endif - len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen; entry = lp->tx_new & lp->tx_ring_mod_mask; ib->btx_ring [entry].length = (-len) | 0xf000; ib->btx_ring [entry].misc = 0; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/am79c961a.c linux.24rc5/drivers/net/am79c961a.c --- linux.vanilla/drivers/net/am79c961a.c Sun Mar 25 17:31:20 2001 +++ linux.24rc5/drivers/net/am79c961a.c Fri Feb 7 06:41:20 2003 @@ -524,11 +524,24 @@ if (!dev->tbusy) { again: if (!test_and_set_bit(0, (void*)&dev->tbusy)) { - unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + unsigned int length = skb->len; unsigned int hdraddr, bufaddr; unsigned int head; unsigned long flags; + + /* FIXME: I thought the 79c961 could do padding - RMK ??? */ + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + dev->tbusy = 0; + return 0; + } + length = ETH_ZLEN; + } + head = priv->txhead; hdraddr = priv->txhdr + (head << 3); bufaddr = priv->txbuffer[head]; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/ariadne.c linux.24rc5/drivers/net/ariadne.c --- linux.vanilla/drivers/net/ariadne.c Sun Mar 25 17:31:18 2001 +++ linux.24rc5/drivers/net/ariadne.c Fri Feb 7 06:42:35 2003 @@ -547,6 +547,7 @@ struct AriadneBoard *board = priv->board; int entry; unsigned long flags; + int len = skb->len; /* Transmitter timeout, serious problems. */ if (dev->tbusy) { @@ -608,6 +609,18 @@ } /* Fill in a Tx ring entry */ + /* FIXME: is the 79C960 new enough to do its own padding right ? */ + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + dev->tbusy = 0; + return 0; + } + len = ETH_ZLEN; + } ++ #if 0 printk("TX pkt type 0x%04x from ", ((u_short *)skb->data)[6]); @@ -637,7 +650,7 @@ priv->tx_ring[entry]->TMD2 = swapw((u_short)-skb->len); priv->tx_ring[entry]->TMD3 = 0x0000; - memcpyw(priv->tx_buff[entry], (u_short *)skb->data, skb->len); + memcpyw(priv->tx_buff[entry], (u_short *)skb->data, len); #if 0 { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/at1700.c linux.24rc5/drivers/net/at1700.c --- linux.vanilla/drivers/net/at1700.c Sun Mar 25 17:31:16 2001 +++ linux.24rc5/drivers/net/at1700.c Thu Feb 13 20:18:49 2003 @@ -576,7 +576,8 @@ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) printk("%s: Transmitter access conflict.\n", dev->name); else { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + short length = skb->len; + static u8 pad[ETH_ZLEN]; unsigned char *buf = skb->data; /* We may not start transmitting unless we finish transferring @@ -587,7 +588,17 @@ lp->tx_queue_ready = 0; { outw(length, ioaddr + DATAPORT); + /* Packet data */ outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1); + /* Check for dribble byte */ + if(length & 1) + { + outw(skb->data[skb->len-1], ioaddr + DATAPORT); + length--; + } + /* Check for packet padding */ + if(length != skb->len) + outsw(ioaddr + DATAPORT, pad, (length - skb->len + 1) >> 1); lp->tx_queue++; lp->tx_queue_len += length + 2; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/atarilance.c linux.24rc5/drivers/net/atarilance.c --- linux.vanilla/drivers/net/atarilance.c Sun Mar 25 17:31:18 2001 +++ linux.24rc5/drivers/net/atarilance.c Fri Feb 7 06:43:57 2003 @@ -766,6 +766,21 @@ DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n", dev->name, DREG )); + /* The old LANCE chips doesn't automatically pad buffers to min. size. */ + len = skb->len; + if(len < ETH_ZLEN) + len = ETH_ZLEN; + /* PAM-Card has a bug: Can only send packets with even number of bytes! */ + else if (lp->cardtype == PAM_CARD && (len & 1)) + ++len; + + if(len > skb->len) + { + skb = skb_padto(skb, len); + if(skb == NULL) + return 0; + } + /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (test_and_set_bit( 0, (void*)&dev->tbusy ) != 0) { @@ -807,12 +822,6 @@ * last. */ - /* The old LANCE chips doesn't automatically pad buffers to min. size. */ - len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; - /* PAM-Card has a bug: Can only send packets with even number of bytes! */ - if (lp->cardtype == PAM_CARD && (len & 1)) - ++len; - head->length = -len; head->misc = 0; lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len ); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/atp.c linux.24rc5/drivers/net/atp.c --- linux.vanilla/drivers/net/atp.c Sun Mar 25 17:31:15 2001 +++ linux.24rc5/drivers/net/atp.c Fri Feb 7 07:15:33 2003 @@ -133,7 +133,7 @@ static unsigned short eeprom_op(short ioaddr, unsigned int cmd); static int net_open(struct device *dev); static void hardware_init(struct device *dev); -static void write_packet(short ioaddr, int length, unsigned char *packet, int mode); +static void write_packet(short ioaddr, int length, unsigned char *packet, int pad, int mode); static void trigger_send(short ioaddr, int length); static int net_send_packet(struct sk_buff *skb, struct device *dev); static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs); @@ -381,15 +381,23 @@ write_reg(ioaddr, CMR1, CMR1_Xmit); } -static void write_packet(short ioaddr, int length, unsigned char *packet, int data_mode) +static void write_packet(short ioaddr, int length, unsigned char *packet, int pad_len, int data_mode) { - length = (length + 1) & ~1; /* Round up to word length. */ + if(length & 1) + { + length++; + pad_len++; + } + outb(EOC+MAR, ioaddr + PAR_DATA); if ((data_mode & 1) == 0) { /* Write the packet out, starting with the write addr. */ outb(WrAddr+MAR, ioaddr + PAR_DATA); do { write_byte_mode0(ioaddr, *packet++); + } while (--length > pad_len) ; + do { + write_byte_mode0(ioaddr, 0); } while (--length > 0) ; } else { /* Write the packet out in slow mode. */ @@ -403,8 +411,10 @@ outbyte >>= 4; outb(outbyte & 0x0f, ioaddr + PAR_DATA); outb(Ctrl_HNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL); - while (--length > 0) + while (--length > pad_len) write_byte_mode1(ioaddr, *packet++); + while (--length > 0) + write_byte_mode1(ioaddr, 0); } /* Terminate the Tx frame. End of write: ECB. */ outb(0xff, ioaddr + PAR_DATA); @@ -450,7 +460,7 @@ write_reg_high(ioaddr, IMR, 0); restore_flags(flags); - write_packet(ioaddr, length, buf, dev->if_port); + write_packet(ioaddr, length, buf, length-skb->len, dev->if_port); lp->pac_cnt_in_tx_buf++; if (lp->tx_unit_busy == 0) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/bagetlance.c linux.24rc5/drivers/net/bagetlance.c --- linux.vanilla/drivers/net/bagetlance.c Sun Mar 25 17:31:21 2001 +++ linux.24rc5/drivers/net/bagetlance.c Fri Feb 7 06:44:03 2003 @@ -831,6 +831,19 @@ struct lance_tx_head *head; unsigned long flags; + /* The old LANCE chips doesn't automatically pad buffers to min. size. */ + len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; + /* PAM-Card has a bug: Can only send packets with even number of bytes! */ + if (lp->cardtype == PAM_CARD && (len & 1)) + ++len; + + if (len > skb->len) + { + skb = skb_padto(skb, len); + if(skb == NULL) + return 0; + } + /* Transmitter timeout, serious problems. */ if (dev->tbusy) { int tickssofar = jiffies - dev->trans_start; @@ -917,12 +930,6 @@ * last. */ - /* The old LANCE chips doesn't automatically pad buffers to min. size. */ - len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; - /* PAM-Card has a bug: Can only send packets with even number of bytes! */ - if (lp->cardtype == PAM_CARD && (len & 1)) - ++len; - head->length = -len; head->misc = 0; lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len ); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/de600.c linux.24rc5/drivers/net/de600.c --- linux.vanilla/drivers/net/de600.c Sun Mar 25 17:31:16 2001 +++ linux.24rc5/drivers/net/de600.c Fri Feb 7 07:15:51 2003 @@ -404,6 +404,7 @@ int len; int tickssofar; byte *buffer = skb->data; + int i; if (free_tx_pages <= 0) { /* Do timeouts, to avoid hangs. */ tickssofar = jiffies - dev->trans_start; @@ -447,8 +448,10 @@ #endif de600_setup_address(transmit_from, RW_ADDR); - for ( ; len > 0; --len, ++buffer) + for (i = 0; i < skb->len ; ++i, ++buffer) de600_put_byte(*buffer); + for (; i < len; ++i) + de600_put_byte(0); if (free_tx_pages-- == TX_PAGES) { /* No transmission going on */ dev->trans_start = jiffies; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/de620.c linux.24rc5/drivers/net/de620.c --- linux.vanilla/drivers/net/de620.c Sun Mar 25 17:31:16 2001 +++ linux.24rc5/drivers/net/de620.c Fri Feb 7 07:16:26 2003 @@ -310,7 +310,7 @@ } static inline void -de620_write_block(struct device *dev, byte *buffer, int count) +de620_write_block(struct device *dev, byte *buffer, int count, int pad) { #ifndef LOWSPEED byte uflip = NIC_Cmd ^ (DS0 | DS1); @@ -329,6 +329,9 @@ for ( ; count > 0; --count, ++buffer) { de620_put_byte(dev,*buffer); } + for ( count = pad ; count > 0; --count, ++buffer) { + de620_put_byte(dev, 0); + } de620_send_command(dev,W_DUMMY); #ifdef COUNT_LOOPS /* trial debug output: loops per byte in de620_ready() */ @@ -570,7 +573,7 @@ return 1; break; } - de620_write_block(dev, buffer, len); + de620_write_block(dev, buffer, skb->len, len-skb->len); dev->trans_start = jiffies; dev->tbusy = (using_txbuf == (TXBF0 | TXBF1)); /* Boolean! */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/declance.c linux.24rc5/drivers/net/declance.c --- linux.vanilla/drivers/net/declance.c Sun Mar 25 17:31:21 2001 +++ linux.24rc5/drivers/net/declance.c Fri Feb 7 06:45:28 2003 @@ -873,12 +873,23 @@ return -1; } skblen = skb->len; + len = skblen; + + if(len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + dev->tbusy = 0; + return 0; + } + len = ETH_ZLEN; + } save_and_cli(flags); if (!TX_BUFFS_AVAIL) { restore_flags(flags); return -1; } - len = (skblen <= ETH_ZLEN) ? ETH_ZLEN : skblen; lp->stats.tx_bytes += len; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/depca.c linux.24rc5/drivers/net/depca.c --- linux.vanilla/drivers/net/depca.c Wed Sep 18 15:23:17 2002 +++ linux.24rc5/drivers/net/depca.c Fri Feb 7 06:46:28 2003 @@ -836,6 +836,13 @@ } return status; } else if (skb->len > 0) { + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } + /* Enforce 1 process per h/w access */ if (test_and_set_bit(0, (void *) &dev->tbusy) != 0) { printk("%s: Transmitter access conflict.\n", dev->name); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/eepro.c linux.24rc5/drivers/net/eepro.c --- linux.vanilla/drivers/net/eepro.c Wed Sep 18 15:23:17 2002 +++ linux.24rc5/drivers/net/eepro.c Fri Feb 7 06:47:29 2003 @@ -1067,12 +1067,21 @@ { struct eepro_local *lp = (struct eepro_local *)dev->priv; int ioaddr = dev->base_addr; + short length = skb->len; unsigned long flags; if (net_debug > 5) printk(KERN_DEBUG "%s: entering eepro_send_packet routine.\n", dev->name); + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } + eepro_dis_int(ioaddr); spin_lock_irqsave(&lp->lock, flags); @@ -1094,7 +1103,6 @@ printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name); lp->stats.tx_aborted_errors++; } else { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; if (hardware_send_packet(dev, skb->data, length)) /* we won't unset tbusy because we're out of space. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/eexpress.c linux.24rc5/drivers/net/eexpress.c --- linux.vanilla/drivers/net/eexpress.c Sun Mar 25 17:31:15 2001 +++ linux.24rc5/drivers/net/eexpress.c Fri Feb 7 06:48:08 2003 @@ -522,12 +522,21 @@ static int eexp_xmit(struct sk_buff *buf, struct device *dev) { struct net_local *lp = (struct net_local *)dev->priv; + short length = buf->len; unsigned long flags; #if NET_DEBUG > 6 printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name); #endif + if(buf->len < ETH_ZLEN) + { + buf = skb_padto(buf, ETH_ZLEN); + if(buf == NULL) + return 0; + length = buf->len; + } + disable_irq(dev->irq); /* @@ -571,8 +580,6 @@ } else { - unsigned short length = (ETH_ZLEN < buf->len) ? buf->len : - ETH_ZLEN; unsigned short *data = (unsigned short *)buf->data; lp->stats.tx_bytes += length; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/epic100.c linux.24rc5/drivers/net/epic100.c --- linux.vanilla/drivers/net/epic100.c Sun Mar 25 17:31:20 2001 +++ linux.24rc5/drivers/net/epic100.c Fri Feb 7 06:48:17 2003 @@ -879,6 +879,13 @@ int entry, free_count; u32 ctrl_word; long flags; + + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } /* Block a timer-based transmit from overlapping. This could better be done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/eth16i.c linux.24rc5/drivers/net/eth16i.c --- linux.vanilla/drivers/net/eth16i.c Sun Mar 25 17:31:17 2001 +++ linux.24rc5/drivers/net/eth16i.c Fri Feb 7 06:49:32 2003 @@ -1122,9 +1122,19 @@ status = -1; } else { - ushort length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + ushort length = skb->len; unsigned char *buf = skb->data; + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + dev->tbusy = 0; + return 0; + } + length = ETH_ZLEN; + } if( (length + 2) > (lp->tx_buf_size - lp->tx_queue_len)) { if(eth16i_debug > 0) printk(KERN_WARNING "%s: Transmit buffer full.\n", dev->name); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/fmv18x.c linux.24rc5/drivers/net/fmv18x.c --- linux.vanilla/drivers/net/fmv18x.c Sun Mar 25 17:31:17 2001 +++ linux.24rc5/drivers/net/fmv18x.c Fri Feb 7 06:50:37 2003 @@ -369,7 +369,7 @@ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) printk("%s: Transmitter access conflict.\n", dev->name); else { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + short length = skb->len; unsigned char *buf = skb->data; if (length > ETH_FRAME_LEN) { @@ -378,6 +378,17 @@ dev->name, length); return 1; } + + if (length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + dev->tbusy = 0; + return 0; + } + length = ETH_ZLEN; + } if (net_debug > 4) printk("%s: Transmitting a packet of length %lu.\n", dev->name, diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/hp100.c linux.24rc5/drivers/net/hp100.c --- linux.vanilla/drivers/net/hp100.c Sun Mar 25 17:31:16 2001 +++ linux.24rc5/drivers/net/hp100.c Fri Feb 7 06:51:37 2003 @@ -1658,6 +1658,13 @@ if ( skb->len <= 0 ) return 0; + if (skb->len < ETH_ZLEN && lp->chip == HP100_CHIPID_SHASTA) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + } + /* Get Tx ring tail pointer */ if( lp->txrtail->next==lp->txrhead ) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/lance.c linux.24rc5/drivers/net/lance.c --- linux.vanilla/drivers/net/lance.c Sun Mar 25 17:37:34 2001 +++ linux.24rc5/drivers/net/lance.c Fri Feb 7 06:52:48 2003 @@ -919,8 +919,15 @@ /* The old LANCE chips doesn't automatically pad buffers to min. size. */ if (chip_table[lp->chip_version].flags & LANCE_MUST_PAD) { - lp->tx_ring[entry].length = - -(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN); + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + goto out; + lp->tx_ring[entry].length = -ETH_ZLEN; + } + else + lp->tx_ring[entry].length = -skb->len; } else lp->tx_ring[entry].length = -skb->len; @@ -950,6 +957,7 @@ dev->trans_start = jiffies; +out: save_flags(flags); cli(); lp->lock = 0; @@ -1174,7 +1182,6 @@ { int ioaddr = dev->base_addr; struct lance_private *lp = (struct lance_private *)dev->priv; - int i; dev->start = 0; dev->tbusy = 1; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/lp486e.c linux.24rc5/drivers/net/lp486e.c --- linux.vanilla/drivers/net/lp486e.c Sun Mar 25 17:37:34 2001 +++ linux.24rc5/drivers/net/lp486e.c Fri Feb 7 06:53:47 2003 @@ -932,9 +932,22 @@ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { printk("%s: Transmitter access conflict.\n", dev->name); } else { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + short length; dev->trans_start = jiffies; + length = skb->len; + + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + dev->tbusy = 0; + return 0; + } + length = ETH_ZLEN; + } + tx_cmd = (struct tx_cmd *) kmalloc ((sizeof (struct tx_cmd) + sizeof (struct i596_tbd)), GFP_ATOMIC); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/ni5010.c linux.24rc5/drivers/net/ni5010.c --- linux.vanilla/drivers/net/ni5010.c Sun Mar 25 17:31:19 2001 +++ linux.24rc5/drivers/net/ni5010.c Fri Feb 7 07:18:49 2003 @@ -113,7 +113,7 @@ static int process_xmt_interrupt(struct device *dev); #define tx_done(dev) 1 -extern void hardware_send_packet(struct device *dev, char *buf, int length); +extern void hardware_send_packet(struct device *dev, char *buf, int length, int pad); extern void chipset_init(struct device *dev, int startp); static void dump_packet(void *buf, int len); static void show_registers(struct device *dev); @@ -457,7 +457,7 @@ } else { int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - hardware_send_packet(dev, (unsigned char *)skb->data, length); + hardware_send_packet(dev, (unsigned char *)skb->data, length, length-skb->len); dev->trans_start = jiffies; } dev_kfree_skb (skb); @@ -702,7 +702,7 @@ } } -extern void hardware_send_packet(struct device *dev, char *buf, int length) +extern void hardware_send_packet(struct device *dev, char *buf, int length, int pad) { struct ni5010_local *lp = (struct ni5010_local *)dev->priv; int ioaddr = dev->base_addr; @@ -727,8 +727,8 @@ if (NI5010_DEBUG > 3) dump_packet(buf, length); - buf_offs = NI5010_BUFSIZE - length; - lp->o_pkt_size = length; + buf_offs = NI5010_BUFSIZE - length - pad ; + lp->o_pkt_size = length + pad ; save_flags(flags); cli(); @@ -739,6 +739,9 @@ outw(buf_offs, IE_GP); /* Point GP at start of packet */ outsb(IE_XBUF, buf, length); /* Put data in buffer */ + while(pad--) + outb(0, IE_XBUF); + outw(buf_offs, IE_GP); /* Rewrite where packet starts */ /* should work without that outb() (Crynwr used it) */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/ni52.c linux.24rc5/drivers/net/ni52.c --- linux.vanilla/drivers/net/ni52.c Fri Nov 2 16:39:07 2001 +++ linux.24rc5/drivers/net/ni52.c Fri Feb 7 07:19:32 2003 @@ -1174,8 +1174,13 @@ #endif else { + len = skb->len; + if(len < ETH_ZLEN) + { + len = ETH_ZLEN; + memset((char *)p->xmit_cbuffs[p->xmit_count]+skb->len, 0, len - skb->len); + } memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len); - len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN; #if (NUM_XMIT_BUFFS == 1) # ifdef NO_NOPCOMMANDS diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/ni65.c linux.24rc5/drivers/net/ni65.c --- linux.vanilla/drivers/net/ni65.c Sun Mar 25 17:31:16 2001 +++ linux.24rc5/drivers/net/ni65.c Fri Feb 7 07:19:39 2003 @@ -1124,6 +1124,8 @@ memcpy((char *) p->tmdbounce[p->tmdbouncenum] ,(char *)skb->data, (skb->len > T_BUF_SIZE) ? T_BUF_SIZE : skb->len); + if(len > skb->len) + memset((char *)p->tmdbounce[p->tmdbouncenum]+skb->len, 0, len-skb->len); dev_kfree_skb (skb); save_flags(flags); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/rtl8139.c linux.24rc5/drivers/net/rtl8139.c --- linux.vanilla/drivers/net/rtl8139.c Fri Nov 2 16:39:07 2001 +++ linux.24rc5/drivers/net/rtl8139.c Wed Feb 19 13:27:25 2003 @@ -970,6 +970,16 @@ rtl8129_tx_timeout(dev); return 1; } + + if(skb->len < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + clear_bit(0, (void *)&dev->tbusy); + return 0; + } + } /* Calculate the next Tx descriptor entry. */ entry = tp->cur_tx % NUM_TX_DESC; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/seeq8005.c linux.24rc5/drivers/net/seeq8005.c --- linux.vanilla/drivers/net/seeq8005.c Sun Mar 25 17:31:17 2001 +++ linux.24rc5/drivers/net/seeq8005.c Fri Feb 7 07:00:17 2003 @@ -393,9 +393,20 @@ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) printk("%s: Transmitter access conflict.\n", dev->name); else { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + short length = skb->len; unsigned char *buf = skb->data; + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + dev->tbusy = 0; + return 0; + } + length = ETH_ZLEN; + } + hardware_send_packet(dev, buf, length); dev->trans_start = jiffies; lp->stats.tx_bytes += length; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/sgiseeq.c linux.24rc5/drivers/net/sgiseeq.c --- linux.vanilla/drivers/net/sgiseeq.c Sun Mar 25 17:31:19 2001 +++ linux.24rc5/drivers/net/sgiseeq.c Fri Feb 7 07:20:14 2003 @@ -562,6 +562,8 @@ * added this new entry and restarted it. */ memcpy((char *)td->buf_vaddr, skb->data, skblen); + if(len != skblen) + memset((char *)(long)td->buf_vaddr + skb->len, 0, len-skblen); td->tdma.cntinfo = ((len) & HPCDMA_BCNT) | (HPCDMA_XIU | HPCDMA_EOXP | HPCDMA_XIE | HPCDMA_EOX); if(sp->tx_old != sp->tx_new) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/sk_g16.c linux.24rc5/drivers/net/sk_g16.c --- linux.vanilla/drivers/net/sk_g16.c Sun Mar 25 17:31:16 2001 +++ linux.24rc5/drivers/net/sk_g16.c Fri Feb 7 07:59:56 2003 @@ -1175,6 +1175,7 @@ { struct priv *p = (struct priv *) dev->priv; struct tmd *tmdp; + static char pad[64]; if (dev->tbusy) { @@ -1221,6 +1222,8 @@ /* Copy data into dual ported ram */ memcpy_toio((tmdp->u.buffer & 0x00ffffff), skb->data, skb->len); + if(len != skb->len) + memcpy_toio((tmdp->u.buffer & 0x00ffffff) + skb->len, pad, len-skb->len); writew(-len, tmdp->blen); /* set length to transmit */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/smc9194.c linux.24rc5/drivers/net/smc9194.c --- linux.vanilla/drivers/net/smc9194.c Sun Mar 25 17:31:17 2001 +++ linux.24rc5/drivers/net/smc9194.c Mon Mar 3 14:59:59 2003 @@ -563,10 +563,17 @@ printk(CARDNAME": Bad Craziness - sent packet while busy.\n" ); return 1; } - lp->saved_skb = skb; - length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; + length = skb->len; + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } + lp->saved_skb = skb; /* ** The MMU wants the number of pages to be the number of 256 bytes diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/starfire.c linux.24rc5/drivers/net/starfire.c --- linux.vanilla/drivers/net/starfire.c Fri Aug 30 14:49:10 2002 +++ linux.24rc5/drivers/net/starfire.c Thu Dec 19 18:52:38 2002 @@ -1046,25 +1046,22 @@ { struct netdev_private *np = dev->priv; long ioaddr = dev->base_addr; + int old_debug; printk(KERN_WARNING "%s: Transmit timed out, status %8.8x," " resetting...\n", dev->name, (int)readl(ioaddr + IntrStatus)); -#ifndef __alpha__ - { - int i; - printk(KERN_DEBUG " Rx ring %p: ", np->rx_ring); - for (i = 0; i < RX_RING_SIZE; i++) - printk(" %8.8x", (unsigned int)le32_to_cpu(np->rx_ring[i].rxaddr)); - printk("\n"KERN_DEBUG" Tx ring %p: ", np->tx_ring); - for (i = 0; i < TX_RING_SIZE; i++) - printk(" %4.4x", le32_to_cpu(np->tx_ring[i].status)); - printk("\n"); - } -#endif - /* Perhaps we should reinitialize the hardware here. */ - /* Stop and restart the chip's Tx processes . */ + + /* + * Stop and restart the chip's Tx processes. + * Cheat and increase the debug level temporarily. + */ + old_debug = debug; + debug = 2; + netdev_close(dev); + netdev_open(dev); + debug = old_debug; /* Trigger an immediate transmit demand. */ @@ -1933,6 +1930,8 @@ writel(0, ioaddr + IntrEnable); /* Stop the chip's Tx and Rx processes. */ + writel(0, ioaddr + GenCtrl); + readl(ioaddr + GenCtrl); #ifdef __i386__ if (debug > 2) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/tulip.c linux.24rc5/drivers/net/tulip.c --- linux.vanilla/drivers/net/tulip.c Fri Nov 2 16:39:07 2001 +++ linux.24rc5/drivers/net/tulip.c Mon Mar 3 14:56:36 2003 @@ -23,6 +23,9 @@ Updated 12/17/2000 by Jim McQuillan to include support for the Linksys LNE100TX card based on the Admtek 985 Centaur-P chipset. + + 2002 Dec 21 Neale Banks + Gracefully handle the case where init_etherdev() returns NULL */ #define SMP_CHECK @@ -695,6 +698,11 @@ dev = init_etherdev(dev, 0); + if (dev == NULL) { + printk(KERN_ERR "tulip: Unable to allocate net_device structure!\n"); + return NULL; + } + /* Make certain the data structures are quadword aligned. */ tp = (void *)(((long)kmalloc(sizeof(*tp), GFP_KERNEL | GFP_DMA) + 7) & ~7); memset(tp, 0, sizeof(*tp)); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/via-rhine.c linux.24rc5/drivers/net/via-rhine.c --- linux.vanilla/drivers/net/via-rhine.c Fri Nov 2 16:39:07 2001 +++ linux.24rc5/drivers/net/via-rhine.c Fri Feb 7 07:02:22 2003 @@ -969,6 +969,15 @@ /* Calculate the next Tx descriptor entry. */ entry = np->cur_tx % TX_RING_SIZE; + if (skb->len < ETH_ZLEN) { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + { + dev->tbusy = 0; + return 0; + } + } + np->tx_skbuff[entry] = skb; if ((np->drv_flags & ReqTxAlign) && ((long)skb->data & 3)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/net/znet.c linux.24rc5/drivers/net/znet.c --- linux.vanilla/drivers/net/znet.c Sun Mar 25 17:31:16 2001 +++ linux.24rc5/drivers/net/znet.c Fri Feb 7 07:04:02 2003 @@ -318,10 +318,19 @@ { int ioaddr = dev->base_addr; struct net_local *lp = (struct net_local *)dev->priv; + short length = skb->len; if (znet_debug > 4) printk(KERN_DEBUG "%s: ZNet_send_packet(%ld).\n", dev->name, dev->tbusy); + if(length < ETH_ZLEN) + { + skb = skb_padto(skb, ETH_ZLEN); + if(skb == NULL) + return 0; + length = ETH_ZLEN; + } + /* Transmitter timeout, likely just recovery after suspending the machine. */ if (dev->tbusy) { ushort event, tx_status, rx_offset, state; @@ -353,7 +362,6 @@ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name); else { - short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; unsigned char *buf = (void *)skb->data; ushort *tx_link = zn.tx_cur - 1; ushort rnd_len = (length + 1)>>1; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/pipe.c linux.24rc5/fs/pipe.c --- linux.vanilla/fs/pipe.c Sun Mar 25 17:30:58 2001 +++ linux.24rc5/fs/pipe.c Mon Dec 16 18:56:34 2002 @@ -105,9 +105,17 @@ else free = 1; /* can't do it atomically, wait for any free space */ up(&inode->i_sem); - if (down_interruptible(&inode->i_atomic_write)) { - down(&inode->i_sem); - return -ERESTARTSYS; + if (filp->f_flags & O_NONBLOCK) { + if (down_trylock(&inode->i_atomic_write)) { + down(&inode->i_sem); + return -ERESTARTSYS; + } + } + else { + if (down_interruptible(&inode->i_atomic_write)) { + down(&inode->i_sem); + return -ERESTARTSYS; + } } while (count>0) { while ((PIPE_FREE(*inode) < free) || PIPE_LOCK(*inode)) { diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/fs/proc/mem.c linux.24rc5/fs/proc/mem.c --- linux.vanilla/fs/proc/mem.c Fri Nov 2 16:39:08 2001 +++ linux.24rc5/fs/proc/mem.c Mon Dec 16 19:03:21 2002 @@ -209,113 +209,6 @@ return offset; } -/* - * This isn't really reliable by any means.. - */ -int mem_mmap(struct file * file, struct vm_area_struct * vma) -{ - struct task_struct *tsk; - pgd_t *src_dir, *dest_dir; - pmd_t *src_middle, *dest_middle; - pte_t *src_table, *dest_table; - unsigned long stmp, dtmp, mapnr; - struct vm_area_struct *src_vma = NULL; - struct inode *inode = file->f_dentry->d_inode; - - /* Get the source's task information */ - - tsk = get_task(inode->i_ino >> 16); - - if (!tsk) - return -ESRCH; - - /* Ensure that we have a valid source area. (Has to be mmap'ed and - have valid page information.) We can't map shared memory at the - moment because working out the vm_area_struct & nattach stuff isn't - worth it. */ - - src_vma = tsk->mm->mmap; - stmp = vma->vm_offset; - while (stmp < vma->vm_offset + (vma->vm_end - vma->vm_start)) { - while (src_vma && stmp > src_vma->vm_end) - src_vma = src_vma->vm_next; - if (!src_vma || (src_vma->vm_flags & VM_SHM)) - return -EINVAL; - - src_dir = pgd_offset(tsk->mm, stmp); - if (pgd_none(*src_dir)) - return -EINVAL; - if (pgd_bad(*src_dir)) { - printk("Bad source page dir entry %08lx\n", pgd_val(*src_dir)); - return -EINVAL; - } - src_middle = pmd_offset(src_dir, stmp); - if (pmd_none(*src_middle)) - return -EINVAL; - if (pmd_bad(*src_middle)) { - printk("Bad source page middle entry %08lx\n", pmd_val(*src_middle)); - return -EINVAL; - } - src_table = pte_offset(src_middle, stmp); - if (pte_none(*src_table)) - return -EINVAL; - - if (stmp < src_vma->vm_start) { - if (!(src_vma->vm_flags & VM_GROWSDOWN)) - return -EINVAL; - if (src_vma->vm_end - stmp > current->rlim[RLIMIT_STACK].rlim_cur) - return -EINVAL; - } - stmp += PAGE_SIZE; - } - - src_vma = tsk->mm->mmap; - stmp = vma->vm_offset; - dtmp = vma->vm_start; - - flush_cache_range(vma->vm_mm, vma->vm_start, vma->vm_end); - flush_cache_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end); - while (dtmp < vma->vm_end) { - while (src_vma && stmp > src_vma->vm_end) - src_vma = src_vma->vm_next; - - src_dir = pgd_offset(tsk->mm, stmp); - src_middle = pmd_offset(src_dir, stmp); - src_table = pte_offset(src_middle, stmp); - - dest_dir = pgd_offset(current->mm, dtmp); - dest_middle = pmd_alloc(dest_dir, dtmp); - if (!dest_middle) - return -ENOMEM; - dest_table = pte_alloc(dest_middle, dtmp); - if (!dest_table) - return -ENOMEM; - - if (!pte_present(*src_table)) { - if (handle_mm_fault(tsk, src_vma, stmp, 1) < 0) - return -ENOMEM; - } - - if ((vma->vm_flags & VM_WRITE) && !pte_write(*src_table)) { - if (handle_mm_fault(tsk, src_vma, stmp, 1) < 0) - return -ENOMEM; - } - - set_pte(src_table, pte_mkdirty(*src_table)); - set_pte(dest_table, *src_table); - mapnr = MAP_NR(pte_page(*src_table)); - if (mapnr < max_mapnr) - atomic_inc(&mem_map[MAP_NR(pte_page(*src_table))].count); - - stmp += PAGE_SIZE; - dtmp += PAGE_SIZE; - } - - flush_tlb_range(vma->vm_mm, vma->vm_start, vma->vm_end); - flush_tlb_range(src_vma->vm_mm, src_vma->vm_start, src_vma->vm_end); - return 0; -} - static struct file_operations proc_mem_operations = { mem_lseek, mem_read, @@ -323,7 +216,7 @@ NULL, /* mem_readdir */ NULL, /* mem_poll */ NULL, /* mem_ioctl */ - mem_mmap, /* mmap */ + NULL, /* mmap */ NULL, /* no special open code */ NULL, /* flush */ NULL, /* no special release code */ diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/include/linux/skbuff.h linux.24rc5/include/linux/skbuff.h --- linux.vanilla/include/linux/skbuff.h Sun Mar 25 17:31:03 2001 +++ linux.24rc5/include/linux/skbuff.h Fri Feb 7 07:52:13 2003 @@ -149,6 +149,7 @@ extern struct sk_buff * skb_clone(struct sk_buff *skb, int priority); extern struct sk_buff * skb_copy(struct sk_buff *skb, int priority); extern struct sk_buff * skb_realloc_headroom(struct sk_buff *skb, int newheadroom); +extern struct sk_buff * skb_pad(struct sk_buff *skb, int pad); #define dev_kfree_skb(a) kfree_skb(a) extern unsigned char * skb_put(struct sk_buff *skb, unsigned int len); extern unsigned char * skb_push(struct sk_buff *skb, unsigned int len); @@ -564,13 +565,38 @@ headroom = (headroom+15)&~15; if ((unsigned)skb_headroom(skb) < headroom || skb_cloned(skb)) { - struct sk_buff *skb2 = skb_realloc_headroom(skb, headroom); + struct sk_buff *skb2; + + if ((unsigned)skb_headroom(skb) < headroom) + skb2 = skb_realloc_headroom(skb, headroom); + else + skb2 = skb_copy(skb, GFP_ATOMIC); kfree_skb(skb); skb = skb2; } return skb; } +/** + * skb_padto - pad an skbuff up to a minimal size + * @skb: buffer to pad + * @len: minimal length + * + * Pads up a buffer to ensure the trailing bytes exist and are + * blanked. If the buffer already contains sufficient data it + * is untouched. Returns the buffer, which may be a replacement + * for the original, or NULL for out of memory - in which case + * the original buffer is still freed. + */ + +static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) +{ + unsigned int size = skb->len; + if(size >= len) + return skb; + return skb_pad(skb, len-size); +} + extern struct sk_buff * skb_recv_datagram(struct sock *sk,unsigned flags,int noblock, int *err); extern unsigned int datagram_poll(struct file *file, struct socket *sock, struct poll_table_struct *wait); extern int skb_copy_datagram(struct sk_buff *from, int offset, char *to,int size); diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/core/skbuff.c linux.24rc5/net/core/skbuff.c --- linux.vanilla/net/core/skbuff.c Wed Sep 18 15:23:20 2002 +++ linux.24rc5/net/core/skbuff.c Fri Feb 7 07:26:09 2003 @@ -312,6 +312,55 @@ return n; } +struct sk_buff *skb_copy_grow(struct sk_buff *skb, int pad, int gfp_mask) +{ + struct sk_buff *n; + unsigned long offset; + + /* + * Allocate the copy buffer + */ + + n=alloc_skb(skb->end - skb->head + pad, gfp_mask); + if(n==NULL) + return NULL; + + /* + * Shift between the two data areas in bytes + */ + + offset=n->head-skb->head; + + /* Set the data pointer */ + skb_reserve(n,skb->data-skb->head); + /* Set the tail pointer and length */ + skb_put(n,skb->len); + /* Copy the bytes */ + memcpy(n->head,skb->head,skb->end-skb->head); + n->csum = skb->csum; + n->list=NULL; + n->sk=NULL; + n->dev=skb->dev; + n->priority=skb->priority; + n->protocol=skb->protocol; + n->dst=dst_clone(skb->dst); + n->h.raw=skb->h.raw+offset; + n->nh.raw=skb->nh.raw+offset; + n->mac.raw=skb->mac.raw+offset; + memcpy(n->cb, skb->cb, sizeof(skb->cb)); + n->used=skb->used; + n->is_clone=0; + atomic_set(&n->users, 1); + n->pkt_type=skb->pkt_type; + n->stamp=skb->stamp; + n->destructor = NULL; + n->security=skb->security; +#ifdef CONFIG_IP_FIREWALL + n->fwmark = skb->fwmark; +#endif + return n; +} + struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, int newheadroom) { struct sk_buff *n; @@ -362,6 +411,36 @@ return n; } +/** + * skb_pad - zero pad the tail of an skb + * @skb: buffer to pad + * @pad: space to pad + * + * Ensure that a buffer is followed by a padding area that is zero + * filled. Used by network drivers which may DMA or transfer data + * beyond the buffer end onto the wire. + * + * May return NULL in out of memory cases. + */ + +struct sk_buff *skb_pad(struct sk_buff *skb, int pad) +{ + struct sk_buff *nskb; + + /* If the skbuff is non linear tailroom is always zero.. */ + if(skb_tailroom(skb) >= pad) + { + memset(skb->data+skb->len, 0, pad); + return skb; + } + + nskb = skb_copy_grow(skb, pad, GFP_ATOMIC); + kfree_skb(skb); + if(nskb) + memset(nskb->data+nskb->len, 0, pad); + return nskb; +} + #if 0 /* * Tune the memory allocator for a new MTU size. diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/core/sock.c linux.24rc5/net/core/sock.c --- linux.vanilla/net/core/sock.c Fri Nov 2 16:39:16 2001 +++ linux.24rc5/net/core/sock.c Mon Mar 3 14:55:45 2003 @@ -80,6 +80,7 @@ * Andi Kleen : Add sock_kmalloc()/sock_kfree_s() * Andi Kleen : Fix write_space callback * Chris Evans : Security fixes - signedness again + * Holger Smolinski:       Fix initialization of sk->sleep * * To Fix: * @@ -1079,6 +1080,8 @@ sk->type = sock->type; sk->sleep = &sock->wait; sock->sk = sk; + } else { + sk->sleep = NULL; } sk->state_change = sock_def_wakeup; diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/ipv4/tcp_ipv4.c linux.24rc5/net/ipv4/tcp_ipv4.c --- linux.vanilla/net/ipv4/tcp_ipv4.c Sun Mar 25 17:37:41 2001 +++ linux.24rc5/net/ipv4/tcp_ipv4.c Mon Mar 3 14:55:30 2003 @@ -44,7 +44,9 @@ * Andi Kleen: various fixes. * Vitaly E. Lavrov : Transparent proxy revived after year coma. * Andi Kleen : Fix new listen. - * Andi Kleen : Fix accept error reporting. + * Andi Kleen : Fix accept error reporting.a + * Holger Smolinski : Fix initialization of newsk->sleep which + * points to a potentially invalid wait_queue */ #include @@ -1474,6 +1476,7 @@ newsk->timer.function = &net_timer; newsk->timer.data = (unsigned long) newsk; newsk->socket = NULL; + newsk->sleep = NULL; newtp->tstamp_ok = req->tstamp_ok; if((newtp->sack_ok = req->sack_ok) != 0) diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/net/netsyms.c linux.24rc5/net/netsyms.c --- linux.vanilla/net/netsyms.c Sun Mar 25 17:37:41 2001 +++ linux.24rc5/net/netsyms.c Wed Feb 19 13:25:32 2003 @@ -489,6 +489,7 @@ EXPORT_SYMBOL(__kfree_skb); EXPORT_SYMBOL(skb_clone); EXPORT_SYMBOL(skb_copy); +EXPORT_SYMBOL(skb_pad); EXPORT_SYMBOL(netif_rx); EXPORT_SYMBOL(dev_add_pack); EXPORT_SYMBOL(dev_remove_pack);