aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211')
-rw-r--r--net/ieee80211/Kconfig1
-rw-r--r--net/ieee80211/ieee80211_crypt.c3
-rw-r--r--net/ieee80211/ieee80211_crypt_ccmp.c3
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c3
-rw-r--r--net/ieee80211/ieee80211_rx.c4
-rw-r--r--net/ieee80211/ieee80211_tx.c15
-rw-r--r--net/ieee80211/ieee80211_wx.c7
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_assoc.c31
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_auth.c32
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_io.c6
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c36
11 files changed, 106 insertions, 35 deletions
diff --git a/net/ieee80211/Kconfig b/net/ieee80211/Kconfig
index dbb08528ddf5..f7e84e9d13ad 100644
--- a/net/ieee80211/Kconfig
+++ b/net/ieee80211/Kconfig
@@ -58,6 +58,7 @@ config IEEE80211_CRYPT_TKIP
58 depends on IEEE80211 && NET_RADIO 58 depends on IEEE80211 && NET_RADIO
59 select CRYPTO 59 select CRYPTO
60 select CRYPTO_MICHAEL_MIC 60 select CRYPTO_MICHAEL_MIC
61 select CRC32
61 ---help--- 62 ---help---
62 Include software based cipher suites in support of IEEE 802.11i 63 Include software based cipher suites in support of IEEE 802.11i
63 (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled 64 (aka TGi, WPA, WPA2, WPA-PSK, etc.) for use with TKIP enabled
diff --git a/net/ieee80211/ieee80211_crypt.c b/net/ieee80211/ieee80211_crypt.c
index cb71d794a7d1..5ed0a98b2d76 100644
--- a/net/ieee80211/ieee80211_crypt.c
+++ b/net/ieee80211/ieee80211_crypt.c
@@ -110,11 +110,10 @@ int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
110 unsigned long flags; 110 unsigned long flags;
111 struct ieee80211_crypto_alg *alg; 111 struct ieee80211_crypto_alg *alg;
112 112
113 alg = kmalloc(sizeof(*alg), GFP_KERNEL); 113 alg = kzalloc(sizeof(*alg), GFP_KERNEL);
114 if (alg == NULL) 114 if (alg == NULL)
115 return -ENOMEM; 115 return -ENOMEM;
116 116
117 memset(alg, 0, sizeof(*alg));
118 alg->ops = ops; 117 alg->ops = ops;
119 118
120 spin_lock_irqsave(&ieee80211_crypto_lock, flags); 119 spin_lock_irqsave(&ieee80211_crypto_lock, flags);
diff --git a/net/ieee80211/ieee80211_crypt_ccmp.c b/net/ieee80211/ieee80211_crypt_ccmp.c
index 492647382ad0..ed90a8af1444 100644
--- a/net/ieee80211/ieee80211_crypt_ccmp.c
+++ b/net/ieee80211/ieee80211_crypt_ccmp.c
@@ -76,10 +76,9 @@ static void *ieee80211_ccmp_init(int key_idx)
76{ 76{
77 struct ieee80211_ccmp_data *priv; 77 struct ieee80211_ccmp_data *priv;
78 78
79 priv = kmalloc(sizeof(*priv), GFP_ATOMIC); 79 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
80 if (priv == NULL) 80 if (priv == NULL)
81 goto fail; 81 goto fail;
82 memset(priv, 0, sizeof(*priv));
83 priv->key_idx = key_idx; 82 priv->key_idx = key_idx;
84 83
85 priv->tfm = crypto_alloc_tfm("aes", 0); 84 priv->tfm = crypto_alloc_tfm("aes", 0);
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index c5a87724aabe..0ebf235f6939 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -39,10 +39,9 @@ static void *prism2_wep_init(int keyidx)
39{ 39{
40 struct prism2_wep_data *priv; 40 struct prism2_wep_data *priv;
41 41
42 priv = kmalloc(sizeof(*priv), GFP_ATOMIC); 42 priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
43 if (priv == NULL) 43 if (priv == NULL)
44 goto fail; 44 goto fail;
45 memset(priv, 0, sizeof(*priv));
46 priv->key_idx = keyidx; 45 priv->key_idx = keyidx;
47 46
48 priv->tfm = crypto_alloc_tfm("arc4", 0); 47 priv->tfm = crypto_alloc_tfm("arc4", 0);
diff --git a/net/ieee80211/ieee80211_rx.c b/net/ieee80211/ieee80211_rx.c
index 47ccf159372c..72d4d4e04d42 100644
--- a/net/ieee80211/ieee80211_rx.c
+++ b/net/ieee80211/ieee80211_rx.c
@@ -368,6 +368,7 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
368 368
369 /* Put this code here so that we avoid duplicating it in all 369 /* Put this code here so that we avoid duplicating it in all
370 * Rx paths. - Jean II */ 370 * Rx paths. - Jean II */
371#ifdef CONFIG_WIRELESS_EXT
371#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */ 372#ifdef IW_WIRELESS_SPY /* defined in iw_handler.h */
372 /* If spy monitoring on */ 373 /* If spy monitoring on */
373 if (ieee->spy_data.spy_number > 0) { 374 if (ieee->spy_data.spy_number > 0) {
@@ -396,15 +397,16 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
396 wireless_spy_update(ieee->dev, hdr->addr2, &wstats); 397 wireless_spy_update(ieee->dev, hdr->addr2, &wstats);
397 } 398 }
398#endif /* IW_WIRELESS_SPY */ 399#endif /* IW_WIRELESS_SPY */
400#endif /* CONFIG_WIRELESS_EXT */
399 401
400#ifdef NOT_YET 402#ifdef NOT_YET
401 hostap_update_rx_stats(local->ap, hdr, rx_stats); 403 hostap_update_rx_stats(local->ap, hdr, rx_stats);
402#endif 404#endif
403 405
404 if (ieee->iw_mode == IW_MODE_MONITOR) { 406 if (ieee->iw_mode == IW_MODE_MONITOR) {
405 ieee80211_monitor_rx(ieee, skb, rx_stats);
406 stats->rx_packets++; 407 stats->rx_packets++;
407 stats->rx_bytes += skb->len; 408 stats->rx_bytes += skb->len;
409 ieee80211_monitor_rx(ieee, skb, rx_stats);
408 return 1; 410 return 1;
409 } 411 }
410 412
diff --git a/net/ieee80211/ieee80211_tx.c b/net/ieee80211/ieee80211_tx.c
index de148ae594f3..bf042139c7ab 100644
--- a/net/ieee80211/ieee80211_tx.c
+++ b/net/ieee80211/ieee80211_tx.c
@@ -562,10 +562,13 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee,
562 struct net_device_stats *stats = &ieee->stats; 562 struct net_device_stats *stats = &ieee->stats;
563 struct sk_buff *skb_frag; 563 struct sk_buff *skb_frag;
564 int priority = -1; 564 int priority = -1;
565 int fraglen = total_len;
566 int headroom = ieee->tx_headroom;
567 struct ieee80211_crypt_data *crypt = ieee->crypt[ieee->tx_keyidx];
565 568
566 spin_lock_irqsave(&ieee->lock, flags); 569 spin_lock_irqsave(&ieee->lock, flags);
567 570
568 if (encrypt_mpdu && !ieee->sec.encrypt) 571 if (encrypt_mpdu && (!ieee->sec.encrypt || !crypt))
569 encrypt_mpdu = 0; 572 encrypt_mpdu = 0;
570 573
571 /* If there is no driver handler to take the TXB, dont' bother 574 /* If there is no driver handler to take the TXB, dont' bother
@@ -581,20 +584,24 @@ int ieee80211_tx_frame(struct ieee80211_device *ieee,
581 goto success; 584 goto success;
582 } 585 }
583 586
584 if (encrypt_mpdu) 587 if (encrypt_mpdu) {
585 frame->frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); 588 frame->frame_ctl |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
589 fraglen += crypt->ops->extra_mpdu_prefix_len +
590 crypt->ops->extra_mpdu_postfix_len;
591 headroom += crypt->ops->extra_mpdu_prefix_len;
592 }
586 593
587 /* When we allocate the TXB we allocate enough space for the reserve 594 /* When we allocate the TXB we allocate enough space for the reserve
588 * and full fragment bytes (bytes_per_frag doesn't include prefix, 595 * and full fragment bytes (bytes_per_frag doesn't include prefix,
589 * postfix, header, FCS, etc.) */ 596 * postfix, header, FCS, etc.) */
590 txb = ieee80211_alloc_txb(1, total_len, ieee->tx_headroom, GFP_ATOMIC); 597 txb = ieee80211_alloc_txb(1, fraglen, headroom, GFP_ATOMIC);
591 if (unlikely(!txb)) { 598 if (unlikely(!txb)) {
592 printk(KERN_WARNING "%s: Could not allocate TXB\n", 599 printk(KERN_WARNING "%s: Could not allocate TXB\n",
593 ieee->dev->name); 600 ieee->dev->name);
594 goto failed; 601 goto failed;
595 } 602 }
596 txb->encrypted = 0; 603 txb->encrypted = 0;
597 txb->payload_size = total_len; 604 txb->payload_size = fraglen;
598 605
599 skb_frag = txb->fragments[0]; 606 skb_frag = txb->fragments[0];
600 607
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index a78c4f845f66..5cb9cfd35397 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -369,11 +369,10 @@ int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
369 struct ieee80211_crypt_data *new_crypt; 369 struct ieee80211_crypt_data *new_crypt;
370 370
371 /* take WEP into use */ 371 /* take WEP into use */
372 new_crypt = kmalloc(sizeof(struct ieee80211_crypt_data), 372 new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
373 GFP_KERNEL); 373 GFP_KERNEL);
374 if (new_crypt == NULL) 374 if (new_crypt == NULL)
375 return -ENOMEM; 375 return -ENOMEM;
376 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
377 new_crypt->ops = ieee80211_get_crypto_ops("WEP"); 376 new_crypt->ops = ieee80211_get_crypto_ops("WEP");
378 if (!new_crypt->ops) { 377 if (!new_crypt->ops) {
379 request_module("ieee80211_crypt_wep"); 378 request_module("ieee80211_crypt_wep");
@@ -616,13 +615,11 @@ int ieee80211_wx_set_encodeext(struct ieee80211_device *ieee,
616 615
617 ieee80211_crypt_delayed_deinit(ieee, crypt); 616 ieee80211_crypt_delayed_deinit(ieee, crypt);
618 617
619 new_crypt = (struct ieee80211_crypt_data *) 618 new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
620 kmalloc(sizeof(*new_crypt), GFP_KERNEL);
621 if (new_crypt == NULL) { 619 if (new_crypt == NULL) {
622 ret = -ENOMEM; 620 ret = -ENOMEM;
623 goto done; 621 goto done;
624 } 622 }
625 memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
626 new_crypt->ops = ops; 623 new_crypt->ops = ops;
627 if (new_crypt->ops && try_module_get(new_crypt->ops->owner)) 624 if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
628 new_crypt->priv = new_crypt->ops->init(idx); 625 new_crypt->priv = new_crypt->ops->init(idx);
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c
index 5e9a90651d04..44215ce64d4e 100644
--- a/net/ieee80211/softmac/ieee80211softmac_assoc.c
+++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c
@@ -47,9 +47,7 @@ ieee80211softmac_assoc(struct ieee80211softmac_device *mac, struct ieee80211soft
47 47
48 dprintk(KERN_INFO PFX "sent association request!\n"); 48 dprintk(KERN_INFO PFX "sent association request!\n");
49 49
50 /* Change the state to associating */
51 spin_lock_irqsave(&mac->lock, flags); 50 spin_lock_irqsave(&mac->lock, flags);
52 mac->associnfo.associating = 1;
53 mac->associated = 0; /* just to make sure */ 51 mac->associated = 0; /* just to make sure */
54 52
55 /* Set a timer for timeout */ 53 /* Set a timer for timeout */
@@ -63,6 +61,7 @@ void
63ieee80211softmac_assoc_timeout(void *d) 61ieee80211softmac_assoc_timeout(void *d)
64{ 62{
65 struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d; 63 struct ieee80211softmac_device *mac = (struct ieee80211softmac_device *)d;
64 struct ieee80211softmac_network *n;
66 unsigned long flags; 65 unsigned long flags;
67 66
68 spin_lock_irqsave(&mac->lock, flags); 67 spin_lock_irqsave(&mac->lock, flags);
@@ -75,11 +74,12 @@ ieee80211softmac_assoc_timeout(void *d)
75 mac->associnfo.associating = 0; 74 mac->associnfo.associating = 0;
76 mac->associnfo.bssvalid = 0; 75 mac->associnfo.bssvalid = 0;
77 mac->associated = 0; 76 mac->associated = 0;
77
78 n = ieee80211softmac_get_network_by_bssid_locked(mac, mac->associnfo.bssid);
78 spin_unlock_irqrestore(&mac->lock, flags); 79 spin_unlock_irqrestore(&mac->lock, flags);
79 80
80 dprintk(KERN_INFO PFX "assoc request timed out!\n"); 81 dprintk(KERN_INFO PFX "assoc request timed out!\n");
81 /* FIXME: we need to know the network here. that requires a bit of restructuring */ 82 ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, n);
82 ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_TIMEOUT, NULL);
83} 83}
84 84
85void 85void
@@ -203,6 +203,10 @@ ieee80211softmac_assoc_work(void *d)
203 if (mac->associated) 203 if (mac->associated)
204 ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); 204 ieee80211softmac_send_disassoc_req(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
205 205
206 spin_lock_irqsave(&mac->lock, flags);
207 mac->associnfo.associating = 1;
208 spin_unlock_irqrestore(&mac->lock, flags);
209
206 /* try to find the requested network in our list, if we found one already */ 210 /* try to find the requested network in our list, if we found one already */
207 if (bssvalid || mac->associnfo.bssfixed) 211 if (bssvalid || mac->associnfo.bssfixed)
208 found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); 212 found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid);
@@ -295,19 +299,32 @@ ieee80211softmac_assoc_work(void *d)
295 memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1); 299 memcpy(mac->associnfo.associate_essid.data, found->essid.data, IW_ESSID_MAX_SIZE + 1);
296 300
297 /* we found a network! authenticate (if necessary) and associate to it. */ 301 /* we found a network! authenticate (if necessary) and associate to it. */
298 if (!found->authenticated) { 302 if (found->authenticating) {
303 dprintk(KERN_INFO PFX "Already requested authentication, waiting...\n");
304 if(!mac->associnfo.assoc_wait) {
305 mac->associnfo.assoc_wait = 1;
306 ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
307 }
308 return;
309 }
310 if (!found->authenticated && !found->authenticating) {
299 /* This relies on the fact that _auth_req only queues the work, 311 /* This relies on the fact that _auth_req only queues the work,
300 * otherwise adding the notification would be racy. */ 312 * otherwise adding the notification would be racy. */
301 if (!ieee80211softmac_auth_req(mac, found)) { 313 if (!ieee80211softmac_auth_req(mac, found)) {
302 dprintk(KERN_INFO PFX "cannot associate without being authenticated, requested authentication\n"); 314 if(!mac->associnfo.assoc_wait) {
303 ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL); 315 dprintk(KERN_INFO PFX "Cannot associate without being authenticated, requested authentication\n");
316 mac->associnfo.assoc_wait = 1;
317 ieee80211softmac_notify_internal(mac, IEEE80211SOFTMAC_EVENT_ANY, found, ieee80211softmac_assoc_notify_auth, NULL, GFP_KERNEL);
318 }
304 } else { 319 } else {
305 printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n"); 320 printkl(KERN_WARNING PFX "Not authenticated, but requesting authentication failed. Giving up to associate\n");
321 mac->associnfo.assoc_wait = 0;
306 ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found); 322 ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_FAILED, found);
307 } 323 }
308 return; 324 return;
309 } 325 }
310 /* finally! now we can start associating */ 326 /* finally! now we can start associating */
327 mac->associnfo.assoc_wait = 0;
311 ieee80211softmac_assoc(mac, found); 328 ieee80211softmac_assoc(mac, found);
312} 329}
313 330
diff --git a/net/ieee80211/softmac/ieee80211softmac_auth.c b/net/ieee80211/softmac/ieee80211softmac_auth.c
index 90b8484e509b..4cef39e171d0 100644
--- a/net/ieee80211/softmac/ieee80211softmac_auth.c
+++ b/net/ieee80211/softmac/ieee80211softmac_auth.c
@@ -36,8 +36,9 @@ ieee80211softmac_auth_req(struct ieee80211softmac_device *mac,
36 struct ieee80211softmac_auth_queue_item *auth; 36 struct ieee80211softmac_auth_queue_item *auth;
37 unsigned long flags; 37 unsigned long flags;
38 38
39 if (net->authenticating) 39 if (net->authenticating || net->authenticated)
40 return 0; 40 return 0;
41 net->authenticating = 1;
41 42
42 /* Add the network if it's not already added */ 43 /* Add the network if it's not already added */
43 ieee80211softmac_add_network(mac, net); 44 ieee80211softmac_add_network(mac, net);
@@ -92,7 +93,6 @@ ieee80211softmac_auth_queue(void *data)
92 return; 93 return;
93 } 94 }
94 net->authenticated = 0; 95 net->authenticated = 0;
95 net->authenticating = 1;
96 /* add a timeout call so we eventually give up waiting for an auth reply */ 96 /* add a timeout call so we eventually give up waiting for an auth reply */
97 schedule_delayed_work(&auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT); 97 schedule_delayed_work(&auth->work, IEEE80211SOFTMAC_AUTH_TIMEOUT);
98 auth->retry--; 98 auth->retry--;
@@ -116,6 +116,16 @@ ieee80211softmac_auth_queue(void *data)
116 kfree(auth); 116 kfree(auth);
117} 117}
118 118
119/* Sends a response to an auth challenge (for shared key auth). */
120static void
121ieee80211softmac_auth_challenge_response(void *_aq)
122{
123 struct ieee80211softmac_auth_queue_item *aq = _aq;
124
125 /* Send our response */
126 ieee80211softmac_send_mgt_frame(aq->mac, aq->net, IEEE80211_STYPE_AUTH, aq->state);
127}
128
119/* Handle the auth response from the AP 129/* Handle the auth response from the AP
120 * This should be registered with ieee80211 as handle_auth 130 * This should be registered with ieee80211 as handle_auth
121 */ 131 */
@@ -197,24 +207,30 @@ ieee80211softmac_auth_resp(struct net_device *dev, struct ieee80211_auth *auth)
197 case IEEE80211SOFTMAC_AUTH_SHARED_CHALLENGE: 207 case IEEE80211SOFTMAC_AUTH_SHARED_CHALLENGE:
198 /* Check to make sure we have a challenge IE */ 208 /* Check to make sure we have a challenge IE */
199 data = (u8 *)auth->info_element; 209 data = (u8 *)auth->info_element;
200 if(*data++ != MFIE_TYPE_CHALLENGE){ 210 if (*data++ != MFIE_TYPE_CHALLENGE) {
201 printkl(KERN_NOTICE PFX "Shared Key Authentication failed due to a missing challenge.\n"); 211 printkl(KERN_NOTICE PFX "Shared Key Authentication failed due to a missing challenge.\n");
202 break; 212 break;
203 } 213 }
204 /* Save the challenge */ 214 /* Save the challenge */
205 spin_lock_irqsave(&mac->lock, flags); 215 spin_lock_irqsave(&mac->lock, flags);
206 net->challenge_len = *data++; 216 net->challenge_len = *data++;
207 if(net->challenge_len > WLAN_AUTH_CHALLENGE_LEN) 217 if (net->challenge_len > WLAN_AUTH_CHALLENGE_LEN)
208 net->challenge_len = WLAN_AUTH_CHALLENGE_LEN; 218 net->challenge_len = WLAN_AUTH_CHALLENGE_LEN;
209 if(net->challenge != NULL) 219 if (net->challenge != NULL)
210 kfree(net->challenge); 220 kfree(net->challenge);
211 net->challenge = kmalloc(net->challenge_len, GFP_ATOMIC); 221 net->challenge = kmalloc(net->challenge_len, GFP_ATOMIC);
212 memcpy(net->challenge, data, net->challenge_len); 222 memcpy(net->challenge, data, net->challenge_len);
213 aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE; 223 aq->state = IEEE80211SOFTMAC_AUTH_SHARED_RESPONSE;
214 spin_unlock_irqrestore(&mac->lock, flags);
215 224
216 /* Send our response */ 225 /* We reuse the work struct from the auth request here.
217 ieee80211softmac_send_mgt_frame(mac, aq->net, IEEE80211_STYPE_AUTH, aq->state); 226 * It is safe to do so as each one is per-request, and
227 * at this point (dealing with authentication response)
228 * we have obviously already sent the initial auth
229 * request. */
230 cancel_delayed_work(&aq->work);
231 INIT_WORK(&aq->work, &ieee80211softmac_auth_challenge_response, (void *)aq);
232 schedule_work(&aq->work);
233 spin_unlock_irqrestore(&mac->lock, flags);
218 return 0; 234 return 0;
219 case IEEE80211SOFTMAC_AUTH_SHARED_PASS: 235 case IEEE80211SOFTMAC_AUTH_SHARED_PASS:
220 kfree(net->challenge); 236 kfree(net->challenge);
diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c
index 09541611e48c..6ae5a1dc7956 100644
--- a/net/ieee80211/softmac/ieee80211softmac_io.c
+++ b/net/ieee80211/softmac/ieee80211softmac_io.c
@@ -96,8 +96,7 @@ ieee80211softmac_alloc_mgt(u32 size)
96 if(size > IEEE80211_DATA_LEN) 96 if(size > IEEE80211_DATA_LEN)
97 return NULL; 97 return NULL;
98 /* Allocate the frame */ 98 /* Allocate the frame */
99 data = kmalloc(size, GFP_ATOMIC); 99 data = kzalloc(size, GFP_ATOMIC);
100 memset(data, 0, size);
101 return data; 100 return data;
102} 101}
103 102
@@ -229,6 +228,9 @@ ieee80211softmac_assoc_req(struct ieee80211_assoc_request **pkt,
229 return 0; 228 return 0;
230 ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid); 229 ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid);
231 230
231 /* Fill in the capabilities */
232 (*pkt)->capability = ieee80211softmac_capabilities(mac, net);
233
232 /* Fill in Listen Interval (?) */ 234 /* Fill in Listen Interval (?) */
233 (*pkt)->listen_interval = cpu_to_le16(10); 235 (*pkt)->listen_interval = cpu_to_le16(10);
234 236
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index 0e65ff4e33fc..75320b6842ab 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -70,12 +70,44 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
70 char *extra) 70 char *extra)
71{ 71{
72 struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); 72 struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
73 struct ieee80211softmac_network *n;
74 struct ieee80211softmac_auth_queue_item *authptr;
73 int length = 0; 75 int length = 0;
74 unsigned long flags; 76 unsigned long flags;
75 77
78 /* Check if we're already associating to this or another network
79 * If it's another network, cancel and start over with our new network
80 * If it's our network, ignore the change, we're already doing it!
81 */
82 if((sm->associnfo.associating || sm->associated) &&
83 (data->essid.flags && data->essid.length && extra)) {
84 /* Get the associating network */
85 n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
86 if(n && n->essid.len == (data->essid.length - 1) &&
87 !memcmp(n->essid.data, extra, n->essid.len)) {
88 dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
89 MAC_ARG(sm->associnfo.bssid));
90 return 0;
91 } else {
92 dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
93 spin_lock_irqsave(&sm->lock,flags);
94 /* Cancel assoc work */
95 cancel_delayed_work(&sm->associnfo.work);
96 /* We don't have to do this, but it's a little cleaner */
97 list_for_each_entry(authptr, &sm->auth_queue, list)
98 cancel_delayed_work(&authptr->work);
99 sm->associnfo.bssvalid = 0;
100 sm->associnfo.bssfixed = 0;
101 spin_unlock_irqrestore(&sm->lock,flags);
102 flush_scheduled_work();
103 }
104 }
105
106
76 spin_lock_irqsave(&sm->lock, flags); 107 spin_lock_irqsave(&sm->lock, flags);
77 108
78 sm->associnfo.static_essid = 0; 109 sm->associnfo.static_essid = 0;
110 sm->associnfo.assoc_wait = 0;
79 111
80 if (data->essid.flags && data->essid.length && extra /*required?*/) { 112 if (data->essid.flags && data->essid.length && extra /*required?*/) {
81 length = min(data->essid.length - 1, IW_ESSID_MAX_SIZE); 113 length = min(data->essid.length - 1, IW_ESSID_MAX_SIZE);