diff options
-rw-r--r-- | include/net/ieee80211softmac.h | 5 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_assoc.c | 20 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_module.c | 2 | ||||
-rw-r--r-- | net/ieee80211/softmac/ieee80211softmac_wx.c | 27 |
4 files changed, 39 insertions, 15 deletions
diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h index 6b3693f05ca0..b1ebfbae397f 100644 --- a/include/net/ieee80211softmac.h +++ b/include/net/ieee80211softmac.h | |||
@@ -96,10 +96,13 @@ struct ieee80211softmac_assoc_info { | |||
96 | * | 96 | * |
97 | * bssvalid is true if we found a matching network | 97 | * bssvalid is true if we found a matching network |
98 | * and saved it's BSSID into the bssid above. | 98 | * and saved it's BSSID into the bssid above. |
99 | * | ||
100 | * bssfixed is used for SIOCSIWAP. | ||
99 | */ | 101 | */ |
100 | u8 static_essid:1, | 102 | u8 static_essid:1, |
101 | associating:1, | 103 | associating:1, |
102 | bssvalid:1; | 104 | bssvalid:1, |
105 | bssfixed:1; | ||
103 | 106 | ||
104 | /* Scan retries remaining */ | 107 | /* Scan retries remaining */ |
105 | int scan_retry; | 108 | int scan_retry; |
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index 4498023841dc..fb79ce7d6439 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c | |||
@@ -144,6 +144,12 @@ network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_ne | |||
144 | if (!we_support_all_basic_rates(mac, net->rates_ex, net->rates_ex_len)) | 144 | if (!we_support_all_basic_rates(mac, net->rates_ex, net->rates_ex_len)) |
145 | return 0; | 145 | return 0; |
146 | 146 | ||
147 | /* assume that users know what they're doing ... | ||
148 | * (note we don't let them select a net we're incompatible with) */ | ||
149 | if (mac->associnfo.bssfixed) { | ||
150 | return !memcmp(mac->associnfo.bssid, net->bssid, ETH_ALEN); | ||
151 | } | ||
152 | |||
147 | /* if 'ANY' network requested, take any that doesn't have privacy enabled */ | 153 | /* if 'ANY' network requested, take any that doesn't have privacy enabled */ |
148 | if (mac->associnfo.req_essid.len == 0 | 154 | if (mac->associnfo.req_essid.len == 0 |
149 | && !(net->capability & WLAN_CAPABILITY_PRIVACY)) | 155 | && !(net->capability & WLAN_CAPABILITY_PRIVACY)) |
@@ -176,7 +182,7 @@ ieee80211softmac_assoc_work(void *d) | |||
176 | ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); | 182 | ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); |
177 | 183 | ||
178 | /* try to find the requested network in our list, if we found one already */ | 184 | /* try to find the requested network in our list, if we found one already */ |
179 | if (mac->associnfo.bssvalid) | 185 | if (mac->associnfo.bssvalid || mac->associnfo.bssfixed) |
180 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); | 186 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); |
181 | 187 | ||
182 | /* Search the ieee80211 networks for this network if we didn't find it by bssid, | 188 | /* Search the ieee80211 networks for this network if we didn't find it by bssid, |
@@ -241,19 +247,25 @@ ieee80211softmac_assoc_work(void *d) | |||
241 | if (ieee80211softmac_start_scan(mac)) | 247 | if (ieee80211softmac_start_scan(mac)) |
242 | dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); | 248 | dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); |
243 | return; | 249 | return; |
244 | } | 250 | } else { |
245 | else { | ||
246 | spin_lock_irqsave(&mac->lock, flags); | 251 | spin_lock_irqsave(&mac->lock, flags); |
247 | mac->associnfo.associating = 0; | 252 | mac->associnfo.associating = 0; |
248 | mac->associated = 0; | 253 | mac->associated = 0; |
249 | spin_unlock_irqrestore(&mac->lock, flags); | 254 | spin_unlock_irqrestore(&mac->lock, flags); |
250 | 255 | ||
251 | dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); | 256 | dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); |
257 | /* reset the retry counter for the next user request since we | ||
258 | * break out and don't reschedule ourselves after this point. */ | ||
259 | mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
252 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); | 260 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); |
253 | return; | 261 | return; |
254 | } | 262 | } |
255 | } | 263 | } |
256 | 264 | ||
265 | /* reset the retry counter for the next user request since we | ||
266 | * now found a net and will try to associate to it, but not | ||
267 | * schedule this function again. */ | ||
268 | mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
257 | mac->associnfo.bssvalid = 1; | 269 | mac->associnfo.bssvalid = 1; |
258 | memcpy(mac->associnfo.bssid, found->bssid, ETH_ALEN); | 270 | memcpy(mac->associnfo.bssid, found->bssid, ETH_ALEN); |
259 | /* copy the ESSID for displaying it */ | 271 | /* copy the ESSID for displaying it */ |
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c index 60f06a31f0d1..be83bdc1644a 100644 --- a/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/net/ieee80211/softmac/ieee80211softmac_module.c | |||
@@ -45,6 +45,8 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv) | |||
45 | softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc; | 45 | softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc; |
46 | softmac->scaninfo = NULL; | 46 | softmac->scaninfo = NULL; |
47 | 47 | ||
48 | softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
49 | |||
48 | /* TODO: initialise all the other callbacks in the ieee struct | 50 | /* TODO: initialise all the other callbacks in the ieee struct |
49 | * (once they're written) | 51 | * (once they're written) |
50 | */ | 52 | */ |
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index 00f0d4f71897..27edb2b5581a 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c | |||
@@ -27,7 +27,8 @@ | |||
27 | #include "ieee80211softmac_priv.h" | 27 | #include "ieee80211softmac_priv.h" |
28 | 28 | ||
29 | #include <net/iw_handler.h> | 29 | #include <net/iw_handler.h> |
30 | 30 | /* for is_broadcast_ether_addr and is_zero_ether_addr */ | |
31 | #include <linux/etherdevice.h> | ||
31 | 32 | ||
32 | int | 33 | int |
33 | ieee80211softmac_wx_trigger_scan(struct net_device *net_dev, | 34 | ieee80211softmac_wx_trigger_scan(struct net_device *net_dev, |
@@ -83,7 +84,6 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, | |||
83 | sm->associnfo.static_essid = 1; | 84 | sm->associnfo.static_essid = 1; |
84 | } | 85 | } |
85 | } | 86 | } |
86 | sm->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
87 | 87 | ||
88 | /* set our requested ESSID length. | 88 | /* set our requested ESSID length. |
89 | * If applicable, we have already copied the data in */ | 89 | * If applicable, we have already copied the data in */ |
@@ -310,8 +310,6 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
310 | char *extra) | 310 | char *extra) |
311 | { | 311 | { |
312 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | 312 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); |
313 | static const unsigned char any[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
314 | static const unsigned char off[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
315 | unsigned long flags; | 313 | unsigned long flags; |
316 | 314 | ||
317 | /* sanity check */ | 315 | /* sanity check */ |
@@ -320,10 +318,17 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
320 | } | 318 | } |
321 | 319 | ||
322 | spin_lock_irqsave(&mac->lock, flags); | 320 | spin_lock_irqsave(&mac->lock, flags); |
323 | if (!memcmp(any, data->ap_addr.sa_data, ETH_ALEN) || | 321 | if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { |
324 | !memcmp(off, data->ap_addr.sa_data, ETH_ALEN)) { | 322 | /* the bssid we have is not to be fixed any longer, |
325 | schedule_work(&mac->associnfo.work); | 323 | * and we should reassociate to the best AP. */ |
326 | goto out; | 324 | mac->associnfo.bssfixed = 0; |
325 | /* force reassociation */ | ||
326 | mac->associnfo.bssvalid = 0; | ||
327 | if (mac->associated) | ||
328 | schedule_work(&mac->associnfo.work); | ||
329 | } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { | ||
330 | /* the bssid we have is no longer fixed */ | ||
331 | mac->associnfo.bssfixed = 0; | ||
327 | } else { | 332 | } else { |
328 | if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { | 333 | if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { |
329 | if (mac->associnfo.associating || mac->associated) { | 334 | if (mac->associnfo.associating || mac->associated) { |
@@ -333,12 +338,14 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
333 | } else { | 338 | } else { |
334 | /* copy new value in data->ap_addr.sa_data to bssid */ | 339 | /* copy new value in data->ap_addr.sa_data to bssid */ |
335 | memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN); | 340 | memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN); |
336 | } | 341 | } |
342 | /* tell the other code that this bssid should be used no matter what */ | ||
343 | mac->associnfo.bssfixed = 1; | ||
337 | /* queue associate if new bssid or (old one again and not associated) */ | 344 | /* queue associate if new bssid or (old one again and not associated) */ |
338 | schedule_work(&mac->associnfo.work); | 345 | schedule_work(&mac->associnfo.work); |
339 | } | 346 | } |
340 | 347 | ||
341 | out: | 348 | out: |
342 | spin_unlock_irqrestore(&mac->lock, flags); | 349 | spin_unlock_irqrestore(&mac->lock, flags); |
343 | return 0; | 350 | return 0; |
344 | } | 351 | } |