Commit 9162b02b authored by Jeff Garzik's avatar Jeff Garzik

Merge redhat.com:/garz/repo/linus-2.5

into redhat.com:/garz/repo/net-drivers-2.5
parents 1a1b6495 afe1ba38
...@@ -18,7 +18,8 @@ dev->open: ...@@ -18,7 +18,8 @@ dev->open:
dev->stop: dev->stop:
Synchronization: rtnl_lock() semaphore. Synchronization: rtnl_lock() semaphore.
Context: process Context: process
Notes: netif_running() is guaranteed false when this is called Note1: netif_running() is guaranteed false
Note2: dev->poll() is guaranteed to be stopped
dev->do_ioctl: dev->do_ioctl:
Synchronization: rtnl_lock() semaphore. Synchronization: rtnl_lock() semaphore.
...@@ -31,10 +32,12 @@ dev->get_stats: ...@@ -31,10 +32,12 @@ dev->get_stats:
dev->hard_start_xmit: dev->hard_start_xmit:
Synchronization: dev->xmit_lock spinlock. Synchronization: dev->xmit_lock spinlock.
Context: BHs disabled Context: BHs disabled
Notes: netif_queue_stopped() is guaranteed false
dev->tx_timeout: dev->tx_timeout:
Synchronization: dev->xmit_lock spinlock. Synchronization: dev->xmit_lock spinlock.
Context: BHs disabled Context: BHs disabled
Notes: netif_queue_stopped() is guaranteed true
dev->set_multicast_list: dev->set_multicast_list:
Synchronization: dev->xmit_lock spinlock. Synchronization: dev->xmit_lock spinlock.
......
...@@ -153,19 +153,5 @@ config PCMCIA_IBMTR ...@@ -153,19 +153,5 @@ config PCMCIA_IBMTR
The module will be called ibmtr_cs. If you want to compile it as The module will be called ibmtr_cs. If you want to compile it as
a module, say M here and read <file:Documentation/modules.txt>. a module, say M here and read <file:Documentation/modules.txt>.
config AIRONET4500_CS
tristate "Aironet 4500/4800 PCMCIA support"
depends on NET_PCMCIA_RADIO && AIRONET4500 && PCMCIA
help
Say Y here if you have a PCMCIA Aironet 4500/4800 card which you
want to use with the standard PCMCIA cardservices provided by the
pcmcia-cs package.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called aironet4500_cs. If you want to
compile it as a module, say M here and read
<file:Documentation/modules.txt>.
endmenu endmenu
...@@ -13,7 +13,4 @@ obj-$(CONFIG_PCMCIA_XIRC2PS) += xirc2ps_cs.o ...@@ -13,7 +13,4 @@ obj-$(CONFIG_PCMCIA_XIRC2PS) += xirc2ps_cs.o
obj-$(CONFIG_ARCNET_COM20020_CS)+= com20020_cs.o obj-$(CONFIG_ARCNET_COM20020_CS)+= com20020_cs.o
obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o obj-$(CONFIG_PCMCIA_AXNET) += axnet_cs.o
# 16-bit wireless client drivers
obj-$(CONFIG_AIRONET4500_CS) += aironet4500_cs.o
obj-$(CONFIG_PCMCIA_IBMTR) += ibmtr_cs.o obj-$(CONFIG_PCMCIA_IBMTR) += ibmtr_cs.o
/*
* Aironet 4500 Pcmcia driver
*
* Elmer Joandi, Januar 1999
* Copyright Elmer Joandi, all rights restricted
*
*
* Revision 0.1 ,started 30.12.1998
*
*
*/
#define DRV_NAME "aironet4500_cs"
#define DRV_VERSION "0.1"
static const char *awc_version =
DRV_NAME ".c v" DRV_VERSION " 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/ethtool.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/ioport.h>
#include <pcmcia/version.h>
#include <pcmcia/cs_types.h>
#include <pcmcia/cs.h>
#include <pcmcia/cistpl.h>
#include <pcmcia/cisreg.h>
#include <pcmcia/ciscode.h>
#include <pcmcia/ds.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include "../aironet4500.h"
static u_int irq_mask = 0x5eF8;
static int awc_ports[] = {0x140,0x100,0xc0, 0x80 };
#if LINUX_VERSION_CODE > 0x20100
MODULE_PARM(irq_mask, "i");
#endif
#define RUN_AT(x) (jiffies+(x))
#ifdef PCMCIA_DEBUG
static int pc_debug = PCMCIA_DEBUG;
MODULE_PARM(pc_debug, "i");
#define PC_DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
static char *version =
"aironet4500_cs.c v0.1 1/1/99 Elmer Joandi, elmer@ylenurme.ee.\n";
#else
#define PC_DEBUG(n, args...)
#endif
/* Index of functions. */
static dev_info_t dev_info = "aironet4500_cs";
static dev_link_t *awc_attach(void);
static void awc_detach(dev_link_t *);
static void awc_release(u_long arg);
static int awc_event(event_t event, int priority,
event_callback_args_t *args);
static dev_link_t *dev_list;
static void cs_error(client_handle_t handle, int func, int ret)
{
#if CS_RELEASE_CODE < 0x2911
CardServices(ReportError, dev_info, (void *)func, (void *)ret);
#else
error_info_t err = { func, ret };
CardServices(ReportError, handle, &err);
#endif
}
#define CFG_CHECK(fn, args...) if (CardServices(fn, args) != 0) goto next_entry
static void flush_stale_links(void)
{
dev_link_t *link, *next;
for (link = dev_list; link; link = next) {
next = link->next;
if (link->state & DEV_STALE_LINK)
awc_detach(link);
}
}
/*
We never need to do anything when a awc device is "initialized"
by the net software, because we only register already-found cards.
*/
static int awc_pcmcia_init(struct net_device *dev)
{
return awc_init(dev);
}
static int awc_pcmcia_open(struct net_device *dev)
{
dev_link_t *link;
int status;
for (link = dev_list; link; link = link->next)
if (link->priv == dev) break;
if (!DEV_OK(link))
return -ENODEV;
status = awc_open(dev);
if (!status )
link->open++;
return status;
}
static int awc_pcmcia_close(struct net_device *dev)
{
// int ioaddr = dev->base_addr;
dev_link_t *link;
int ret;
for (link = dev_list; link; link = link->next)
if (link->priv == dev) break;
if (link == NULL)
return -ENODEV;
PC_DEBUG(2, "%s: closing device.\n", dev->name);
link->open--;
ret = awc_close(dev);
if (link->state & DEV_STALE_CONFIG) {
link->release.expires = RUN_AT( HZ/20 );
link->state |= DEV_RELEASE_PENDING;
add_timer(&link->release);
}
return ret;
}
static int netdev_ethtool_ioctl (struct net_device *dev, void *useraddr)
{
u32 ethcmd;
/* dev_ioctl() in ../../net/core/dev.c has already checked
capable(CAP_NET_ADMIN), so don't bother with that here. */
if (get_user(ethcmd, (u32 *)useraddr))
return -EFAULT;
switch (ethcmd) {
case ETHTOOL_GDRVINFO: {
struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
strcpy (info.driver, DRV_NAME);
strcpy (info.version, DRV_VERSION);
sprintf(info.bus_info, "PCMCIA 0x%lx", dev->base_addr);
if (copy_to_user (useraddr, &info, sizeof (info)))
return -EFAULT;
return 0;
}
#ifdef PCMCIA_DEBUG
/* get message-level */
case ETHTOOL_GMSGLVL: {
struct ethtool_value edata = {ETHTOOL_GMSGLVL};
edata.data = pc_debug;
if (copy_to_user(useraddr, &edata, sizeof(edata)))
return -EFAULT;
return 0;
}
/* set message-level */
case ETHTOOL_SMSGLVL: {
struct ethtool_value edata;
if (copy_from_user(&edata, useraddr, sizeof(edata)))
return -EFAULT;
pc_debug = edata.data;
return 0;
}
#endif
default:
break;
}
return -EOPNOTSUPP;
}
static int awc_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
switch (cmd) {
case SIOCETHTOOL:
return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
default:
return -EOPNOTSUPP;
}
return 0;
}
/*
awc_attach() creates an "instance" of the driver, allocating
local data structures for one device. The device is registered
with Card Services.
*/
static dev_link_t *awc_attach(void)
{
client_reg_t client_reg;
dev_link_t *link = NULL;
struct net_device *dev = NULL;
int ret;
PC_DEBUG(0, "awc_attach()\n");
flush_stale_links();
/* Create the PC card device object. */
link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
if (!link)
return NULL;
memset(link, 0, sizeof(struct dev_link_t));
link->dev = kmalloc(sizeof(struct dev_node_t), GFP_KERNEL);
if (!link->dev) {
kfree(link);
return NULL;
}
memset(link->dev, 0, sizeof(struct dev_node_t));
init_timer(&link->release);
link->release.function = &awc_release;
link->release.data = (u_long)link;
// link->io.NumPorts1 = 32;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
// link->io.IOAddrLines = 5;
link->irq.Attributes = IRQ_HANDLE_PRESENT ; // |IRQ_TYPE_EXCLUSIVE ;
link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
link->irq.IRQInfo2 = irq_mask;
link->irq.Handler = &awc_interrupt;
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
link->conf.IntType = INT_MEMORY_AND_IO;
link->conf.ConfigIndex = 1;
link->conf.Present = PRESENT_OPTION;
/* Create the network device object. */
dev = kmalloc(sizeof(struct net_device ), GFP_KERNEL);
// dev = init_etherdev(0, sizeof(struct awc_private) );
if (!dev ) {
printk(KERN_CRIT "out of mem on dev alloc \n");
kfree(link->dev);
kfree(link);
return NULL;
};
memset(dev,0,sizeof(struct net_device));
dev->priv = kmalloc(sizeof(struct awc_private), GFP_KERNEL);
if (!dev->priv ) {printk(KERN_CRIT "out of mem on dev priv alloc \n"); return NULL;};
memset(dev->priv,0,sizeof(struct awc_private));
// link->dev->minor = dev->minor;
// link->dev->major = dev->major;
/* The 4500-specific entries in the device structure. */
// dev->tx_queue_len = tx_queue_len;
dev->hard_start_xmit = &awc_start_xmit;
// dev->set_config = &awc_config_misiganes,aga mitte awc_config;
dev->get_stats = &awc_get_stats;
// dev->set_multicast_list = &awc_set_multicast_list;
dev->do_ioctl = &awc_ioctl;
strcpy(dev->name, ((struct awc_private *)dev->priv)->node.dev_name);
ether_setup(dev);
dev->init = &awc_pcmcia_init;
dev->open = &awc_pcmcia_open;
dev->stop = &awc_pcmcia_close;
link->priv = dev;
#if CS_RELEASE_CODE > 0x2911
link->irq.Instance = dev;
#endif
/* Register with Card Services */
link->next = dev_list;
dev_list = link;
client_reg.dev_info = &dev_info;
client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
client_reg.EventMask =
CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
client_reg.event_handler = &awc_event;
client_reg.Version = 0x0210;
client_reg.event_callback_args.client_data = link;
ret = CardServices(RegisterClient, &link->handle, &client_reg);
if (ret != 0) {
cs_error(link->handle, RegisterClient, ret);
awc_detach(link);
return NULL;
}
return link;
} /* awc_attach */
/*
This deletes a driver "instance". The device is de-registered
with Card Services. If it has been released, all local data
structures are freed. Otherwise, the structures will be freed
when the device is released.
*/
static void awc_detach(dev_link_t *link)
{
dev_link_t **linkp;
unsigned long flags;
int i=0;
DEBUG(0, "awc_detach(0x%p)\n", link);
/* Locate device structure */
for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
if (*linkp == link) break;
if (*linkp == NULL)
return;
save_flags(flags);
cli();
if (link->state & DEV_RELEASE_PENDING) {
del_timer(&link->release);
link->state &= ~DEV_RELEASE_PENDING;
}
restore_flags(flags);
if (link->state & DEV_CONFIG) {
awc_release((u_long)link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
}
}
if (link->handle)
CardServices(DeregisterClient, link->handle);
/* Unlink device structure, free bits */
*linkp = link->next;
i=0;
while ( i < MAX_AWCS) {
if (!aironet4500_devices[i])
{i++; continue;}
if (aironet4500_devices[i] == link->priv){
if (awc_proc_unset_fun)
awc_proc_unset_fun(i);
aironet4500_devices[i]=0;
}
i++;
}
if (link->priv) {
//struct net_device *dev = link->priv;
// dam dam damn mif (dev->priv)
// kfree(dev->priv);
kfree(link->priv);
}
kfree(link->dev);
kfree(link);
} /* awc_detach */
/*
awc_pcmcia_config() is scheduled to run after a CARD_INSERTION event
is received, to configure the PCMCIA socket, and to make the
ethernet device available to the system.
*/
#define CS_CHECK(fn, args...) \
while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
static void awc_pcmcia_config(dev_link_t *link)
{
client_handle_t handle;
struct net_device *dev;
struct awc_private *lp;
tuple_t tuple;
int ii;
cisparse_t parse;
u_short buf[64];
int last_fn, last_ret, i = 0;
// int ioaddr;
u16 *phys_addr;
int retval;
handle = link->handle;
dev = link->priv;
phys_addr = (u16 *)dev->dev_addr;
PC_DEBUG(0, "awc_pcmcia_config(0x%p)\n", link);
tuple.Attributes = 0;
tuple.DesiredTuple = CISTPL_CONFIG;
CS_CHECK(GetFirstTuple, handle, &tuple);
tuple.TupleData = (cisdata_t *)buf;
tuple.TupleDataMax = 64;
tuple.TupleOffset = 0;
CS_CHECK(GetTupleData, handle, &tuple);
CS_CHECK(ParseTuple, handle, &tuple, &parse);
link->conf.ConfigBase = parse.config.base;
link->conf.Present = parse.config.rmask[0];
/* Configure card */
link->state |= DEV_CONFIG;
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
CS_CHECK(GetFirstTuple, handle, &tuple);
while (1) {
cistpl_cftable_entry_t dflt = { 0 };
cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
CFG_CHECK(GetTupleData, handle, &tuple);
CFG_CHECK(ParseTuple, handle, &tuple, &parse);
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
if (cfg->index == 0) goto next_entry;
link->conf.ConfigIndex = cfg->index;
/* Use power settings for Vcc and Vpp if present */
/* Note that the CIS values need to be rescaled */
if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vcc = cfg->vcc.param[CISTPL_POWER_VNOM]/10000;
else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vcc = dflt.vcc.param[CISTPL_POWER_VNOM]/10000;
if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 =
cfg->vpp1.param[CISTPL_POWER_VNOM]/10000;
else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM))
link->conf.Vpp1 = link->conf.Vpp2 =
dflt.vpp1.param[CISTPL_POWER_VNOM]/10000;
/* Do we need to allocate an interrupt? */
if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1)
link->conf.Attributes |= CONF_ENABLE_IRQ;
/* IO window settings */
link->io.NumPorts1 = link->io.NumPorts2 = 0;
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
if (!(io->flags & CISTPL_IO_8BIT))
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
if (!(io->flags & CISTPL_IO_16BIT)) {
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
printk(KERN_CRIT "8-bit IO not supported on this aironet 4500 driver \n");
}
link->io.BasePort1 = io->win[0].base;
link->io.NumPorts1 = io->win[0].len;
if (io->nwin > 1) {
link->io.Attributes2 = link->io.Attributes1;
link->io.BasePort2 = io->win[1].base;
link->io.NumPorts2 = io->win[1].len;
}
}
ii = 0;
last_fn = RequestIO;
while ((last_ret = CardServices(RequestIO, link->handle, &link->io)) ){
if (ii > 4)
goto cs_failed;
link->io.BasePort1 = awc_ports[ii];
ii++;
};
break;
next_entry:
if (CardServices(GetNextTuple, handle, &tuple))
break;
}
if (link->conf.Attributes & CONF_ENABLE_IRQ){
ii = 0; last_fn = RequestIRQ;
while ((last_ret = CardServices(RequestIRQ, link->handle, &link->irq)) ){
ii++;
while (!(irq_mask & (1 << ii) ) && ii < 15)
ii++;
link->irq.IRQInfo2 = 1 << ii;
if(ii > 15)
goto cs_failed;
printk("trying irq %d , mask %x \n",ii, link->irq.IRQInfo2);
};
}
CS_CHECK(RequestConfiguration, link->handle, &link->conf);
dev->irq = link->irq.AssignedIRQ;
dev->base_addr = link->io.BasePort1;
awc_private_init( dev);
retval = register_netdev(dev);
if (retval != 0) {
printk(KERN_NOTICE "awc_cs: register_netdev() failed for dev %x retval %x\n",(unsigned int)dev,retval);
goto failed;
}
if(awc_pcmcia_init(dev)) goto failed;
i=0;
while (aironet4500_devices[i] && i < MAX_AWCS-1) i++;
if (!aironet4500_devices[i]){
aironet4500_devices[i]=dev;
if (awc_proc_set_fun)
awc_proc_set_fun(i);
}
link->state &= ~DEV_CONFIG_PENDING;
lp = (struct awc_private *)dev->priv;
DEBUG(1,"pcmcia config complete on port %x \n",(unsigned int)dev->base_addr);
return;
cs_failed:
cs_error(link->handle, last_fn, last_ret);
link->dev=NULL;
failed:
awc_release((u_long)link);
return;
} /* awc_pcmcia_config */
/*
After a card is removed, awc_release() will unregister the net
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
*/
static void awc_release(u_long arg)
{
dev_link_t *link = (dev_link_t *)arg;
struct net_device *dev = link->priv;
DEBUG(0, "awc_release(0x%p)\n", link);
if (link->open) {
DEBUG(1, "awc_cs: release postponed, '%s' still open\n",
link->dev->dev_name);
link->state |= DEV_STALE_CONFIG;
return;
}
CardServices(ReleaseConfiguration, link->handle);
CardServices(ReleaseIO, link->handle, &link->io);
CardServices(ReleaseIRQ, link->handle, &link->irq);
CardServices(ReleaseWindow, link->win);
if (link->dev)
unregister_netdev(dev);
// link->dev = NULL;
link->state &= ~DEV_CONFIG;
if (link->state & DEV_STALE_LINK)
awc_detach(link);
} /* awc_release */
/*
The card status event handler. Mostly, this schedules other
stuff to run after an event is received. A CARD_REMOVAL event
also sets some flags to discourage the net drivers from trying
to talk to the card any more.
*/
static int awc_event(event_t event, int priority,
event_callback_args_t *args)
{
dev_link_t *link = args->client_data;
struct net_device *dev = link->priv;
PC_DEBUG(1, "awc_event(0x%06x)\n", event);
switch (event) {
case CS_EVENT_CARD_REMOVAL:
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(dev);
link->release.expires = RUN_AT( HZ/20 );
add_timer(&link->release);
}
break;
case CS_EVENT_CARD_INSERTION:
link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
awc_pcmcia_config(link);
break;
case CS_EVENT_PM_SUSPEND:
link->state |= DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_RESET_PHYSICAL:
if (link->state & DEV_CONFIG) {
if (link->open)
netif_device_detach(dev);
CardServices(ReleaseConfiguration, link->handle);
}
break;
case CS_EVENT_PM_RESUME:
link->state &= ~DEV_SUSPEND;
/* Fall through... */
case CS_EVENT_CARD_RESET:
if (link->state & DEV_CONFIG) {
CardServices(RequestConfiguration, link->handle, &link->conf);
if (link->open) {
// awc_reset(dev);
netif_device_attach(dev);
}
}
break;
}
return 0;
} /* awc_event */
static int __init aironet_cs_init(void)
{
servinfo_t serv;
/* Always emit the version, before any failure. */
printk(KERN_INFO"%s", awc_version);
PC_DEBUG(0, "%s\n", version);
CardServices(GetCardServicesInfo, &serv);
if (serv.Revision != CS_RELEASE_CODE) {
printk(KERN_NOTICE "awc_cs: Card Services release "
"does not match!\n");
return -1;
}
register_pcmcia_driver(&dev_info, &awc_attach, &awc_detach);
return 0;
}
static void __exit aironet_cs_exit(void)
{
DEBUG(0, "awc_cs: unloading %c ",'\n');
unregister_pcmcia_driver(&dev_info);
while (dev_list != NULL) {
if (dev_list->state & DEV_CONFIG)
awc_release((u_long)dev_list);
awc_detach(dev_list);
}
// while (dev_list != NULL)
// awc_detach(dev_list);
}
module_init(aironet_cs_init);
module_exit(aironet_cs_exit);
MODULE_LICENSE("GPL");
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/if_vlan.h> #include <linux/if_vlan.h>
#include <linux/ip.h> #include <linux/ip.h>
#include <linux/tcp.h> #include <linux/tcp.h>
#include <linux/workqueue.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -54,8 +55,8 @@ ...@@ -54,8 +55,8 @@
#define DRV_MODULE_NAME "tg3" #define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "1.4" #define DRV_MODULE_VERSION "1.4c"
#define DRV_MODULE_RELDATE "Feb 1, 2003" #define DRV_MODULE_RELDATE "Feb 18, 2003"
#define TG3_DEF_MAC_MODE 0 #define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0 #define TG3_DEF_RX_MODE 0
...@@ -216,6 +217,12 @@ static void tg3_disable_ints(struct tg3 *tp) ...@@ -216,6 +217,12 @@ static void tg3_disable_ints(struct tg3 *tp)
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
} }
static inline void tg3_cond_int(struct tg3 *tp)
{
if (tp->hw_status->status & SD_STATUS_UPDATED)
tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
}
static void tg3_enable_ints(struct tg3 *tp) static void tg3_enable_ints(struct tg3 *tp)
{ {
tw32(TG3PCI_MISC_HOST_CTRL, tw32(TG3PCI_MISC_HOST_CTRL,
...@@ -223,9 +230,55 @@ static void tg3_enable_ints(struct tg3 *tp) ...@@ -223,9 +230,55 @@ static void tg3_enable_ints(struct tg3 *tp)
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000);
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
if (tp->hw_status->status & SD_STATUS_UPDATED) tg3_cond_int(tp);
tw32(GRC_LOCAL_CTRL, }
tp->grc_local_ctrl | GRC_LCLCTRL_SETINT);
/* these netif_xxx funcs should be moved into generic net layer */
static void netif_poll_disable(struct net_device *dev)
{
while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
current->state = TASK_INTERRUPTIBLE;
schedule_timeout(1);
}
}
static inline void netif_poll_enable(struct net_device *dev)
{
clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
}
/* same as netif_rx_complete, except that local_irq_save(flags)
* has already been issued
*/
static inline void __netif_rx_complete(struct net_device *dev)
{
if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG();
list_del(&dev->poll_list);
clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
}
static inline void netif_tx_disable(struct net_device *dev)
{
spin_lock_bh(&dev->xmit_lock);
netif_stop_queue(dev);
spin_unlock_bh(&dev->xmit_lock);
}
static inline void tg3_netif_stop(struct tg3 *tp)
{
netif_poll_disable(tp->dev);
netif_tx_disable(tp->dev);
}
static inline void tg3_netif_start(struct tg3 *tp)
{
netif_wake_queue(tp->dev);
/* NOTE: unconditional netif_wake_queue is only appropriate
* so long as all callers are assured to have free tx slots
* (such as after tg3_init_hw)
*/
netif_poll_enable(tp->dev);
tg3_cond_int(tp);
} }
static void tg3_switch_clocks(struct tg3 *tp) static void tg3_switch_clocks(struct tg3 *tp)
...@@ -387,7 +440,6 @@ static int tg3_phy_reset(struct tg3 *tp, int force) ...@@ -387,7 +440,6 @@ static int tg3_phy_reset(struct tg3 *tp, int force)
} }
static int tg3_setup_phy(struct tg3 *); static int tg3_setup_phy(struct tg3 *);
static int tg3_halt(struct tg3 *);
static int tg3_set_power_state(struct tg3 *tp, int state) static int tg3_set_power_state(struct tg3 *tp, int state)
{ {
...@@ -458,8 +510,6 @@ static int tg3_set_power_state(struct tg3 *tp, int state) ...@@ -458,8 +510,6 @@ static int tg3_set_power_state(struct tg3 *tp, int state)
tg3_setup_phy(tp); tg3_setup_phy(tp);
} }
tg3_halt(tp);
pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps); pci_read_config_word(tp->pdev, pm + PCI_PM_PMC, &power_caps);
if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) { if (tp->tg3_flags & TG3_FLAG_WOL_ENABLE) {
...@@ -2044,7 +2094,12 @@ static int tg3_poll(struct net_device *netdev, int *budget) ...@@ -2044,7 +2094,12 @@ static int tg3_poll(struct net_device *netdev, int *budget)
spin_unlock(&tp->tx_lock); spin_unlock(&tp->tx_lock);
} }
/* run RX thread, within the bounds set by NAPI */ spin_unlock_irqrestore(&tp->lock, flags);
/* run RX thread, within the bounds set by NAPI.
* All RX "locking" is done by ensuring outside
* code synchronizes with dev->poll()
*/
done = 1; done = 1;
if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) { if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) {
int orig_budget = *budget; int orig_budget = *budget;
...@@ -2064,11 +2119,11 @@ static int tg3_poll(struct net_device *netdev, int *budget) ...@@ -2064,11 +2119,11 @@ static int tg3_poll(struct net_device *netdev, int *budget)
/* if no more work, tell net stack and NIC we're done */ /* if no more work, tell net stack and NIC we're done */
if (done) { if (done) {
netif_rx_complete(netdev); spin_lock_irqsave(&tp->lock, flags);
__netif_rx_complete(netdev);
tg3_enable_ints(tp); tg3_enable_ints(tp);
}
spin_unlock_irqrestore(&tp->lock, flags); spin_unlock_irqrestore(&tp->lock, flags);
}
return (done ? 0 : 1); return (done ? 0 : 1);
} }
...@@ -2136,17 +2191,21 @@ static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) ...@@ -2136,17 +2191,21 @@ static void tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static void tg3_init_rings(struct tg3 *); static void tg3_init_rings(struct tg3 *);
static int tg3_init_hw(struct tg3 *); static int tg3_init_hw(struct tg3 *);
static int tg3_halt(struct tg3 *);
static void tg3_tx_timeout(struct net_device *dev) static void tg3_reset_task(void *_data)
{ {
struct tg3 *tp = dev->priv; struct tg3 *tp = _data;
unsigned int restart_timer;
printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", tg3_netif_stop(tp);
dev->name);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock); spin_lock(&tp->tx_lock);
restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER;
tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER;
tg3_halt(tp); tg3_halt(tp);
tg3_init_rings(tp); tg3_init_rings(tp);
tg3_init_hw(tp); tg3_init_hw(tp);
...@@ -2154,7 +2213,20 @@ static void tg3_tx_timeout(struct net_device *dev) ...@@ -2154,7 +2213,20 @@ static void tg3_tx_timeout(struct net_device *dev)
spin_unlock(&tp->tx_lock); spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
netif_wake_queue(dev); tg3_netif_start(tp);
if (restart_timer)
mod_timer(&tp->timer, jiffies + 1);
}
static void tg3_tx_timeout(struct net_device *dev)
{
struct tg3 *tp = dev->priv;
printk(KERN_ERR PFX "%s: transmit timed out, resetting\n",
dev->name);
schedule_work(&tp->reset_task);
} }
#if !PCI_DMA_BUS_IS_PHYS #if !PCI_DMA_BUS_IS_PHYS
...@@ -2686,6 +2758,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) ...@@ -2686,6 +2758,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
return 0; return 0;
} }
tg3_netif_stop(tp);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock); spin_lock(&tp->tx_lock);
...@@ -2698,6 +2771,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) ...@@ -2698,6 +2771,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu)
spin_unlock(&tp->tx_lock); spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
tg3_netif_start(tp);
return 0; return 0;
} }
...@@ -3073,6 +3147,7 @@ static int tg3_abort_hw(struct tg3 *tp) ...@@ -3073,6 +3147,7 @@ static int tg3_abort_hw(struct tg3 *tp)
static void tg3_chip_reset(struct tg3 *tp) static void tg3_chip_reset(struct tg3 *tp)
{ {
u32 val; u32 val;
u32 flags_save;
/* Force NVRAM to settle. /* Force NVRAM to settle.
* This deals with a chip bug which can result in EEPROM * This deals with a chip bug which can result in EEPROM
...@@ -3089,8 +3164,21 @@ static void tg3_chip_reset(struct tg3 *tp) ...@@ -3089,8 +3164,21 @@ static void tg3_chip_reset(struct tg3 *tp)
} }
} }
/*
* We must avoid the readl() that normally takes place.
* It locks machines, causes machine checks, and other
* fun things. So, temporarily disable the 5701
* hardware workaround, while we do the reset.
*/
flags_save = tp->tg3_flags;
tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG;
/* do the reset */
tw32(GRC_MISC_CFG, GRC_MISC_CFG_CORECLK_RESET); tw32(GRC_MISC_CFG, GRC_MISC_CFG_CORECLK_RESET);
/* restore 5701 hardware bug workaround flag */
tp->tg3_flags = flags_save;
/* Flush PCI posted writes. The normal MMIO registers /* Flush PCI posted writes. The normal MMIO registers
* are inaccessible at this time so this is the only * are inaccessible at this time so this is the only
* way to make this reliably. I tried to use indirect * way to make this reliably. I tried to use indirect
...@@ -4394,9 +4482,11 @@ static void tg3_timer(unsigned long __opaque) ...@@ -4394,9 +4482,11 @@ static void tg3_timer(unsigned long __opaque)
} }
if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
tg3_halt(tp); tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER;
tg3_init_rings(tp); spin_unlock(&tp->tx_lock);
tg3_init_hw(tp); spin_unlock_irqrestore(&tp->lock, flags);
schedule_work(&tp->reset_task);
return;
} }
/* This part only runs once per second. */ /* This part only runs once per second. */
...@@ -4527,8 +4617,6 @@ static int tg3_open(struct net_device *dev) ...@@ -4527,8 +4617,6 @@ static int tg3_open(struct net_device *dev)
return err; return err;
} }
netif_start_queue(dev);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock); spin_lock(&tp->tx_lock);
...@@ -4537,6 +4625,8 @@ static int tg3_open(struct net_device *dev) ...@@ -4537,6 +4625,8 @@ static int tg3_open(struct net_device *dev)
spin_unlock(&tp->tx_lock); spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
netif_start_queue(dev);
return 0; return 0;
} }
...@@ -5302,6 +5392,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -5302,6 +5392,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
(ering.tx_pending > TG3_TX_RING_SIZE - 1)) (ering.tx_pending > TG3_TX_RING_SIZE - 1))
return -EINVAL; return -EINVAL;
tg3_netif_stop(tp);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock); spin_lock(&tp->tx_lock);
...@@ -5315,6 +5406,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -5315,6 +5406,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
netif_wake_queue(tp->dev); netif_wake_queue(tp->dev);
spin_unlock(&tp->tx_lock); spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
tg3_netif_start(tp);
return 0; return 0;
} }
...@@ -5337,6 +5429,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -5337,6 +5429,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
if (copy_from_user(&epause, useraddr, sizeof(epause))) if (copy_from_user(&epause, useraddr, sizeof(epause)))
return -EFAULT; return -EFAULT;
tg3_netif_stop(tp);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock); spin_lock(&tp->tx_lock);
if (epause.autoneg) if (epause.autoneg)
...@@ -5356,6 +5449,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr) ...@@ -5356,6 +5449,7 @@ static int tg3_ethtool_ioctl (struct net_device *dev, void *useraddr)
tg3_init_hw(tp); tg3_init_hw(tp);
spin_unlock(&tp->tx_lock); spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
tg3_netif_start(tp);
return 0; return 0;
} }
...@@ -6710,6 +6804,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, ...@@ -6710,6 +6804,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
spin_lock_init(&tp->lock); spin_lock_init(&tp->lock);
spin_lock_init(&tp->tx_lock); spin_lock_init(&tp->tx_lock);
spin_lock_init(&tp->indirect_lock); spin_lock_init(&tp->indirect_lock);
PREPARE_WORK(&tp->reset_task, tg3_reset_task, tp);
tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len); tp->regs = (unsigned long) ioremap(tg3reg_base, tg3reg_len);
if (tp->regs == 0UL) { if (tp->regs == 0UL) {
...@@ -6851,6 +6946,8 @@ static int tg3_suspend(struct pci_dev *pdev, u32 state) ...@@ -6851,6 +6946,8 @@ static int tg3_suspend(struct pci_dev *pdev, u32 state)
if (!netif_running(dev)) if (!netif_running(dev))
return 0; return 0;
tg3_netif_stop(tp);
spin_lock_irq(&tp->lock); spin_lock_irq(&tp->lock);
spin_lock(&tp->tx_lock); spin_lock(&tp->tx_lock);
tg3_disable_ints(tp); tg3_disable_ints(tp);
...@@ -6877,6 +6974,7 @@ static int tg3_suspend(struct pci_dev *pdev, u32 state) ...@@ -6877,6 +6974,7 @@ static int tg3_suspend(struct pci_dev *pdev, u32 state)
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
netif_device_attach(dev); netif_device_attach(dev);
tg3_netif_start(tp);
} }
return err; return err;
...@@ -6907,6 +7005,8 @@ static int tg3_resume(struct pci_dev *pdev) ...@@ -6907,6 +7005,8 @@ static int tg3_resume(struct pci_dev *pdev)
spin_unlock(&tp->tx_lock); spin_unlock(&tp->tx_lock);
spin_unlock_irq(&tp->lock); spin_unlock_irq(&tp->lock);
tg3_netif_start(tp);
return 0; return 0;
} }
......
...@@ -1821,6 +1821,8 @@ struct tg3 { ...@@ -1821,6 +1821,8 @@ struct tg3 {
#define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000 #define TG3_FLAG_GOT_SERDES_FLOWCTL 0x20000000
#define TG3_FLAG_SPLIT_MODE 0x40000000 #define TG3_FLAG_SPLIT_MODE 0x40000000
#define TG3_FLAG_INIT_COMPLETE 0x80000000 #define TG3_FLAG_INIT_COMPLETE 0x80000000
u32 tg3_flags2;
#define TG3_FLG2_RESTART_TIMER 0x00000001
u32 split_mode_max_reqs; u32 split_mode_max_reqs;
#define SPLIT_MODE_5704_MAX_REQ 3 #define SPLIT_MODE_5704_MAX_REQ 3
...@@ -1889,6 +1891,7 @@ struct tg3 { ...@@ -1889,6 +1891,7 @@ struct tg3 {
struct tg3_hw_stats *hw_stats; struct tg3_hw_stats *hw_stats;
dma_addr_t stats_mapping; dma_addr_t stats_mapping;
struct work_struct reset_task;
}; };
#endif /* !(_T3_H) */ #endif /* !(_T3_H) */
...@@ -6,13 +6,13 @@ menu "Wireless LAN (non-hamradio)" ...@@ -6,13 +6,13 @@ menu "Wireless LAN (non-hamradio)"
depends on NETDEVICES depends on NETDEVICES
config NET_RADIO config NET_RADIO
bool "Wireless LAN (non-hamradio)" bool "Wireless LAN drivers (non-hamradio) & Wireless Extensions"
---help--- ---help---
Support for wireless LANs and everything having to do with radio, Support for wireless LANs and everything having to do with radio,
but not with amateur radio or FM broadcasting. but not with amateur radio or FM broadcasting.
Saying Y here also enables the Wireless Extensions (creates Saying Y here also enables the Wireless Extensions (creates
/proc/net/wireless and enables ifconfig access). The Wireless /proc/net/wireless and enables iwconfig access). The Wireless
Extension is a generic API allowing a driver to expose to the user Extension is a generic API allowing a driver to expose to the user
space configuration and statistics specific to common Wireless LANs. space configuration and statistics specific to common Wireless LANs.
The beauty of it is that a single set of tool can support all the The beauty of it is that a single set of tool can support all the
...@@ -28,6 +28,11 @@ config NET_RADIO ...@@ -28,6 +28,11 @@ config NET_RADIO
special kernel support are available from special kernel support are available from
<ftp://shadow.cabi.net/pub/Linux/>. <ftp://shadow.cabi.net/pub/Linux/>.
# Note : the cards are obsolete (can't buy them anymore), but the drivers
# are not, as people are still using them...
comment "Obsolete Wireless cards support (pre-802.11)"
depends on NET_RADIO && (INET || ISA || PCMCIA)
config STRIP config STRIP
tristate "STRIP (Metricom starmode radio IP)" tristate "STRIP (Metricom starmode radio IP)"
depends on NET_RADIO && INET depends on NET_RADIO && INET
...@@ -68,10 +73,6 @@ config ARLAN ...@@ -68,10 +73,6 @@ config ARLAN
On some computers the card ends up in non-valid state after some On some computers the card ends up in non-valid state after some
time. Use a ping-reset script to clear it. time. Use a ping-reset script to clear it.
comment "Wireless ISA/PCI cards support"
depends on NET_RADIO && (ISA || PCI || ALL_PPC || PCMCIA)
# Good old obsolete Wavelan.
config WAVELAN config WAVELAN
tristate "AT&T/Lucent old WaveLAN & DEC RoamAbout DS ISA support" tristate "AT&T/Lucent old WaveLAN & DEC RoamAbout DS ISA support"
depends on NET_RADIO && ISA depends on NET_RADIO && ISA
...@@ -102,7 +103,54 @@ config WAVELAN ...@@ -102,7 +103,54 @@ config WAVELAN
module, say M here and read <file:Documentation/modules.txt> as well module, say M here and read <file:Documentation/modules.txt> as well
as <file:Documentation/networking/net-modules.txt>. as <file:Documentation/networking/net-modules.txt>.
# 802.11b cards config PCMCIA_WAVELAN
tristate "AT&T/Lucent old WaveLAN Pcmcia wireless support"
depends on NET_RADIO && PCMCIA
help
Say Y here if you intend to attach an AT&T/Lucent Wavelan PCMCIA
(PC-card) wireless Ethernet networking card to your computer. This
driver is for the non-IEEE-802.11 Wavelan cards.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called wavelan_cs. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
If unsure, say N.
config PCMCIA_NETWAVE
tristate "Xircom Netwave AirSurfer Pcmcia wireless support"
depends on NET_RADIO && PCMCIA
help
Say Y here if you intend to attach this type of PCMCIA (PC-card)
wireless Ethernet networking card to your computer.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called netwave_cs. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
If unsure, say N.
comment "Wireless 802.11 Frequency Hopping cards support"
depends on NET_RADIO && PCMCIA
config PCMCIA_RAYCS
tristate "Aviator/Raytheon 2.4MHz wireless support"
depends on NET_RADIO && PCMCIA
---help---
Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
(PC-card) wireless Ethernet networking card to your computer.
Please read the file <file:Documentation/networking/ray_cs.txt> for
details.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called ray_cs. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. If
unsure, say N.
comment "Wireless 802.11b ISA/PCI cards support"
depends on NET_RADIO && (ISA || PCI || ALL_PPC || PCMCIA)
config AIRO config AIRO
tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards" tristate "Cisco/Aironet 34X/35X/4500/4800 ISA and PCI cards"
depends on NET_RADIO && (ISA || PCI) depends on NET_RADIO && (ISA || PCI)
...@@ -175,41 +223,12 @@ config PCI_HERMES ...@@ -175,41 +223,12 @@ config PCI_HERMES
this variety. this variety.
# If Pcmcia is compiled in, offer Pcmcia cards... # If Pcmcia is compiled in, offer Pcmcia cards...
comment "Wireless Pcmcia/Cardbus cards support" comment "Wireless 802.11b Pcmcia/Cardbus cards support"
depends on NET_RADIO && PCMCIA depends on NET_RADIO && PCMCIA
# Obsolete cards
config PCMCIA_NETWAVE
tristate "Xircom Netwave AirSurfer Pcmcia wireless support"
depends on NET_RADIO && PCMCIA
help
Say Y here if you intend to attach this type of PCMCIA (PC-card)
wireless Ethernet networking card to your computer.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called netwave_cs. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
If unsure, say N.
config PCMCIA_WAVELAN
tristate "AT&T/Lucent old Wavelan Pcmcia wireless support"
depends on NET_RADIO && PCMCIA
help
Say Y here if you intend to attach an AT&T/Lucent Wavelan PCMCIA
(PC-card) wireless Ethernet networking card to your computer. This
driver is for the non-IEEE-802.11 Wavelan cards.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called wavelan_cs. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
If unsure, say N.
# 802.11b cards
config PCMCIA_HERMES config PCMCIA_HERMES
tristate "Hermes PCMCIA card support" tristate "Hermes PCMCIA card support"
depends on PCMCIA!=n && HERMES depends on NET_RADIO && PCMCIA && HERMES
---help--- ---help---
A driver for "Hermes" chipset based PCMCIA wireless adaptors, such A driver for "Hermes" chipset based PCMCIA wireless adaptors, such
as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/ as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/
...@@ -249,34 +268,6 @@ config AIRO_CS ...@@ -249,34 +268,6 @@ config AIRO_CS
for location). You also want to check out the PCMCIA-HOWTO, for location). You also want to check out the PCMCIA-HOWTO,
available from <http://www.linuxdoc.org/docs.html#howto>. available from <http://www.linuxdoc.org/docs.html#howto>.
config NET_PCMCIA_RADIO
bool "PCMCIA Wireless LAN"
depends on NET_PCMCIA
help
Say Y here if you would like to use a PCMCIA (PC-card) device to
connect to a wireless local area network. Then say Y to the driver
for your particular card below.
To use your PC-cards, you will need supporting software from David
Hinds' pcmcia-cs package (see the file <file:Documentation/Changes>
for location). You also want to check out the PCMCIA-HOWTO,
available from <http://www.linuxdoc.org/docs.html#howto>.
config PCMCIA_RAYCS
tristate "Aviator/Raytheon 2.4MHz wireless support"
depends on NET_PCMCIA_RADIO && PCMCIA
---help---
Say Y here if you intend to attach an Aviator/Raytheon PCMCIA
(PC-card) wireless Ethernet networking card to your computer.
Please read the file <file:Documentation/networking/ray_cs.txt> for
details.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called ray_cs. If you want to compile it as a
module, say M here and read <file:Documentation/modules.txt>. If
unsure, say N.
# yes, this works even when no drivers are selected # yes, this works even when no drivers are selected
config NET_WIRELESS config NET_WIRELESS
bool bool
......
...@@ -2,28 +2,14 @@ ...@@ -2,28 +2,14 @@
------------- -------------
1) Bring other kernel Wireless LAN drivers here 1) Bring other kernel Wireless LAN drivers here
Already done : Completed
o hermes.c/orinoco.c -> Wavelan IEEE driver + Airport driver
o airo.c/airo_cs.c -> Ben's Aironet driver
o wavelan.c -> old Wavelan ISA driver
o wavelan_cs.c -> old Wavelan Pcmcia driver
o netwave_cs.c -> Netwave Pcmcia driver
Drivers likely to go :
o ray_cs.c -> Raytheon/Aviator driver (maintainer MIA)
Drivers I have absolutely no control over :
o arlan.c -> old Aironet Arlan 655 (need to ask Elmer)
o aironet4500_xxx.c -> Elmer's Aironet driver (need to ask Elmer)
o strip.c -> Metricom's stuff. Not a wlan. Hum...
ETA : Kernel 2.5.X
2) Bring new Wireless LAN driver not yet in the kernel there 2) Bring new Wireless LAN driver not yet in the kernel there
See my web page for details See my web page for details
In particular : HostAP
3) Misc 3) Misc
o Mark wavelan, wavelan_cs, netwave_cs drivers as obsolete o Mark wavelan, wavelan_cs, netwave_cs drivers as obsolete
o Maybe arlan.c, ray_cs.c and strip.c also deserve to be obsolete o Maybe arlan.c, ray_cs.c and strip.c also deserve to be obsolete
o Use new Probe/module stuff in wavelan.c
o New Wireless Extension API (pending)
Jean II Jean II
...@@ -19,5 +19,3 @@ obj-$(CONFIG_NET_DIVERT) += dv.o ...@@ -19,5 +19,3 @@ obj-$(CONFIG_NET_DIVERT) += dv.o
obj-$(CONFIG_NET_PROFILE) += profile.o obj-$(CONFIG_NET_PROFILE) += profile.o
obj-$(CONFIG_NET_PKTGEN) += pktgen.o obj-$(CONFIG_NET_PKTGEN) += pktgen.o
obj-$(CONFIG_NET_RADIO) += wireless.o obj-$(CONFIG_NET_RADIO) += wireless.o
# Ugly. I wish all wireless drivers were moved in drivers/net/wireless
obj-$(CONFIG_NET_PCMCIA_RADIO) += wireless.o
...@@ -107,10 +107,10 @@ ...@@ -107,10 +107,10 @@
#include <linux/kmod.h> #include <linux/kmod.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/kallsyms.h> #include <linux/kallsyms.h>
#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO) #ifdef CONFIG_NET_RADIO
#include <linux/wireless.h> /* Note : will define WIRELESS_EXT */ #include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
#include <net/iw_handler.h> #include <net/iw_handler.h>
#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ #endif /* CONFIG_NET_RADIO */
#ifdef CONFIG_PLIP #ifdef CONFIG_PLIP
extern int plip_init(void); extern int plip_init(void);
#endif #endif
......
...@@ -646,12 +646,12 @@ EXPORT_SYMBOL(register_gifconf); ...@@ -646,12 +646,12 @@ EXPORT_SYMBOL(register_gifconf);
EXPORT_SYMBOL(softnet_data); EXPORT_SYMBOL(softnet_data);
#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO) #ifdef CONFIG_NET_RADIO
/* Don't include the whole header mess for a single function */ /* Don't include the whole header mess for a single function */
union iwreq_data; union iwreq_data;
extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra); extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra);
EXPORT_SYMBOL(wireless_send_event); EXPORT_SYMBOL(wireless_send_event);
#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ #endif /* CONFIG_NET_RADIO */
EXPORT_SYMBOL(linkwatch_fire_event); EXPORT_SYMBOL(linkwatch_fire_event);
......
...@@ -83,9 +83,9 @@ ...@@ -83,9 +83,9 @@
#include <linux/kmod.h> #include <linux/kmod.h>
#endif #endif
#if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO) #ifdef CONFIG_NET_RADIO
#include <linux/wireless.h> /* Note : will define WIRELESS_EXT */ #include <linux/wireless.h> /* Note : will define WIRELESS_EXT */
#endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ #endif /* CONFIG_NET_RADIO */
#include <asm/uaccess.h> #include <asm/uaccess.h>
......
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