aboutsummaryrefslogtreecommitdiffstats
path: root/net/ieee80211/softmac/ieee80211softmac_wx.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee80211/softmac/ieee80211softmac_wx.c')
-rw-r--r--net/ieee80211/softmac/ieee80211softmac_wx.c71
1 files changed, 44 insertions, 27 deletions
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c
index 2aa779d18f38..23068a830f7d 100644
--- a/net/ieee80211/softmac/ieee80211softmac_wx.c
+++ b/net/ieee80211/softmac/ieee80211softmac_wx.c
@@ -73,13 +73,14 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
73 struct ieee80211softmac_network *n; 73 struct ieee80211softmac_network *n;
74 struct ieee80211softmac_auth_queue_item *authptr; 74 struct ieee80211softmac_auth_queue_item *authptr;
75 int length = 0; 75 int length = 0;
76 unsigned long flags; 76
77 mutex_lock(&sm->associnfo.mutex);
77 78
78 /* Check if we're already associating to this or another network 79 /* 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 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 * 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 (data->essid.flags && data->essid.length)) { 84 (data->essid.flags && data->essid.length)) {
84 /* Get the associating network */ 85 /* Get the associating network */
85 n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid); 86 n = ieee80211softmac_get_network_by_bssid(sm, sm->associnfo.bssid);
@@ -87,10 +88,9 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
87 !memcmp(n->essid.data, extra, n->essid.len)) { 88 !memcmp(n->essid.data, extra, n->essid.len)) {
88 dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n", 89 dprintk(KERN_INFO PFX "Already associating or associated to "MAC_FMT"\n",
89 MAC_ARG(sm->associnfo.bssid)); 90 MAC_ARG(sm->associnfo.bssid));
90 return 0; 91 goto out;
91 } else { 92 } else {
92 dprintk(KERN_INFO PFX "Canceling existing associate request!\n"); 93 dprintk(KERN_INFO PFX "Canceling existing associate request!\n");
93 spin_lock_irqsave(&sm->lock,flags);
94 /* Cancel assoc work */ 94 /* Cancel assoc work */
95 cancel_delayed_work(&sm->associnfo.work); 95 cancel_delayed_work(&sm->associnfo.work);
96 /* We don't have to do this, but it's a little cleaner */ 96 /* We don't have to do this, but it's a little cleaner */
@@ -98,14 +98,13 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
98 cancel_delayed_work(&authptr->work); 98 cancel_delayed_work(&authptr->work);
99 sm->associnfo.bssvalid = 0; 99 sm->associnfo.bssvalid = 0;
100 sm->associnfo.bssfixed = 0; 100 sm->associnfo.bssfixed = 0;
101 spin_unlock_irqrestore(&sm->lock,flags);
102 flush_scheduled_work(); 101 flush_scheduled_work();
102 sm->associnfo.associating = 0;
103 sm->associnfo.associated = 0;
103 } 104 }
104 } 105 }
105 106
106 107
107 spin_lock_irqsave(&sm->lock, flags);
108
109 sm->associnfo.static_essid = 0; 108 sm->associnfo.static_essid = 0;
110 sm->associnfo.assoc_wait = 0; 109 sm->associnfo.assoc_wait = 0;
111 110
@@ -121,10 +120,12 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev,
121 * If applicable, we have already copied the data in */ 120 * If applicable, we have already copied the data in */
122 sm->associnfo.req_essid.len = length; 121 sm->associnfo.req_essid.len = length;
123 122
123 sm->associnfo.associating = 1;
124 /* queue lower level code to do work (if necessary) */ 124 /* queue lower level code to do work (if necessary) */
125 schedule_work(&sm->associnfo.work); 125 schedule_work(&sm->associnfo.work);
126out:
127 mutex_unlock(&sm->associnfo.mutex);
126 128
127 spin_unlock_irqrestore(&sm->lock, flags);
128 return 0; 129 return 0;
129} 130}
130EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid); 131EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_essid);
@@ -136,10 +137,8 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev,
136 char *extra) 137 char *extra)
137{ 138{
138 struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); 139 struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
139 unsigned long flags;
140 140
141 /* avoid getting inconsistent information */ 141 mutex_lock(&sm->associnfo.mutex);
142 spin_lock_irqsave(&sm->lock, flags);
143 /* If all fails, return ANY (empty) */ 142 /* If all fails, return ANY (empty) */
144 data->essid.length = 0; 143 data->essid.length = 0;
145 data->essid.flags = 0; /* active */ 144 data->essid.flags = 0; /* active */
@@ -152,12 +151,13 @@ ieee80211softmac_wx_get_essid(struct net_device *net_dev,
152 } 151 }
153 152
154 /* If we're associating/associated, return that */ 153 /* If we're associating/associated, return that */
155 if (sm->associated || sm->associnfo.associating) { 154 if (sm->associnfo.associated || sm->associnfo.associating) {
156 data->essid.length = sm->associnfo.associate_essid.len; 155 data->essid.length = sm->associnfo.associate_essid.len;
157 data->essid.flags = 1; /* active */ 156 data->essid.flags = 1; /* active */
158 memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len); 157 memcpy(extra, sm->associnfo.associate_essid.data, sm->associnfo.associate_essid.len);
159 } 158 }
160 spin_unlock_irqrestore(&sm->lock, flags); 159 mutex_unlock(&sm->associnfo.mutex);
160
161 return 0; 161 return 0;
162} 162}
163EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid); 163EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_essid);
@@ -322,15 +322,15 @@ ieee80211softmac_wx_get_wap(struct net_device *net_dev,
322{ 322{
323 struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); 323 struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
324 int err = 0; 324 int err = 0;
325 unsigned long flags;
326 325
327 spin_lock_irqsave(&mac->lock, flags); 326 mutex_lock(&mac->associnfo.mutex);
328 if (mac->associnfo.bssvalid) 327 if (mac->associnfo.bssvalid)
329 memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN); 328 memcpy(data->ap_addr.sa_data, mac->associnfo.bssid, ETH_ALEN);
330 else 329 else
331 memset(data->ap_addr.sa_data, 0xff, ETH_ALEN); 330 memset(data->ap_addr.sa_data, 0xff, ETH_ALEN);
332 data->ap_addr.sa_family = ARPHRD_ETHER; 331 data->ap_addr.sa_family = ARPHRD_ETHER;
333 spin_unlock_irqrestore(&mac->lock, flags); 332 mutex_unlock(&mac->associnfo.mutex);
333
334 return err; 334 return err;
335} 335}
336EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap); 336EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_wap);
@@ -342,28 +342,27 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
342 char *extra) 342 char *extra)
343{ 343{
344 struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); 344 struct ieee80211softmac_device *mac = ieee80211_priv(net_dev);
345 unsigned long flags;
346 345
347 /* sanity check */ 346 /* sanity check */
348 if (data->ap_addr.sa_family != ARPHRD_ETHER) { 347 if (data->ap_addr.sa_family != ARPHRD_ETHER) {
349 return -EINVAL; 348 return -EINVAL;
350 } 349 }
351 350
352 spin_lock_irqsave(&mac->lock, flags); 351 mutex_lock(&mac->associnfo.mutex);
353 if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { 352 if (is_broadcast_ether_addr(data->ap_addr.sa_data)) {
354 /* the bssid we have is not to be fixed any longer, 353 /* the bssid we have is not to be fixed any longer,
355 * and we should reassociate to the best AP. */ 354 * and we should reassociate to the best AP. */
356 mac->associnfo.bssfixed = 0; 355 mac->associnfo.bssfixed = 0;
357 /* force reassociation */ 356 /* force reassociation */
358 mac->associnfo.bssvalid = 0; 357 mac->associnfo.bssvalid = 0;
359 if (mac->associated) 358 if (mac->associnfo.associated)
360 schedule_work(&mac->associnfo.work); 359 schedule_work(&mac->associnfo.work);
361 } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { 360 } else if (is_zero_ether_addr(data->ap_addr.sa_data)) {
362 /* the bssid we have is no longer fixed */ 361 /* the bssid we have is no longer fixed */
363 mac->associnfo.bssfixed = 0; 362 mac->associnfo.bssfixed = 0;
364 } else { 363 } else {
365 if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { 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 /* bssid unchanged and associated or associating - just return */ 366 /* bssid unchanged and associated or associating - just return */
368 goto out; 367 goto out;
369 } 368 }
@@ -378,7 +377,8 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev,
378 } 377 }
379 378
380 out: 379 out:
381 spin_unlock_irqrestore(&mac->lock, flags); 380 mutex_unlock(&mac->associnfo.mutex);
381
382 return 0; 382 return 0;
383} 383}
384EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap); 384EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_wap);
@@ -394,7 +394,8 @@ ieee80211softmac_wx_set_genie(struct net_device *dev,
394 int err = 0; 394 int err = 0;
395 char *buf; 395 char *buf;
396 int i; 396 int i;
397 397
398 mutex_lock(&mac->associnfo.mutex);
398 spin_lock_irqsave(&mac->lock, flags); 399 spin_lock_irqsave(&mac->lock, flags);
399 /* bleh. shouldn't be locked for that kmalloc... */ 400 /* bleh. shouldn't be locked for that kmalloc... */
400 401
@@ -432,6 +433,8 @@ ieee80211softmac_wx_set_genie(struct net_device *dev,
432 433
433 out: 434 out:
434 spin_unlock_irqrestore(&mac->lock, flags); 435 spin_unlock_irqrestore(&mac->lock, flags);
436 mutex_unlock(&mac->associnfo.mutex);
437
435 return err; 438 return err;
436} 439}
437EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie); 440EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_genie);
@@ -446,7 +449,8 @@ ieee80211softmac_wx_get_genie(struct net_device *dev,
446 unsigned long flags; 449 unsigned long flags;
447 int err = 0; 450 int err = 0;
448 int space = wrqu->data.length; 451 int space = wrqu->data.length;
449 452
453 mutex_lock(&mac->associnfo.mutex);
450 spin_lock_irqsave(&mac->lock, flags); 454 spin_lock_irqsave(&mac->lock, flags);
451 455
452 wrqu->data.length = 0; 456 wrqu->data.length = 0;
@@ -459,6 +463,8 @@ ieee80211softmac_wx_get_genie(struct net_device *dev,
459 err = -E2BIG; 463 err = -E2BIG;
460 } 464 }
461 spin_unlock_irqrestore(&mac->lock, flags); 465 spin_unlock_irqrestore(&mac->lock, flags);
466 mutex_lock(&mac->associnfo.mutex);
467
462 return err; 468 return err;
463} 469}
464EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie); 470EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_genie);
@@ -473,10 +479,13 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
473 struct iw_mlme *mlme = (struct iw_mlme *)extra; 479 struct iw_mlme *mlme = (struct iw_mlme *)extra;
474 u16 reason = cpu_to_le16(mlme->reason_code); 480 u16 reason = cpu_to_le16(mlme->reason_code);
475 struct ieee80211softmac_network *net; 481 struct ieee80211softmac_network *net;
482 int err = -EINVAL;
483
484 mutex_lock(&mac->associnfo.mutex);
476 485
477 if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) { 486 if (memcmp(mac->associnfo.bssid, mlme->addr.sa_data, ETH_ALEN)) {
478 printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n"); 487 printk(KERN_DEBUG PFX "wx_set_mlme: requested operation on net we don't use\n");
479 return -EINVAL; 488 goto out;
480 } 489 }
481 490
482 switch (mlme->cmd) { 491 switch (mlme->cmd) {
@@ -484,14 +493,22 @@ ieee80211softmac_wx_set_mlme(struct net_device *dev,
484 net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data); 493 net = ieee80211softmac_get_network_by_bssid_locked(mac, mlme->addr.sa_data);
485 if (!net) { 494 if (!net) {
486 printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n"); 495 printk(KERN_DEBUG PFX "wx_set_mlme: we should know the net here...\n");
487 return -EINVAL; 496 goto out;
488 } 497 }
489 return ieee80211softmac_deauth_req(mac, net, reason); 498 return ieee80211softmac_deauth_req(mac, net, reason);
490 case IW_MLME_DISASSOC: 499 case IW_MLME_DISASSOC:
491 ieee80211softmac_send_disassoc_req(mac, reason); 500 ieee80211softmac_send_disassoc_req(mac, reason);
492 return 0; 501 mac->associnfo.associated = 0;
502 mac->associnfo.associating = 0;
503 err = 0;
504 goto out;
493 default: 505 default:
494 return -EOPNOTSUPP; 506 err = -EOPNOTSUPP;
495 } 507 }
508
509out:
510 mutex_unlock(&mac->associnfo.mutex);
511
512 return err;
496} 513}
497EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme); 514EXPORT_SYMBOL_GPL(ieee80211softmac_wx_set_mlme);