Commit 975a605c authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://kernel.bkbits.net/jgarzik/net-drivers-2.6

into home.osdl.org:/home/torvalds/v2.5/linux
parents 9c89bd10 40fe7665
......@@ -2107,14 +2107,16 @@ S: Germany
N: Arnaldo Carvalho de Melo
E: acme@conectiva.com.br
E: acme@kernel.org
E: acme@gnu.org
W: http://bazar.conectiva.com.br/~acme
W: http://bazar2.conectiva.com.br/~acme
W: http://advogato.org/person/acme
P: 1024D/9224DF01 D5DF E3BB E3C8 BCBB F8AD 841A B6AB 4681 9224 DF01
D: wanrouter hacking
D: misc Makefile, Config.in, drivers and network stacks fixes
D: IPX Maintainer
D: IPX & LLC network stacks maintainer
D: Cyclom 2X synchronous card driver
D: wl3501 PCMCIA wireless card driver
D: i18n for minicom, net-tools, util-linux, fetchmail, etc
S: Conectiva S.A.
S: R. Tocantins, 89 - Cristo Rei
......@@ -2360,6 +2362,15 @@ S: Zum Schiersteiner Grund 2
S: 55127 Mainz
S: Germany
N: Gustavo Niemeyer
E: niemeyer@conectiva.com
W: https://moin.conectiva.com.br/GustavoNiemeyer
D: wl3501 PCMCIA wireless card initial support for wireless extensions in 2.4
S: Conectiva S.A.
S: R. Tocantins 89
S: 80050-430 Curitiba PR
S: Brazil
N: David C. Niemi
E: niemi@tux.org
W: http://www.tux.org/~niemi/
......
......@@ -478,7 +478,7 @@ S: Maintained
CYCLADES 2X SYNC CARD DRIVER
P: Arnaldo Carvalho de Melo
M: acme@conectiva.com.br
W: http://www.conectiva.com.br/~acme
W: http://advogato.org/person/acme
L: cycsyn-devel@bazar.conectiva.com.br
S: Maintained
......@@ -2185,6 +2185,12 @@ M: zaga@fly.cc.fer.hr
L: linux-scsi@vger.kernel.org
S: Maintained
WL3501 WIRELESS PCMCIA CARD DRIVER
P: Arnaldo Carvalho de Melo
M: acme@conectiva.com.br
W: http://advogato.org/person/acme
S: Maintained
X.25 NETWORK LAYER
P: Henner Eisen
M: eis@baty.hanse.de
......
......@@ -657,7 +657,7 @@ static int __init am79c961_init(void)
struct dev_priv *priv;
int i, ret;
dev = init_etherdev(NULL, sizeof(struct dev_priv));
dev = alloc_etherdev(sizeof(struct dev_priv));
ret = -ENOMEM;
if (!dev)
goto out;
......@@ -715,12 +715,13 @@ static int __init am79c961_init(void)
dev->set_multicast_list = am79c961_setmulticastlist;
dev->tx_timeout = am79c961_timeout;
return 0;
ret = register_netdev(dev);
if (ret == 0)
return 0;
release:
release_region(dev->base_addr, 0x18);
nodev:
unregister_netdev(dev);
kfree(dev);
out:
return ret;
......
......@@ -706,16 +706,6 @@ static int ether00_open(struct net_device* dev)
if (!is_valid_ether_addr(dev->dev_addr))
return -EINVAL;
/* Allocate private memory */
dev->priv=kmalloc(sizeof(struct net_priv),GFP_KERNEL);
if(!dev->priv)
return -ENOMEM;
memset(dev->priv,0,sizeof(struct net_priv));
priv=(struct net_priv*)dev->priv;
priv->tq_memupdate.routine=ether00_mem_update;
priv->tq_memupdate.data=(void*) dev;
spin_lock_init(&priv->rx_lock);
/* Install interrupt handlers */
result=request_irq(dev->irq,ether00_int,0,"ether00",dev);
if(result)
......@@ -772,7 +762,6 @@ static int ether00_open(struct net_device* dev)
open_err2:
free_irq(dev->irq,dev);
open_err1:
kfree(dev->priv);
return result;
}
......@@ -848,7 +837,6 @@ static int ether00_stop(struct net_device* dev)
free_irq(dev->irq,dev);
free_irq(2,dev);
iounmap(priv->dma_data);
kfree(priv);
return 0;
}
......@@ -901,23 +889,6 @@ static void ether00_get_ethernet_address(struct net_device* dev)
}
static int ether00_init(struct net_device* dev)
{
ether_setup(dev);
dev->open=ether00_open;
dev->stop=ether00_stop;
dev->set_multicast_list=ether00_set_multicast;
dev->hard_start_xmit=ether00_tx;
dev->get_stats=ether00_stats;
ether00_get_ethernet_address(dev);
SET_MODULE_OWNER(dev);
return 0;
}
/*
* Keep a mapping of dev_info addresses -> port lines to use when
* removing ports dev==NULL indicates unused entry
......@@ -929,13 +900,13 @@ static struct net_device* dev_list[ETH_NR];
static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data)
{
struct net_device *dev;
struct net_priv *priv;
void *map_addr;
int result;
int i;
i=0;
while(dev_list[i])
while(dev_list[i] && i < ETH_NR)
i++;
if(i==ETH_NR){
......@@ -944,37 +915,61 @@ static int ether00_add_device(struct pldhs_dev_info* dev_info,void* dev_ps_data)
}
dev=kmalloc(sizeof(struct net_device),GFP_KERNEL);
if(!dev){
return -ENOMEM;
if (!request_mem_region(dev_info->base_addr, MAC_REG_SIZE, "ether00"))
return -EBUSY;
dev = alloc_etherdev(sizeof(struct net_priv));
if(!dev) {
result = -ENOMEM;
goto out_release;
}
memset(dev,0,sizeof(struct net_device));
memset(dev->priv, 0, sizeof(struct net_priv));
priv = dev->priv;
priv->tq_memupdate.routine=ether00_mem_update;
priv->tq_memupdate.data=(void*) dev;
spin_lock_init(&priv->rx_lock);
map_addr=ioremap_nocache(dev_info->base_addr,SZ_4K);
if(!map_addr){
return -ENOMEM;
result = -ENOMEM;
out_kfree;
}
dev->init=ether00_init;
strcpy(dev->name,"eth%d");
dev->open=ether00_open;
dev->stop=ether00_stop;
dev->set_multicast_list=ether00_set_multicast;
dev->hard_start_xmit=ether00_tx;
dev->get_stats=ether00_stats;
ether00_get_ethernet_address(dev);
SET_MODULE_OWNER(dev);
dev->base_addr=(unsigned int)map_addr;
dev->irq=dev_info->irq;
dev->features=NETIF_F_DYNALLOC | NETIF_F_HW_CSUM;
if(check_mem_region((unsigned int)map_addr, MAC_REG_SIZE)){
return -EBUSY;
}
request_mem_region((unsigned int)map_addr, MAC_REG_SIZE, "ether00");
result=register_netdev(dev);
if(result){
printk("Ether00: Error %i registering driver\n",result);
return result;
goto out_unmap;
}
printk("registered ether00 device at %#x\n",dev_info->base_addr);
dev_list[i]=dev;
return result;
out_unmap:
iounmap(map_addr);
out_kfree:
kfree(dev);
out_release:
release_mem_region(dev_info->base_addr, MAC_REG_SIZE);
return result;
}
......
......@@ -722,7 +722,7 @@ ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
tx.tx_command = CMD_TX | CMD_INTR;
tx.tx_link = nopaddr;
tx.tx_tbdoffset = tbdaddr;
tbd.tbd_opts = TBD_EOL | len;
tbd.tbd_opts = TBD_EOL | skb->len;
tbd.tbd_link = I82586_NULL;
tbd.tbd_bufl = dataddr;
tbd.tbd_bufh = 0;
......@@ -1013,7 +1013,7 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
ether1_banner();
dev = init_etherdev(NULL, sizeof(struct ether1_priv));
dev = alloc_etherdev(sizeof(struct ether1_priv));
if (!dev) {
ret = -ENOMEM;
goto out;
......@@ -1057,13 +1057,16 @@ ether1_probe(struct expansion_card *ec, const struct ecard_id *id)
dev->tx_timeout = ether1_timeout;
dev->watchdog_timeo = 5 * HZ / 100;
ret = register_netdev(dev);
if (ret)
goto release;
ecard_set_drvdata(ec, dev);
return 0;
release:
release_region(dev->base_addr, 16);
release_region(dev->base_addr + 0x800, 4096);
unregister_netdev(dev);
kfree(dev);
out:
return ret;
......
......@@ -822,7 +822,7 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
ether3_banner();
dev = init_etherdev(NULL, sizeof(struct dev_priv));
dev = alloc_etherdev(sizeof(struct dev_priv));
if (!dev) {
ret = -ENOMEM;
goto out;
......@@ -898,13 +898,16 @@ ether3_probe(struct expansion_card *ec, const struct ecard_id *id)
dev->tx_timeout = ether3_timeout;
dev->watchdog_timeo = 5 * HZ / 100;
ret = register_netdev(dev);
if (ret)
goto failed;
ecard_set_drvdata(ec, dev);
return 0;
failed:
release_region(dev->base_addr, 128);
free:
unregister_netdev(dev);
kfree(dev);
out:
return ret;
......
......@@ -551,14 +551,14 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
etherh_banner();
dev = init_etherdev(NULL, sizeof(struct etherh_priv));
dev = alloc_etherdev(sizeof(struct etherh_priv));
if (!dev) {
ret = -ENOMEM;
goto out;
}
/*
* init_etherdev allocs and zeros dev->priv
* alloc_etherdev allocs and zeros dev->priv
*/
eh = dev->priv;
......@@ -694,17 +694,19 @@ etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
etherh_reset(dev);
NS8390_init(dev, 0);
ret = register_netdev(dev);
if (ret)
goto release;
ecard_set_drvdata(ec, dev);
return 0;
release:
release:
release_region(dev->base_addr, 16);
free:
unregister_netdev(dev);
kfree(dev->priv);
free:
kfree(dev);
out:
out:
return ret;
}
......
......@@ -232,7 +232,7 @@ static char mii_preamble_required = 0;
/* Index of functions. */
static void tc574_config(dev_link_t *link);
static void tc574_release(unsigned long arg);
static void tc574_release(dev_link_t *link);
static int tc574_event(event_t event, int priority,
event_callback_args_t *args);
......@@ -298,9 +298,6 @@ static dev_link_t *tc574_attach(void)
link->priv = dev;
spin_lock_init(&lp->window_lock);
init_timer(&link->release);
link->release.function = &tc574_release;
link->release.data = (unsigned long)link;
link->io.NumPorts1 = 32;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
......@@ -374,9 +371,8 @@ static void tc574_detach(dev_link_t *link)
if (*linkp == NULL)
return;
del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
tc574_release((unsigned long)link);
tc574_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -555,7 +551,7 @@ static void tc574_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
tc574_release((unsigned long)link);
tc574_release(link);
return;
} /* tc574_config */
......@@ -566,10 +562,8 @@ static void tc574_config(dev_link_t *link)
still open, this will be postponed until it is closed.
*/
static void tc574_release(unsigned long arg)
static void tc574_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
DEBUG(0, "3c574_release(0x%p)\n", link);
if (link->open) {
......@@ -607,7 +601,7 @@ static int tc574_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(dev);
mod_timer(&link->release, jiffies + HZ/20);
tc574_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -1323,7 +1317,7 @@ static int el3_close(struct net_device *dev)
netif_stop_queue(dev);
del_timer_sync(&lp->media);
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
tc574_release(link);
return 0;
}
......
......@@ -148,7 +148,7 @@ DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
/*====================================================================*/
static void tc589_config(dev_link_t *link);
static void tc589_release(unsigned long arg);
static void tc589_release(dev_link_t *link);
static int tc589_event(event_t event, int priority,
event_callback_args_t *args);
......@@ -220,9 +220,6 @@ static dev_link_t *tc589_attach(void)
link->priv = dev;
spin_lock_init(&lp->lock);
init_timer(&link->release);
link->release.function = &tc589_release;
link->release.data = (unsigned long)link;
link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
......@@ -298,9 +295,8 @@ static void tc589_detach(dev_link_t *link)
if (*linkp == NULL)
return;
del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
tc589_release((unsigned long)link);
tc589_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -439,7 +435,7 @@ static void tc589_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
tc589_release((unsigned long)link);
tc589_release(link);
return;
} /* tc589_config */
......@@ -452,10 +448,8 @@ static void tc589_config(dev_link_t *link)
======================================================================*/
static void tc589_release(unsigned long arg)
static void tc589_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
DEBUG(0, "3c589_release(0x%p)\n", link);
if (link->open) {
......@@ -495,7 +489,7 @@ static int tc589_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(dev);
mod_timer(&link->release, jiffies + HZ/20);
tc589_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -1137,7 +1131,7 @@ static int el3_close(struct net_device *dev)
netif_stop_queue(dev);
del_timer_sync(&lp->media);
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
tc589_release(link);
return 0;
}
......
......@@ -92,7 +92,7 @@ static char *version =
/*====================================================================*/
static void axnet_config(dev_link_t *link);
static void axnet_release(u_long arg);
static void axnet_release(dev_link_t *link);
static int axnet_event(event_t event, int priority,
event_callback_args_t *args);
static int axnet_open(struct net_device *dev);
......@@ -194,10 +194,6 @@ static dev_link_t *axnet_attach(void)
memset(info, 0, sizeof(*info));
link = &info->link; dev = &info->dev;
link->priv = info;
init_timer(&link->release);
link->release.function = &axnet_release;
link->release.data = (u_long)link;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
if (irq_list[0] == -1)
......@@ -258,9 +254,8 @@ static void axnet_detach(dev_link_t *link)
if (*linkp == NULL)
return;
del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
axnet_release((u_long)link);
axnet_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -518,7 +513,7 @@ static void axnet_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
axnet_release((u_long)link);
axnet_release(link);
link->state &= ~DEV_CONFIG_PENDING;
return;
} /* axnet_config */
......@@ -531,10 +526,8 @@ static void axnet_config(dev_link_t *link)
======================================================================*/
static void axnet_release(u_long arg)
static void axnet_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
DEBUG(0, "axnet_release(0x%p)\n", link);
if (link->open) {
......@@ -574,7 +567,7 @@ static int axnet_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(&info->dev);
mod_timer(&link->release, jiffies + HZ/20);
axnet_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -708,7 +701,7 @@ static int axnet_close(struct net_device *dev)
netif_stop_queue(dev);
del_timer_sync(&info->watchdog);
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
axnet_release(link);
return 0;
} /* axnet_close */
......
......@@ -126,7 +126,7 @@ MODULE_LICENSE("GPL");
/*====================================================================*/
static void com20020_config(dev_link_t *link);
static void com20020_release(u_long arg);
static void com20020_release(dev_link_t *link);
static int com20020_event(event_t event, int priority,
event_callback_args_t *args);
......@@ -205,9 +205,6 @@ static dev_link_t *com20020_attach(void)
memset(link, 0, sizeof(struct dev_link_t));
dev->priv = lp;
init_timer(&link->release);
link->release.function = &com20020_release;
link->release.data = (u_long)link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 16;
link->io.IOAddrLines = 16;
......@@ -292,7 +289,7 @@ static void com20020_detach(dev_link_t *link)
dev = info->dev;
if (link->state & DEV_CONFIG) {
com20020_release((u_long)link);
com20020_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -456,7 +453,7 @@ static void com20020_config(dev_link_t *link)
cs_error(link->handle, last_fn, last_ret);
failed:
DEBUG(1,"com20020_config failed...\n");
com20020_release((u_long)link);
com20020_release(link);
} /* com20020_config */
/*======================================================================
......@@ -467,9 +464,8 @@ static void com20020_config(dev_link_t *link)
======================================================================*/
static void com20020_release(u_long arg)
static void com20020_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
DEBUG(1,"release...\n");
......@@ -513,9 +509,7 @@ static int com20020_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(dev);
link->release.expires = jiffies + HZ/20;
link->state |= DEV_RELEASE_PENDING;
add_timer(&link->release);
}
break;
case CS_EVENT_CARD_INSERTION:
......
......@@ -94,7 +94,7 @@ static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23";
static void fmvj18x_config(dev_link_t *link);
static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id);
static int fmvj18x_setup_mfc(dev_link_t *link);
static void fmvj18x_release(u_long arg);
static void fmvj18x_release(dev_link_t *link);
static int fmvj18x_event(event_t event, int priority,
event_callback_args_t *args);
static dev_link_t *fmvj18x_attach(void);
......@@ -279,10 +279,6 @@ static dev_link_t *fmvj18x_attach(void)
link = &lp->link;
link->priv = dev;
init_timer(&link->release);
link->release.function = &fmvj18x_release;
link->release.data = (u_long)link;
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 32;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
......@@ -355,9 +351,8 @@ static void fmvj18x_detach(dev_link_t *link)
if (*linkp == NULL)
return;
del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
fmvj18x_release((u_long)link);
fmvj18x_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -638,7 +633,7 @@ static void fmvj18x_config(dev_link_t *link)
/* All Card Services errors end up here */
cs_error(link->handle, last_fn, last_ret);
failed:
fmvj18x_release((u_long)link);
fmvj18x_release(link);
link->state &= ~DEV_CONFIG_PENDING;
} /* fmvj18x_config */
......@@ -742,9 +737,8 @@ static int fmvj18x_setup_mfc(dev_link_t *link)
}
/*====================================================================*/
static void fmvj18x_release(u_long arg)
static void fmvj18x_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
DEBUG(0, "fmvj18x_release(0x%p)\n", link);
......@@ -784,7 +778,7 @@ static int fmvj18x_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(dev);
mod_timer(&link->release, jiffies + HZ/20);
fmvj18x_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -1306,7 +1300,7 @@ static int fjn_close(struct net_device *dev)
link->open--;
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
fmvj18x_release(link);
return 0;
} /* fjn_close */
......
......@@ -114,7 +114,7 @@ MODULE_LICENSE("GPL");
static void ibmtr_config(dev_link_t *link);
static void ibmtr_hw_setup(struct net_device *dev, u_int mmiobase);
static void ibmtr_release(u_long arg);
static void ibmtr_release(dev_link_t *link);
static int ibmtr_event(event_t event, int priority,
event_callback_args_t *args);
......@@ -216,9 +216,6 @@ static dev_link_t *ibmtr_attach(void)
link = &info->link;
link->priv = info;
init_timer(&link->release);
link->release.function = &ibmtr_release;
link->release.data = (u_long)link;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
link->io.NumPorts1 = 4;
link->io.IOAddrLines = 16;
......@@ -295,9 +292,8 @@ static void ibmtr_detach(dev_link_t *link)
struct tok_info *ti = (struct tok_info *)dev->priv;
del_timer_sync(&(ti->tr_timer));
}
del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
ibmtr_release((u_long)link);
ibmtr_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -434,7 +430,7 @@ static void ibmtr_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
ibmtr_release((u_long)link);
ibmtr_release(link);
} /* ibmtr_config */
/*======================================================================
......@@ -445,9 +441,8 @@ static void ibmtr_config(dev_link_t *link)
======================================================================*/
static void ibmtr_release(u_long arg)
static void ibmtr_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
ibmtr_dev_t *info = link->priv;
struct net_device *dev = info->dev;
......@@ -499,7 +494,7 @@ static int ibmtr_event(event_t event, int priority,
/* set flag to bypass normal interrupt code */
((struct tok_info *)dev->priv)->sram_virt |= 1;
netif_device_detach(dev);
mod_timer(&link->release, jiffies + HZ/20);
ibmtr_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......
......@@ -427,7 +427,7 @@ Function Prototypes
---------------------------------------------------------------------------- */
static void nmclan_config(dev_link_t *link);
static void nmclan_release(u_long arg);
static void nmclan_release(dev_link_t *link);
static int nmclan_event(event_t event, int priority,
event_callback_args_t *args);
......@@ -490,9 +490,6 @@ static dev_link_t *nmclan_attach(void)
link->priv = dev;
spin_lock_init(&lp->bank_lock);
init_timer(&link->release);
link->release.function = &nmclan_release;
link->release.data = (u_long)link;
link->io.NumPorts1 = 32;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 5;
......@@ -569,9 +566,8 @@ static void nmclan_detach(dev_link_t *link)
if (*linkp == NULL)
return;
del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
nmclan_release((u_long)link);
nmclan_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -815,7 +811,7 @@ static void nmclan_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
nmclan_release((u_long)link);
nmclan_release(link);
return;
} /* nmclan_config */
......@@ -826,9 +822,8 @@ nmclan_release
net device, and release the PCMCIA configuration. If the device
is still open, this will be postponed until it is closed.
---------------------------------------------------------------------------- */
static void nmclan_release(u_long arg)
static void nmclan_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
DEBUG(0, "nmclan_release(0x%p)\n", link);
......@@ -867,7 +862,7 @@ static int nmclan_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(dev);
mod_timer(&link->release, jiffies + HZ/20);
nmclan_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -1012,7 +1007,7 @@ static int mace_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
nmclan_release(link);
return 0;
} /* mace_close */
......
......@@ -110,7 +110,7 @@ MODULE_PARM(hw_addr, "6i");
static void mii_phy_probe(struct net_device *dev);
static void pcnet_config(dev_link_t *link);
static void pcnet_release(u_long arg);
static void pcnet_release(dev_link_t *link);
static int pcnet_event(event_t event, int priority,
event_callback_args_t *args);
static int pcnet_open(struct net_device *dev);
......@@ -293,9 +293,6 @@ static dev_link_t *pcnet_attach(void)
link = &info->link; dev = &info->dev;
link->priv = info;
init_timer(&link->release);
link->release.function = &pcnet_release;
link->release.data = (u_long)link;
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID;
if (irq_list[0] == -1)
......@@ -357,9 +354,8 @@ static void pcnet_detach(dev_link_t *link)
if (*linkp == NULL)
return;
del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
pcnet_release((u_long)link);
pcnet_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -787,7 +783,7 @@ static void pcnet_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
pcnet_release((u_long)link);
pcnet_release(link);
link->state &= ~DEV_CONFIG_PENDING;
return;
} /* pcnet_config */
......@@ -800,9 +796,8 @@ static void pcnet_config(dev_link_t *link)
======================================================================*/
static void pcnet_release(u_long arg)
static void pcnet_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
pcnet_dev_t *info = link->priv;
DEBUG(0, "pcnet_release(0x%p)\n", link);
......@@ -848,7 +843,7 @@ static int pcnet_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(&info->dev);
mod_timer(&link->release, jiffies + HZ/20);
pcnet_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -1054,7 +1049,7 @@ static int pcnet_close(struct net_device *dev)
netif_stop_queue(dev);
del_timer_sync(&info->watchdog);
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
pcnet_release(link);
return 0;
} /* pcnet_close */
......
......@@ -283,7 +283,7 @@ enum RxCfg { RxAllMulti = 0x0004, RxPromisc = 0x0002,
static dev_link_t *smc91c92_attach(void);
static void smc91c92_detach(dev_link_t *);
static void smc91c92_config(dev_link_t *link);
static void smc91c92_release(u_long arg);
static void smc91c92_release(dev_link_t *link);
static int smc91c92_event(event_t event, int priority,
event_callback_args_t *args);
......@@ -351,9 +351,6 @@ static dev_link_t *smc91c92_attach(void)
link->priv = dev;
spin_lock_init(&smc->lock);
init_timer(&link->release);
link->release.function = &smc91c92_release;
link->release.data = (u_long)link;
link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
link->io.IOAddrLines = 4;
......@@ -433,9 +430,8 @@ static void smc91c92_detach(dev_link_t *link)
if (*linkp == NULL)
return;
del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
smc91c92_release((u_long)link);
smc91c92_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -1068,7 +1064,7 @@ static void smc91c92_config(dev_link_t *link)
config_undo:
unregister_netdev(dev);
config_failed: /* CS_EXIT_TEST() calls jump to here... */
smc91c92_release((u_long)link);
smc91c92_release(link);
link->state &= ~DEV_CONFIG_PENDING;
} /* smc91c92_config */
......@@ -1081,9 +1077,8 @@ static void smc91c92_config(dev_link_t *link)
======================================================================*/
static void smc91c92_release(u_long arg)
static void smc91c92_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
DEBUG(0, "smc91c92_release(0x%p)\n", link);
......@@ -1132,7 +1127,7 @@ static int smc91c92_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(dev);
mod_timer(&link->release, jiffies + HZ/20);
smc91c92_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -1332,7 +1327,7 @@ static int smc_close(struct net_device *dev)
link->open--;
del_timer_sync(&smc->media);
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
smc91c92_release(link);
return 0;
} /* smc_close */
......
......@@ -295,7 +295,7 @@ static void mii_wr(ioaddr_t ioaddr, u_char phyaddr, u_char phyreg,
static int has_ce2_string(dev_link_t * link);
static void xirc2ps_config(dev_link_t * link);
static void xirc2ps_release(u_long arg);
static void xirc2ps_release(dev_link_t * link);
static int xirc2ps_event(event_t event, int priority,
event_callback_args_t * args);
......@@ -611,10 +611,6 @@ xirc2ps_attach(void)
link = &local->link;
link->priv = dev;
init_timer(&link->release);
link->release.function = &xirc2ps_release;
link->release.data = (u_long) link;
/* General socket configuration */
link->conf.Attributes = CONF_ENABLE_IRQ;
link->conf.Vcc = 50;
......@@ -689,9 +685,8 @@ xirc2ps_detach(dev_link_t * link)
* the release() function is called, that will trigger a proper
* detach().
*/
del_timer_sync(&link->release);
if (link->state & DEV_CONFIG) {
xirc2ps_release((unsigned long)link);
xirc2ps_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -1164,7 +1159,7 @@ xirc2ps_config(dev_link_t * link)
config_error:
link->state &= ~DEV_CONFIG_PENDING;
xirc2ps_release((u_long)link);
xirc2ps_release(link);
return;
cis_error:
......@@ -1179,9 +1174,8 @@ xirc2ps_config(dev_link_t * link)
* still open, this will be postponed until it is closed.
*/
static void
xirc2ps_release(u_long arg)
xirc2ps_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *) arg;
DEBUG(0, "release(0x%p)\n", link);
......@@ -1243,7 +1237,7 @@ xirc2ps_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(dev);
mod_timer(&link->release, jiffies + HZ/20);
xirc2ps_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -2045,7 +2039,7 @@ do_stop(struct net_device *dev)
link->open--;
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
xirc2ps_release(link);
return 0;
}
......
......@@ -299,6 +299,7 @@ static int do8bitIO = 0;
#define CMD_DEALLOCATETX 0x000c
#define NOP 0x0010
#define CMD_WORKAROUND 0x0011
#define CMD_ALLOCATEAUX 0x0020
#define CMD_ACCESS 0x0021
#define CMD_PCIBAP 0x0022
#define CMD_PCIAUX 0x0023
......@@ -403,6 +404,7 @@ static int do8bitIO = 0;
#define EV_ALLOC 0x08
#define EV_LINK 0x80
#define EV_AWAKE 0x100
#define EV_TXCPY 0x400
#define EV_UNKNOWN 0x800
#define EV_MIC 0x1000 /* Message Integrity Check Interrupt */
#define STATUS_INTS ( EV_AWAKE | EV_LINK | EV_TXEXC | EV_TX | EV_RX | EV_MIC )
......@@ -633,7 +635,7 @@ typedef struct {
u16 SSIDlen;
char SSID[32];
char apName[16];
char bssid[4][ETH_ALEN];
u8 bssid[4][ETH_ALEN];
u16 beaconPeriod;
u16 dimPeriod;
u16 atimDuration;
......@@ -1041,11 +1043,15 @@ struct airo_info {
struct iw_statistics wstats; // wireless stats
unsigned long scan_timestamp; /* Time started to scan */
struct work_struct event_task;
#if WIRELESS_EXT > 15
struct iw_spy_data spy_data;
#else /* WIRELESS_EXT > 15 */
#ifdef WIRELESS_SPY
int spy_number;
u_char spy_address[IW_MAX_SPY][ETH_ALEN];
struct iw_quality spy_stat[IW_MAX_SPY];
#endif /* WIRELESS_SPY */
#endif /* WIRELESS_EXT > 15 */
#endif /* WIRELESS_EXT */
/* MIC stuff */
mic_module mod[2];
......@@ -1197,13 +1203,13 @@ static int writeConfigRid(struct airo_info*ai, int lock) {
ai->need_commit = 0;
checkThrottle(ai);
cfgr = ai->config;
if ((cfgr.opmode & 0xFF) == MODE_STA_IBSS)
ai->flags |= FLAG_ADHOC;
else
ai->flags &= ~FLAG_ADHOC;
cfgr = ai->config;
for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s);
for(s = &cfgr.shortRetryLimit; s <= &cfgr.radioType; s++)
......@@ -1602,13 +1608,10 @@ static void del_airo_dev( struct net_device *dev );
void stop_airo_card( struct net_device *dev, int freeres )
{
struct airo_info *ai = dev->priv;
flush_scheduled_work();
disable_interrupts(ai);
free_irq( dev->irq, dev );
if (ai->flash)
kfree(ai->flash);
if (ai->rssi)
kfree(ai->rssi);
if (auto_wep)
del_timer_sync(&ai->timer);
takedown_proc_entry( dev, ai );
if (ai->registered) {
unregister_netdev( dev );
......@@ -1619,7 +1622,11 @@ void stop_airo_card( struct net_device *dev, int freeres )
}
ai->registered = 0;
}
if (auto_wep) del_timer_sync(&ai->timer);
flush_scheduled_work();
if (ai->flash)
kfree(ai->flash);
if (ai->rssi)
kfree(ai->rssi);
if (freeres) {
/* PCMCIA frees this stuff, so only for PCI and ISA */
release_region( dev->base_addr, 64 );
......@@ -2111,7 +2118,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
}
}
if (len) {
#if 0 && WIRELESS_EXT > 15
#if WIRELESS_EXT > 15
#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
if (apriv->spy_data.spy_number > 0) {
char *sa;
......@@ -2383,7 +2390,7 @@ static u16 setup_card(struct airo_info *ai, u8 *mac)
ai->config.opmode = adhoc ? MODE_STA_IBSS : MODE_STA_ESS;
#ifdef MICSUPPORT
if ((cap_rid.len==sizeof(cap_rid)) && (cap_rid.extSoftCap&1)) {
if ((cap_rid.len>=sizeof(cap_rid)) && (cap_rid.extSoftCap&1)) {
ai->config.opmode |= MODE_MIC;
ai->flags |= FLAG_MIC_CAPABLE;
micsetup(ai);
......@@ -5190,7 +5197,7 @@ static int airo_get_aplist(struct net_device *dev,
& status_rid.bssid[i][2]
& status_rid.bssid[i][3]
& status_rid.bssid[i][4]
& status_rid.bssid[i][5])!=-1 &&
& status_rid.bssid[i][5])!=0xff &&
(status_rid.bssid[i][0]
| status_rid.bssid[i][1]
| status_rid.bssid[i][2]
......@@ -5284,7 +5291,7 @@ static inline char *airo_translate_scan(struct net_device *dev,
capabilities = le16_to_cpu(list->cap);
if(capabilities & (CAP_ESS | CAP_IBSS)) {
if(capabilities & CAP_ESS)
iwe.u.mode = IW_MODE_INFRA;
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
......
......@@ -94,7 +94,7 @@ void stop_airo_card( struct net_device *, int );
int reset_airo_card( struct net_device * );
static void airo_config(dev_link_t *link);
static void airo_release(u_long arg);
static void airo_release(dev_link_t *link);
static int airo_event(event_t event, int priority,
event_callback_args_t *args);
......@@ -208,9 +208,6 @@ static dev_link_t *airo_attach(void)
return NULL;
}
memset(link, 0, sizeof(struct dev_link_t));
init_timer(&link->release);
link->release.function = &airo_release;
link->release.data = (u_long)link;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
......@@ -286,10 +283,9 @@ static void airo_detach(dev_link_t *link)
if (*linkp == NULL)
return;
del_timer(&link->release);
if ( link->state & DEV_CONFIG ) {
airo_release( (int)link );
if ( link->state & DEV_STALE_CONFIG ) {
if (link->state & DEV_CONFIG) {
airo_release(link);
if (link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
}
......@@ -513,7 +509,7 @@ static void airo_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
airo_release((u_long)link);
airo_release(link);
} /* airo_config */
......@@ -525,10 +521,8 @@ static void airo_config(dev_link_t *link)
======================================================================*/
static void airo_release(u_long arg)
static void airo_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
DEBUG(0, "airo_release(0x%p)\n", link);
/*
......@@ -588,7 +582,7 @@ static int airo_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(local->eth_dev);
mod_timer(&link->release, jiffies + HZ/20);
airo_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -639,7 +633,7 @@ static void airo_cs_cleanup(void)
/* XXX: this really needs to move into generic code.. */
while (dev_list != NULL) {
if (dev_list->state & DEV_CONFIG)
airo_release((u_long)dev_list);
airo_release(dev_list);
airo_detach(dev_list);
}
}
......
......@@ -204,7 +204,7 @@ MODULE_PARM(irq_list, "1-4i");
/*====================================================================*/
/* PCMCIA (Card Services) related functions */
static void netwave_release(u_long arg); /* Card removal */
static void netwave_release(dev_link_t *link); /* Card removal */
static int netwave_event(event_t event, int priority,
event_callback_args_t *args);
static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card
......@@ -455,10 +455,6 @@ static dev_link_t *netwave_attach(void)
link = &priv->link;
link->priv = dev;
init_timer(&link->release);
link->release.function = &netwave_release;
link->release.data = (u_long)link;
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 16;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
......@@ -552,9 +548,8 @@ static void netwave_detach(dev_link_t *link)
the release() function is called, that will trigger a proper
detach().
*/
del_timer(&link->release);
if (link->state & DEV_CONFIG) {
netwave_release((u_long) link);
netwave_release(link);
if (link->state & DEV_STALE_CONFIG) {
DEBUG(1, "netwave_cs: detach postponed, '%s' still "
"locked\n", link->dev->dev_name);
......@@ -1149,7 +1144,7 @@ static void netwave_pcmcia_config(dev_link_t *link) {
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
netwave_release((u_long)link);
netwave_release(link);
} /* netwave_pcmcia_config */
/*
......@@ -1159,8 +1154,8 @@ static void netwave_pcmcia_config(dev_link_t *link) {
* device, and release the PCMCIA configuration. If the device is
* still open, this will be postponed until it is closed.
*/
static void netwave_release(u_long arg) {
dev_link_t *link = (dev_link_t *)arg;
static void netwave_release(dev_link_t *link)
{
struct net_device *dev = link->priv;
netwave_private *priv = dev->priv;
......@@ -1220,7 +1215,7 @@ static int netwave_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
if (link->state & DEV_CONFIG) {
netif_device_detach(dev);
mod_timer(&link->release, jiffies + HZ/20);
netwave_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -1738,8 +1733,7 @@ static int netwave_close(struct net_device *dev) {
link->open--;
netif_stop_queue(dev);
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
netwave_release(link);
return 0;
}
......
......@@ -110,7 +110,7 @@ static int orinoco_cs_hard_reset(struct orinoco_private *priv);
/* PCMCIA gumpf */
static void orinoco_cs_config(dev_link_t * link);
static void orinoco_cs_release(u_long arg);
static void orinoco_cs_release(dev_link_t * link);
static int orinoco_cs_event(event_t event, int priority,
event_callback_args_t * args);
......@@ -202,11 +202,6 @@ orinoco_cs_attach(void)
link = &card->link;
link->priv = dev;
/* Initialize the dev_link_t structure */
init_timer(&link->release);
link->release.function = &orinoco_cs_release;
link->release.data = (u_long) link;
/* Interrupt setup */
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
......@@ -272,7 +267,7 @@ orinoco_cs_detach(dev_link_t * link)
}
if (link->state & DEV_CONFIG) {
orinoco_cs_release((u_long)link);
orinoco_cs_release(link);
if (link->state & DEV_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -530,7 +525,7 @@ orinoco_cs_config(dev_link_t *link)
orinoco_cs_error(link->handle, last_fn, last_ret);
failed:
orinoco_cs_release((u_long) link);
orinoco_cs_release(link);
} /* orinoco_cs_config */
/*
......@@ -539,9 +534,8 @@ orinoco_cs_config(dev_link_t *link)
* still open, this will be postponed until it is closed.
*/
static void
orinoco_cs_release(u_long arg)
orinoco_cs_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *) arg;
struct net_device *dev = link->priv;
struct orinoco_private *priv = dev->priv;
unsigned long flags;
......@@ -697,7 +691,7 @@ exit_orinoco_cs(void)
DEBUG(0, "orinoco_cs: Removing leftover devices.\n");
while (dev_list != NULL) {
if (dev_list->state & DEV_CONFIG)
orinoco_cs_release((u_long) dev_list);
orinoco_cs_release(dev_list);
orinoco_cs_detach(dev_list);
}
}
......
......@@ -94,7 +94,7 @@ MODULE_PARM(pc_debug, "i");
#endif
/** Prototypes based on PCMCIA skeleton driver *******************************/
static void ray_config(dev_link_t *link);
static void ray_release(u_long arg);
static void ray_release(dev_link_t *link);
static int ray_event(event_t event, int priority, event_callback_args_t *args);
static dev_link_t *ray_attach(void);
static void ray_detach(dev_link_t *);
......@@ -374,10 +374,6 @@ static dev_link_t *ray_attach(void)
memset(dev, 0, sizeof(struct net_device));
memset(local, 0, sizeof(ray_dev_t));
init_timer(&link->release);
link->release.function = &ray_release;
link->release.data = (u_long)link;
/* The io structure describes IO port mapping. None used here */
link->io.NumPorts1 = 0;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
......@@ -482,9 +478,8 @@ static void ray_detach(dev_link_t *link)
the release() function is called, that will trigger a proper
detach().
*/
del_timer(&link->release);
if (link->state & DEV_CONFIG) {
ray_release((u_long)link);
ray_release(link);
if(link->state & DEV_STALE_CONFIG) {
link->state |= DEV_STALE_LINK;
return;
......@@ -602,14 +597,14 @@ static void ray_config(dev_link_t *link)
DEBUG(3,"ray_config rmem=%p\n",local->rmem);
DEBUG(3,"ray_config amem=%p\n",local->amem);
if (ray_init(dev) < 0) {
ray_release((u_long)link);
ray_release(link);
return;
}
i = register_netdev(dev);
if (i != 0) {
printk("ray_config register_netdev() failed\n");
ray_release((u_long)link);
ray_release(link);
return;
}
......@@ -627,7 +622,7 @@ static void ray_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
ray_release((u_long)link);
ray_release(link);
} /* ray_config */
/*===========================================================================*/
static int ray_init(struct net_device *dev)
......@@ -898,9 +893,8 @@ static void join_net(u_long data)
device, and release the PCMCIA configuration. If the device is
still open, this will be postponed until it is closed.
=============================================================================*/
static void ray_release(u_long arg)
static void ray_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
struct net_device *dev = link->priv;
ray_dev_t *local = dev->priv;
int i;
......@@ -959,7 +953,7 @@ static int ray_event(event_t event, int priority,
link->state &= ~DEV_PRESENT;
netif_device_detach(dev);
if (link->state & DEV_CONFIG) {
mod_timer(&link->release, jiffies + HZ/20);
ray_release(link);
del_timer(&local->timer);
}
break;
......@@ -1769,7 +1763,7 @@ static int ray_dev_close(struct net_device *dev)
link->open--;
netif_stop_queue(dev);
if (link->state & DEV_STALE_CONFIG)
mod_timer(&link->release, jiffies + HZ/20);
ray_release(link);
/* In here, we should stop the hardware (stop card from beeing active)
* and set local->card_status to CARD_AWAITING_PARAM, so that while the
......
......@@ -4128,7 +4128,7 @@ wv_pcmcia_config(dev_link_t * link)
/* If any step failed, release any partially configured state */
if(i != 0)
{
wv_pcmcia_release((u_long) link);
wv_pcmcia_release(link);
return FALSE;
}
......@@ -4148,9 +4148,8 @@ wv_pcmcia_config(dev_link_t * link)
* still open, this will be postponed until it is closed.
*/
static void
wv_pcmcia_release(u_long arg) /* Address of the interface struct */
wv_pcmcia_release(dev_link_t *link)
{
dev_link_t * link = (dev_link_t *) arg;
device * dev = (device *) link->priv;
#ifdef DEBUG_CONFIG_TRACE
......@@ -4675,7 +4674,7 @@ wavelan_close(device * dev)
else
/* The card is no more there (flag is activated in wv_pcmcia_release) */
if(link->state & DEV_STALE_CONFIG)
wv_pcmcia_release((u_long)link);
wv_pcmcia_release(link);
#ifdef DEBUG_CALLBACK_TRACE
printk(KERN_DEBUG "%s: <-wavelan_close()\n", dev->name);
......@@ -4714,10 +4713,6 @@ wavelan_attach(void)
if (!link) return NULL;
memset(link, 0, sizeof(struct dev_link_t));
/* Unused for the Wavelan */
link->release.function = &wv_pcmcia_release;
link->release.data = (u_long) link;
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 8;
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
......@@ -4857,7 +4852,7 @@ wavelan_detach(dev_link_t * link)
if(link->state & DEV_CONFIG)
{
/* Some others haven't done their job : give them another chance */
wv_pcmcia_release((u_long) link);
wv_pcmcia_release(link);
if(link->state & DEV_STALE_CONFIG)
{
#ifdef DEBUG_CONFIG_INFO
......@@ -4965,7 +4960,7 @@ wavelan_event(event_t event, /* The event received */
netif_device_detach(dev);
/* Release the card */
wv_pcmcia_release((u_long) link);
wv_pcmcia_release(link);
}
break;
......
......@@ -761,7 +761,7 @@ static inline void
static inline int
wv_pcmcia_config(dev_link_t *); /* Configure the pcmcia interface */
static void
wv_pcmcia_release(u_long), /* Remove a device */
wv_pcmcia_release(dev_link_t *),/* Remove a device */
wv_flush_stale_links(void); /* "detach" all possible devices */
/* ---------------------- INTERRUPT HANDLING ---------------------- */
static irqreturn_t
......
......@@ -203,7 +203,69 @@ enum wl3501_status {
#define IW_REG_DOMAIN_MKK1 0x41 /* Channel 1-14 Japan */
#define IW_REG_DOMAIN_ISRAEL 0x50 /* Channel 3 - 9 Israel */
#define WL3501_ESSID_MAX_LEN (IW_ESSID_MAX_SIZE + 2)
#define IW_MGMT_RATE_LABEL_MANDATORY 128 /* MSB */
enum iw_mgmt_rate_labels {
IW_MGMT_RATE_LABEL_1MBIT = 2,
IW_MGMT_RATE_LABEL_2MBIT = 4,
IW_MGMT_RATE_LABEL_5_5MBIT = 11,
IW_MGMT_RATE_LABEL_11MBIT = 22,
};
enum iw_mgmt_info_element_ids {
IW_MGMT_INFO_ELEMENT_SSID, /* Service Set Identity */
IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
IW_MGMT_INFO_ELEMENT_FH_PARAMETER_SET,
IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
IW_MGMT_INFO_ELEMENT_CS_PARAMETER_SET,
IW_MGMT_INFO_ELEMENT_CS_TIM, /* Traffic Information Map */
IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
/* 7-15: Reserved, unused */
IW_MGMT_INFO_ELEMENT_CHALLENGE_TEXT = 16,
/* 17-31 Reserved for challenge text extension */
/* 32-255 Reserved, unused */
};
struct iw_mgmt_info_element {
u8 id; /* one of enum iw_mgmt_info_element_ids,
but sizeof(enum) > sizeof(u8) :-( */
u8 len;
u8 data[0];
} __attribute__ ((packed));
struct iw_mgmt_essid_pset {
struct iw_mgmt_info_element el;
u8 essid[IW_ESSID_MAX_SIZE];
} __attribute__ ((packed));
/*
* According to 802.11 Wireless Netowors, the definitive guide - O'Reilly
* Pg 75
*/
#define IW_DATA_RATE_MAX_LABELS 8
struct iw_mgmt_data_rset {
struct iw_mgmt_info_element el;
u8 data_rate_labels[IW_DATA_RATE_MAX_LABELS];
} __attribute__ ((packed));
struct iw_mgmt_ds_pset {
struct iw_mgmt_info_element el;
u8 chan;
} __attribute__ ((packed));
struct iw_mgmt_cf_pset {
struct iw_mgmt_info_element el;
u8 cfp_count;
u8 cfp_period;
u16 cfp_max_duration;
u16 cfp_dur_remaining;
} __attribute__ ((packed));
struct iw_mgmt_ibss_pset {
struct iw_mgmt_info_element el;
u16 atim_window;
} __attribute__ ((packed));
struct wl3501_tx_hdr {
u16 tx_cnt;
......@@ -244,19 +306,19 @@ struct wl3501_rx_hdr {
};
struct wl3501_start_req {
u16 next_blk;
u8 sig_id;
u8 bss_type;
u16 beacon_period;
u16 dtim_period;
u16 probe_delay;
u16 cap_info;
char ssid[WL3501_ESSID_MAX_LEN];
u8 bss_basic_rate_set[10];
u8 operational_rate_set[10];
u8 cf_pset[8];
u8 phy_pset[3];
u8 ibss_pset[4];
u16 next_blk;
u8 sig_id;
u8 bss_type;
u16 beacon_period;
u16 dtim_period;
u16 probe_delay;
u16 cap_info;
struct iw_mgmt_essid_pset ssid;
struct iw_mgmt_data_rset bss_basic_rset;
struct iw_mgmt_data_rset operational_rset;
struct iw_mgmt_cf_pset cf_pset;
struct iw_mgmt_ds_pset ds_pset;
struct iw_mgmt_ibss_pset ibss_pset;
};
struct wl3501_assoc_req {
......@@ -317,25 +379,25 @@ struct wl3501_get_confirm {
};
struct wl3501_join_req {
u16 next_blk;
u8 sig_id;
u8 reserved;
u8 operational_rate_set[10];
u16 reserved2;
u16 timeout;
u16 probe_delay;
u8 timestamp[8];
u8 local_time[8];
u16 beacon_period;
u16 dtim_period;
u16 cap_info;
u8 bss_type;
u8 bssid[ETH_ALEN];
char ssid[WL3501_ESSID_MAX_LEN];
u8 phy_pset[3];
u8 cf_pset[8];
u8 ibss_pset[4];
u8 bss_basic_rate_set[10];
u16 next_blk;
u8 sig_id;
u8 reserved;
struct iw_mgmt_data_rset operational_rset;
u16 reserved2;
u16 timeout;
u16 probe_delay;
u8 timestamp[8];
u8 local_time[8];
u16 beacon_period;
u16 dtim_period;
u16 cap_info;
u8 bss_type;
u8 bssid[ETH_ALEN];
struct iw_mgmt_essid_pset ssid;
struct iw_mgmt_ds_pset ds_pset;
struct iw_mgmt_cf_pset cf_pset;
struct iw_mgmt_ibss_pset ibss_pset;
struct iw_mgmt_data_rset bss_basic_rset;
};
struct wl3501_join_confirm {
......@@ -361,36 +423,36 @@ struct wl3501_pwr_mgmt_confirm {
};
struct wl3501_scan_req {
u16 next_blk;
u8 sig_id;
u8 bss_type;
u16 probe_delay;
u16 min_chan_time;
u16 max_chan_time;
u8 chan_list[14];
u8 bssid[ETH_ALEN];
char ssid[WL3501_ESSID_MAX_LEN];
enum wl3501_scan_type scan_type;
u16 next_blk;
u8 sig_id;
u8 bss_type;
u16 probe_delay;
u16 min_chan_time;
u16 max_chan_time;
u8 chan_list[14];
u8 bssid[ETH_ALEN];
struct iw_mgmt_essid_pset ssid;
enum wl3501_scan_type scan_type;
};
struct wl3501_scan_confirm {
u16 next_blk;
u8 sig_id;
u8 reserved;
u16 status;
char timestamp[8];
char localtime[8];
u16 beacon_period;
u16 dtim_period;
u16 cap_info;
u8 bss_type;
u8 bssid[ETH_ALEN];
char ssid[WL3501_ESSID_MAX_LEN];
u8 phy_pset[3];
u8 cf_pset[8];
u8 ibss_pset[4];
u8 bss_basic_rate_set[10];
u8 rssi;
u16 next_blk;
u8 sig_id;
u8 reserved;
u16 status;
char timestamp[8];
char localtime[8];
u16 beacon_period;
u16 dtim_period;
u16 cap_info;
u8 bss_type;
u8 bssid[ETH_ALEN];
struct iw_mgmt_essid_pset ssid;
struct iw_mgmt_ds_pset ds_pset;
struct iw_mgmt_cf_pset cf_pset;
struct iw_mgmt_ibss_pset ibss_pset;
struct iw_mgmt_data_rset bss_basic_rset;
u8 rssi;
};
struct wl3501_start_confirm {
......@@ -527,10 +589,10 @@ struct wl3501_card {
u16 esbq_confirm_start;
u16 esbq_confirm_end;
u16 esbq_confirm;
u8 essid[WL3501_ESSID_MAX_LEN];
struct iw_mgmt_essid_pset essid;
struct iw_mgmt_essid_pset keep_essid;
u8 bssid[ETH_ALEN];
int net_type;
u8 keep_essid[WL3501_ESSID_MAX_LEN];
char nick[32];
char card_name[32];
char firmware_date[32];
......
......@@ -45,7 +45,6 @@
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/wireless.h>
#include <net/iw_handler.h>
......@@ -112,7 +111,7 @@ static int wl3501_irq_list[4] = { -1 };
* are invoked from the wl24 event handler.
*/
static void wl3501_config(dev_link_t *link);
static void wl3501_release(unsigned long arg);
static void wl3501_release(dev_link_t *link);
static int wl3501_event(event_t event, int pri, event_callback_args_t *args);
/*
......@@ -220,6 +219,21 @@ static int iw_default_channel(int reg_domain)
return rc;
}
static void iw_set_mgmt_info_element(enum iw_mgmt_info_element_ids id,
struct iw_mgmt_info_element *el,
void *value, int len)
{
el->id = id;
el->len = len;
memcpy(el->data, value, len);
}
static void iw_copy_mgmt_info_element(struct iw_mgmt_info_element *to,
struct iw_mgmt_info_element *from)
{
iw_set_mgmt_info_element(from->id, to, from->data, from->len);
}
/*
* A linked list of "instances" of the wl24 device. Each actual PCMCIA card
* corresponds to one device instance, and is described by one dev_link_t
......@@ -621,10 +635,12 @@ static int wl3501_mgmt_scan(struct wl3501_card *this, u16 chan_time)
static int wl3501_mgmt_join(struct wl3501_card *this, u16 stas)
{
struct wl3501_join_req sig = {
.sig_id = WL3501_SIG_JOIN_REQ,
.timeout = 10,
.phy_pset = {
[2] = this->chan,
.sig_id = WL3501_SIG_JOIN_REQ,
.timeout = 10,
.ds_pset = {
.el.id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
.el.len = 1,
.chan = this->chan,
},
};
......@@ -638,24 +654,42 @@ static int wl3501_mgmt_start(struct wl3501_card *this)
.sig_id = WL3501_SIG_START_REQ,
.beacon_period = 400,
.dtim_period = 1,
.phy_pset = {
[0] = 3, [1] = 1, [2] = this->chan,
.ds_pset = {
.el.id = IW_MGMT_INFO_ELEMENT_DS_PARAMETER_SET,
.el.len = 1,
.chan = this->chan,
},
.bss_basic_rate_set = {
[0] = 0x01, [1] = 0x02, [2] = 0x82, [3] = 0x84,
.bss_basic_rset = {
.el.id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
.el.len = 2,
.data_rate_labels = {
[0] = IW_MGMT_RATE_LABEL_MANDATORY |
IW_MGMT_RATE_LABEL_1MBIT,
[1] = IW_MGMT_RATE_LABEL_MANDATORY |
IW_MGMT_RATE_LABEL_2MBIT,
},
},
.operational_rate_set = {
[0] = 0x01, [1] = 0x02, [2] = 0x82, [3] = 0x84,
.operational_rset = {
.el.id = IW_MGMT_INFO_ELEMENT_SUPPORTED_RATES,
.el.len = 2,
.data_rate_labels = {
[0] = IW_MGMT_RATE_LABEL_MANDATORY |
IW_MGMT_RATE_LABEL_1MBIT,
[1] = IW_MGMT_RATE_LABEL_MANDATORY |
IW_MGMT_RATE_LABEL_2MBIT,
},
},
.ibss_pset = {
[0] = 6, [1] = 2, [2] = 10,
.el.id = IW_MGMT_INFO_ELEMENT_IBSS_PARAMETER_SET,
.el.len = 2,
.atim_window = 10,
},
.bss_type = wl3501_fw_bss_type(this),
.cap_info = wl3501_fw_cap_info(this),
};
memcpy(sig.ssid, this->essid, WL3501_ESSID_MAX_LEN);
memcpy(this->keep_essid, this->essid, WL3501_ESSID_MAX_LEN);
iw_copy_mgmt_info_element(&sig.ssid.el, &this->essid.el);
iw_copy_mgmt_info_element(&this->keep_essid.el, &this->essid.el);
return wl3501_esbq_exec(this, &sig, sizeof(sig));
}
......@@ -674,15 +708,15 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
(this->net_type == IW_MODE_ADHOC &&
(sig.cap_info & WL3501_MGMT_CAPABILITY_IBSS)) ||
this->net_type == IW_MODE_AUTO) {
if (!this->essid[1])
if (!this->essid.el.len)
matchflag = 1;
else if (this->essid[1] == 3 &&
!strncmp((char *)&this->essid[2], "ANY", 3))
else if (this->essid.el.len == 3 &&
!memcmp(this->essid.essid, "ANY", 3))
matchflag = 1;
else if (this->essid[1] != sig.ssid[1])
else if (this->essid.el.len != sig.ssid.el.len)
matchflag = 0;
else if (memcmp(&this->essid[2], &sig.ssid[2],
this->essid[1]))
else if (memcmp(this->essid.essid, sig.ssid.essid,
this->essid.el.len))
matchflag = 0;
else
matchflag = 1;
......@@ -894,17 +928,18 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr)
const int i = this->join_sta_bss;
memcpy(this->bssid,
this->bss_set[i].bssid, ETH_ALEN);
this->chan = this->bss_set[i].phy_pset[2];
memcpy(this->keep_essid, this->bss_set[i].ssid,
WL3501_ESSID_MAX_LEN);
this->chan = this->bss_set[i].ds_pset.chan;
iw_copy_mgmt_info_element(&this->keep_essid.el,
&this->bss_set[i].ssid.el);
wl3501_mgmt_auth(this);
}
} else {
const int i = this->join_sta_bss;
memcpy(this->bssid, this->bss_set[i].bssid, ETH_ALEN);
this->chan = this->bss_set[i].phy_pset[2];
memcpy(this->keep_essid,
this->bss_set[i].ssid, WL3501_ESSID_MAX_LEN);
memcpy(&this->bssid, &this->bss_set[i].bssid, ETH_ALEN);
this->chan = this->bss_set[i].ds_pset.chan;
iw_copy_mgmt_info_element(&this->keep_essid.el,
&this->bss_set[i].ssid.el);
wl3501_online(dev);
}
} else {
......@@ -1262,9 +1297,8 @@ static int wl3501_close(struct net_device *dev)
wl3501_block_interrupt(this);
if (link->state & DEV_STALE_CONFIG) {
link->release.expires = jiffies + WL3501_RELEASE_TIMEOUT;
link->state |= DEV_RELEASE_PENDING;
add_timer(&link->release);
wl3501_release(link);
}
rc = 0;
printk(KERN_INFO "%s: WL3501 closed\n", dev->name);
......@@ -1688,19 +1722,79 @@ static int wl3501_get_wap(struct net_device *dev, struct iw_request_info *info,
return 0;
}
static int wl3501_set_scan(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
/*
* FIXME: trigger scanning with a reset, yes, I'm lazy
*/
return wl3501_reset(dev);
}
static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct wl3501_card *this = dev->priv;
int i;
char *current_ev = extra;
struct iw_event iwe;
for (i = 0; i < this->bss_cnt; ++i) {
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
current_ev = iwe_stream_add_event(current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_ADDR_LEN);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = this->bss_set[i].ssid.el.len;
current_ev = iwe_stream_add_point(current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe,
this->bss_set[i].ssid.essid);
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = this->bss_set[i].bss_type;
current_ev = iwe_stream_add_event(current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
iwe.u.freq.e = 0;
current_ev = iwe_stream_add_event(current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_FREQ_LEN);
iwe.cmd = SIOCGIWENCODE;
if (this->bss_set[i].cap_info & WL3501_MGMT_CAPABILITY_PRIVACY)
iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
current_ev = iwe_stream_add_point(current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, NULL);
}
/* Length of data */
wrqu->data.length = (current_ev - extra);
wrqu->data.flags = 0; /* FIXME: set properly these flags */
return 0;
}
static int wl3501_set_essid(struct net_device *dev,
struct iw_request_info *info,
union iwreq_data *wrqu, char *extra)
{
struct wl3501_card *this = dev->priv;
int rc = 0;
if (wrqu->data.flags) {
strlcpy(this->essid + 2, extra, min_t(u16, wrqu->data.length,
IW_ESSID_MAX_SIZE));
rc = wl3501_reset(dev);
iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID,
&this->essid.el,
extra, wrqu->data.length);
} else { /* We accept any ESSID */
iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID,
&this->essid.el, "ANY", 3);
}
return rc;
return wl3501_reset(dev);
}
static int wl3501_get_essid(struct net_device *dev,
......@@ -1712,8 +1806,8 @@ static int wl3501_get_essid(struct net_device *dev,
spin_lock_irqsave(&this->lock, flags);
wrqu->essid.flags = 1;
wrqu->essid.length = IW_ESSID_MAX_SIZE;
strlcpy(extra, this->essid + 2, IW_ESSID_MAX_SIZE);
wrqu->essid.length = this->essid.el.len;
memcpy(extra, this->essid.essid, this->essid.el.len);
spin_unlock_irqrestore(&this->lock, flags);
return 0;
}
......@@ -1902,6 +1996,8 @@ static const iw_handler wl3501_handler[] = {
[SIOCGIWTHRSPY - SIOCIWFIRST] = iw_handler_get_thrspy,
[SIOCSIWAP - SIOCIWFIRST] = wl3501_set_wap,
[SIOCGIWAP - SIOCIWFIRST] = wl3501_get_wap,
[SIOCSIWSCAN - SIOCIWFIRST] = wl3501_set_scan,
[SIOCGIWSCAN - SIOCIWFIRST] = wl3501_get_scan,
[SIOCSIWESSID - SIOCIWFIRST] = wl3501_set_essid,
[SIOCGIWESSID - SIOCIWFIRST] = wl3501_get_essid,
[SIOCSIWNICKN - SIOCIWFIRST] = wl3501_set_nick,
......@@ -1944,9 +2040,6 @@ static dev_link_t *wl3501_attach(void)
if (!link)
goto out;
memset(link, 0, sizeof(struct dev_link_t));
init_timer(&link->release);
link->release.function = wl3501_release;
link->release.data = (unsigned long)link;
/* The io structure describes IO port mapping */
link->io.NumPorts1 = 16;
......@@ -2118,11 +2211,8 @@ static void wl3501_config(dev_link_t *link)
this->bss_cnt = 0;
this->join_sta_bss = 0;
this->adhoc_times = 0;
this->essid[0] = 0;
this->essid[1] = 3;
this->essid[2] = 'A';
this->essid[3] = 'N';
this->essid[4] = 'Y';
iw_set_mgmt_info_element(IW_MGMT_INFO_ELEMENT_SSID, &this->essid.el,
"ANY", 3);
this->card_name[0] = '\0';
this->firmware_date[0] = '\0';
this->rssi = 255;
......@@ -2135,7 +2225,7 @@ static void wl3501_config(dev_link_t *link)
cs_failed:
cs_error(link->handle, last_fn, last_ret);
failed:
wl3501_release((unsigned long)link);
wl3501_release(link);
out:
return;
}
......@@ -2148,9 +2238,8 @@ static void wl3501_config(dev_link_t *link)
* and release the PCMCIA configuration. If the device is still open, this
* will be postponed until it is closed.
*/
static void wl3501_release(unsigned long arg)
static void wl3501_release(dev_link_t *link)
{
dev_link_t *link = (dev_link_t *)arg;
struct net_device *dev = link->priv;
/* If the device is currently in use, we won't release until it is
......@@ -2206,9 +2295,7 @@ static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
while (link->open > 0)
wl3501_close(dev);
netif_device_detach(dev);
link->release.expires = jiffies +
WL3501_RELEASE_TIMEOUT;
add_timer(&link->release);
wl3501_release(link);
}
break;
case CS_EVENT_CARD_INSERTION:
......@@ -2275,11 +2362,10 @@ static void __exit wl3501_exit_module(void)
dprintk(0, ": unloading");
pcmcia_unregister_driver(&wl3501_driver);
while (wl3501_dev_list) {
del_timer(&wl3501_dev_list->release);
/* Mark the device as non-existing to minimize calls to card */
wl3501_dev_list->state &= ~DEV_PRESENT;
if (wl3501_dev_list->state & DEV_CONFIG)
wl3501_release((unsigned long)wl3501_dev_list);
wl3501_release(wl3501_dev_list);
wl3501_detach(wl3501_dev_list);
}
}
......
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