diff -Nru a/drivers/net/8139cp.c b/drivers/net/8139cp.c --- a/drivers/net/8139cp.c Mon Aug 25 19:03:08 2003 +++ b/drivers/net/8139cp.c Mon Aug 25 19:03:08 2003 @@ -468,7 +468,7 @@ #if CP_VLAN_TAG_USED if (cp->vlgrp && (desc->opts2 & RxVlanTagged)) { - vlan_hwaccel_rx(skb, cp->vlgrp, desc->opts2 & 0xffff); + vlan_hwaccel_rx(skb, cp->vlgrp, be16_to_cpu(desc->opts2 & 0xffff)); } else #endif netif_rx(skb); @@ -774,7 +774,7 @@ #if CP_VLAN_TAG_USED if (cp->vlgrp && vlan_tx_tag_present(skb)) - vlan_tag = TxVlanTag | vlan_tx_tag_get(skb); + vlan_tag = TxVlanTag | cpu_to_be16(vlan_tx_tag_get(skb)); #endif entry = cp->tx_head; diff -Nru a/drivers/net/8139too.c b/drivers/net/8139too.c --- a/drivers/net/8139too.c Mon Aug 25 19:03:08 2003 +++ b/drivers/net/8139too.c Mon Aug 25 19:03:08 2003 @@ -565,6 +565,7 @@ void *mmio_addr; int drv_flags; struct pci_dev *pci_dev; + u32 pci_state[16]; struct net_device_stats stats; unsigned char *rx_ring; unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */ @@ -2569,6 +2570,9 @@ tp->stats.rx_missed_errors += RTL_R32 (RxMissed); RTL_W32 (RxMissed, 0); + pci_set_power_state (pdev, 3); + pci_save_state (pdev, tp->pci_state); + spin_unlock_irqrestore (&tp->lock, flags); return 0; } @@ -2577,11 +2581,15 @@ static int rtl8139_resume (struct pci_dev *pdev) { struct net_device *dev = pci_get_drvdata (pdev); + struct rtl8139_private *tp = dev->priv; if (!netif_running (dev)) return 0; - netif_device_attach (dev); + pci_restore_state (pdev, tp->pci_state); + pci_set_power_state (pdev, 0); + rtl8139_init_ring (dev); rtl8139_hw_start (dev); + netif_device_attach (dev); return 0; } diff -Nru a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c --- a/drivers/net/bonding/bond_main.c Mon Aug 25 19:03:08 2003 +++ b/drivers/net/bonding/bond_main.c Mon Aug 25 19:03:08 2003 @@ -3330,10 +3330,10 @@ static struct net_device_stats *bond_get_stats(struct net_device *dev) { bonding_t *bond = dev->priv; - struct net_device_stats *stats = bond->stats, *sstats; + struct net_device_stats *stats = &(bond->stats), *sstats; slave_t *slave; - memset(bond->stats, 0, sizeof(struct net_device_stats)); + memset(stats, 0, sizeof(struct net_device_stats)); read_lock_bh(&bond->lock); @@ -3566,13 +3566,6 @@ /* initialize rwlocks */ rwlock_init(&bond->lock); rwlock_init(&bond->ptrlock); - - bond->stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL); - if (bond->stats == NULL) { - kfree(bond); - return -ENOMEM; - } - memset(bond->stats, 0, sizeof(struct net_device_stats)); bond->next = bond->prev = (slave_t *)bond; bond->current_slave = NULL; @@ -3603,7 +3596,6 @@ break; default: printk(KERN_ERR "Unknown bonding mode %d\n", bond_mode); - kfree(bond->stats); kfree(bond); return -EINVAL; } @@ -3654,7 +3646,6 @@ if (bond->bond_proc_dir == NULL) { printk(KERN_ERR "%s: Cannot init /proc/net/%s/\n", dev->name, dev->name); - kfree(bond->stats); kfree(bond); return -ENOMEM; } @@ -3665,7 +3656,6 @@ printk(KERN_ERR "%s: Cannot init /proc/net/%s/info\n", dev->name, dev->name); remove_proc_entry(dev->name, proc_net); - kfree(bond->stats); kfree(bond); return -ENOMEM; } @@ -4007,9 +3997,8 @@ remove_proc_entry(dev_bond->name, proc_net); #endif unregister_netdev(dev_bond); - kfree(bond->stats); kfree(dev_bond->priv); - + dev_bond->priv = NULL; dev_bond++; } diff -Nru a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h --- a/drivers/net/bonding/bonding.h Mon Aug 25 19:03:08 2003 +++ b/drivers/net/bonding/bonding.h Mon Aug 25 19:03:08 2003 @@ -99,7 +99,7 @@ rwlock_t ptrlock; struct timer_list mii_timer; struct timer_list arp_timer; - struct net_device_stats *stats; + struct net_device_stats stats; #ifdef CONFIG_PROC_FS struct proc_dir_entry *bond_proc_dir; struct proc_dir_entry *bond_proc_info_file; diff -Nru a/drivers/net/net_init.c b/drivers/net/net_init.c --- a/drivers/net/net_init.c Mon Aug 25 19:03:08 2003 +++ b/drivers/net/net_init.c Mon Aug 25 19:03:08 2003 @@ -71,7 +71,7 @@ */ -static struct net_device *alloc_netdev(int sizeof_priv, const char *mask, +struct net_device *alloc_netdev(int sizeof_priv, const char *mask, void (*setup)(struct net_device *)) { struct net_device *dev; @@ -97,6 +97,7 @@ return dev; } +EXPORT_SYMBOL(alloc_netdev); static struct net_device *init_alloc_dev(int sizeof_priv) { diff -Nru a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c --- a/drivers/net/tulip/tulip_core.c Mon Aug 25 19:03:08 2003 +++ b/drivers/net/tulip/tulip_core.c Mon Aug 25 19:03:08 2003 @@ -232,6 +232,7 @@ { 0x17B3, 0xAB08, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, { 0x14f1, 0x1803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CONEXANT }, { 0x10b9, 0x5261, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DM910X }, /* ALi 1563 integrated ethernet */ + { 0x10b7, 0x9300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, COMET }, /* 3Com 3CSOHO100B-TX */ { } /* terminate list */ }; MODULE_DEVICE_TABLE(pci, tulip_pci_tbl); diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c --- a/drivers/net/wireless/airo.c Mon Aug 25 19:03:08 2003 +++ b/drivers/net/wireless/airo.c Mon Aug 25 19:03:08 2003 @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include @@ -305,6 +304,7 @@ #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 @@ -409,6 +409,7 @@ #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 ) @@ -639,7 +640,7 @@ u16 SSIDlen; char SSID[32]; char apName[16]; - char bssid[4][ETH_ALEN]; + u8 bssid[4][ETH_ALEN]; u16 beaconPeriod; u16 dimPeriod; u16 atimDuration; @@ -963,8 +964,6 @@ static void enable_interrupts(struct airo_info*); static void disable_interrupts(struct airo_info*); static u16 issuecommand(struct airo_info*, Cmd *pCmd, Resp *pRsp); -static u16 sendcommand(struct airo_info *ai, Cmd *pCmd); -static void completecommand(struct airo_info *ai, Resp *pRsp); static int bap_setup(struct airo_info*, u16 rid, u16 offset, int whichbap); static int aux_bap_read(struct airo_info*, u16 *pu16Dst, int bytelen, int whichbap); @@ -984,6 +983,8 @@ static void airo_interrupt( int irq, void* dev_id, struct pt_regs *regs); +static int airo_thread(void *data); +static void timer_func( struct net_device *dev ); static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); #ifdef WIRELESS_EXT struct iw_statistics *airo_get_wireless_stats (struct net_device *dev); @@ -994,8 +995,8 @@ int flashcard(struct net_device *dev, aironet_ioctl *comp); #endif /* CISCO_EXT */ #ifdef MICSUPPORT -static void micinit(struct airo_info *ai, MICRid *micr); -static void micsetup(struct airo_info *ai); +static void micinit(struct airo_info *ai); +static int micsetup(struct airo_info *ai); static int encapsulate(struct airo_info *ai, etherHead *pPacket, MICBuffer *buffer, int len); static int decapsulate(struct airo_info *ai, MICBuffer *mic, etherHead *pPacket, u16 payLen); #endif @@ -1013,50 +1014,63 @@ int need_commit; // Need to set config char keyindex; // Used with auto wep char defindex; // Used with auto wep - struct timer_list timer; struct proc_dir_entry *proc_entry; struct airo_info *next; spinlock_t aux_lock; unsigned long flags; -#define FLAG_PROMISC IFF_PROMISC /* 0x100 - include/linux/if.h */ -#define FLAG_RADIO_OFF 0x02 /* User disabling of MAC */ -#define FLAG_RADIO_DOWN 0x08 /* ifup/ifdown disabling of MAC */ -#define FLAG_FLASHING 0x10 -#define FLAG_ADHOC 0x01 /* Needed by MIC */ -#define FLAG_MIC_CAPABLE 0x20 -#define FLAG_UPDATE_MULTI 0x40 -#define FLAG_UPDATE_UNI 0x80 -#define FLAG_802_11 0x200 -#define FLAG_PENDING_XMIT 0x400 -#define FLAG_PENDING_XMIT11 0x800 +#define FLAG_PROMISC 8 /* IFF_PROMISC 0x100 - include/linux/if.h */ +#define FLAG_RADIO_OFF 0 /* User disabling of MAC */ +#define FLAG_RADIO_DOWN 1 /* ifup/ifdown disabling of MAC */ +#define FLAG_RADIO_MASK 0x03 +#define FLAG_FLASHING 2 +#define FLAG_ADHOC 3 /* Needed by MIC */ +#define FLAG_MIC_CAPABLE 4 +#define FLAG_UPDATE_MULTI 5 +#define FLAG_UPDATE_UNI 6 +#define FLAG_802_11 7 +#define FLAG_PENDING_XMIT 9 +#define FLAG_PENDING_XMIT11 10 +#define FLAG_PCI 11 +#define JOB_MASK 0xff0000 +#define JOB_DIE 16 +#define JOB_XMIT 17 +#define JOB_XMIT11 18 +#define JOB_STATS 19 +#define JOB_PROMISC 20 +#define JOB_MIC 21 +#define JOB_EVENT 22 +#define JOB_AUTOWEP 23 int (*bap_read)(struct airo_info*, u16 *pu16Dst, int bytelen, int whichbap); unsigned short *flash; tdsRssiEntry *rssi; - struct semaphore sem; struct task_struct *task; - struct tq_struct stats_task; - struct tq_struct promisc_task; + struct semaphore sem; + pid_t thr_pid; + wait_queue_head_t thr_wait; + struct completion thr_exited; + unsigned long expires; struct { struct sk_buff *skb; int fid; - struct tq_struct task; } xmit, xmit11; struct net_device *wifidev; #ifdef WIRELESS_EXT struct iw_statistics wstats; // wireless stats unsigned long scan_timestamp; /* Time started to scan */ - struct tq_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]; mic_statistics micstats; - struct tq_struct mic_task; }; static inline int bap_read(struct airo_info *ai, u16 *pu16Dst, int bytelen, @@ -1203,12 +1217,12 @@ ai->need_commit = 0; checkThrottle(ai); + cfgr = ai->config; + if ((cfgr.opmode & 0xFF) == MODE_STA_IBSS) - ai->flags |= FLAG_ADHOC; + set_bit(FLAG_ADHOC, &ai->flags); else - ai->flags &= ~FLAG_ADHOC; - - cfgr = ai->config; + clear_bit(FLAG_ADHOC, &ai->flags); for(s = &cfgr.len; s <= &cfgr.rtsThres; s++) *s = cpu_to_le16(*s); @@ -1272,7 +1286,7 @@ struct airo_info *info = dev->priv; Resp rsp; - if (info->flags & FLAG_FLASHING) + if (test_bit(FLAG_FLASHING, &info->flags)) return -EIO; /* Make sure the card is configured. @@ -1286,7 +1300,7 @@ if (info->wifidev != dev) { /* Power on the MAC controller (which may have been disabled) */ - info->flags &= ~FLAG_RADIO_DOWN; + clear_bit(FLAG_RADIO_DOWN, &info->flags); enable_interrupts(info); } enable_MAC(info, &rsp, 1); @@ -1344,7 +1358,7 @@ } } -static void airo_do_xmit(struct net_device *dev) { +static void airo_end_xmit(struct net_device *dev) { u16 status; int i; struct airo_info *priv = dev->priv; @@ -1352,17 +1366,10 @@ int fid = priv->xmit.fid; u32 *fids = priv->fids; - if (down_trylock(&priv->sem) != 0) { - priv->flags |= FLAG_PENDING_XMIT; - netif_stop_queue(dev); - priv->xmit.task.routine = (void (*)(void *))airo_do_xmit; - priv->xmit.task.data = (void *)dev; - schedule_task(&priv->xmit.task); - return; - } + clear_bit(JOB_XMIT, &priv->flags); + clear_bit(FLAG_PENDING_XMIT, &priv->flags); status = transmit_802_3_packet (priv, fids[fid], skb->data); up(&priv->sem); - priv->flags &= ~FLAG_PENDING_XMIT; i = 0; if ( status == SUCCESS ) { @@ -1406,11 +1413,17 @@ fids[i] |= (len << 16); priv->xmit.skb = skb; priv->xmit.fid = i; - airo_do_xmit(dev); + if (down_trylock(&priv->sem) != 0) { + set_bit(FLAG_PENDING_XMIT, &priv->flags); + netif_stop_queue(dev); + set_bit(JOB_XMIT, &priv->flags); + wake_up_interruptible(&priv->thr_wait); + } else + airo_end_xmit(dev); return 0; } -static void airo_do_xmit11(struct net_device *dev) { +static void airo_end_xmit11(struct net_device *dev) { u16 status; int i; struct airo_info *priv = dev->priv; @@ -1418,17 +1431,10 @@ int fid = priv->xmit11.fid; u32 *fids = priv->fids; - if (down_trylock(&priv->sem) != 0) { - priv->flags |= FLAG_PENDING_XMIT11; - netif_stop_queue(dev); - priv->xmit11.task.routine = (void (*)(void *))airo_do_xmit11; - priv->xmit11.task.data = (void *)dev; - schedule_task(&priv->xmit11.task); - return; - } + clear_bit(JOB_XMIT11, &priv->flags); + clear_bit(FLAG_PENDING_XMIT11, &priv->flags); status = transmit_802_11_packet (priv, fids[fid], skb->data); up(&priv->sem); - priv->flags &= ~FLAG_PENDING_XMIT11; i = MAX_FIDS / 2; if ( status == SUCCESS ) { @@ -1472,7 +1478,13 @@ fids[i] |= (len << 16); priv->xmit11.skb = skb; priv->xmit11.fid = i; - airo_do_xmit11(dev); + if (down_trylock(&priv->sem) != 0) { + set_bit(FLAG_PENDING_XMIT11, &priv->flags); + netif_stop_queue(dev); + set_bit(JOB_XMIT11, &priv->flags); + wake_up_interruptible(&priv->thr_wait); + } else + airo_end_xmit11(dev); return 0; } @@ -1480,29 +1492,24 @@ StatsRid stats_rid; u32 *vals = stats_rid.vals; - if (down_trylock(&ai->sem) == 0) { - readStatsRid(ai, &stats_rid, RID_STATS, 0); - up(&ai->sem); + clear_bit(JOB_STATS, &ai->flags); + readStatsRid(ai, &stats_rid, RID_STATS, 0); + up(&ai->sem); - ai->stats.rx_packets = vals[43] + vals[44] + vals[45]; - ai->stats.tx_packets = vals[39] + vals[40] + vals[41]; - ai->stats.rx_bytes = vals[92]; - ai->stats.tx_bytes = vals[91]; - ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4]; - ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors; - ai->stats.multicast = vals[43]; - ai->stats.collisions = vals[89]; - - /* detailed rx_errors: */ - ai->stats.rx_length_errors = vals[3]; - ai->stats.rx_crc_errors = vals[4]; - ai->stats.rx_frame_errors = vals[2]; - ai->stats.rx_fifo_errors = vals[0]; - } else { - ai->stats_task.routine = (void (*)(void *))airo_read_stats; - ai->stats_task.data = (void *)ai; - schedule_task(&ai->stats_task); - } + ai->stats.rx_packets = vals[43] + vals[44] + vals[45]; + ai->stats.tx_packets = vals[39] + vals[40] + vals[41]; + ai->stats.rx_bytes = vals[92]; + ai->stats.tx_bytes = vals[91]; + ai->stats.rx_errors = vals[0] + vals[2] + vals[3] + vals[4]; + ai->stats.tx_errors = vals[42] + ai->stats.tx_fifo_errors; + ai->stats.multicast = vals[43]; + ai->stats.collisions = vals[89]; + + /* detailed rx_errors: */ + ai->stats.rx_length_errors = vals[3]; + ai->stats.rx_crc_errors = vals[4]; + ai->stats.rx_frame_errors = vals[2]; + ai->stats.rx_fifo_errors = vals[0]; } struct net_device_stats *airo_get_stats(struct net_device *dev) @@ -1510,46 +1517,37 @@ struct airo_info *local = dev->priv; /* Get stats out of the card if available */ - airo_read_stats(local); + if (down_trylock(&local->sem) != 0) { + set_bit(JOB_STATS, &local->flags); + wake_up_interruptible(&local->thr_wait); + } else + airo_read_stats(local); return &local->stats; } -static void airo_end_promisc(struct airo_info *ai) { - Resp rsp; - - if ((IN4500(ai, EVSTAT) & EV_CMD) != 0) { - completecommand(ai, &rsp); - up(&ai->sem); - } else { - ai->promisc_task.routine = (void (*)(void *))airo_end_promisc; - ai->promisc_task.data = (void *)ai; - schedule_task(&ai->promisc_task); - } -} - static void airo_set_promisc(struct airo_info *ai) { Cmd cmd; + Resp rsp; - if (down_trylock(&ai->sem) == 0) { - memset(&cmd, 0, sizeof(cmd)); - cmd.cmd=CMD_SETMODE; - cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC; - sendcommand(ai, &cmd); - airo_end_promisc(ai); - } else { - ai->promisc_task.routine = (void (*)(void *))airo_set_promisc; - ai->promisc_task.data = (void *)ai; - schedule_task(&ai->promisc_task); - } + memset(&cmd, 0, sizeof(cmd)); + cmd.cmd=CMD_SETMODE; + clear_bit(JOB_PROMISC, &ai->flags); + cmd.parm0=(ai->flags&IFF_PROMISC) ? PROMISC : NOPROMISC; + issuecommand(ai, &cmd, &rsp); + up(&ai->sem); } static void airo_set_multicast_list(struct net_device *dev) { struct airo_info *ai = dev->priv; if ((dev->flags ^ ai->flags) & IFF_PROMISC) { - ai->flags ^= IFF_PROMISC; - airo_set_promisc(ai); + change_bit(FLAG_PROMISC, &ai->flags); + if (down_trylock(&ai->sem) != 0) { + set_bit(JOB_PROMISC, &ai->flags); + wake_up_interruptible(&ai->thr_wait); + } else + airo_set_promisc(ai); } if ((dev->flags&IFF_ALLMULTI)||dev->mc_count>0) { @@ -1595,7 +1593,7 @@ * That's the method that is most friendly towards the network * stack (i.e. the network stack won't try to broadcast * anything on the interface and routes are gone. Jean II */ - ai->flags |= FLAG_RADIO_DOWN; + set_bit(FLAG_RADIO_DOWN, &ai->flags); disable_MAC(ai, 1); #endif disable_interrupts( ai ); @@ -1608,13 +1606,8 @@ void stop_airo_card( struct net_device *dev, int freeres ) { struct airo_info *ai = dev->priv; - flush_scheduled_tasks(); disable_interrupts(ai); free_irq( dev->irq, dev ); - if (ai->flash) - kfree(ai->flash); - if (ai->rssi) - kfree(ai->rssi); takedown_proc_entry( dev, ai ); if (ai->registered) { unregister_netdev( dev ); @@ -1625,7 +1618,13 @@ } ai->registered = 0; } - if (auto_wep) del_timer_sync(&ai->timer); + set_bit(JOB_DIE, &ai->flags); + kill_proc(ai->thr_pid, SIGTERM, 1); + wait_for_completion(&ai->thr_exited); + 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 ); @@ -1726,9 +1725,14 @@ sema_init(&ai->sem, 1); ai->need_commit = 0; ai->config.len = 0; + init_waitqueue_head (&ai->thr_wait); + init_completion (&ai->thr_exited); + ai->thr_pid = kernel_thread(airo_thread, dev, CLONE_FS | CLONE_FILES); + if (ai->thr_pid < 0) + goto err_out_free; rc = add_airo_dev( dev ); if (rc) - goto err_out_free; + goto err_out_thr; /* The Airo-specific entries in the device structure. */ dev->hard_start_xmit = &airo_start_xmit; @@ -1768,7 +1772,7 @@ } } else { ai->bap_read = fast_bap_read; - ai->flags |= FLAG_FLASHING; + set_bit(FLAG_FLASHING, &ai->flags); } rc = register_netdev(dev); @@ -1799,6 +1803,10 @@ free_irq(dev->irq, dev); err_out_unlink: del_airo_dev(dev); +err_out_thr: + set_bit(JOB_DIE, &ai->flags); + kill_proc(ai->thr_pid, SIGTERM, 1); + wait_for_completion(&ai->thr_exited); err_out_free: kfree(dev); return NULL; @@ -1862,38 +1870,108 @@ union iwreq_data wrqu; StatusRid status_rid; - if (down_trylock(&ai->sem) == 0) { - PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0); - up(&ai->sem); - wrqu.data.length = 0; - wrqu.data.flags = 0; - memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN); - wrqu.ap_addr.sa_family = ARPHRD_ETHER; + clear_bit(JOB_EVENT, &ai->flags); + PC4500_readrid(ai, RID_STATUS, &status_rid, sizeof(status_rid), 0); + up(&ai->sem); + wrqu.data.length = 0; + wrqu.data.flags = 0; + memcpy(wrqu.ap_addr.sa_data, status_rid.bssid[0], ETH_ALEN); + wrqu.ap_addr.sa_family = ARPHRD_ETHER; - /* Send event to user space */ - wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); - } else { - ai->event_task.routine = (void (*)(void *))airo_send_event; - ai->event_task.data = (void *)dev; - schedule_task(&ai->event_task); - } + /* Send event to user space */ + wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); } #endif -static void airo_read_mic(struct airo_info *ai) { - MICRid mic_rid; +static int airo_thread(void *data) { + struct net_device *dev = data; + struct airo_info *ai = dev->priv; + int locked; + + daemonize(); + reparent_to_init(); + spin_lock_irq(¤t->sigmask_lock); + sigemptyset(¤t->blocked); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + strncpy (current->comm, dev->name, sizeof(current->comm) - 1); + current->comm[sizeof(current->comm) - 1] = '\0'; + + while(1) { + if (signal_pending(current)) { + spin_lock_irq(¤t->sigmask_lock); + flush_signals(current); + spin_unlock_irq(¤t->sigmask_lock); + } + + if (test_bit(JOB_DIE, &ai->flags)) + break; - if (down_trylock(&ai->sem) == 0) { - PC4500_readrid(ai, RID_MIC, &mic_rid, sizeof(mic_rid), 0); - up(&ai->sem); + if (ai->flags & JOB_MASK) { + locked = down_interruptible(&ai->sem); + } else { + wait_queue_t wait; + + init_waitqueue_entry(&wait, current); + add_wait_queue(&ai->thr_wait, &wait); + for (;;) { + set_current_state(TASK_INTERRUPTIBLE); + if (ai->flags & JOB_MASK) + break; + if (ai->expires) { + if (time_after_eq(jiffies,ai->expires)){ + set_bit(JOB_AUTOWEP,&ai->flags); + break; + } + if (!signal_pending(current)) { + schedule_timeout(ai->expires - jiffies); + continue; + } + } else if (!signal_pending(current)) { + schedule(); + continue; + } + break; + } + current->state = TASK_RUNNING; + remove_wait_queue(&ai->thr_wait, &wait); + locked = 1; + } + + if (locked) + continue; + + if (test_bit(JOB_DIE, &ai->flags)) { + up(&ai->sem); + break; + } + + if (test_bit(FLAG_FLASHING, &ai->flags)) { + up(&ai->sem); + continue; + } + + if (test_bit(JOB_XMIT, &ai->flags)) + airo_end_xmit(dev); + else if (test_bit(JOB_XMIT11, &ai->flags)) + airo_end_xmit11(dev); + else if (test_bit(JOB_STATS, &ai->flags)) + airo_read_stats(ai); + else if (test_bit(JOB_PROMISC, &ai->flags)) + airo_set_promisc(ai); #ifdef MICSUPPORT - micinit (ai, &mic_rid); + else if (test_bit(JOB_MIC, &ai->flags)) + micinit(ai); #endif - } else { - ai->mic_task.routine = (void (*)(void *))airo_read_mic; - ai->mic_task.data = (void *)ai; - schedule_task(&ai->mic_task); +#if WIRELESS_EXT > 13 + else if (test_bit(JOB_EVENT, &ai->flags)) + airo_send_event(dev); +#endif + else if (test_bit(JOB_AUTOWEP, &ai->flags)) + timer_func(dev); } + complete_and_exit (&ai->thr_exited, 0); } static void airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) { @@ -1922,8 +2000,15 @@ if ( status & EV_MIC ) { OUT4500( apriv, EVACK, EV_MIC ); - if (apriv->flags & FLAG_MIC_CAPABLE) - airo_read_mic( apriv ); +#ifdef MICSUPPORT + if (test_bit(FLAG_MIC_CAPABLE, &apriv->flags)) { + if (down_trylock(&apriv->sem) != 0) { + set_bit(JOB_MIC, &apriv->flags); + wake_up_interruptible(&apriv->thr_wait); + } else + micinit (apriv); + } +#endif } if ( status & EV_LINK ) { #if WIRELESS_EXT > 13 @@ -1965,15 +2050,18 @@ #define RC_NOAUTH 9 /* Station requesting (Re)Association is not Authenticated with the responding station */ if (newStatus != ASSOCIATED) { - if (auto_wep && !timer_pending(&apriv->timer)) { - apriv->timer.expires = RUN_AT(HZ*3); - add_timer(&apriv->timer); + if (auto_wep && !apriv->expires) { + apriv->expires = RUN_AT(3*HZ); + wake_up_interruptible(&apriv->thr_wait); } } else { struct task_struct *task = apriv->task; + if (auto_wep) + apriv->expires = 0; if (task) wake_up_process (task); - apriv->flags|=FLAG_UPDATE_UNI|FLAG_UPDATE_MULTI; + set_bit(FLAG_UPDATE_UNI, &apriv->flags); + set_bit(FLAG_UPDATE_MULTI, &apriv->flags); } #if WIRELESS_EXT > 13 /* Question : is ASSOCIATED the only status @@ -1994,7 +2082,11 @@ wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL); apriv->scan_timestamp = 0; } - airo_send_event(dev); + if (down_trylock(&apriv->sem) != 0) { + set_bit(JOB_EVENT, &apriv->flags); + wake_up_interruptible(&apriv->thr_wait); + } else + airo_send_event(dev); } else { memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); wrqu.ap_addr.sa_family = ARPHRD_ETHER; @@ -2025,7 +2117,7 @@ fid = IN4500( apriv, RXFID ); /* Get the packet length */ - if (apriv->flags & FLAG_802_11) { + if (test_bit(FLAG_802_11, &apriv->flags)) { bap_setup (apriv, fid, 4, BAP0); bap_read (apriv, (u16*)&hdr, sizeof(hdr), BAP0); /* Bad CRC. Ignore packet */ @@ -2044,7 +2136,7 @@ len = 0; } if (len) { - if (apriv->flags & FLAG_802_11) { + if (test_bit(FLAG_802_11, &apriv->flags)) { bap_read (apriv, (u16*)&fc, sizeof(fc), BAP0); fc = le16_to_cpu(fc); switch (fc & 0xc) { @@ -2073,7 +2165,7 @@ } if (len) { buffer = (u16*)skb_put (skb, len + hdrlen); - if (apriv->flags & FLAG_802_11) { + if (test_bit(FLAG_802_11, &apriv->flags)) { buffer[0] = fc; bap_read (apriv, buffer + 1, hdrlen - 2, BAP0); if (hdrlen == 24) @@ -2120,11 +2212,12 @@ char *sa; struct iw_quality wstats; /* Prepare spy data : addr + qual */ - sa = (char*)buffer + ((apriv->flags & FLAG_802_11) ? 10 : 6); - if (!(apriv->flags & FLAG_802_11)) { + if (!test_bit(FLAG_802_11, &apriv->flags)) { + sa = (char*)buffer + 6; bap_setup (apriv, fid, 8, BAP0); bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); - } + } else + sa = (char*)buffer + 10; wstats.qual = hdr.rssi[0]; if (apriv->rssi) wstats.level = 0x100 - apriv->rssi[hdr.rssi[1]].rssidBm; @@ -2141,12 +2234,12 @@ int i; char *sa; - sa = (char*)buffer + ((apriv->flags & FLAG_802_11) ? 10 : 6); + sa = (char*)buffer + (test_bit(FLAG_802_11, &apriv->flags) ? 10 : 6); for (i=0; ispy_number; i++) if (!memcmp(sa,apriv->spy_address[i],ETH_ALEN)) { - if (!(apriv->flags & FLAG_802_11)) { + if (!test_bit(FLAG_802_11, &apriv->flags)) { bap_setup (apriv, fid, 8, BAP0); bap_read (apriv, (u16*)hdr.rssi, 2, BAP0); } @@ -2164,7 +2257,7 @@ #endif /* WIRELESS_EXT > 15 */ OUT4500( apriv, EVACK, EV_RX); - if (apriv->flags & FLAG_802_11) { + if (test_bit(FLAG_802_11, &apriv->flags)) { skb->mac.raw = skb->data; skb->pkt_type = PACKET_OTHERHOST; skb->dev = apriv->wifidev; @@ -2202,10 +2295,10 @@ /* Set up to be used again */ apriv->fids[index] &= 0xffff; if (index < MAX_FIDS / 2) { - if (!(apriv->flags & FLAG_PENDING_XMIT)) + if (!test_bit(FLAG_PENDING_XMIT, &apriv->flags)) netif_wake_queue(dev); } else { - if (!(apriv->flags & FLAG_PENDING_XMIT11)) + if (!test_bit(FLAG_PENDING_XMIT11, &apriv->flags)) netif_wake_queue(apriv->wifidev); } } else { @@ -2265,7 +2358,7 @@ * instead of this flag, but I don't trust it *within* the * open/close functions, and testing both flags together is * "cheaper" - Jean II */ - if (ai->flags & (FLAG_RADIO_OFF|FLAG_RADIO_DOWN)) return SUCCESS; + if (ai->flags & FLAG_RADIO_MASK) return SUCCESS; memset(&cmd, 0, sizeof(cmd)); cmd.cmd = MAC_ENABLE; if (!lock) @@ -2386,10 +2479,10 @@ 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) && + (micsetup(ai) == SUCCESS)) { ai->config.opmode |= MODE_MIC; - ai->flags |= FLAG_MIC_CAPABLE; - micsetup(ai); + set_bit(FLAG_MIC_CAPABLE, &ai->flags); } #endif @@ -2455,34 +2548,15 @@ rc = readWepKeyRid(ai, &wkr, 0); } while(lastindex != wkr.kindex); - if (auto_wep && !timer_pending(&ai->timer)) { - ai->timer.expires = RUN_AT(HZ*3); - add_timer(&ai->timer); + if (auto_wep) { + ai->expires = RUN_AT(3*HZ); + wake_up_interruptible(&ai->thr_wait); } - return SUCCESS; -} -static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) { - // Im really paranoid about letting it run forever! - int max_tries = 600000; - - if (sendcommand(ai, pCmd) == (u16)ERROR) - return ERROR; - - while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) { - if (!in_interrupt() && (max_tries & 255) == 0) - schedule(); - } - if ( max_tries == -1 ) { - printk( KERN_ERR - "airo: Max tries exceeded waiting for command\n" ); - return ERROR; - } - completecommand(ai, pRsp); return SUCCESS; } -static u16 sendcommand(struct airo_info *ai, Cmd *pCmd) { +static u16 issuecommand(struct airo_info *ai, Cmd *pCmd, Resp *pRsp) { // Im really paranoid about letting it run forever! int max_tries = 600000; u16 cmd; @@ -2501,10 +2575,16 @@ "airo: Max tries exceeded when issueing command\n" ); return ERROR; } - return SUCCESS; -} -static void completecommand(struct airo_info *ai, Resp *pRsp) { + while (max_tries-- && (IN4500(ai, EVSTAT) & EV_CMD) == 0) { + if (!in_interrupt() && (max_tries & 255) == 0) + schedule(); + } + if ( max_tries == -1 ) { + printk( KERN_ERR + "airo: Max tries exceeded waiting for command\n" ); + return ERROR; + } // command completed pRsp->status = IN4500(ai, STATUS); pRsp->rsp0 = IN4500(ai, RESP0); @@ -2517,6 +2597,8 @@ } // acknowledge processing the status/response OUT4500(ai, EVACK, EV_CMD); + + return SUCCESS; } /* Sets up the bap to start exchange data. whichbap should @@ -2803,7 +2885,7 @@ len -= ETH_ALEN * 2; #ifdef MICSUPPORT - if ((ai->flags & FLAG_MIC_CAPABLE) && ai->micstats.enabled && + if (test_bit(FLAG_MIC_CAPABLE, &ai->flags) && ai->micstats.enabled && (ntohs(((u16 *)pPacket)[6]) != 0x888E)) { if (encapsulate(ai,(etherHead *)pPacket,&pMic,len) != SUCCESS) return ERROR; @@ -3306,7 +3388,7 @@ if ((ai->config.rmode & 0xff) >= RXMODE_RFMON) ai->need_commit = 2; ai->config.rmode &= 0xfe00; - ai->flags &= ~FLAG_802_11; + clear_bit (FLAG_802_11, &ai->flags); ai->config.opmode &= 0xFF00; ai->config.scanMode = SCANMODE_ACTIVE; if ( line[0] == 'a' ) { @@ -3316,11 +3398,11 @@ if ( line[0] == 'r' ) { ai->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER; ai->config.scanMode = SCANMODE_PASSIVE; - ai->flags |= FLAG_802_11; + set_bit (FLAG_802_11, &ai->flags); } else if ( line[0] == 'y' ) { ai->config.rmode |= RXMODE_RFMON_ANYBSS | RXMODE_DISABLE_802_3_HEADER; ai->config.scanMode = SCANMODE_PASSIVE; - ai->flags |= FLAG_802_11; + set_bit (FLAG_802_11, &ai->flags); } else if ( line[0] == 'l' ) ai->config.rmode |= RXMODE_LANMON; } @@ -3331,9 +3413,9 @@ else if (!strncmp(line,"Radio: ", 7)) { line += 7; if (!strncmp(line,"off",3)) { - ai->flags |= FLAG_RADIO_OFF; + set_bit (FLAG_RADIO_OFF, &ai->flags); } else { - ai->flags &= ~FLAG_RADIO_OFF; + clear_bit (FLAG_RADIO_OFF, &ai->flags); } } /*** NodeName processing */ @@ -3537,7 +3619,7 @@ (ai->config.opmode & 0xFF) == 1 ? get_rmode(ai->config.rmode): (ai->config.opmode & 0xFF) == 2 ? "AP" : (ai->config.opmode & 0xFF) == 3 ? "AP RPTR" : "Error", - ai->flags&FLAG_RADIO_OFF ? "off" : "on", + test_bit(FLAG_RADIO_OFF, &ai->flags) ? "off" : "on", ai->config.nodeName, ai->config.powerSaveMode == 0 ? "CAM" : ai->config.powerSaveMode == 1 ? "PSP" : @@ -4004,23 +4086,14 @@ will switch WEP modes to see if that will help. If the card is associated we will check every minute to see if anything has changed. */ -static void timer_func( u_long data ) { - struct net_device *dev = (struct net_device*)data; +static void timer_func( struct net_device *dev ) { struct airo_info *apriv = dev->priv; - u16 linkstat = IN4500(apriv, LINKSTAT); Resp rsp; - if (!(apriv->flags & FLAG_FLASHING) && (linkstat != 0x400)) { /* We don't have a link so try changing the authtype */ - if (down_trylock(&apriv->sem) != 0) { - apriv->timer.expires = RUN_AT(1); - add_timer(&apriv->timer); - return; - } - - readConfigRid(apriv, 0); - disable_MAC(apriv, 0); - switch(apriv->config.authType) { + readConfigRid(apriv, 0); + disable_MAC(apriv, 0); + switch(apriv->config.authType) { case AUTH_ENCRYPT: /* So drop to OPEN */ apriv->config.authType = AUTH_OPEN; @@ -4039,16 +4112,15 @@ break; default: /* We'll escalate to SHAREDKEY */ apriv->config.authType = AUTH_SHAREDKEY; - } - apriv->need_commit = 1; - writeConfigRid(apriv, 0); - enable_MAC(apriv, &rsp, 0); - up(&apriv->sem); + } + apriv->need_commit = 1; + writeConfigRid(apriv, 0); + enable_MAC(apriv, &rsp, 0); + up(&apriv->sem); /* Schedule check to see if the change worked */ - apriv->timer.expires = RUN_AT(HZ*3); - add_timer(&apriv->timer); - } + clear_bit(JOB_AUTOWEP, &apriv->flags); + apriv->expires = RUN_AT(HZ*3); } static int add_airo_dev( struct net_device *dev ) { @@ -4056,15 +4128,6 @@ if ( !node ) return -ENOMEM; - if ( auto_wep ) { - struct airo_info *apriv=dev->priv; - struct timer_list *timer = &apriv->timer; - - timer->function = timer_func; - timer->data = (u_long)dev; - init_timer(timer); - } - node->dev = dev; node->next = airo_devices; airo_devices = node; @@ -4095,6 +4158,7 @@ return -ENODEV; pci_set_drvdata(pdev, dev); + clear_bit (FLAG_PCI, &((struct airo_info *)dev->priv)->flags); return 0; } @@ -4136,11 +4200,19 @@ static void __exit airo_cleanup_module( void ) { + int is_pci = 0; while( airo_devices ) { printk( KERN_INFO "airo: Unregistering %s\n", airo_devices->dev->name ); +#ifdef CONFIG_PCI + if (test_bit(FLAG_PCI, &((struct airo_info *)airo_devices->dev->priv)->flags)) + is_pci = 1; +#endif stop_airo_card( airo_devices->dev, 1 ); } remove_proc_entry("aironet", proc_root_driver); + + if (is_pci) + pci_unregister_driver(&airo_driver); } #ifdef WIRELESS_EXT @@ -4606,28 +4678,28 @@ local->config.opmode |= MODE_STA_IBSS; local->config.rmode &= 0xfe00; local->config.scanMode = SCANMODE_ACTIVE; - local->flags &= ~FLAG_802_11; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_INFRA: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_STA_ESS; local->config.rmode &= 0xfe00; local->config.scanMode = SCANMODE_ACTIVE; - local->flags &= ~FLAG_802_11; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_MASTER: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_AP; local->config.rmode &= 0xfe00; local->config.scanMode = SCANMODE_ACTIVE; - local->flags &= ~FLAG_802_11; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_REPEAT: local->config.opmode &= 0xFF00; local->config.opmode |= MODE_AP_RPTR; local->config.rmode &= 0xfe00; local->config.scanMode = SCANMODE_ACTIVE; - local->flags &= ~FLAG_802_11; + clear_bit (FLAG_802_11, &local->flags); break; case IW_MODE_MONITOR: local->config.opmode &= 0xFF00; @@ -4635,7 +4707,7 @@ local->config.rmode &= 0xfe00; local->config.rmode |= RXMODE_RFMON | RXMODE_DISABLE_802_3_HEADER; local->config.scanMode = SCANMODE_PASSIVE; - local->flags |= FLAG_802_11; + set_bit (FLAG_802_11, &local->flags); break; default: return -EINVAL; @@ -4824,14 +4896,14 @@ readCapabilityRid(local, &cap_rid); if (vwrq->disabled) { - local->flags |= FLAG_RADIO_OFF; + set_bit (FLAG_RADIO_OFF, &local->flags); local->need_commit = 1; return -EINPROGRESS; /* Call commit handler */ } if (vwrq->flags != IW_TXPOW_MWATT) { return -EINVAL; } - local->flags &= ~FLAG_RADIO_OFF; + clear_bit (FLAG_RADIO_OFF, &local->flags); for (i = 0; cap_rid.txPowerLevels[i] && (i < 8); i++) if ((vwrq->value==cap_rid.txPowerLevels[i])) { local->config.txPower = vwrq->value; @@ -4855,7 +4927,7 @@ vwrq->value = local->config.txPower; vwrq->fixed = 1; /* No power control */ - vwrq->disabled = (local->flags & FLAG_RADIO_OFF); + vwrq->disabled = test_bit(FLAG_RADIO_OFF, &local->flags); vwrq->flags = IW_TXPOW_MWATT; return 0; @@ -5199,7 +5271,7 @@ & 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] @@ -5293,7 +5365,7 @@ 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); @@ -5505,10 +5577,14 @@ writeSsidRid(local, &SSID_rid); writeAPListRid(local, &APList_rid); } - writeConfigRid(local, 1); - enable_MAC(local, &rsp, 1); + if (down_interruptible(&local->sem)) + return -ERESTARTSYS; + writeConfigRid(local, 0); + enable_MAC(local, &rsp, 0); if (local->need_commit > 1) airo_set_promisc(local); + else + up(&local->sem); return 0; } @@ -6046,7 +6122,7 @@ unsigned char *iobuf; struct airo_info *ai = dev->priv; - if (ai->flags & FLAG_FLASHING) + if (test_bit(FLAG_FLASHING, &ai->flags)) return -EIO; switch(comp->command) @@ -6114,7 +6190,7 @@ if (!capable(CAP_NET_ADMIN)) return -EPERM; - if (ai->flags & FLAG_FLASHING) + if (test_bit(FLAG_FLASHING, &ai->flags)) return -EIO; ridcode = 0; @@ -6188,13 +6264,13 @@ if (comp->command == AIROPCFG) { ConfigRid *cfg = (ConfigRid *)iobuf; - if (ai->flags & FLAG_MIC_CAPABLE) + if (test_bit(FLAG_MIC_CAPABLE, &ai->flags)) cfg->opmode |= MODE_MIC; if ((cfg->opmode & 0xFF) == MODE_STA_IBSS) - ai->flags |= FLAG_ADHOC; + set_bit (FLAG_ADHOC, &ai->flags); else - ai->flags &= ~FLAG_ADHOC; + clear_bit (FLAG_ADHOC, &ai->flags); } if((*writer)(ai, ridcode, iobuf,comp->len,1)) { @@ -6305,7 +6381,7 @@ */ int setflashmode (struct airo_info *ai) { - ai->flags |= FLAG_FLASHING; + set_bit (FLAG_FLASHING, &ai->flags); OUT4500(ai, SWS0, FLASH_COMMAND); OUT4500(ai, SWS1, FLASH_COMMAND); @@ -6321,7 +6397,7 @@ schedule_timeout (HZ/2); /* 500ms delay */ if(!waitbusy(ai)) { - ai->flags &= ~FLAG_FLASHING; + clear_bit (FLAG_FLASHING, &ai->flags); printk(KERN_INFO "Waitbusy hang after setflash mode\n"); return -EIO; } @@ -6427,7 +6503,7 @@ set_current_state (TASK_UNINTERRUPTIBLE); schedule_timeout (HZ); /* Added 12/7/00 */ - ai->flags &= ~FLAG_FLASHING; + clear_bit (FLAG_FLASHING, &ai->flags); status = setup_card(ai, dev->dev_addr); for( i = 0; i < MAX_FIDS; i++ ) { diff -Nru a/include/linux/netdevice.h b/include/linux/netdevice.h --- a/include/linux/netdevice.h Mon Aug 25 19:03:08 2003 +++ b/include/linux/netdevice.h Mon Aug 25 19:03:08 2003 @@ -801,6 +801,8 @@ extern void fc_setup(struct net_device *dev); extern void fc_freedev(struct net_device *dev); /* Support for loadable net-drivers */ +extern struct net_device *alloc_netdev(int sizeof_priv, const char *name, + void (*setup)(struct net_device *)); extern int register_netdev(struct net_device *dev); extern void unregister_netdev(struct net_device *dev); /* Functions used for multicast support */