diff options
Diffstat (limited to 'drivers/net/wireless/libertas/assoc.c')
-rw-r--r-- | drivers/net/wireless/libertas/assoc.c | 345 |
1 files changed, 229 insertions, 116 deletions
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c index c260bd1b3d46..ee82413b426d 100644 --- a/drivers/net/wireless/libertas/assoc.c +++ b/drivers/net/wireless/libertas/assoc.c | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | #include <linux/bitops.h> | 3 | #include <linux/bitops.h> |
4 | #include <net/ieee80211.h> | 4 | #include <net/ieee80211.h> |
5 | #include <linux/etherdevice.h> | ||
5 | 6 | ||
6 | #include "assoc.h" | 7 | #include "assoc.h" |
7 | #include "join.h" | 8 | #include "join.h" |
@@ -13,59 +14,88 @@ | |||
13 | static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; | 14 | static const u8 bssid_any[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
14 | static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; | 15 | static const u8 bssid_off[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
15 | 16 | ||
17 | static void print_assoc_req(const char * extra, struct assoc_request * assoc_req) | ||
18 | { | ||
19 | lbs_deb_assoc( | ||
20 | "#### Association Request: %s\n" | ||
21 | " flags: 0x%08lX\n" | ||
22 | " SSID: '%s'\n" | ||
23 | " channel: %d\n" | ||
24 | " band: %d\n" | ||
25 | " mode: %d\n" | ||
26 | " BSSID: " MAC_FMT "\n" | ||
27 | " Encryption:%s%s%s\n" | ||
28 | " auth: %d\n", | ||
29 | extra, assoc_req->flags, | ||
30 | escape_essid(assoc_req->ssid, assoc_req->ssid_len), | ||
31 | assoc_req->channel, assoc_req->band, assoc_req->mode, | ||
32 | MAC_ARG(assoc_req->bssid), | ||
33 | assoc_req->secinfo.WPAenabled ? " WPA" : "", | ||
34 | assoc_req->secinfo.WPA2enabled ? " WPA2" : "", | ||
35 | assoc_req->secinfo.wep_enabled ? " WEP" : "", | ||
36 | assoc_req->secinfo.auth_mode); | ||
37 | } | ||
38 | |||
39 | |||
16 | static int assoc_helper_essid(wlan_private *priv, | 40 | static int assoc_helper_essid(wlan_private *priv, |
17 | struct assoc_request * assoc_req) | 41 | struct assoc_request * assoc_req) |
18 | { | 42 | { |
19 | wlan_adapter *adapter = priv->adapter; | 43 | wlan_adapter *adapter = priv->adapter; |
20 | int ret = 0; | 44 | int ret = 0; |
21 | int i; | 45 | struct bss_descriptor * bss; |
46 | int channel = -1; | ||
22 | 47 | ||
23 | ENTER(); | 48 | lbs_deb_enter(LBS_DEB_ASSOC); |
24 | 49 | ||
25 | lbs_pr_debug(1, "New SSID requested: %s\n", assoc_req->ssid.ssid); | 50 | /* FIXME: take channel into account when picking SSIDs if a channel |
51 | * is set. | ||
52 | */ | ||
53 | |||
54 | if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) | ||
55 | channel = assoc_req->channel; | ||
56 | |||
57 | lbs_deb_assoc("New SSID requested: '%s'\n", | ||
58 | escape_essid(assoc_req->ssid, assoc_req->ssid_len)); | ||
26 | if (assoc_req->mode == IW_MODE_INFRA) { | 59 | if (assoc_req->mode == IW_MODE_INFRA) { |
27 | if (adapter->prescan) { | 60 | if (adapter->prescan) { |
28 | libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 1); | 61 | libertas_send_specific_ssid_scan(priv, assoc_req->ssid, |
62 | assoc_req->ssid_len, 0); | ||
29 | } | 63 | } |
30 | 64 | ||
31 | i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, | 65 | bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid, |
32 | NULL, IW_MODE_INFRA); | 66 | assoc_req->ssid_len, NULL, IW_MODE_INFRA, channel); |
33 | if (i >= 0) { | 67 | if (bss != NULL) { |
34 | lbs_pr_debug(1, | 68 | lbs_deb_assoc("SSID found in scan list, associating\n"); |
35 | "SSID found in scan list ... associating...\n"); | 69 | memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); |
36 | 70 | ret = wlan_associate(priv, assoc_req); | |
37 | ret = wlan_associate(priv, &adapter->scantable[i]); | ||
38 | if (ret == 0) { | ||
39 | memcpy(&assoc_req->bssid, | ||
40 | &adapter->scantable[i].macaddress, | ||
41 | ETH_ALEN); | ||
42 | } | ||
43 | } else { | 71 | } else { |
44 | lbs_pr_debug(1, "SSID '%s' not found; cannot associate\n", | 72 | lbs_deb_assoc("SSID not found; cannot associate\n"); |
45 | assoc_req->ssid.ssid); | ||
46 | } | 73 | } |
47 | } else if (assoc_req->mode == IW_MODE_ADHOC) { | 74 | } else if (assoc_req->mode == IW_MODE_ADHOC) { |
48 | /* Scan for the network, do not save previous results. Stale | 75 | /* Scan for the network, do not save previous results. Stale |
49 | * scan data will cause us to join a non-existant adhoc network | 76 | * scan data will cause us to join a non-existant adhoc network |
50 | */ | 77 | */ |
51 | libertas_send_specific_SSID_scan(priv, &assoc_req->ssid, 0); | 78 | libertas_send_specific_ssid_scan(priv, assoc_req->ssid, |
79 | assoc_req->ssid_len, 1); | ||
52 | 80 | ||
53 | /* Search for the requested SSID in the scan table */ | 81 | /* Search for the requested SSID in the scan table */ |
54 | i = libertas_find_SSID_in_list(adapter, &assoc_req->ssid, NULL, | 82 | bss = libertas_find_ssid_in_list(adapter, assoc_req->ssid, |
55 | IW_MODE_ADHOC); | 83 | assoc_req->ssid_len, NULL, IW_MODE_ADHOC, channel); |
56 | if (i >= 0) { | 84 | if (bss != NULL) { |
57 | lbs_pr_debug(1, "SSID found at %d in List, so join\n", ret); | 85 | lbs_deb_assoc("SSID found, will join\n"); |
58 | libertas_join_adhoc_network(priv, &adapter->scantable[i]); | 86 | memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); |
87 | libertas_join_adhoc_network(priv, assoc_req); | ||
59 | } else { | 88 | } else { |
60 | /* else send START command */ | 89 | /* else send START command */ |
61 | lbs_pr_debug(1, "SSID not found in list, so creating adhoc" | 90 | lbs_deb_assoc("SSID not found, creating adhoc network\n"); |
62 | " with SSID '%s'\n", assoc_req->ssid.ssid); | 91 | memcpy(&assoc_req->bss.ssid, &assoc_req->ssid, |
63 | libertas_start_adhoc_network(priv, &assoc_req->ssid); | 92 | IW_ESSID_MAX_SIZE); |
93 | assoc_req->bss.ssid_len = assoc_req->ssid_len; | ||
94 | libertas_start_adhoc_network(priv, assoc_req); | ||
64 | } | 95 | } |
65 | memcpy(&assoc_req->bssid, &adapter->current_addr, ETH_ALEN); | ||
66 | } | 96 | } |
67 | 97 | ||
68 | LEAVE(); | 98 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
69 | return ret; | 99 | return ret; |
70 | } | 100 | } |
71 | 101 | ||
@@ -74,33 +104,31 @@ static int assoc_helper_bssid(wlan_private *priv, | |||
74 | struct assoc_request * assoc_req) | 104 | struct assoc_request * assoc_req) |
75 | { | 105 | { |
76 | wlan_adapter *adapter = priv->adapter; | 106 | wlan_adapter *adapter = priv->adapter; |
77 | int i, ret = 0; | 107 | int ret = 0; |
78 | 108 | struct bss_descriptor * bss; | |
79 | ENTER(); | ||
80 | 109 | ||
81 | lbs_pr_debug(1, "ASSOC: WAP: BSSID = " MAC_FMT "\n", | 110 | lbs_deb_enter_args(LBS_DEB_ASSOC, "BSSID " MAC_FMT, |
82 | MAC_ARG(assoc_req->bssid)); | 111 | MAC_ARG(assoc_req->bssid)); |
83 | 112 | ||
84 | /* Search for index position in list for requested MAC */ | 113 | /* Search for index position in list for requested MAC */ |
85 | i = libertas_find_BSSID_in_list(adapter, assoc_req->bssid, | 114 | bss = libertas_find_bssid_in_list(adapter, assoc_req->bssid, |
86 | assoc_req->mode); | 115 | assoc_req->mode); |
87 | if (i < 0) { | 116 | if (bss == NULL) { |
88 | lbs_pr_debug(1, "ASSOC: WAP: BSSID " MAC_FMT " not found, " | 117 | lbs_deb_assoc("ASSOC: WAP: BSSID " MAC_FMT " not found, " |
89 | "cannot associate.\n", MAC_ARG(assoc_req->bssid)); | 118 | "cannot associate.\n", MAC_ARG(assoc_req->bssid)); |
90 | goto out; | 119 | goto out; |
91 | } | 120 | } |
92 | 121 | ||
122 | memcpy(&assoc_req->bss, bss, sizeof(struct bss_descriptor)); | ||
93 | if (assoc_req->mode == IW_MODE_INFRA) { | 123 | if (assoc_req->mode == IW_MODE_INFRA) { |
94 | ret = wlan_associate(priv, &adapter->scantable[i]); | 124 | ret = wlan_associate(priv, assoc_req); |
95 | lbs_pr_debug(1, "ASSOC: return from wlan_associate(bssd) was %d\n", ret); | 125 | lbs_deb_assoc("ASSOC: wlan_associate(bssid) returned %d\n", ret); |
96 | } else if (assoc_req->mode == IW_MODE_ADHOC) { | 126 | } else if (assoc_req->mode == IW_MODE_ADHOC) { |
97 | libertas_join_adhoc_network(priv, &adapter->scantable[i]); | 127 | libertas_join_adhoc_network(priv, assoc_req); |
98 | } | 128 | } |
99 | memcpy(&assoc_req->ssid, &adapter->scantable[i].ssid, | ||
100 | sizeof(struct WLAN_802_11_SSID)); | ||
101 | 129 | ||
102 | out: | 130 | out: |
103 | LEAVE(); | 131 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
104 | return ret; | 132 | return ret; |
105 | } | 133 | } |
106 | 134 | ||
@@ -113,12 +141,12 @@ static int assoc_helper_associate(wlan_private *priv, | |||
113 | /* If we're given and 'any' BSSID, try associating based on SSID */ | 141 | /* If we're given and 'any' BSSID, try associating based on SSID */ |
114 | 142 | ||
115 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { | 143 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { |
116 | if (memcmp(bssid_any, assoc_req->bssid, ETH_ALEN) | 144 | if (compare_ether_addr(bssid_any, assoc_req->bssid) |
117 | && memcmp(bssid_off, assoc_req->bssid, ETH_ALEN)) { | 145 | && compare_ether_addr(bssid_off, assoc_req->bssid)) { |
118 | ret = assoc_helper_bssid(priv, assoc_req); | 146 | ret = assoc_helper_bssid(priv, assoc_req); |
119 | done = 1; | 147 | done = 1; |
120 | if (ret) { | 148 | if (ret) { |
121 | lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret); | 149 | lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret); |
122 | } | 150 | } |
123 | } | 151 | } |
124 | } | 152 | } |
@@ -126,7 +154,7 @@ static int assoc_helper_associate(wlan_private *priv, | |||
126 | if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { | 154 | if (!done && test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { |
127 | ret = assoc_helper_essid(priv, assoc_req); | 155 | ret = assoc_helper_essid(priv, assoc_req); |
128 | if (ret) { | 156 | if (ret) { |
129 | lbs_pr_debug(1, "ASSOC: bssid: ret = %d\n", ret); | 157 | lbs_deb_assoc("ASSOC: bssid: ret = %d\n", ret); |
130 | } | 158 | } |
131 | } | 159 | } |
132 | 160 | ||
@@ -140,12 +168,10 @@ static int assoc_helper_mode(wlan_private *priv, | |||
140 | wlan_adapter *adapter = priv->adapter; | 168 | wlan_adapter *adapter = priv->adapter; |
141 | int ret = 0; | 169 | int ret = 0; |
142 | 170 | ||
143 | ENTER(); | 171 | lbs_deb_enter(LBS_DEB_ASSOC); |
144 | 172 | ||
145 | if (assoc_req->mode == adapter->mode) { | 173 | if (assoc_req->mode == adapter->mode) |
146 | LEAVE(); | 174 | goto done; |
147 | return 0; | ||
148 | } | ||
149 | 175 | ||
150 | if (assoc_req->mode == IW_MODE_INFRA) { | 176 | if (assoc_req->mode == IW_MODE_INFRA) { |
151 | if (adapter->psstate != PS_STATE_FULL_POWER) | 177 | if (adapter->psstate != PS_STATE_FULL_POWER) |
@@ -158,9 +184,73 @@ static int assoc_helper_mode(wlan_private *priv, | |||
158 | cmd_802_11_snmp_mib, | 184 | cmd_802_11_snmp_mib, |
159 | 0, cmd_option_waitforrsp, | 185 | 0, cmd_option_waitforrsp, |
160 | OID_802_11_INFRASTRUCTURE_MODE, | 186 | OID_802_11_INFRASTRUCTURE_MODE, |
161 | (void *) (size_t) assoc_req->mode); | 187 | /* Shoot me now */ (void *) (size_t) assoc_req->mode); |
188 | |||
189 | done: | ||
190 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | ||
191 | return ret; | ||
192 | } | ||
193 | |||
194 | |||
195 | static int update_channel(wlan_private * priv) | ||
196 | { | ||
197 | /* the channel in f/w could be out of sync, get the current channel */ | ||
198 | return libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel, | ||
199 | cmd_opt_802_11_rf_channel_get, | ||
200 | cmd_option_waitforrsp, 0, NULL); | ||
201 | } | ||
202 | |||
203 | static int assoc_helper_channel(wlan_private *priv, | ||
204 | struct assoc_request * assoc_req) | ||
205 | { | ||
206 | wlan_adapter *adapter = priv->adapter; | ||
207 | int ret = 0; | ||
208 | |||
209 | lbs_deb_enter(LBS_DEB_ASSOC); | ||
210 | |||
211 | ret = update_channel(priv); | ||
212 | if (ret < 0) { | ||
213 | lbs_deb_assoc("ASSOC: channel: error getting channel."); | ||
214 | } | ||
215 | |||
216 | if (assoc_req->channel == adapter->curbssparams.channel) | ||
217 | goto done; | ||
218 | |||
219 | lbs_deb_assoc("ASSOC: channel: %d -> %d\n", | ||
220 | adapter->curbssparams.channel, assoc_req->channel); | ||
221 | |||
222 | ret = libertas_prepare_and_send_command(priv, cmd_802_11_rf_channel, | ||
223 | cmd_opt_802_11_rf_channel_set, | ||
224 | cmd_option_waitforrsp, 0, &assoc_req->channel); | ||
225 | if (ret < 0) { | ||
226 | lbs_deb_assoc("ASSOC: channel: error setting channel."); | ||
227 | } | ||
228 | |||
229 | ret = update_channel(priv); | ||
230 | if (ret < 0) { | ||
231 | lbs_deb_assoc("ASSOC: channel: error getting channel."); | ||
232 | } | ||
233 | |||
234 | if (assoc_req->channel != adapter->curbssparams.channel) { | ||
235 | lbs_deb_assoc("ASSOC: channel: failed to update channel to %d", | ||
236 | assoc_req->channel); | ||
237 | goto done; | ||
238 | } | ||
239 | |||
240 | if ( assoc_req->secinfo.wep_enabled | ||
241 | && (assoc_req->wep_keys[0].len | ||
242 | || assoc_req->wep_keys[1].len | ||
243 | || assoc_req->wep_keys[2].len | ||
244 | || assoc_req->wep_keys[3].len)) { | ||
245 | /* Make sure WEP keys are re-sent to firmware */ | ||
246 | set_bit(ASSOC_FLAG_WEP_KEYS, &assoc_req->flags); | ||
247 | } | ||
162 | 248 | ||
163 | LEAVE(); | 249 | /* Must restart/rejoin adhoc networks after channel change */ |
250 | set_bit(ASSOC_FLAG_SSID, &assoc_req->flags); | ||
251 | |||
252 | done: | ||
253 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | ||
164 | return ret; | 254 | return ret; |
165 | } | 255 | } |
166 | 256 | ||
@@ -172,7 +262,7 @@ static int assoc_helper_wep_keys(wlan_private *priv, | |||
172 | int i; | 262 | int i; |
173 | int ret = 0; | 263 | int ret = 0; |
174 | 264 | ||
175 | ENTER(); | 265 | lbs_deb_enter(LBS_DEB_ASSOC); |
176 | 266 | ||
177 | /* Set or remove WEP keys */ | 267 | /* Set or remove WEP keys */ |
178 | if ( assoc_req->wep_keys[0].len | 268 | if ( assoc_req->wep_keys[0].len |
@@ -216,7 +306,7 @@ static int assoc_helper_wep_keys(wlan_private *priv, | |||
216 | mutex_unlock(&adapter->lock); | 306 | mutex_unlock(&adapter->lock); |
217 | 307 | ||
218 | out: | 308 | out: |
219 | LEAVE(); | 309 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
220 | return ret; | 310 | return ret; |
221 | } | 311 | } |
222 | 312 | ||
@@ -226,14 +316,24 @@ static int assoc_helper_secinfo(wlan_private *priv, | |||
226 | wlan_adapter *adapter = priv->adapter; | 316 | wlan_adapter *adapter = priv->adapter; |
227 | int ret = 0; | 317 | int ret = 0; |
228 | 318 | ||
229 | ENTER(); | 319 | lbs_deb_enter(LBS_DEB_ASSOC); |
230 | 320 | ||
231 | memcpy(&adapter->secinfo, &assoc_req->secinfo, | 321 | memcpy(&adapter->secinfo, &assoc_req->secinfo, |
232 | sizeof(struct wlan_802_11_security)); | 322 | sizeof(struct wlan_802_11_security)); |
233 | 323 | ||
234 | ret = libertas_set_mac_packet_filter(priv); | 324 | ret = libertas_set_mac_packet_filter(priv); |
325 | if (ret) | ||
326 | goto out; | ||
327 | |||
328 | /* enable/disable RSN */ | ||
329 | ret = libertas_prepare_and_send_command(priv, | ||
330 | cmd_802_11_enable_rsn, | ||
331 | cmd_act_set, | ||
332 | cmd_option_waitforrsp, | ||
333 | 0, assoc_req); | ||
235 | 334 | ||
236 | LEAVE(); | 335 | out: |
336 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); | ||
237 | return ret; | 337 | return ret; |
238 | } | 338 | } |
239 | 339 | ||
@@ -243,16 +343,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv, | |||
243 | { | 343 | { |
244 | int ret = 0; | 344 | int ret = 0; |
245 | 345 | ||
246 | ENTER(); | 346 | lbs_deb_enter(LBS_DEB_ASSOC); |
247 | |||
248 | /* enable/Disable RSN */ | ||
249 | ret = libertas_prepare_and_send_command(priv, | ||
250 | cmd_802_11_enable_rsn, | ||
251 | cmd_act_set, | ||
252 | cmd_option_waitforrsp, | ||
253 | 0, assoc_req); | ||
254 | if (ret) | ||
255 | goto out; | ||
256 | 347 | ||
257 | ret = libertas_prepare_and_send_command(priv, | 348 | ret = libertas_prepare_and_send_command(priv, |
258 | cmd_802_11_key_material, | 349 | cmd_802_11_key_material, |
@@ -260,8 +351,7 @@ static int assoc_helper_wpa_keys(wlan_private *priv, | |||
260 | cmd_option_waitforrsp, | 351 | cmd_option_waitforrsp, |
261 | 0, assoc_req); | 352 | 0, assoc_req); |
262 | 353 | ||
263 | out: | 354 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
264 | LEAVE(); | ||
265 | return ret; | 355 | return ret; |
266 | } | 356 | } |
267 | 357 | ||
@@ -272,7 +362,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv, | |||
272 | wlan_adapter *adapter = priv->adapter; | 362 | wlan_adapter *adapter = priv->adapter; |
273 | int ret = 0; | 363 | int ret = 0; |
274 | 364 | ||
275 | ENTER(); | 365 | lbs_deb_enter(LBS_DEB_ASSOC); |
276 | 366 | ||
277 | if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { | 367 | if (assoc_req->secinfo.WPAenabled || assoc_req->secinfo.WPA2enabled) { |
278 | memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len); | 368 | memcpy(&adapter->wpa_ie, &assoc_req->wpa_ie, assoc_req->wpa_ie_len); |
@@ -282,7 +372,7 @@ static int assoc_helper_wpa_ie(wlan_private *priv, | |||
282 | adapter->wpa_ie_len = 0; | 372 | adapter->wpa_ie_len = 0; |
283 | } | 373 | } |
284 | 374 | ||
285 | LEAVE(); | 375 | lbs_deb_leave_args(LBS_DEB_ASSOC, "ret %d", ret); |
286 | return ret; | 376 | return ret; |
287 | } | 377 | } |
288 | 378 | ||
@@ -294,21 +384,21 @@ static int should_deauth_infrastructure(wlan_adapter *adapter, | |||
294 | return 0; | 384 | return 0; |
295 | 385 | ||
296 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { | 386 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { |
297 | lbs_pr_debug(1, "Deauthenticating due to new SSID in " | 387 | lbs_deb_assoc("Deauthenticating due to new SSID in " |
298 | " configuration request.\n"); | 388 | " configuration request.\n"); |
299 | return 1; | 389 | return 1; |
300 | } | 390 | } |
301 | 391 | ||
302 | if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { | 392 | if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { |
303 | if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) { | 393 | if (adapter->secinfo.auth_mode != assoc_req->secinfo.auth_mode) { |
304 | lbs_pr_debug(1, "Deauthenticating due to updated security " | 394 | lbs_deb_assoc("Deauthenticating due to updated security " |
305 | "info in configuration request.\n"); | 395 | "info in configuration request.\n"); |
306 | return 1; | 396 | return 1; |
307 | } | 397 | } |
308 | } | 398 | } |
309 | 399 | ||
310 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { | 400 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { |
311 | lbs_pr_debug(1, "Deauthenticating due to new BSSID in " | 401 | lbs_deb_assoc("Deauthenticating due to new BSSID in " |
312 | " configuration request.\n"); | 402 | " configuration request.\n"); |
313 | return 1; | 403 | return 1; |
314 | } | 404 | } |
@@ -329,10 +419,9 @@ static int should_stop_adhoc(wlan_adapter *adapter, | |||
329 | if (adapter->connect_status != libertas_connected) | 419 | if (adapter->connect_status != libertas_connected) |
330 | return 0; | 420 | return 0; |
331 | 421 | ||
332 | if (adapter->curbssparams.ssid.ssidlength != assoc_req->ssid.ssidlength) | 422 | if (libertas_ssid_cmp(adapter->curbssparams.ssid, |
333 | return 1; | 423 | adapter->curbssparams.ssid_len, |
334 | if (memcmp(adapter->curbssparams.ssid.ssid, assoc_req->ssid.ssid, | 424 | assoc_req->ssid, assoc_req->ssid_len) != 0) |
335 | adapter->curbssparams.ssid.ssidlength)) | ||
336 | return 1; | 425 | return 1; |
337 | 426 | ||
338 | /* FIXME: deal with 'auto' mode somehow */ | 427 | /* FIXME: deal with 'auto' mode somehow */ |
@@ -341,11 +430,16 @@ static int should_stop_adhoc(wlan_adapter *adapter, | |||
341 | return 1; | 430 | return 1; |
342 | } | 431 | } |
343 | 432 | ||
433 | if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { | ||
434 | if (assoc_req->channel != adapter->curbssparams.channel) | ||
435 | return 1; | ||
436 | } | ||
437 | |||
344 | return 0; | 438 | return 0; |
345 | } | 439 | } |
346 | 440 | ||
347 | 441 | ||
348 | void wlan_association_worker(struct work_struct *work) | 442 | void libertas_association_worker(struct work_struct *work) |
349 | { | 443 | { |
350 | wlan_private *priv = container_of(work, wlan_private, assoc_work.work); | 444 | wlan_private *priv = container_of(work, wlan_private, assoc_work.work); |
351 | wlan_adapter *adapter = priv->adapter; | 445 | wlan_adapter *adapter = priv->adapter; |
@@ -353,40 +447,38 @@ void wlan_association_worker(struct work_struct *work) | |||
353 | int ret = 0; | 447 | int ret = 0; |
354 | int find_any_ssid = 0; | 448 | int find_any_ssid = 0; |
355 | 449 | ||
356 | ENTER(); | 450 | lbs_deb_enter(LBS_DEB_ASSOC); |
357 | 451 | ||
358 | mutex_lock(&adapter->lock); | 452 | mutex_lock(&adapter->lock); |
359 | assoc_req = adapter->assoc_req; | 453 | assoc_req = adapter->pending_assoc_req; |
360 | adapter->assoc_req = NULL; | 454 | adapter->pending_assoc_req = NULL; |
455 | adapter->in_progress_assoc_req = assoc_req; | ||
361 | mutex_unlock(&adapter->lock); | 456 | mutex_unlock(&adapter->lock); |
362 | 457 | ||
363 | if (!assoc_req) { | 458 | if (!assoc_req) |
364 | LEAVE(); | 459 | goto done; |
365 | return; | ||
366 | } | ||
367 | 460 | ||
368 | lbs_pr_debug(1, "ASSOC: starting new association request: flags = 0x%lX\n", | 461 | print_assoc_req(__func__, assoc_req); |
369 | assoc_req->flags); | ||
370 | 462 | ||
371 | /* If 'any' SSID was specified, find an SSID to associate with */ | 463 | /* If 'any' SSID was specified, find an SSID to associate with */ |
372 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) | 464 | if (test_bit(ASSOC_FLAG_SSID, &assoc_req->flags) |
373 | && !assoc_req->ssid.ssidlength) | 465 | && !assoc_req->ssid_len) |
374 | find_any_ssid = 1; | 466 | find_any_ssid = 1; |
375 | 467 | ||
376 | /* But don't use 'any' SSID if there's a valid locked BSSID to use */ | 468 | /* But don't use 'any' SSID if there's a valid locked BSSID to use */ |
377 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { | 469 | if (test_bit(ASSOC_FLAG_BSSID, &assoc_req->flags)) { |
378 | if (memcmp(&assoc_req->bssid, bssid_any, ETH_ALEN) | 470 | if (compare_ether_addr(assoc_req->bssid, bssid_any) |
379 | && memcmp(&assoc_req->bssid, bssid_off, ETH_ALEN)) | 471 | && compare_ether_addr(assoc_req->bssid, bssid_off)) |
380 | find_any_ssid = 0; | 472 | find_any_ssid = 0; |
381 | } | 473 | } |
382 | 474 | ||
383 | if (find_any_ssid) { | 475 | if (find_any_ssid) { |
384 | u8 new_mode; | 476 | u8 new_mode; |
385 | 477 | ||
386 | ret = libertas_find_best_network_SSID(priv, &assoc_req->ssid, | 478 | ret = libertas_find_best_network_ssid(priv, assoc_req->ssid, |
387 | assoc_req->mode, &new_mode); | 479 | &assoc_req->ssid_len, assoc_req->mode, &new_mode); |
388 | if (ret) { | 480 | if (ret) { |
389 | lbs_pr_debug(1, "Could not find best network\n"); | 481 | lbs_deb_assoc("Could not find best network\n"); |
390 | ret = -ENETUNREACH; | 482 | ret = -ENETUNREACH; |
391 | goto out; | 483 | goto out; |
392 | } | 484 | } |
@@ -406,7 +498,7 @@ void wlan_association_worker(struct work_struct *work) | |||
406 | if (should_deauth_infrastructure(adapter, assoc_req)) { | 498 | if (should_deauth_infrastructure(adapter, assoc_req)) { |
407 | ret = libertas_send_deauthentication(priv); | 499 | ret = libertas_send_deauthentication(priv); |
408 | if (ret) { | 500 | if (ret) { |
409 | lbs_pr_debug(1, "Deauthentication due to new " | 501 | lbs_deb_assoc("Deauthentication due to new " |
410 | "configuration request failed: %d\n", | 502 | "configuration request failed: %d\n", |
411 | ret); | 503 | ret); |
412 | } | 504 | } |
@@ -415,7 +507,7 @@ void wlan_association_worker(struct work_struct *work) | |||
415 | if (should_stop_adhoc(adapter, assoc_req)) { | 507 | if (should_stop_adhoc(adapter, assoc_req)) { |
416 | ret = libertas_stop_adhoc_network(priv); | 508 | ret = libertas_stop_adhoc_network(priv); |
417 | if (ret) { | 509 | if (ret) { |
418 | lbs_pr_debug(1, "Teardown of AdHoc network due to " | 510 | lbs_deb_assoc("Teardown of AdHoc network due to " |
419 | "new configuration request failed: %d\n", | 511 | "new configuration request failed: %d\n", |
420 | ret); | 512 | ret); |
421 | } | 513 | } |
@@ -427,7 +519,16 @@ void wlan_association_worker(struct work_struct *work) | |||
427 | if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { | 519 | if (test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) { |
428 | ret = assoc_helper_mode(priv, assoc_req); | 520 | ret = assoc_helper_mode(priv, assoc_req); |
429 | if (ret) { | 521 | if (ret) { |
430 | lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret); | 522 | lbs_deb_assoc("ASSOC(:%d) mode: ret = %d\n", __LINE__, ret); |
523 | goto out; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | if (test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) { | ||
528 | ret = assoc_helper_channel(priv, assoc_req); | ||
529 | if (ret) { | ||
530 | lbs_deb_assoc("ASSOC(:%d) channel: ret = %d\n", | ||
531 | __LINE__, ret); | ||
431 | goto out; | 532 | goto out; |
432 | } | 533 | } |
433 | } | 534 | } |
@@ -436,7 +537,7 @@ lbs_pr_debug(1, "ASSOC(:%d) mode: ret = %d\n", __LINE__, ret); | |||
436 | || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { | 537 | || test_bit(ASSOC_FLAG_WEP_TX_KEYIDX, &assoc_req->flags)) { |
437 | ret = assoc_helper_wep_keys(priv, assoc_req); | 538 | ret = assoc_helper_wep_keys(priv, assoc_req); |
438 | if (ret) { | 539 | if (ret) { |
439 | lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret); | 540 | lbs_deb_assoc("ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret); |
440 | goto out; | 541 | goto out; |
441 | } | 542 | } |
442 | } | 543 | } |
@@ -444,7 +545,7 @@ lbs_pr_debug(1, "ASSOC(:%d) wep_keys: ret = %d\n", __LINE__, ret); | |||
444 | if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { | 545 | if (test_bit(ASSOC_FLAG_SECINFO, &assoc_req->flags)) { |
445 | ret = assoc_helper_secinfo(priv, assoc_req); | 546 | ret = assoc_helper_secinfo(priv, assoc_req); |
446 | if (ret) { | 547 | if (ret) { |
447 | lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret); | 548 | lbs_deb_assoc("ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret); |
448 | goto out; | 549 | goto out; |
449 | } | 550 | } |
450 | } | 551 | } |
@@ -452,7 +553,7 @@ lbs_pr_debug(1, "ASSOC(:%d) secinfo: ret = %d\n", __LINE__, ret); | |||
452 | if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { | 553 | if (test_bit(ASSOC_FLAG_WPA_IE, &assoc_req->flags)) { |
453 | ret = assoc_helper_wpa_ie(priv, assoc_req); | 554 | ret = assoc_helper_wpa_ie(priv, assoc_req); |
454 | if (ret) { | 555 | if (ret) { |
455 | lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret); | 556 | lbs_deb_assoc("ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret); |
456 | goto out; | 557 | goto out; |
457 | } | 558 | } |
458 | } | 559 | } |
@@ -461,7 +562,7 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_ie: ret = %d\n", __LINE__, ret); | |||
461 | || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { | 562 | || test_bit(ASSOC_FLAG_WPA_UCAST_KEY, &assoc_req->flags)) { |
462 | ret = assoc_helper_wpa_keys(priv, assoc_req); | 563 | ret = assoc_helper_wpa_keys(priv, assoc_req); |
463 | if (ret) { | 564 | if (ret) { |
464 | lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); | 565 | lbs_deb_assoc("ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); |
465 | goto out; | 566 | goto out; |
466 | } | 567 | } |
467 | } | 568 | } |
@@ -475,21 +576,23 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); | |||
475 | 576 | ||
476 | ret = assoc_helper_associate(priv, assoc_req); | 577 | ret = assoc_helper_associate(priv, assoc_req); |
477 | if (ret) { | 578 | if (ret) { |
478 | lbs_pr_debug(1, "ASSOC: association attempt unsuccessful: %d\n", | 579 | lbs_deb_assoc("ASSOC: association attempt unsuccessful: %d\n", |
479 | ret); | 580 | ret); |
480 | success = 0; | 581 | success = 0; |
481 | } | 582 | } |
482 | 583 | ||
483 | if (adapter->connect_status != libertas_connected) { | 584 | if (adapter->connect_status != libertas_connected) { |
484 | lbs_pr_debug(1, "ASSOC: assoication attempt unsuccessful, " | 585 | lbs_deb_assoc("ASSOC: assoication attempt unsuccessful, " |
485 | "not connected.\n"); | 586 | "not connected.\n"); |
486 | success = 0; | 587 | success = 0; |
487 | } | 588 | } |
488 | 589 | ||
489 | if (success) { | 590 | if (success) { |
490 | lbs_pr_debug(1, "ASSOC: association attempt successful. " | 591 | lbs_deb_assoc("ASSOC: association attempt successful. " |
491 | "Associated to '%s' (" MAC_FMT ")\n", | 592 | "Associated to '%s' (" MAC_FMT ")\n", |
492 | assoc_req->ssid.ssid, MAC_ARG(assoc_req->bssid)); | 593 | escape_essid(adapter->curbssparams.ssid, |
594 | adapter->curbssparams.ssid_len), | ||
595 | MAC_ARG(adapter->curbssparams.bssid)); | ||
493 | libertas_prepare_and_send_command(priv, | 596 | libertas_prepare_and_send_command(priv, |
494 | cmd_802_11_rssi, | 597 | cmd_802_11_rssi, |
495 | 0, cmd_option_waitforrsp, 0, NULL); | 598 | 0, cmd_option_waitforrsp, 0, NULL); |
@@ -498,18 +601,23 @@ lbs_pr_debug(1, "ASSOC(:%d) wpa_keys: ret = %d\n", __LINE__, ret); | |||
498 | cmd_802_11_get_log, | 601 | cmd_802_11_get_log, |
499 | 0, cmd_option_waitforrsp, 0, NULL); | 602 | 0, cmd_option_waitforrsp, 0, NULL); |
500 | } else { | 603 | } else { |
501 | |||
502 | ret = -1; | 604 | ret = -1; |
503 | } | 605 | } |
504 | } | 606 | } |
505 | 607 | ||
506 | out: | 608 | out: |
507 | if (ret) { | 609 | if (ret) { |
508 | lbs_pr_debug(1, "ASSOC: reconfiguration attempt unsuccessful: %d\n", | 610 | lbs_deb_assoc("ASSOC: reconfiguration attempt unsuccessful: %d\n", |
509 | ret); | 611 | ret); |
510 | } | 612 | } |
613 | |||
614 | mutex_lock(&adapter->lock); | ||
615 | adapter->in_progress_assoc_req = NULL; | ||
616 | mutex_unlock(&adapter->lock); | ||
511 | kfree(assoc_req); | 617 | kfree(assoc_req); |
512 | LEAVE(); | 618 | |
619 | done: | ||
620 | lbs_deb_leave(LBS_DEB_ASSOC); | ||
513 | } | 621 | } |
514 | 622 | ||
515 | 623 | ||
@@ -520,9 +628,10 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) | |||
520 | { | 628 | { |
521 | struct assoc_request * assoc_req; | 629 | struct assoc_request * assoc_req; |
522 | 630 | ||
523 | if (!adapter->assoc_req) { | 631 | if (!adapter->pending_assoc_req) { |
524 | adapter->assoc_req = kzalloc(sizeof(struct assoc_request), GFP_KERNEL); | 632 | adapter->pending_assoc_req = kzalloc(sizeof(struct assoc_request), |
525 | if (!adapter->assoc_req) { | 633 | GFP_KERNEL); |
634 | if (!adapter->pending_assoc_req) { | ||
526 | lbs_pr_info("Not enough memory to allocate association" | 635 | lbs_pr_info("Not enough memory to allocate association" |
527 | " request!\n"); | 636 | " request!\n"); |
528 | return NULL; | 637 | return NULL; |
@@ -532,15 +641,19 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) | |||
532 | /* Copy current configuration attributes to the association request, | 641 | /* Copy current configuration attributes to the association request, |
533 | * but don't overwrite any that are already set. | 642 | * but don't overwrite any that are already set. |
534 | */ | 643 | */ |
535 | assoc_req = adapter->assoc_req; | 644 | assoc_req = adapter->pending_assoc_req; |
536 | if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { | 645 | if (!test_bit(ASSOC_FLAG_SSID, &assoc_req->flags)) { |
537 | memcpy(&assoc_req->ssid, adapter->curbssparams.ssid.ssid, | 646 | memcpy(&assoc_req->ssid, &adapter->curbssparams.ssid, |
538 | adapter->curbssparams.ssid.ssidlength); | 647 | IW_ESSID_MAX_SIZE); |
648 | assoc_req->ssid_len = adapter->curbssparams.ssid_len; | ||
539 | } | 649 | } |
540 | 650 | ||
541 | if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) | 651 | if (!test_bit(ASSOC_FLAG_CHANNEL, &assoc_req->flags)) |
542 | assoc_req->channel = adapter->curbssparams.channel; | 652 | assoc_req->channel = adapter->curbssparams.channel; |
543 | 653 | ||
654 | if (!test_bit(ASSOC_FLAG_BAND, &assoc_req->flags)) | ||
655 | assoc_req->band = adapter->curbssparams.band; | ||
656 | |||
544 | if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) | 657 | if (!test_bit(ASSOC_FLAG_MODE, &assoc_req->flags)) |
545 | assoc_req->mode = adapter->mode; | 658 | assoc_req->mode = adapter->mode; |
546 | 659 | ||
@@ -581,7 +694,7 @@ struct assoc_request * wlan_get_association_request(wlan_adapter *adapter) | |||
581 | assoc_req->wpa_ie_len = adapter->wpa_ie_len; | 694 | assoc_req->wpa_ie_len = adapter->wpa_ie_len; |
582 | } | 695 | } |
583 | 696 | ||
697 | print_assoc_req(__func__, assoc_req); | ||
698 | |||
584 | return assoc_req; | 699 | return assoc_req; |
585 | } | 700 | } |
586 | |||
587 | |||