···204204205205 /* couple of flags */206206 u8 scanning:1, /* protects scanning from being done multiple times at once */207207- associated:1;207207+ associated:1,208208+ running:1;208209209210 struct ieee80211softmac_scaninfo *scaninfo;210211 struct ieee80211softmac_assoc_info associnfo;
+15-2
net/ieee80211/softmac/ieee80211softmac_assoc.c
···5151 spin_lock_irqsave(&mac->lock, flags);5252 mac->associnfo.associating = 1;5353 mac->associated = 0; /* just to make sure */5454- spin_unlock_irqrestore(&mac->lock, flags);55545655 /* Set a timer for timeout */5756 /* FIXME: make timeout configurable */5858- schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ);5757+ if (likely(mac->running))5858+ schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ);5959+ spin_unlock_irqrestore(&mac->lock, flags);5960}60616162void···320319 u16 status = le16_to_cpup(&resp->status);321320 struct ieee80211softmac_network *network = NULL;322321 unsigned long flags;322322+323323+ if (unlikely(!mac->running))324324+ return -ENODEV;323325324326 spin_lock_irqsave(&mac->lock, flags);325327···381377{382378 struct ieee80211softmac_device *mac = ieee80211_priv(dev);383379 unsigned long flags;380380+381381+ if (unlikely(!mac->running))382382+ return -ENODEV;383383+384384 if (memcmp(disassoc->header.addr2, mac->associnfo.bssid, ETH_ALEN))385385 return 0;386386+386387 if (memcmp(disassoc->header.addr1, mac->dev->dev_addr, ETH_ALEN))387388 return 0;389389+388390 dprintk(KERN_INFO PFX "got disassoc frame\n");389391 netif_carrier_off(dev);390392 spin_lock_irqsave(&mac->lock, flags);···409399{410400 struct ieee80211softmac_device *mac = ieee80211_priv(dev);411401 struct ieee80211softmac_network *network;402402+403403+ if (unlikely(!mac->running))404404+ return -ENODEV;412405413406 network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3);414407 if (!network) {
+14-2
net/ieee80211/softmac/ieee80211softmac_auth.c
···86868787 /* Lock and set flags */8888 spin_lock_irqsave(&mac->lock, flags);8989+ if (unlikely(!mac->running)) {9090+ /* Prevent reschedule on workqueue flush */9191+ spin_unlock_irqrestore(&mac->lock, flags);9292+ return;9393+ }8994 net->authenticated = 0;9095 net->authenticating = 1;9196 /* add a timeout call so we eventually give up waiting for an auth reply */···129124 unsigned long flags;130125 u8 * data;131126127127+ if (unlikely(!mac->running))128128+ return -ENODEV;129129+132130 /* Find correct auth queue item */133131 spin_lock_irqsave(&mac->lock, flags);134132 list_for_each(list_ptr, &mac->auth_queue) {···306298307299 /* can't transmit data right now... */308300 netif_carrier_off(mac->dev);309309- /* let's try to re-associate */310310- schedule_work(&mac->associnfo.work);311301 spin_unlock_irqrestore(&mac->lock, flags);312302}313303···344338 struct ieee80211softmac_network *net = NULL;345339 struct ieee80211softmac_device *mac = ieee80211_priv(dev);346340341341+ if (unlikely(!mac->running))342342+ return -ENODEV;343343+347344 if (!deauth) {348345 dprintk("deauth without deauth packet. eek!\n");349346 return 0;···369360 }370361371362 ieee80211softmac_deauth_from_net(mac, net);363363+364364+ /* let's try to re-associate */365365+ schedule_work(&mac->associnfo.work);372366 return 0;373367}
+4
net/ieee80211/softmac/ieee80211softmac_module.c
···8989 ieee80211softmac_wait_for_scan(sm);90909191 spin_lock_irqsave(&sm->lock, flags);9292+ sm->running = 0;9393+9294 /* Free all pending assoc work items */9395 cancel_delayed_work(&sm->associnfo.work);9496···206204 assert(0);207205 if (mac->txrates_change)208206 mac->txrates_change(dev, change, &oldrates);207207+208208+ mac->running = 1;209209}210210EXPORT_SYMBOL_GPL(ieee80211softmac_start);211211
+8
net/ieee80211/softmac/ieee80211softmac_scan.c
···115115 // TODO: is this if correct, or should we do this only if scanning from assoc request?116116 if (sm->associnfo.req_essid.len)117117 ieee80211softmac_send_mgt_frame(sm, &sm->associnfo.req_essid, IEEE80211_STYPE_PROBE_REQ, 0);118118+119119+ spin_lock_irqsave(&sm->lock, flags);120120+ if (unlikely(!sm->running)) {121121+ /* Prevent reschedule on workqueue flush */122122+ spin_unlock_irqrestore(&sm->lock, flags);123123+ break;124124+ }118125 schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);126126+ spin_unlock_irqrestore(&sm->lock, flags);119127 return;120128 } else {121129 dprintk(PFX "Not probing Channel %d (not allowed here)\n", si->channels[current_channel_idx].channel);