Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into upstream-fixes

+238 -151
+76 -29
drivers/net/wireless/airo.c
··· 2897 2897 goto err_out_map; 2898 2898 } 2899 2899 ai->wifidev = init_wifidev(ai, dev); 2900 + if (!ai->wifidev) 2901 + goto err_out_reg; 2900 2902 2901 2903 set_bit(FLAG_REGISTERED,&ai->flags); 2902 2904 airo_print_info(dev->name, "MAC enabled %x:%x:%x:%x:%x:%x", ··· 2910 2908 for( i = 0; i < MAX_FIDS; i++ ) 2911 2909 ai->fids[i] = transmit_allocate(ai,AIRO_DEF_MTU,i>=MAX_FIDS/2); 2912 2910 2913 - setup_proc_entry( dev, dev->priv ); /* XXX check for failure */ 2911 + if (setup_proc_entry(dev, dev->priv) < 0) 2912 + goto err_out_wifi; 2913 + 2914 2914 netif_start_queue(dev); 2915 2915 SET_MODULE_OWNER(dev); 2916 2916 return dev; 2917 2917 2918 + err_out_wifi: 2919 + unregister_netdev(ai->wifidev); 2920 + free_netdev(ai->wifidev); 2921 + err_out_reg: 2922 + unregister_netdev(dev); 2918 2923 err_out_map: 2919 2924 if (test_bit(FLAG_MPI,&ai->flags) && pci) { 2920 2925 pci_free_consistent(pci, PCI_SHARED_LEN, ai->shared, ai->shared_dma); ··· 3098 3089 set_bit(JOB_AUTOWEP, &ai->jobs); 3099 3090 break; 3100 3091 } 3101 - if (!kthread_should_stop()) { 3092 + if (!kthread_should_stop() && 3093 + !freezing(current)) { 3102 3094 unsigned long wake_at; 3103 3095 if (!ai->expires || !ai->scan_timeout) { 3104 3096 wake_at = max(ai->expires, ··· 3111 3101 schedule_timeout(wake_at - jiffies); 3112 3102 continue; 3113 3103 } 3114 - } else if (!kthread_should_stop()) { 3104 + } else if (!kthread_should_stop() && 3105 + !freezing(current)) { 3115 3106 schedule(); 3116 3107 continue; 3117 3108 } ··· 4506 4495 apriv->proc_entry = create_proc_entry(apriv->proc_name, 4507 4496 S_IFDIR|airo_perm, 4508 4497 airo_entry); 4509 - apriv->proc_entry->uid = proc_uid; 4510 - apriv->proc_entry->gid = proc_gid; 4511 - apriv->proc_entry->owner = THIS_MODULE; 4498 + if (!apriv->proc_entry) 4499 + goto fail; 4500 + apriv->proc_entry->uid = proc_uid; 4501 + apriv->proc_entry->gid = proc_gid; 4502 + apriv->proc_entry->owner = THIS_MODULE; 4512 4503 4513 4504 /* Setup the StatsDelta */ 4514 4505 entry = create_proc_entry("StatsDelta", 4515 4506 S_IFREG | (S_IRUGO&proc_perm), 4516 4507 apriv->proc_entry); 4517 - entry->uid = proc_uid; 4518 - entry->gid = proc_gid; 4508 + if (!entry) 4509 + goto fail_stats_delta; 4510 + entry->uid = proc_uid; 4511 + entry->gid = proc_gid; 4519 4512 entry->data = dev; 4520 - entry->owner = THIS_MODULE; 4513 + entry->owner = THIS_MODULE; 4521 4514 SETPROC_OPS(entry, proc_statsdelta_ops); 4522 4515 4523 4516 /* Setup the Stats */ 4524 4517 entry = create_proc_entry("Stats", 4525 4518 S_IFREG | (S_IRUGO&proc_perm), 4526 4519 apriv->proc_entry); 4527 - entry->uid = proc_uid; 4528 - entry->gid = proc_gid; 4520 + if (!entry) 4521 + goto fail_stats; 4522 + entry->uid = proc_uid; 4523 + entry->gid = proc_gid; 4529 4524 entry->data = dev; 4530 - entry->owner = THIS_MODULE; 4525 + entry->owner = THIS_MODULE; 4531 4526 SETPROC_OPS(entry, proc_stats_ops); 4532 4527 4533 4528 /* Setup the Status */ 4534 4529 entry = create_proc_entry("Status", 4535 4530 S_IFREG | (S_IRUGO&proc_perm), 4536 4531 apriv->proc_entry); 4537 - entry->uid = proc_uid; 4538 - entry->gid = proc_gid; 4532 + if (!entry) 4533 + goto fail_status; 4534 + entry->uid = proc_uid; 4535 + entry->gid = proc_gid; 4539 4536 entry->data = dev; 4540 - entry->owner = THIS_MODULE; 4537 + entry->owner = THIS_MODULE; 4541 4538 SETPROC_OPS(entry, proc_status_ops); 4542 4539 4543 4540 /* Setup the Config */ 4544 4541 entry = create_proc_entry("Config", 4545 4542 S_IFREG | proc_perm, 4546 4543 apriv->proc_entry); 4547 - entry->uid = proc_uid; 4548 - entry->gid = proc_gid; 4544 + if (!entry) 4545 + goto fail_config; 4546 + entry->uid = proc_uid; 4547 + entry->gid = proc_gid; 4549 4548 entry->data = dev; 4550 - entry->owner = THIS_MODULE; 4549 + entry->owner = THIS_MODULE; 4551 4550 SETPROC_OPS(entry, proc_config_ops); 4552 4551 4553 4552 /* Setup the SSID */ 4554 4553 entry = create_proc_entry("SSID", 4555 4554 S_IFREG | proc_perm, 4556 4555 apriv->proc_entry); 4557 - entry->uid = proc_uid; 4558 - entry->gid = proc_gid; 4556 + if (!entry) 4557 + goto fail_ssid; 4558 + entry->uid = proc_uid; 4559 + entry->gid = proc_gid; 4559 4560 entry->data = dev; 4560 - entry->owner = THIS_MODULE; 4561 + entry->owner = THIS_MODULE; 4561 4562 SETPROC_OPS(entry, proc_SSID_ops); 4562 4563 4563 4564 /* Setup the APList */ 4564 4565 entry = create_proc_entry("APList", 4565 4566 S_IFREG | proc_perm, 4566 4567 apriv->proc_entry); 4567 - entry->uid = proc_uid; 4568 - entry->gid = proc_gid; 4568 + if (!entry) 4569 + goto fail_aplist; 4570 + entry->uid = proc_uid; 4571 + entry->gid = proc_gid; 4569 4572 entry->data = dev; 4570 - entry->owner = THIS_MODULE; 4573 + entry->owner = THIS_MODULE; 4571 4574 SETPROC_OPS(entry, proc_APList_ops); 4572 4575 4573 4576 /* Setup the BSSList */ 4574 4577 entry = create_proc_entry("BSSList", 4575 4578 S_IFREG | proc_perm, 4576 4579 apriv->proc_entry); 4580 + if (!entry) 4581 + goto fail_bsslist; 4577 4582 entry->uid = proc_uid; 4578 4583 entry->gid = proc_gid; 4579 4584 entry->data = dev; 4580 - entry->owner = THIS_MODULE; 4585 + entry->owner = THIS_MODULE; 4581 4586 SETPROC_OPS(entry, proc_BSSList_ops); 4582 4587 4583 4588 /* Setup the WepKey */ 4584 4589 entry = create_proc_entry("WepKey", 4585 4590 S_IFREG | proc_perm, 4586 4591 apriv->proc_entry); 4587 - entry->uid = proc_uid; 4588 - entry->gid = proc_gid; 4592 + if (!entry) 4593 + goto fail_wepkey; 4594 + entry->uid = proc_uid; 4595 + entry->gid = proc_gid; 4589 4596 entry->data = dev; 4590 - entry->owner = THIS_MODULE; 4597 + entry->owner = THIS_MODULE; 4591 4598 SETPROC_OPS(entry, proc_wepkey_ops); 4592 4599 4593 4600 return 0; 4601 + 4602 + fail_wepkey: 4603 + remove_proc_entry("BSSList", apriv->proc_entry); 4604 + fail_bsslist: 4605 + remove_proc_entry("APList", apriv->proc_entry); 4606 + fail_aplist: 4607 + remove_proc_entry("SSID", apriv->proc_entry); 4608 + fail_ssid: 4609 + remove_proc_entry("Config", apriv->proc_entry); 4610 + fail_config: 4611 + remove_proc_entry("Status", apriv->proc_entry); 4612 + fail_status: 4613 + remove_proc_entry("Stats", apriv->proc_entry); 4614 + fail_stats: 4615 + remove_proc_entry("StatsDelta", apriv->proc_entry); 4616 + fail_stats_delta: 4617 + remove_proc_entry(apriv->proc_name, airo_entry); 4618 + fail: 4619 + return -ENOMEM; 4594 4620 } 4595 4621 4596 4622 static int takedown_proc_entry( struct net_device *dev, ··· 5972 5924 5973 5925 /* Get the current SSID */ 5974 5926 memcpy(extra, status_rid.SSID, status_rid.SSIDlen); 5975 - extra[status_rid.SSIDlen] = '\0'; 5976 5927 /* If none, we may want to get the one that was set */ 5977 5928 5978 5929 /* Push it out ! */
-2
drivers/net/wireless/atmel.c
··· 1678 1678 /* Get the current SSID */ 1679 1679 if (priv->new_SSID_size != 0) { 1680 1680 memcpy(extra, priv->new_SSID, priv->new_SSID_size); 1681 - extra[priv->new_SSID_size] = '\0'; 1682 1681 dwrq->length = priv->new_SSID_size; 1683 1682 } else { 1684 1683 memcpy(extra, priv->SSID, priv->SSID_size); 1685 - extra[priv->SSID_size] = '\0'; 1686 1684 dwrq->length = priv->SSID_size; 1687 1685 } 1688 1686
+23 -5
drivers/net/wireless/bcm43xx/bcm43xx_dma.c
··· 705 705 struct bcm43xx_dmaring *ring; 706 706 int err = -ENOMEM; 707 707 int dma64 = 0; 708 - u32 sbtmstatehi; 708 + u64 mask = bcm43xx_get_supported_dma_mask(bcm); 709 + int nobits; 709 710 710 - sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH); 711 - if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT) 711 + if (mask == DMA_64BIT_MASK) { 712 712 dma64 = 1; 713 + nobits = 64; 714 + } else if (mask == DMA_32BIT_MASK) 715 + nobits = 32; 716 + else 717 + nobits = 30; 718 + err = pci_set_dma_mask(bcm->pci_dev, mask); 719 + err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask); 720 + if (err) { 721 + #ifdef CONFIG_BCM43XX_PIO 722 + printk(KERN_WARNING PFX "DMA not supported on this device." 723 + " Falling back to PIO.\n"); 724 + bcm->__using_pio = 1; 725 + return -ENOSYS; 726 + #else 727 + printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. " 728 + "Please recompile the driver with PIO support.\n"); 729 + return -ENODEV; 730 + #endif /* CONFIG_BCM43XX_PIO */ 731 + } 713 732 714 733 /* setup TX DMA channels. */ 715 734 ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64); ··· 774 755 dma->rx_ring3 = ring; 775 756 } 776 757 777 - dprintk(KERN_INFO PFX "%s DMA initialized\n", 778 - dma64 ? "64-bit" : "32-bit"); 758 + dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits); 779 759 err = 0; 780 760 out: 781 761 return err;
+17
drivers/net/wireless/bcm43xx/bcm43xx_dma.h
··· 314 314 struct ieee80211_txb *txb); 315 315 void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring); 316 316 317 + /* Helper function that returns the dma mask for this device. */ 318 + static inline 319 + u64 bcm43xx_get_supported_dma_mask(struct bcm43xx_private *bcm) 320 + { 321 + int dma64 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH) & 322 + BCM43xx_SBTMSTATEHIGH_DMA64BIT; 323 + u16 mmio_base = bcm43xx_dmacontroller_base(dma64, 0); 324 + u32 mask = BCM43xx_DMA32_TXADDREXT_MASK; 325 + 326 + if (dma64) 327 + return DMA_64BIT_MASK; 328 + bcm43xx_write32(bcm, mmio_base + BCM43xx_DMA32_TXCTL, mask); 329 + if (bcm43xx_read32(bcm, mmio_base + BCM43xx_DMA32_TXCTL) & mask) 330 + return DMA_32BIT_MASK; 331 + return DMA_30BIT_MASK; 332 + } 333 + 317 334 #else /* CONFIG_BCM43XX_DMA */ 318 335 319 336
+1 -1
drivers/net/wireless/bcm43xx/bcm43xx_leds.c
··· 242 242 //TODO 243 243 break; 244 244 case BCM43xx_LED_ASSOC: 245 - if (bcm->softmac->associated) 245 + if (bcm->softmac->associnfo.associated) 246 246 turn_on = 1; 247 247 break; 248 248 #ifdef CONFIG_BCM43XX_DEBUG
+12 -22
drivers/net/wireless/bcm43xx/bcm43xx_main.c
··· 2925 2925 bcm43xx_write16(bcm, 0x043C, 0x000C); 2926 2926 2927 2927 if (active_wlcore) { 2928 - if (bcm43xx_using_pio(bcm)) 2928 + if (bcm43xx_using_pio(bcm)) { 2929 2929 err = bcm43xx_pio_init(bcm); 2930 - else 2930 + } else { 2931 2931 err = bcm43xx_dma_init(bcm); 2932 + if (err == -ENOSYS) 2933 + err = bcm43xx_pio_init(bcm); 2934 + } 2932 2935 if (err) 2933 2936 goto err_chip_cleanup; 2934 2937 } ··· 3167 3164 u32 savedirqs = 0; 3168 3165 int badness; 3169 3166 3167 + mutex_lock(&bcm->mutex); 3170 3168 badness = estimate_periodic_work_badness(bcm->periodic_state); 3171 3169 if (badness > BADNESS_LIMIT) { 3172 3170 /* Periodic work will take a long time, so we want it to 3173 3171 * be preemtible. 3174 3172 */ 3175 - mutex_lock(&bcm->mutex); 3176 3173 netif_tx_disable(bcm->net_dev); 3177 3174 spin_lock_irqsave(&bcm->irq_lock, flags); 3178 3175 bcm43xx_mac_suspend(bcm); ··· 3185 3182 /* Periodic work should take short time, so we want low 3186 3183 * locking overhead. 3187 3184 */ 3188 - mutex_lock(&bcm->mutex); 3189 3185 spin_lock_irqsave(&bcm->irq_lock, flags); 3190 3186 } 3191 3187 ··· 3995 3993 struct net_device *net_dev, 3996 3994 struct pci_dev *pci_dev) 3997 3995 { 3998 - int err; 3999 - 4000 3996 bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT); 4001 3997 bcm->ieee = netdev_priv(net_dev); 4002 3998 bcm->softmac = ieee80211_priv(net_dev); ··· 4012 4012 (void (*)(unsigned long))bcm43xx_interrupt_tasklet, 4013 4013 (unsigned long)bcm); 4014 4014 tasklet_disable_nosync(&bcm->isr_tasklet); 4015 - if (modparam_pio) { 4015 + if (modparam_pio) 4016 4016 bcm->__using_pio = 1; 4017 - } else { 4018 - err = pci_set_dma_mask(pci_dev, DMA_30BIT_MASK); 4019 - err |= pci_set_consistent_dma_mask(pci_dev, DMA_30BIT_MASK); 4020 - if (err) { 4021 - #ifdef CONFIG_BCM43XX_PIO 4022 - printk(KERN_WARNING PFX "DMA not supported. Falling back to PIO.\n"); 4023 - bcm->__using_pio = 1; 4024 - #else 4025 - printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. " 4026 - "Recompile the driver with PIO support, please.\n"); 4027 - return -ENODEV; 4028 - #endif /* CONFIG_BCM43XX_PIO */ 4029 - } 4030 - } 4031 4017 bcm->rts_threshold = BCM43xx_DEFAULT_RTS_THRESHOLD; 4032 4018 4033 4019 /* default to sw encryption for now */ ··· 4194 4208 dprintk(KERN_INFO PFX "Resuming...\n"); 4195 4209 4196 4210 pci_set_power_state(pdev, 0); 4197 - pci_enable_device(pdev); 4211 + err = pci_enable_device(pdev); 4212 + if (err) { 4213 + printk(KERN_ERR PFX "Failure with pci_enable_device!\n"); 4214 + return err; 4215 + } 4198 4216 pci_restore_state(pdev); 4199 4217 4200 4218 bcm43xx_chipset_attach(bcm);
+1 -1
drivers/net/wireless/bcm43xx/bcm43xx_wx.c
··· 847 847 unsigned long flags; 848 848 849 849 wstats = &bcm->stats.wstats; 850 - if (!mac->associated) { 850 + if (!mac->associnfo.associated) { 851 851 wstats->miss.beacon = 0; 852 852 // bcm->ieee->ieee_stats.tx_retry_limit_exceeded = 0; // FIXME: should this be cleared here? 853 853 wstats->discard.retries = 0;
+9 -7
drivers/net/wireless/orinoco.c
··· 2457 2457 /* Wireless extensions */ 2458 2458 /********************************************************************/ 2459 2459 2460 + /* Return : < 0 -> error code ; >= 0 -> length */ 2460 2461 static int orinoco_hw_get_essid(struct orinoco_private *priv, int *active, 2461 2462 char buf[IW_ESSID_MAX_SIZE+1]) 2462 2463 { ··· 2502 2501 len = le16_to_cpu(essidbuf.len); 2503 2502 BUG_ON(len > IW_ESSID_MAX_SIZE); 2504 2503 2505 - memset(buf, 0, IW_ESSID_MAX_SIZE+1); 2504 + memset(buf, 0, IW_ESSID_MAX_SIZE); 2506 2505 memcpy(buf, p, len); 2507 - buf[len] = '\0'; 2506 + err = len; 2508 2507 2509 2508 fail_unlock: 2510 2509 orinoco_unlock(priv, &flags); ··· 3028 3027 3029 3028 if (netif_running(dev)) { 3030 3029 err = orinoco_hw_get_essid(priv, &active, essidbuf); 3031 - if (err) 3030 + if (err < 0) 3032 3031 return err; 3032 + erq->length = err; 3033 3033 } else { 3034 3034 if (orinoco_lock(priv, &flags) != 0) 3035 3035 return -EBUSY; 3036 - memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE + 1); 3036 + memcpy(essidbuf, priv->desired_essid, IW_ESSID_MAX_SIZE); 3037 + erq->length = strlen(priv->desired_essid); 3037 3038 orinoco_unlock(priv, &flags); 3038 3039 } 3039 3040 3040 3041 erq->flags = 1; 3041 - erq->length = strlen(essidbuf); 3042 3042 3043 3043 return 0; 3044 3044 } ··· 3077 3075 if (orinoco_lock(priv, &flags) != 0) 3078 3076 return -EBUSY; 3079 3077 3080 - memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE+1); 3078 + memcpy(nickbuf, priv->nick, IW_ESSID_MAX_SIZE); 3081 3079 orinoco_unlock(priv, &flags); 3082 3080 3083 - nrq->length = strlen(nickbuf); 3081 + nrq->length = strlen(priv->nick); 3084 3082 3085 3083 return 0; 3086 3084 }
-1
drivers/net/wireless/ray_cs.c
··· 1198 1198 1199 1199 /* Get the essid that was set */ 1200 1200 memcpy(extra, local->sparm.b5.a_current_ess_id, IW_ESSID_MAX_SIZE); 1201 - extra[IW_ESSID_MAX_SIZE] = '\0'; 1202 1201 1203 1202 /* Push it out ! */ 1204 1203 dwrq->length = strlen(extra);
+2 -4
drivers/net/wireless/zd1201.c
··· 193 193 struct sk_buff *skb; 194 194 unsigned char type; 195 195 196 - if (!zd) { 197 - free = 1; 198 - goto exit; 199 - } 196 + if (!zd) 197 + return; 200 198 201 199 switch(urb->status) { 202 200 case -EILSEQ:
+1 -1
drivers/net/wireless/zd1211rw/zd_mac.c
··· 1099 1099 int r; 1100 1100 1101 1101 spin_lock_irq(&mac->lock); 1102 - is_associated = sm->associated != 0; 1102 + is_associated = sm->associnfo.associated != 0; 1103 1103 spin_unlock_irq(&mac->lock); 1104 1104 1105 1105 r = zd_chip_control_leds(chip,
+16 -19
include/net/ieee80211softmac.h
··· 63 63 64 64 /* 65 65 * Information about association 66 - * 67 - * Do we need a lock for this? 68 - * We only ever use this structure inlined 69 - * into our global struct. I've used its lock, 70 - * but maybe we need a local one here? 71 66 */ 72 67 struct ieee80211softmac_assoc_info { 68 + 69 + struct mutex mutex; 70 + 73 71 /* 74 72 * This is the requested ESSID. It is written 75 73 * only by the WX handlers. ··· 97 99 * 98 100 * bssfixed is used for SIOCSIWAP. 99 101 */ 100 - u8 static_essid:1, 101 - short_preamble_available:1, 102 - associating:1, 103 - assoc_wait:1, 104 - bssvalid:1, 105 - bssfixed:1; 102 + u8 static_essid; 103 + u8 short_preamble_available; 104 + u8 associating; 105 + u8 associated; 106 + u8 assoc_wait; 107 + u8 bssvalid; 108 + u8 bssfixed; 106 109 107 110 /* Scan retries remaining */ 108 111 int scan_retry; ··· 228 229 /* private stuff follows */ 229 230 /* this lock protects this structure */ 230 231 spinlock_t lock; 231 - 232 - /* couple of flags */ 233 - u8 scanning:1, /* protects scanning from being done multiple times at once */ 234 - associated:1, 235 - running:1; 236 - 232 + 233 + u8 running; /* SoftMAC started? */ 234 + u8 scanning; 235 + 237 236 struct ieee80211softmac_scaninfo *scaninfo; 238 237 struct ieee80211softmac_assoc_info associnfo; 239 238 struct ieee80211softmac_bss_info bssinfo; ··· 247 250 248 251 /* we need to keep a list of network structs we copied */ 249 252 struct list_head network_list; 250 - 253 + 251 254 /* This must be the last item so that it points to the data 252 255 * allocated beyond this structure by alloc_ieee80211 */ 253 256 u8 priv[0]; ··· 292 295 { 293 296 struct ieee80211softmac_txrates *txrates = &mac->txrates; 294 297 295 - if (!mac->associated) 298 + if (!mac->associnfo.associated) 296 299 return txrates->mgt_mcast_rate; 297 300 298 301 /* We are associated, sending unicast frame */
+27 -29
net/ieee80211/softmac/ieee80211softmac_assoc.c
··· 48 48 dprintk(KERN_INFO PFX "sent association request!\n"); 49 49 50 50 spin_lock_irqsave(&mac->lock, flags); 51 - mac->associated = 0; /* just to make sure */ 51 + mac->associnfo.associated = 0; /* just to make sure */ 52 52 53 53 /* Set a timer for timeout */ 54 54 /* FIXME: make timeout configurable */ ··· 62 62 { 63 63 struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; 64 64 struct ieee80211softmac_network *n; 65 - unsigned long flags; 66 65 67 - spin_lock_irqsave(&mac->lock, flags); 66 + mutex_lock(&mac->associnfo.mutex); 68 67 /* we might race against ieee80211softmac_handle_assoc_response, 69 68 * so make sure only one of us does something */ 70 - if (!mac->associnfo.associating) { 71 - spin_unlock_irqrestore(&mac->lock, flags); 72 - return; 73 - } 69 + if (!mac->associnfo.associating) 70 + goto out; 74 71 mac->associnfo.associating = 0; 75 72 mac->associnfo.bssvalid = 0; 76 - mac->associated = 0; 73 + mac->associnfo.associated = 0; 77 74 78 75 n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid); 79 - spin_unlock_irqrestore(&mac->lock, flags); 80 76 81 77 dprintk(KERN_INFO PFX "assoc request timed out!\n"); 82 78 ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n); 79 + out: 80 + mutex_unlock(&mac->associnfo.mutex); 83 81 } 84 82 85 83 void ··· 91 93 92 94 netif_carrier_off(mac->dev); 93 95 94 - mac->associated = 0; 96 + mac->associnfo.associated = 0; 95 97 mac->associnfo.bssvalid = 0; 96 98 mac->associnfo.associating = 0; 97 99 ieee80211softmac_init_bss(mac); ··· 105 107 { 106 108 struct ieee80211softmac_network *found; 107 109 108 - if (mac->associnfo.bssvalid && mac->associated) { 110 + if (mac->associnfo.bssvalid && mac->associnfo.associated) { 109 111 found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); 110 112 if (found) 111 113 ieee80211softmac_send_mgt_frame(mac, found, IEEE80211_STYPE_DISASSOC, reason); ··· 194 196 int bssvalid; 195 197 unsigned long flags; 196 198 199 + mutex_lock(&mac->associnfo.mutex); 200 + 201 + if (!mac->associnfo.associating) 202 + goto out; 203 + 197 204 /* ieee80211_disassoc might clear this */ 198 205 bssvalid = mac->associnfo.bssvalid; 199 206 200 207 /* meh */ 201 - if (mac->associated) 208 + if (mac->associnfo.associated) 202 209 ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); 203 - 204 - spin_lock_irqsave(&mac->lock, flags); 205 - mac->associnfo.associating = 1; 206 - spin_unlock_irqrestore(&mac->lock, flags); 207 210 208 211 /* try to find the requested network in our list, if we found one already */ 209 212 if (bssvalid || mac->associnfo.bssfixed) ··· 259 260 260 261 if (!found) { 261 262 if (mac->associnfo.scan_retry > 0) { 262 - spin_lock_irqsave(&mac->lock, flags); 263 263 mac->associnfo.scan_retry--; 264 - spin_unlock_irqrestore(&mac->lock, flags); 265 - 264 + 266 265 /* We know of no such network. Let's scan. 267 266 * NB: this also happens if we had no memory to copy the network info... 268 267 * Maybe we can hope to have more memory after scanning finishes ;) ··· 269 272 ieee80211softmac_notify(mac->dev, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, ieee80211softmac_assoc_notify_scan, NULL); 270 273 if (ieee80211softmac_start_scan(mac)) 271 274 dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); 272 - return; 275 + goto out; 273 276 } else { 274 - spin_lock_irqsave(&mac->lock, flags); 275 277 mac->associnfo.associating = 0; 276 - mac->associated = 0; 277 - spin_unlock_irqrestore(&mac->lock, flags); 278 + mac->associnfo.associated = 0; 278 279 279 280 dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); 280 281 /* reset the retry counter for the next user request since we 281 282 * break out and don't reschedule ourselves after this point. */ 282 283 mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; 283 284 ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); 284 - return; 285 + goto out; 285 286 } 286 287 } 287 288 ··· 292 297 /* copy the ESSID for displaying it */ 293 298 mac->associnfo.associate_essid.len = found->essid.len; 294 299 memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1); 295 - 300 + 296 301 /* we found a network! authenticate (if necessary) and associate to it. */ 297 302 if (found->authenticating) { 298 303 dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n"); ··· 300 305 mac->associnfo.assoc_wait = 1; 301 306 ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); 302 307 } 303 - return; 308 + goto out; 304 309 } 305 310 if (!found->authenticated && !found->authenticating) { 306 311 /* This relies on the fact that _auth_req only queues the work, ··· 316 321 mac->associnfo.assoc_wait = 0; 317 322 ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); 318 323 } 319 - return; 324 + goto out; 320 325 } 321 326 /* finally! now we can start associating */ 322 327 mac->associnfo.assoc_wait = 0; 323 328 ieee80211softmac_assoc(mac, found); 329 + 330 + out: 331 + mutex_unlock(&mac->associnfo.mutex); 324 332 } 325 333 326 334 /* call this to do whatever is necessary when we're associated */ ··· 339 341 mac->bssinfo.supported_rates = net->supported_rates; 340 342 ieee80211softmac_recalc_txrates(mac); 341 343 342 - mac->associated = 1; 344 + mac->associnfo.associated = 1; 343 345 344 346 mac->associnfo.short_preamble_available = 345 347 (cap & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0; ··· 419 421 dprintk(KERN_INFO PFX "associating failed (reason: 0x%x)!\n", status); 420 422 mac->associnfo.associating = 0; 421 423 mac->associnfo.bssvalid = 0; 422 - mac->associated = 0; 424 + mac->associnfo.associated = 0; 423 425 ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, network); 424 426 } 425 427
+8 -3
net/ieee80211/softmac/ieee80211softmac_io.c
··· 304 304 2 + /* Auth Transaction Seq */ 305 305 2 + /* Status Code */ 306 306 /* Challenge Text IE */ 307 - is_shared_response ? 0 : 1 + 1 + net->challenge_len 307 + (is_shared_response ? 1 + 1 + net->challenge_len : 0) 308 308 ); 309 309 if (unlikely((*pkt) == NULL)) 310 310 return 0; ··· 475 475 { 476 476 struct ieee80211softmac_device *mac = ieee80211_priv(dev); 477 477 478 - if (mac->associated && memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) 479 - ieee80211softmac_process_erp(mac, network->erp_value); 478 + /* This might race, but we don't really care and it's not worth 479 + * adding heavyweight locking in this fastpath. 480 + */ 481 + if (mac->associnfo.associated) { 482 + if (memcmp(network->bssid, mac->associnfo.bssid, ETH_ALEN) == 0) 483 + ieee80211softmac_process_erp(mac, network->erp_value); 484 + } 480 485 481 486 return 0; 482 487 }
+1
net/ieee80211/softmac/ieee80211softmac_module.c
··· 57 57 INIT_LIST_HEAD(&softmac->network_list); 58 58 INIT_LIST_HEAD(&softmac->events); 59 59 60 + mutex_init(&softmac->associnfo.mutex); 60 61 INIT_WORK(&softmac->associnfo.work, ieee80211softmac_assoc_work, softmac); 61 62 INIT_WORK(&softmac->associnfo.timeout, ieee80211softmac_assoc_timeout, softmac); 62 63 softmac->start_scan = ieee80211softmac_start_scan_implementation;
+44 -27
net/ieee80211/softmac/ieee80211softmac_wx.c
··· 73 73 struct ieee80211softmac_network *n; 74 74 struct ieee80211softmac_auth_queue_item *authptr; 75 75 int length = 0; 76 - unsigned long flags; 76 + 77 + mutex_lock(&sm->associnfo.mutex); 77 78 78 79 /* Check if we're already associating to this or another network 79 80 * If it's another network, cancel and start over with our new network 80 81 * If it's our network, ignore the change, we're already doing it! 81 82 */ 82 - if((sm->associnfo.associating || sm->associated) && 83 + if((sm->associnfo.associating || sm->associnfo.associated) && 83 84 (data->essid.flags && data->essid.length)) { 84 85 /* Get the associating network */ 85 86 n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); ··· 88 87 !memcmp(n->essid.data, extra, n->essid.len)) { 89 88 dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", 90 89 MAC_ARG(sm->associnfo.bssid)); 91 - return 0; 90 + goto out; 92 91 } else { 93 92 dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); 94 - spin_lock_irqsave(&sm->lock,flags); 95 93 /* Cancel assoc work */ 96 94 cancel_delayed_work(&sm->associnfo.work); 97 95 /* We don't have to do this, but it's a little cleaner */ ··· 98 98 cancel_delayed_work(&authptr->work); 99 99 sm->associnfo.bssvalid = 0; 100 100 sm->associnfo.bssfixed = 0; 101 - spin_unlock_irqrestore(&sm->lock,flags); 102 101 flush_scheduled_work(); 102 + sm->associnfo.associating = 0; 103 + sm->associnfo.associated = 0; 103 104 } 104 105 } 105 106 106 - 107 - spin_lock_irqsave(&sm->lock, flags); 108 107 109 108 sm->associnfo.static_essid = 0; 110 109 sm->associnfo.assoc_wait = 0; ··· 120 121 * If applicable, we have already copied the data in */ 121 122 sm->associnfo.req_essid.len = length; 122 123 124 + sm->associnfo.associating = 1; 123 125 /* queue lower level code to do work (if necessary) */ 124 126 schedule_work(&sm->associnfo.work); 127 + out: 128 + mutex_unlock(&sm->associnfo.mutex); 125 129 126 - spin_unlock_irqrestore(&sm->lock, flags); 127 130 return 0; 128 131 } 129 132 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); ··· 137 136 char *extra) 138 137 { 139 138 struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); 140 - unsigned long flags; 141 139 142 - /* avoid getting inconsistent information */ 143 - spin_lock_irqsave(&sm->lock, flags); 140 + mutex_lock(&sm->associnfo.mutex); 144 141 /* If all fails, return ANY (empty) */ 145 142 data->essid.length = 0; 146 143 data->essid.flags = 0; /* active */ ··· 151 152 } 152 153 153 154 /* If we're associating/associated, return that */ 154 - if (sm->associated || sm->associnfo.associating) { 155 + if (sm->associnfo.associated || sm->associnfo.associating) { 155 156 data->essid.length = sm->associnfo.associate_essid.len; 156 157 data->essid.flags = 1; /* active */ 157 158 memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); 158 159 } 159 - spin_unlock_irqrestore(&sm->lock, flags); 160 + mutex_unlock(&sm->associnfo.mutex); 161 + 160 162 return 0; 161 163 } 162 164 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); ··· 322 322 { 323 323 struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); 324 324 int err = 0; 325 - unsigned long flags; 326 325 327 - spin_lock_irqsave(&mac->lock, flags); 326 + mutex_lock(&mac->associnfo.mutex); 328 327 if (mac->associnfo.bssvalid) 329 328 memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); 330 329 else 331 330 memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); 332 331 data->ap_addr.sa_family = ARPHRD_ETHER; 333 - spin_unlock_irqrestore(&mac->lock, flags); 332 + mutex_unlock(&mac->associnfo.mutex); 333 + 334 334 return err; 335 335 } 336 336 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); ··· 342 342 char *extra) 343 343 { 344 344 struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); 345 - unsigned long flags; 346 345 347 346 /* sanity check */ 348 347 if (data->ap_addr.sa_family != ARPHRD_ETHER) { 349 348 return -EINVAL; 350 349 } 351 350 352 - spin_lock_irqsave(&mac->lock, flags); 351 + mutex_lock(&mac->associnfo.mutex); 353 352 if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { 354 353 /* the bssid we have is not to be fixed any longer, 355 354 * and we should reassociate to the best AP. */ 356 355 mac->associnfo.bssfixed = 0; 357 356 /* force reassociation */ 358 357 mac->associnfo.bssvalid = 0; 359 - if (mac->associated) 358 + if (mac->associnfo.associated) 360 359 schedule_work(&mac->associnfo.work); 361 360 } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { 362 361 /* the bssid we have is no longer fixed */ 363 362 mac->associnfo.bssfixed = 0; 364 363 } else { 365 364 if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { 366 - if (mac->associnfo.associating || mac->associated) { 365 + if (mac->associnfo.associating || mac->associnfo.associated) { 367 366 /* bssid unchanged and associated or associating - just return */ 368 367 goto out; 369 368 } ··· 377 378 } 378 379 379 380 out: 380 - spin_unlock_irqrestore(&mac->lock, flags); 381 + mutex_unlock(&mac->associnfo.mutex); 382 + 381 383 return 0; 382 384 } 383 385 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); ··· 394 394 int err = 0; 395 395 char *buf; 396 396 int i; 397 - 397 + 398 + mutex_lock(&mac->associnfo.mutex); 398 399 spin_lock_irqsave(&mac->lock, flags); 399 400 /* bleh. shouldn't be locked for that kmalloc... */ 400 401 ··· 433 432 434 433 out: 435 434 spin_unlock_irqrestore(&mac->lock, flags); 435 + mutex_unlock(&mac->associnfo.mutex); 436 + 436 437 return err; 437 438 } 438 439 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); ··· 449 446 unsigned long flags; 450 447 int err = 0; 451 448 int space = wrqu->data.length; 452 - 449 + 450 + mutex_lock(&mac->associnfo.mutex); 453 451 spin_lock_irqsave(&mac->lock, flags); 454 452 455 453 wrqu->data.length = 0; ··· 463 459 err = -E2BIG; 464 460 } 465 461 spin_unlock_irqrestore(&mac->lock, flags); 462 + mutex_lock(&mac->associnfo.mutex); 463 + 466 464 return err; 467 465 } 468 466 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); ··· 479 473 struct iw_mlme *mlme = (struct iw_mlme *)extra; 480 474 u16 reason = cpu_to_le16(mlme->reason_code); 481 475 struct ieee80211softmac_network *net; 476 + int err = -EINVAL; 477 + 478 + mutex_lock(&mac->associnfo.mutex); 482 479 483 480 if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { 484 481 printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); 485 - return -EINVAL; 482 + goto out; 486 483 } 487 484 488 485 switch (mlme->cmd) { ··· 493 484 net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); 494 485 if (!net) { 495 486 printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); 496 - return -EINVAL; 487 + goto out; 497 488 } 498 489 return ieee80211softmac_deauth_req(mac, net, reason); 499 490 case IW_MLME_DISASSOC: 500 491 ieee80211softmac_send_disassoc_req(mac, reason); 501 - return 0; 492 + mac->associnfo.associated = 0; 493 + mac->associnfo.associating = 0; 494 + err = 0; 495 + goto out; 502 496 default: 503 - return -EOPNOTSUPP; 497 + err = -EOPNOTSUPP; 504 498 } 499 + 500 + out: 501 + mutex_unlock(&mac->associnfo.mutex); 502 + 503 + return err; 505 504 } 506 505 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);