Commit 1780a902 authored by Linus Torvalds's avatar Linus Torvalds

Merge http://linux-acpi.bkbits.net/linux-acpi

into home.transmeta.com:/home/torvalds/v2.5/linux
parents d7374b3f 13cb21df
...@@ -53,6 +53,8 @@ Revision History: ...@@ -53,6 +53,8 @@ Revision History:
2. Bug fix: Fixed VLAN support failure. 2. Bug fix: Fixed VLAN support failure.
3. Bug fix: Fixed receive interrupt coalescing bug. 3. Bug fix: Fixed receive interrupt coalescing bug.
4. Dynamic IPG support is disabled by default. 4. Dynamic IPG support is disabled by default.
3.0.3 06/05/2003
1. Bug fix: Fixed failure to close the interface if SMP is enabled.
*/ */
...@@ -89,9 +91,9 @@ Revision History: ...@@ -89,9 +91,9 @@ Revision History:
#include "amd8111e.h" #include "amd8111e.h"
#define MODULE_NAME "amd8111e" #define MODULE_NAME "amd8111e"
#define MODULE_VERSION "3.0.2" #define MODULE_VERSION "3.0.3"
MODULE_AUTHOR("Advanced Micro Devices, Inc."); MODULE_AUTHOR("Advanced Micro Devices, Inc.");
MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.2"); MODULE_DESCRIPTION ("AMD8111 based 10/100 Ethernet Controller. Driver Version 3.0.3");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_PARM(speed_duplex, "1-" __MODULE_STRING (MAX_UNITS) "i"); MODULE_PARM(speed_duplex, "1-" __MODULE_STRING (MAX_UNITS) "i");
MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotitate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex"); MODULE_PARM_DESC(speed_duplex, "Set device speed and duplex modes, 0: Auto Negotitate, 1: 10Mbps Half Duplex, 2: 10Mbps Full Duplex, 3: 100Mbps Half Duplex, 4: 100Mbps Full Duplex");
...@@ -1171,11 +1173,11 @@ static int amd8111e_close(struct net_device * dev) ...@@ -1171,11 +1173,11 @@ static int amd8111e_close(struct net_device * dev)
if(lp->options & OPTION_DYN_IPG_ENABLE) if(lp->options & OPTION_DYN_IPG_ENABLE)
del_timer_sync(&lp->ipg_data.ipg_timer); del_timer_sync(&lp->ipg_data.ipg_timer);
/* Update the statistics before closing */
amd8111e_get_stats(dev);
spin_unlock_irq(&lp->lock); spin_unlock_irq(&lp->lock);
free_irq(dev->irq, dev); free_irq(dev->irq, dev);
/* Update the statistics before closing */
amd8111e_get_stats(dev);
lp->opened = 0; lp->opened = 0;
return 0; return 0;
} }
......
...@@ -390,6 +390,7 @@ ...@@ -390,6 +390,7 @@
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/socket.h> #include <linux/socket.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/inet.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/bitops.h> #include <asm/bitops.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -2792,84 +2793,6 @@ static void activebackup_arp_monitor(struct net_device *master) ...@@ -2792,84 +2793,6 @@ static void activebackup_arp_monitor(struct net_device *master)
mod_timer(&bond->arp_timer, next_timer); mod_timer(&bond->arp_timer, next_timer);
} }
typedef uint32_t in_addr_t;
int
my_inet_aton(char *cp, unsigned long *the_addr) {
static const in_addr_t max[4] = { 0xffffffff, 0xffffff, 0xffff, 0xff };
in_addr_t val;
char c;
union iaddr {
uint8_t bytes[4];
uint32_t word;
} res;
uint8_t *pp = res.bytes;
int digit,base;
res.word = 0;
c = *cp;
for (;;) {
/*
* Collect number up to ``.''.
* Values are specified as for C:
* 0x=hex, 0=octal, isdigit=decimal.
*/
if (!isdigit(c)) goto ret_0;
val = 0; base = 10; digit = 0;
for (;;) {
if (isdigit(c)) {
val = (val * base) + (c - '0');
c = *++cp;
digit = 1;
} else {
break;
}
}
if (c == '.') {
/*
* Internet format:
* a.b.c.d
* a.b.c (with c treated as 16 bits)
* a.b (with b treated as 24 bits)
*/
if (pp > res.bytes + 2 || val > 0xff) {
goto ret_0;
}
*pp++ = val;
c = *++cp;
} else
break;
}
/*
* Check for trailing characters.
*/
if (c != '\0' && (!isascii(c) || !isspace(c))) {
goto ret_0;
}
/*
* Did we get a valid digit?
*/
if (!digit) {
goto ret_0;
}
/* Check whether the last part is in its limits depending on
the number of parts in total. */
if (val > max[pp - res.bytes]) {
goto ret_0;
}
if (the_addr != NULL) {
*the_addr = res.word | htonl (val);
}
return (1);
ret_0:
return (0);
}
static int bond_sethwaddr(struct net_device *master, struct net_device *slave) static int bond_sethwaddr(struct net_device *master, struct net_device *slave)
{ {
#ifdef BONDING_DEBUG #ifdef BONDING_DEBUG
...@@ -3877,15 +3800,18 @@ static int __init bonding_init(void) ...@@ -3877,15 +3800,18 @@ static int __init bonding_init(void)
for (arp_ip_count=0 ; for (arp_ip_count=0 ;
(arp_ip_count < MAX_ARP_IP_TARGETS) && arp_ip_target[arp_ip_count]; (arp_ip_count < MAX_ARP_IP_TARGETS) && arp_ip_target[arp_ip_count];
arp_ip_count++ ) { arp_ip_count++ ) {
/* TODO: check and log bad ip address */ /* not complete check, but should be good enough to
if (my_inet_aton(arp_ip_target[arp_ip_count], catch mistakes */
&arp_target[arp_ip_count]) == 0) { if (!isdigit(arp_ip_target[arp_ip_count][0])) {
printk(KERN_WARNING printk(KERN_WARNING
"bonding_init(): bad arp_ip_target module " "bonding_init(): bad arp_ip_target module "
"parameter (%s), ARP monitoring will not be " "parameter (%s), ARP monitoring will not be "
"performed\n", "performed\n",
arp_ip_target[arp_ip_count]); arp_ip_target[arp_ip_count]);
arp_interval = 0; arp_interval = 0;
} else {
u32 ip = in_aton(arp_ip_target[arp_ip_count]);
*(u32 *)(arp_ip_target[arp_ip_count]) = ip;
} }
} }
......
...@@ -50,7 +50,6 @@ ixgb_eeprom_size(struct ixgb_hw *hw) ...@@ -50,7 +50,6 @@ ixgb_eeprom_size(struct ixgb_hw *hw)
return (IXGB_EEPROM_SIZE << 1); return (IXGB_EEPROM_SIZE << 1);
} }
#define SUPPORTED_10000baseT_Full (1 << 11)
#define SPEED_10000 10000 #define SPEED_10000 10000
static void static void
......
...@@ -358,7 +358,6 @@ static dev_link_t *dev_list; ...@@ -358,7 +358,6 @@ static dev_link_t *dev_list;
typedef struct local_info_t { typedef struct local_info_t {
dev_link_t link; dev_link_t link;
struct net_device dev;
dev_node_t node; dev_node_t node;
struct net_device_stats stats; struct net_device_stats stats;
int card_type; int card_type;
...@@ -432,22 +431,10 @@ get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse) ...@@ -432,22 +431,10 @@ get_tuple(int fn, client_handle_t handle, tuple_t *tuple, cisparse_t *parse)
#define PutByte(reg,value) outb((value), ioaddr+(reg)) #define PutByte(reg,value) outb((value), ioaddr+(reg))
#define PutWord(reg,value) outw((value), ioaddr+(reg)) #define PutWord(reg,value) outw((value), ioaddr+(reg))
static void #define Wait(n) do { \
busy_loop(u_long len) set_current_state(TASK_UNINTERRUPTIBLE); \
{ schedule_timeout(n); \
if (in_interrupt()) { } while (0)
u_long timeout = jiffies + len;
u_long flags;
save_flags(flags);
sti();
while (time_before_eq(jiffies, timeout))
;
restore_flags(flags);
} else {
__set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(len);
}
}
/*====== Functions used for debugging =================================*/ /*====== Functions used for debugging =================================*/
#if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */ #if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */
...@@ -619,11 +606,12 @@ xirc2ps_attach(void) ...@@ -619,11 +606,12 @@ xirc2ps_attach(void)
flush_stale_links(); flush_stale_links();
/* Allocate the device structure */ /* Allocate the device structure */
local = kmalloc(sizeof(*local), GFP_KERNEL); dev = alloc_etherdev(sizeof(local_info_t));
if (!local) return NULL; if (!dev)
memset(local, 0, sizeof(*local)); return NULL;
link = &local->link; dev = &local->dev; local = dev->priv;
link->priv = dev->priv = local; link = &local->link;
link->priv = dev;
init_timer(&link->release); init_timer(&link->release);
link->release.function = &xirc2ps_release; link->release.function = &xirc2ps_release;
...@@ -645,7 +633,6 @@ xirc2ps_attach(void) ...@@ -645,7 +633,6 @@ xirc2ps_attach(void)
dev->get_stats = &do_get_stats; dev->get_stats = &do_get_stats;
dev->do_ioctl = &do_ioctl; dev->do_ioctl = &do_ioctl;
dev->set_multicast_list = &set_multicast_list; dev->set_multicast_list = &set_multicast_list;
ether_setup(dev);
dev->open = &do_open; dev->open = &do_open;
dev->stop = &do_stop; dev->stop = &do_stop;
#ifdef HAVE_TX_TIMEOUT #ifdef HAVE_TX_TIMEOUT
...@@ -684,7 +671,7 @@ xirc2ps_attach(void) ...@@ -684,7 +671,7 @@ xirc2ps_attach(void)
static void static void
xirc2ps_detach(dev_link_t * link) xirc2ps_detach(dev_link_t * link)
{ {
local_info_t *local = link->priv; struct net_device *dev = link->priv;
dev_link_t **linkp; dev_link_t **linkp;
DEBUG(0, "detach(0x%p)\n", link); DEBUG(0, "detach(0x%p)\n", link);
...@@ -706,10 +693,11 @@ xirc2ps_detach(dev_link_t * link) ...@@ -706,10 +693,11 @@ xirc2ps_detach(dev_link_t * link)
*/ */
del_timer(&link->release); del_timer(&link->release);
if (link->state & DEV_CONFIG) { if (link->state & DEV_CONFIG) {
DEBUG(0, "detach postponed, '%s' still locked\n", xirc2ps_release((unsigned long)link);
link->dev->dev_name); if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK; link->state |= DEV_STALE_LINK;
return; return;
}
} }
/* Break the link with Card Services */ /* Break the link with Card Services */
...@@ -719,8 +707,8 @@ xirc2ps_detach(dev_link_t * link) ...@@ -719,8 +707,8 @@ xirc2ps_detach(dev_link_t * link)
/* Unlink device structure, free it */ /* Unlink device structure, free it */
*linkp = link->next; *linkp = link->next;
if (link->dev) if (link->dev)
unregister_netdev(&local->dev); unregister_netdev(dev);
kfree(local); kfree(dev);
} /* xirc2ps_detach */ } /* xirc2ps_detach */
...@@ -745,7 +733,8 @@ xirc2ps_detach(dev_link_t * link) ...@@ -745,7 +733,8 @@ xirc2ps_detach(dev_link_t * link)
static int static int
set_card_type(dev_link_t *link, const void *s) set_card_type(dev_link_t *link, const void *s)
{ {
local_info_t *local = link->priv; struct net_device *dev = link->priv;
local_info_t *local = dev->priv;
#ifdef PCMCIA_DEBUG #ifdef PCMCIA_DEBUG
unsigned cisrev = ((const unsigned char *)s)[2]; unsigned cisrev = ((const unsigned char *)s)[2];
#endif #endif
...@@ -839,8 +828,8 @@ static void ...@@ -839,8 +828,8 @@ static void
xirc2ps_config(dev_link_t * link) xirc2ps_config(dev_link_t * link)
{ {
client_handle_t handle = link->handle; client_handle_t handle = link->handle;
local_info_t *local = link->priv; struct net_device *dev = link->priv;
struct net_device *dev = &local->dev; local_info_t *local = dev->priv;
tuple_t tuple; tuple_t tuple;
cisparse_t parse; cisparse_t parse;
ioaddr_t ioaddr; ioaddr_t ioaddr;
...@@ -1195,11 +1184,10 @@ static void ...@@ -1195,11 +1184,10 @@ static void
xirc2ps_release(u_long arg) xirc2ps_release(u_long arg)
{ {
dev_link_t *link = (dev_link_t *) arg; dev_link_t *link = (dev_link_t *) arg;
local_info_t *local = link->priv;
struct net_device *dev = &local->dev;
DEBUG(0, "release(0x%p)\n", link); DEBUG(0, "release(0x%p)\n", link);
#if 0
/* /*
* If the device is currently in use, we won't release until it * If the device is currently in use, we won't release until it
* is actually closed. * is actually closed.
...@@ -1210,8 +1198,10 @@ xirc2ps_release(u_long arg) ...@@ -1210,8 +1198,10 @@ xirc2ps_release(u_long arg)
link->state |= DEV_STALE_CONFIG; link->state |= DEV_STALE_CONFIG;
return; return;
} }
#endif
if (link->win) { if (link->win) {
struct net_device *dev = link->priv;
local_info_t *local = dev->priv; local_info_t *local = dev->priv;
if (local->dingo) if (local->dingo)
iounmap(local->dingo_ccr - 0x0800); iounmap(local->dingo_ccr - 0x0800);
...@@ -1243,8 +1233,7 @@ xirc2ps_event(event_t event, int priority, ...@@ -1243,8 +1233,7 @@ xirc2ps_event(event_t event, int priority,
event_callback_args_t * args) event_callback_args_t * args)
{ {
dev_link_t *link = args->client_data; dev_link_t *link = args->client_data;
local_info_t *lp = link->priv; struct net_device *dev = link->priv;
struct net_device *dev = &lp->dev;
DEBUG(0, "event(%d)\n", (int)event); DEBUG(0, "event(%d)\n", (int)event);
...@@ -1779,12 +1768,12 @@ hardreset(struct net_device *dev) ...@@ -1779,12 +1768,12 @@ hardreset(struct net_device *dev)
SelectPage(4); SelectPage(4);
udelay(1); udelay(1);
PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */ PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */
busy_loop(HZ/25); /* wait 40 msec */ Wait(HZ/25); /* wait 40 msec */
if (local->mohawk) if (local->mohawk)
PutByte(XIRCREG4_GPR1, 1); /* set bit 0: power up */ PutByte(XIRCREG4_GPR1, 1); /* set bit 0: power up */
else else
PutByte(XIRCREG4_GPR1, 1 | 4); /* set bit 0: power up, bit 2: AIC */ PutByte(XIRCREG4_GPR1, 1 | 4); /* set bit 0: power up, bit 2: AIC */
busy_loop(HZ/50); /* wait 20 msec */ Wait(HZ/50); /* wait 20 msec */
} }
static void static void
...@@ -1798,9 +1787,9 @@ do_reset(struct net_device *dev, int full) ...@@ -1798,9 +1787,9 @@ do_reset(struct net_device *dev, int full)
hardreset(dev); hardreset(dev);
PutByte(XIRCREG_CR, SoftReset); /* set */ PutByte(XIRCREG_CR, SoftReset); /* set */
busy_loop(HZ/50); /* wait 20 msec */ Wait(HZ/50); /* wait 20 msec */
PutByte(XIRCREG_CR, 0); /* clear */ PutByte(XIRCREG_CR, 0); /* clear */
busy_loop(HZ/25); /* wait 40 msec */ Wait(HZ/25); /* wait 40 msec */
if (local->mohawk) { if (local->mohawk) {
SelectPage(4); SelectPage(4);
/* set pin GP1 and GP2 to output (0x0c) /* set pin GP1 and GP2 to output (0x0c)
...@@ -1811,7 +1800,7 @@ do_reset(struct net_device *dev, int full) ...@@ -1811,7 +1800,7 @@ do_reset(struct net_device *dev, int full)
} }
/* give the circuits some time to power up */ /* give the circuits some time to power up */
busy_loop(HZ/2); /* about 500ms */ Wait(HZ/2); /* about 500ms */
local->last_ptr_value = 0; local->last_ptr_value = 0;
local->silicon = local->mohawk ? (GetByte(XIRCREG4_BOV) & 0x70) >> 4 local->silicon = local->mohawk ? (GetByte(XIRCREG4_BOV) & 0x70) >> 4
...@@ -1830,7 +1819,7 @@ do_reset(struct net_device *dev, int full) ...@@ -1830,7 +1819,7 @@ do_reset(struct net_device *dev, int full)
SelectPage(0x42); SelectPage(0x42);
PutByte(XIRCREG42_SWC1, 0x80); PutByte(XIRCREG42_SWC1, 0x80);
} }
busy_loop(HZ/25); /* wait 40 msec to let it complete */ Wait(HZ/25); /* wait 40 msec to let it complete */
#ifdef PCMCIA_DEBUG #ifdef PCMCIA_DEBUG
if (pc_debug) { if (pc_debug) {
...@@ -1889,7 +1878,7 @@ do_reset(struct net_device *dev, int full) ...@@ -1889,7 +1878,7 @@ do_reset(struct net_device *dev, int full)
printk(KERN_INFO "%s: MII selected\n", dev->name); printk(KERN_INFO "%s: MII selected\n", dev->name);
SelectPage(2); SelectPage(2);
PutByte(XIRCREG2_MSR, GetByte(XIRCREG2_MSR) | 0x08); PutByte(XIRCREG2_MSR, GetByte(XIRCREG2_MSR) | 0x08);
busy_loop(HZ/50); Wait(HZ/50);
} else { } else {
printk(KERN_INFO "%s: MII detected; using 10mbs\n", printk(KERN_INFO "%s: MII detected; using 10mbs\n",
dev->name); dev->name);
...@@ -1898,7 +1887,7 @@ do_reset(struct net_device *dev, int full) ...@@ -1898,7 +1887,7 @@ do_reset(struct net_device *dev, int full)
PutByte(XIRCREG42_SWC1, 0xC0); PutByte(XIRCREG42_SWC1, 0xC0);
else /* enable 10BaseT */ else /* enable 10BaseT */
PutByte(XIRCREG42_SWC1, 0x80); PutByte(XIRCREG42_SWC1, 0x80);
busy_loop(HZ/25); /* wait 40 msec to let it complete */ Wait(HZ/25); /* wait 40 msec to let it complete */
} }
if (full_duplex) if (full_duplex)
PutByte(XIRCREG1_ECR, GetByte(XIRCREG1_ECR | FullDuplex)); PutByte(XIRCREG1_ECR, GetByte(XIRCREG1_ECR | FullDuplex));
...@@ -1991,7 +1980,7 @@ init_mii(struct net_device *dev) ...@@ -1991,7 +1980,7 @@ init_mii(struct net_device *dev)
* Fixme: Better to use a timer here! * Fixme: Better to use a timer here!
*/ */
for (i=0; i < 35; i++) { for (i=0; i < 35; i++) {
busy_loop(HZ/10); /* wait 100 msec */ Wait(HZ/10); /* wait 100 msec */
status = mii_rd(ioaddr, 0, 1); status = mii_rd(ioaddr, 0, 1);
if ((status & 0x0020) && (status & 0x0004)) if ((status & 0x0020) && (status & 0x0004))
break; break;
...@@ -2083,12 +2072,8 @@ exit_xirc2ps_cs(void) ...@@ -2083,12 +2072,8 @@ exit_xirc2ps_cs(void)
{ {
pcmcia_unregister_driver(&xirc2ps_cs_driver); pcmcia_unregister_driver(&xirc2ps_cs_driver);
while (dev_list) { while (dev_list)
if (dev_list->state & DEV_CONFIG) xirc2ps_detach(dev_list);
xirc2ps_release((u_long)dev_list);
if (dev_list) /* xirc2ps_release() might already have detached... */
xirc2ps_detach(dev_list);
}
} }
module_init(init_xirc2ps_cs); module_init(init_xirc2ps_cs);
......
...@@ -1003,7 +1003,7 @@ pcnet32_init_ring(struct net_device *dev) ...@@ -1003,7 +1003,7 @@ pcnet32_init_ring(struct net_device *dev)
skb_reserve (rx_skbuff, 2); skb_reserve (rx_skbuff, 2);
} }
if (lp->rx_dma_addr[i] == NULL) if (lp->rx_dma_addr[i] == 0)
lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, rx_skbuff->len, PCI_DMA_FROMDEVICE); lp->rx_dma_addr[i] = pci_map_single(lp->pci_dev, rx_skbuff->tail, rx_skbuff->len, PCI_DMA_FROMDEVICE);
lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]); lp->rx_ring[i].base = (u32)le32_to_cpu(lp->rx_dma_addr[i]);
lp->rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ); lp->rx_ring[i].buf_length = le16_to_cpu(-PKT_BUF_SZ);
......
...@@ -147,7 +147,6 @@ ppp_asynctty_open(struct tty_struct *tty) ...@@ -147,7 +147,6 @@ ppp_asynctty_open(struct tty_struct *tty)
struct asyncppp *ap; struct asyncppp *ap;
int err; int err;
MOD_INC_USE_COUNT;
err = -ENOMEM; err = -ENOMEM;
ap = kmalloc(sizeof(*ap), GFP_KERNEL); ap = kmalloc(sizeof(*ap), GFP_KERNEL);
if (ap == 0) if (ap == 0)
...@@ -183,7 +182,6 @@ ppp_asynctty_open(struct tty_struct *tty) ...@@ -183,7 +182,6 @@ ppp_asynctty_open(struct tty_struct *tty)
out_free: out_free:
kfree(ap); kfree(ap);
out: out:
MOD_DEC_USE_COUNT;
return err; return err;
} }
...@@ -223,7 +221,6 @@ ppp_asynctty_close(struct tty_struct *tty) ...@@ -223,7 +221,6 @@ ppp_asynctty_close(struct tty_struct *tty)
if (ap->tpkt != 0) if (ap->tpkt != 0)
kfree_skb(ap->tpkt); kfree_skb(ap->tpkt);
kfree(ap); kfree(ap);
MOD_DEC_USE_COUNT;
} }
/* /*
...@@ -351,6 +348,7 @@ ppp_asynctty_wakeup(struct tty_struct *tty) ...@@ -351,6 +348,7 @@ ppp_asynctty_wakeup(struct tty_struct *tty)
static struct tty_ldisc ppp_ldisc = { static struct tty_ldisc ppp_ldisc = {
.owner = THIS_MODULE,
.magic = TTY_LDISC_MAGIC, .magic = TTY_LDISC_MAGIC,
.name = "ppp", .name = "ppp",
.open = ppp_asynctty_open, .open = ppp_asynctty_open,
......
...@@ -124,6 +124,7 @@ static struct mii_chip_info { ...@@ -124,6 +124,7 @@ static struct mii_chip_info {
{ "ICS LAN PHY", 0x0015, 0xF440, LAN }, { "ICS LAN PHY", 0x0015, 0xF440, LAN },
{ "NS 83851 PHY", 0x2000, 0x5C20, MIX }, { "NS 83851 PHY", 0x2000, 0x5C20, MIX },
{ "Realtek RTL8201 PHY", 0x0000, 0x8200, LAN }, { "Realtek RTL8201 PHY", 0x0000, 0x8200, LAN },
{ "VIA 6103 PHY", 0x0101, 0x8f20, LAN },
{0,}, {0,},
}; };
......
...@@ -37,7 +37,7 @@ config TULIP ...@@ -37,7 +37,7 @@ config TULIP
---help--- ---help---
This driver is developed for the SMC EtherPower series Ethernet This driver is developed for the SMC EtherPower series Ethernet
cards and also works with cards based on the DECchip cards and also works with cards based on the DECchip
21040/21041/21140 (Tulip series) chips. Some LinkSys PCI cards are 21140 (Tulip series) chips. Some LinkSys PCI cards are
of this type. (If your card is NOT SMC EtherPower 10/100 PCI of this type. (If your card is NOT SMC EtherPower 10/100 PCI
(smc9332dst), you can also try the driver for "Generic DECchip" (smc9332dst), you can also try the driver for "Generic DECchip"
cards, above. However, most people with a network card of this type cards, above. However, most people with a network card of this type
......
...@@ -388,11 +388,14 @@ static int __init flow_cache_init(void) ...@@ -388,11 +388,14 @@ static int __init flow_cache_init(void)
add_timer(&flow_hash_rnd_timer); add_timer(&flow_hash_rnd_timer);
register_cpu_notifier(&flow_cache_cpu_nb); register_cpu_notifier(&flow_cache_cpu_nb);
for (i = 0; i < NR_CPUS; i++) for (i = 0; i < NR_CPUS; i++) {
if (cpu_online(i)) { if (!cpu_online(i))
flow_cache_cpu_prepare(i); continue;
flow_cache_cpu_online(i); if (flow_cache_cpu_prepare(i) == NOTIFY_OK &&
} flow_cache_cpu_online(i) == NOTIFY_OK)
continue;
panic("NET: failed to initialise flow cache hash table\n");
}
return 0; return 0;
} }
......
...@@ -623,15 +623,20 @@ int arp_process(struct sk_buff *skb) ...@@ -623,15 +623,20 @@ int arp_process(struct sk_buff *skb)
int addr_type; int addr_type;
struct neighbour *n; struct neighbour *n;
/* arp_rcv below verifies the ARP header, verifies the device /* arp_rcv below verifies the ARP header and verifies the device
* is ARP'able, and linearizes the SKB (if needed). * is ARP'able.
*/ */
if (in_dev == NULL) if (in_dev == NULL)
goto out; goto out;
/* ARP header, plus 2 device addresses, plus 2 IP addresses. */
if (!pskb_may_pull(skb, (sizeof(struct arphdr) +
(2 * dev->addr_len) +
(2 * sizeof(u32)))))
goto out;
arp = skb->nh.arph; arp = skb->nh.arph;
arp_ptr= (unsigned char *)(arp+1);
switch (dev_type) { switch (dev_type) {
default: default:
...@@ -693,6 +698,7 @@ int arp_process(struct sk_buff *skb) ...@@ -693,6 +698,7 @@ int arp_process(struct sk_buff *skb)
/* /*
* Extract fields * Extract fields
*/ */
arp_ptr= (unsigned char *)(arp+1);
sha = arp_ptr; sha = arp_ptr;
arp_ptr += dev->addr_len; arp_ptr += dev->addr_len;
memcpy(&sip, arp_ptr, 4); memcpy(&sip, arp_ptr, 4);
...@@ -841,11 +847,6 @@ int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt) ...@@ -841,11 +847,6 @@ int arp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
goto out_of_mem; goto out_of_mem;
if (skb_is_nonlinear(skb)) {
if (skb_linearize(skb, GFP_ATOMIC) != 0)
goto freeskb;
}
return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process); return NF_HOOK(NF_ARP, NF_ARP_IN, skb, dev, NULL, arp_process);
freeskb: freeskb:
......
...@@ -247,14 +247,16 @@ unsigned int arpt_do_table(struct sk_buff **pskb, ...@@ -247,14 +247,16 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
{ {
static const char nulldevname[IFNAMSIZ] = { 0 }; static const char nulldevname[IFNAMSIZ] = { 0 };
unsigned int verdict = NF_DROP; unsigned int verdict = NF_DROP;
struct arphdr *arp = (*pskb)->nh.arph; struct arphdr *arp;
int hotdrop = 0; int hotdrop = 0;
struct arpt_entry *e, *back; struct arpt_entry *e, *back;
const char *indev, *outdev; const char *indev, *outdev;
void *table_base; void *table_base;
/* FIXME: Push down to extensions --RR */ /* ARP header, plus 2 device addresses, plus 2 IP addresses. */
if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0) if (!pskb_may_pull((*pskb), (sizeof(struct arphdr) +
(2 * (*pskb)->dev->addr_len) +
(2 * sizeof(u32)))))
return NF_DROP; return NF_DROP;
indev = in ? in->name : nulldevname; indev = in ? in->name : nulldevname;
...@@ -267,6 +269,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb, ...@@ -267,6 +269,7 @@ unsigned int arpt_do_table(struct sk_buff **pskb,
e = get_entry(table_base, table->private->hook_entry[hook]); e = get_entry(table_base, table->private->hook_entry[hook]);
back = get_entry(table_base, table->private->underflow[hook]); back = get_entry(table_base, table->private->underflow[hook]);
arp = (*pskb)->nh.arph;
do { do {
if (arp_packet_match(arp, (*pskb)->dev, indev, outdev, &e->arp)) { if (arp_packet_match(arp, (*pskb)->dev, indev, outdev, &e->arp)) {
struct arpt_entry_target *t; struct arpt_entry_target *t;
......
...@@ -613,12 +613,6 @@ static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp) ...@@ -613,12 +613,6 @@ static int icmpv6_rcv(struct sk_buff **pskb, unsigned int *nhoffp)
case NDISC_NEIGHBOUR_SOLICITATION: case NDISC_NEIGHBOUR_SOLICITATION:
case NDISC_NEIGHBOUR_ADVERTISEMENT: case NDISC_NEIGHBOUR_ADVERTISEMENT:
case NDISC_REDIRECT: case NDISC_REDIRECT:
if (skb_is_nonlinear(skb) &&
skb_linearize(skb, GFP_ATOMIC) != 0) {
kfree_skb(skb);
return 0;
}
ndisc_rcv(skb); ndisc_rcv(skb);
break; break;
......
...@@ -714,12 +714,6 @@ void ndisc_recv_ns(struct sk_buff *skb) ...@@ -714,12 +714,6 @@ void ndisc_recv_ns(struct sk_buff *skb)
struct inet6_ifaddr *ifp; struct inet6_ifaddr *ifp;
struct neighbour *neigh; struct neighbour *neigh;
if (skb->len < sizeof(struct nd_msg)) {
if (net_ratelimit())
printk(KERN_WARNING "ICMP NS: packet too short\n");
return;
}
if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) { if (ipv6_addr_type(&msg->target)&IPV6_ADDR_MULTICAST) {
if (net_ratelimit()) if (net_ratelimit())
printk(KERN_WARNING "ICMP NS: target address is multicast\n"); printk(KERN_WARNING "ICMP NS: target address is multicast\n");
...@@ -1410,7 +1404,12 @@ static void pndisc_redo(struct sk_buff *skb) ...@@ -1410,7 +1404,12 @@ static void pndisc_redo(struct sk_buff *skb)
int ndisc_rcv(struct sk_buff *skb) int ndisc_rcv(struct sk_buff *skb)
{ {
struct nd_msg *msg = (struct nd_msg *) skb->h.raw; struct nd_msg *msg;
if (!pskb_may_pull(skb, skb->len))
return 0;
msg = (struct nd_msg *) skb->h.raw;
__skb_push(skb, skb->data-skb->h.raw); __skb_push(skb, skb->data-skb->h.raw);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment