summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/net/ieee80211softmac.h3
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c17
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_auth.c11
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_module.c4
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_scan.c8
5 files changed, 40 insertions, 3 deletions
diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h
index b1ebfbae397f..052ed596a4e4 100644
--- a/include/net/ieee80211softmac.h
+++ b/include/net/ieee80211softmac.h
@@ -204,7 +204,8 @@ struct ieee80211softmac_device {
/* couple of flags */
u8 scanning:1, /* protects scanning from being done multiple times at once */
- associated:1;
+ associated:1,
+ running:1;
struct ieee80211softmac_scaninfo *scaninfo;
struct ieee80211softmac_assoc_info associnfo;
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index fb79ce7d6439..57ea9f6f465c 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -51,11 +51,12 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft
spin_lock_irqsave(&mac->lock, flags);
mac->associnfo.associating = 1;
mac->associated = 0; /* just to make sure */
- spin_unlock_irqrestore(&mac->lock, flags);
/* Set a timer for timeout */
/* FIXME: make timeout configurable */
- schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ);
+ if (likely(mac->running))
+ schedule_delayed_work(&mac->associnfo.timeout, 5 * HZ);
+ spin_unlock_irqrestore(&mac->lock, flags);
}
void
@@ -319,6 +320,9 @@ ieee80211softmac_handle_assoc_response(struct net_device * dev,
u16 status = le16_to_cpup(&resp->status);
struct ieee80211softmac_network *network = NULL;
unsigned long flags;
+
+ if (unlikely(!mac->running))
+ return -ENODEV;
spin_lock_irqsave(&mac->lock, flags);
@@ -377,10 +381,16 @@ ieee80211softmac_handle_disassoc(struct net_device * dev,
{
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
unsigned long flags;
+
+ if (unlikely(!mac->running))
+ return -ENODEV;
+
if (memcmp(disassoc->header.addr2, mac->associnfo.bssid, ETH_ALEN))
return 0;
+
if (memcmp(disassoc->header.addr1, mac->dev->dev_addr, ETH_ALEN))
return 0;
+
dprintk(KERN_INFO PFX "got disassoc frame\n");
netif_carrier_off(dev);
spin_lock_irqsave(&mac->lock, flags);
@@ -400,6 +410,9 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev,
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
struct ieee80211softmac_network *network;
+ if (unlikely(!mac->running))
+ return -ENODEV;
+
network = ieee80211softmac_get_network_by_bssid(mac, resp->header.addr3);
if (!network) {
dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c
index d6a04f3ab86c..06e332624665 100644
--- a/net/ieee80211/softmac/ieee80211softmac_auth.c
+++ b/net/ieee80211/softmac/ieee80211softmac_auth.c
@@ -86,6 +86,11 @@ ieee80211softmac_auth_queue(void *data)
/* Lock and set flags */
spin_lock_irqsave(&mac->lock, flags);
+ if (unlikely(!mac->running)) {
+ /* Prevent reschedule on workqueue flush */
+ spin_unlock_irqrestore(&mac->lock, flags);
+ return;
+ }
net->authenticated = 0;
net->authenticating = 1;
/* add a timeout call so we eventually give up waiting for an auth reply */
@@ -124,6 +129,9 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
unsigned long flags;
u8 * data;
+ if (unlikely(!mac->running))
+ return -ENODEV;
+
/* Find correct auth queue item */
spin_lock_irqsave(&mac->lock, flags);
list_for_each(list_ptr, &mac->auth_queue) {
@@ -336,6 +344,9 @@ ieee80211softmac_deauth_resp(struct net_device *dev, struct ieee80211_deauth *de
struct ieee80211softmac_network *net = NULL;
struct ieee80211softmac_device *mac = ieee80211_priv(dev);
+ if (unlikely(!mac->running))
+ return -ENODEV;
+
if (!deauth) {
dprintk("deauth without deauth packet. eek!\n");
return 0;
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c
index be83bdc1644a..6252be2c0db9 100644
--- a/net/ieee80211/softmac/ieee80211softmac_module.c
+++ b/net/ieee80211/softmac/ieee80211softmac_module.c
@@ -89,6 +89,8 @@ ieee80211softmac_clear_pending_work(struct ieee80211softmac_device *sm)
ieee80211softmac_wait_for_scan(sm);
spin_lock_irqsave(&sm->lock, flags);
+ sm->running = 0;
+
/* Free all pending assoc work items */
cancel_delayed_work(&sm->associnfo.work);
@@ -204,6 +206,8 @@ void ieee80211softmac_start(struct net_device *dev)
assert(0);
if (mac->txrates_change)
mac->txrates_change(dev, change, &oldrates);
+
+ mac->running = 1;
}
EXPORT_SYMBOL_GPL(ieee80211softmac_start);
diff --git a/net/ieee80211/softmac/ieee80211softmac_scan.c b/net/ieee80211/softmac/ieee80211softmac_scan.c
index 2b9e7edfa3ce..d31cf77498c4 100644
--- a/net/ieee80211/softmac/ieee80211softmac_scan.c
+++ b/net/ieee80211/softmac/ieee80211softmac_scan.c
@@ -115,7 +115,15 @@ void ieee80211softmac_scan(void *d)
// TODO: is this if correct, or should we do this only if scanning from assoc request?
if (sm->associnfo.req_essid.len)
ieee80211softmac_send_mgt_frame(sm, &sm->associnfo.req_essid, IEEE80211_STYPE_PROBE_REQ, 0);
+
+ spin_lock_irqsave(&sm->lock, flags);
+ if (unlikely(!sm->running)) {
+ /* Prevent reschedule on workqueue flush */
+ spin_unlock_irqrestore(&sm->lock, flags);
+ break;
+ }
schedule_delayed_work(&si->softmac_scan, IEEE80211SOFTMAC_PROBE_DELAY);
+ spin_unlock_irqrestore(&sm->lock, flags);
return;
} else {
dprintk(PFX "Not probing Channel %d (not allowed here)\n", si->channels[current_channel_idx].channel);