diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-12-23 07:15:34 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-12-28 16:54:54 -0500 |
commit | f679f65d417c3ea3f91b4bbfb68e3951c9eb8f04 (patch) | |
tree | d4fb47f1197d175fa1851a1d4f75d78246ef4106 | |
parent | 63f170e0c80a131cdd549fab7afb5036009944fc (diff) |
mac80211: generalise management work a bit
As a first step of generalising management work,
this renames a few things and puts more information
directly into the struct so that auth/assoc need
not access the BSS pointer as often -- in fact it
can be removed from auth completely. Also since the
previous patch made sure a new work item is used
for association, we can make the different data a
union.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | net/mac80211/ieee80211_i.h | 53 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 226 |
2 files changed, 172 insertions, 107 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index e21e0301548b..0339e909e0c4 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -227,31 +227,48 @@ struct mesh_preq_queue { | |||
227 | u8 flags; | 227 | u8 flags; |
228 | }; | 228 | }; |
229 | 229 | ||
230 | enum ieee80211_mgd_state { | 230 | enum ieee80211_work_type { |
231 | IEEE80211_MGD_STATE_INVALID, | 231 | IEEE80211_WORK_AUTH_PROBE, |
232 | IEEE80211_MGD_STATE_PROBE, | 232 | IEEE80211_WORK_AUTH, |
233 | IEEE80211_MGD_STATE_AUTH, | 233 | IEEE80211_WORK_ASSOC, |
234 | IEEE80211_MGD_STATE_ASSOC, | ||
235 | }; | 234 | }; |
236 | 235 | ||
237 | struct ieee80211_mgd_work { | 236 | struct ieee80211_work { |
238 | struct list_head list; | 237 | struct list_head list; |
239 | struct ieee80211_bss *bss; | ||
240 | int ie_len; | ||
241 | u8 prev_bssid[ETH_ALEN]; | ||
242 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | ||
243 | u8 ssid_len; | ||
244 | unsigned long timeout; | ||
245 | enum ieee80211_mgd_state state; | ||
246 | u16 auth_alg, auth_transaction; | ||
247 | 238 | ||
248 | int tries; | 239 | struct ieee80211_channel *chan; |
240 | /* XXX: chan type? -- right now not really needed */ | ||
241 | unsigned long timeout; | ||
242 | enum ieee80211_work_type type; | ||
249 | 243 | ||
250 | u8 key[WLAN_KEY_LEN_WEP104]; | 244 | union { |
251 | u8 key_len, key_idx; | 245 | struct { |
246 | int tries; | ||
247 | u16 algorithm, transaction; | ||
248 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | ||
249 | u8 ssid_len; | ||
250 | u8 bssid[ETH_ALEN]; | ||
251 | u8 key[WLAN_KEY_LEN_WEP104]; | ||
252 | u8 key_len, key_idx; | ||
253 | bool privacy; | ||
254 | } auth; | ||
255 | struct { | ||
256 | struct ieee80211_bss *bss; | ||
257 | const u8 *supp_rates; | ||
258 | const u8 *ht_information_ie; | ||
259 | int tries; | ||
260 | u16 capability; | ||
261 | u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN]; | ||
262 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | ||
263 | u8 ssid_len; | ||
264 | u8 supp_rates_len; | ||
265 | bool wmm_used; | ||
266 | } assoc; | ||
267 | }; | ||
252 | 268 | ||
269 | int ie_len; | ||
253 | /* must be last */ | 270 | /* must be last */ |
254 | u8 ie[0]; /* for auth or assoc frame, not probe */ | 271 | u8 ie[0]; |
255 | }; | 272 | }; |
256 | 273 | ||
257 | /* flags used in struct ieee80211_if_managed.flags */ | 274 | /* flags used in struct ieee80211_if_managed.flags */ |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index f060bc616203..c65225f29bb6 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -125,15 +125,15 @@ static int ecw2cw(int ecw) | |||
125 | return (1 << ecw) - 1; | 125 | return (1 << ecw) - 1; |
126 | } | 126 | } |
127 | 127 | ||
128 | static int ieee80211_compatible_rates(struct ieee80211_bss *bss, | 128 | static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len, |
129 | struct ieee80211_supported_band *sband, | 129 | struct ieee80211_supported_band *sband, |
130 | u32 *rates) | 130 | u32 *rates) |
131 | { | 131 | { |
132 | int i, j, count; | 132 | int i, j, count; |
133 | *rates = 0; | 133 | *rates = 0; |
134 | count = 0; | 134 | count = 0; |
135 | for (i = 0; i < bss->supp_rates_len; i++) { | 135 | for (i = 0; i < supp_rates_len; i++) { |
136 | int rate = (bss->supp_rates[i] & 0x7F) * 5; | 136 | int rate = (supp_rates[i] & 0x7F) * 5; |
137 | 137 | ||
138 | for (j = 0; j < sband->n_bitrates; j++) | 138 | for (j = 0; j < sband->n_bitrates; j++) |
139 | if (sband->bitrates[j].bitrate == rate) { | 139 | if (sband->bitrates[j].bitrate == rate) { |
@@ -232,7 +232,7 @@ static u32 ieee80211_enable_ht(struct ieee80211_sub_if_data *sdata, | |||
232 | /* frame sending functions */ | 232 | /* frame sending functions */ |
233 | 233 | ||
234 | static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | 234 | static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, |
235 | struct ieee80211_mgd_work *wk) | 235 | struct ieee80211_work *wk) |
236 | { | 236 | { |
237 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 237 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
238 | struct ieee80211_local *local = sdata->local; | 238 | struct ieee80211_local *local = sdata->local; |
@@ -248,7 +248,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
248 | 248 | ||
249 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | 249 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + |
250 | sizeof(*mgmt) + 200 + wk->ie_len + | 250 | sizeof(*mgmt) + 200 + wk->ie_len + |
251 | wk->ssid_len); | 251 | wk->assoc.ssid_len); |
252 | if (!skb) { | 252 | if (!skb) { |
253 | printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " | 253 | printk(KERN_DEBUG "%s: failed to allocate buffer for assoc " |
254 | "frame\n", sdata->name); | 254 | "frame\n", sdata->name); |
@@ -267,35 +267,37 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
267 | capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; | 267 | capab |= WLAN_CAPABILITY_SHORT_PREAMBLE; |
268 | } | 268 | } |
269 | 269 | ||
270 | if (wk->bss->cbss.capability & WLAN_CAPABILITY_PRIVACY) | 270 | if (wk->assoc.capability & WLAN_CAPABILITY_PRIVACY) |
271 | capab |= WLAN_CAPABILITY_PRIVACY; | 271 | capab |= WLAN_CAPABILITY_PRIVACY; |
272 | if (wk->bss->wmm_used) | 272 | if (wk->assoc.wmm_used) |
273 | wmm = 1; | 273 | wmm = 1; |
274 | 274 | ||
275 | /* get all rates supported by the device and the AP as | 275 | /* get all rates supported by the device and the AP as |
276 | * some APs don't like getting a superset of their rates | 276 | * some APs don't like getting a superset of their rates |
277 | * in the association request (e.g. D-Link DAP 1353 in | 277 | * in the association request (e.g. D-Link DAP 1353 in |
278 | * b-only mode) */ | 278 | * b-only mode) */ |
279 | rates_len = ieee80211_compatible_rates(wk->bss, sband, &rates); | 279 | rates_len = ieee80211_compatible_rates(wk->assoc.supp_rates, |
280 | wk->assoc.supp_rates_len, | ||
281 | sband, &rates); | ||
280 | 282 | ||
281 | if ((wk->bss->cbss.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && | 283 | if ((wk->assoc.capability & WLAN_CAPABILITY_SPECTRUM_MGMT) && |
282 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) | 284 | (local->hw.flags & IEEE80211_HW_SPECTRUM_MGMT)) |
283 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; | 285 | capab |= WLAN_CAPABILITY_SPECTRUM_MGMT; |
284 | 286 | ||
285 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); | 287 | mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); |
286 | memset(mgmt, 0, 24); | 288 | memset(mgmt, 0, 24); |
287 | memcpy(mgmt->da, wk->bss->cbss.bssid, ETH_ALEN); | 289 | memcpy(mgmt->da, wk->assoc.bssid, ETH_ALEN); |
288 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); | 290 | memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); |
289 | memcpy(mgmt->bssid, wk->bss->cbss.bssid, ETH_ALEN); | 291 | memcpy(mgmt->bssid, wk->assoc.bssid, ETH_ALEN); |
290 | 292 | ||
291 | if (!is_zero_ether_addr(wk->prev_bssid)) { | 293 | if (!is_zero_ether_addr(wk->assoc.prev_bssid)) { |
292 | skb_put(skb, 10); | 294 | skb_put(skb, 10); |
293 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | | 295 | mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | |
294 | IEEE80211_STYPE_REASSOC_REQ); | 296 | IEEE80211_STYPE_REASSOC_REQ); |
295 | mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab); | 297 | mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab); |
296 | mgmt->u.reassoc_req.listen_interval = | 298 | mgmt->u.reassoc_req.listen_interval = |
297 | cpu_to_le16(local->hw.conf.listen_interval); | 299 | cpu_to_le16(local->hw.conf.listen_interval); |
298 | memcpy(mgmt->u.reassoc_req.current_ap, wk->prev_bssid, | 300 | memcpy(mgmt->u.reassoc_req.current_ap, wk->assoc.prev_bssid, |
299 | ETH_ALEN); | 301 | ETH_ALEN); |
300 | } else { | 302 | } else { |
301 | skb_put(skb, 4); | 303 | skb_put(skb, 4); |
@@ -307,10 +309,10 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
307 | } | 309 | } |
308 | 310 | ||
309 | /* SSID */ | 311 | /* SSID */ |
310 | ies = pos = skb_put(skb, 2 + wk->ssid_len); | 312 | ies = pos = skb_put(skb, 2 + wk->assoc.ssid_len); |
311 | *pos++ = WLAN_EID_SSID; | 313 | *pos++ = WLAN_EID_SSID; |
312 | *pos++ = wk->ssid_len; | 314 | *pos++ = wk->assoc.ssid_len; |
313 | memcpy(pos, wk->ssid, wk->ssid_len); | 315 | memcpy(pos, wk->assoc.ssid, wk->assoc.ssid_len); |
314 | 316 | ||
315 | /* add all rates which were marked to be used above */ | 317 | /* add all rates which were marked to be used above */ |
316 | supp_rates_len = rates_len; | 318 | supp_rates_len = rates_len; |
@@ -392,7 +394,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata, | |||
392 | */ | 394 | */ |
393 | if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) && | 395 | if (wmm && (ifmgd->flags & IEEE80211_STA_WMM_ENABLED) && |
394 | sband->ht_cap.ht_supported && | 396 | sband->ht_cap.ht_supported && |
395 | (ht_ie = ieee80211_bss_get_ie(&wk->bss->cbss, WLAN_EID_HT_INFORMATION)) && | 397 | (ht_ie = wk->assoc.ht_information_ie) && |
396 | ht_ie[1] >= sizeof(struct ieee80211_ht_info) && | 398 | ht_ie[1] >= sizeof(struct ieee80211_ht_info) && |
397 | (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))) { | 399 | (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N))) { |
398 | struct ieee80211_ht_info *ht_info = | 400 | struct ieee80211_ht_info *ht_info = |
@@ -1003,23 +1005,43 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1003 | netif_carrier_on(sdata->dev); | 1005 | netif_carrier_on(sdata->dev); |
1004 | } | 1006 | } |
1005 | 1007 | ||
1008 | static void ieee80211_remove_auth_bss(struct ieee80211_local *local, | ||
1009 | struct ieee80211_work *wk) | ||
1010 | { | ||
1011 | struct cfg80211_bss *cbss; | ||
1012 | u16 capa_val = WLAN_CAPABILITY_ESS; | ||
1013 | |||
1014 | if (wk->auth.privacy) | ||
1015 | capa_val |= WLAN_CAPABILITY_PRIVACY; | ||
1016 | |||
1017 | cbss = cfg80211_get_bss(local->hw.wiphy, wk->chan, wk->auth.bssid, | ||
1018 | wk->auth.ssid, wk->auth.ssid_len, | ||
1019 | WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_PRIVACY, | ||
1020 | capa_val); | ||
1021 | if (!cbss) | ||
1022 | return; | ||
1023 | |||
1024 | cfg80211_unlink_bss(local->hw.wiphy, cbss); | ||
1025 | cfg80211_put_bss(cbss); | ||
1026 | } | ||
1027 | |||
1006 | static enum rx_mgmt_action __must_check | 1028 | static enum rx_mgmt_action __must_check |
1007 | ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | 1029 | ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, |
1008 | struct ieee80211_mgd_work *wk) | 1030 | struct ieee80211_work *wk) |
1009 | { | 1031 | { |
1010 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1032 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1011 | struct ieee80211_local *local = sdata->local; | 1033 | struct ieee80211_local *local = sdata->local; |
1012 | 1034 | ||
1013 | wk->tries++; | 1035 | wk->auth.tries++; |
1014 | if (wk->tries > IEEE80211_AUTH_MAX_TRIES) { | 1036 | if (wk->auth.tries > IEEE80211_AUTH_MAX_TRIES) { |
1015 | printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n", | 1037 | printk(KERN_DEBUG "%s: direct probe to AP %pM timed out\n", |
1016 | sdata->name, wk->bss->cbss.bssid); | 1038 | sdata->name, wk->auth.bssid); |
1017 | 1039 | ||
1018 | /* | 1040 | /* |
1019 | * Most likely AP is not in the range so remove the | 1041 | * Most likely AP is not in the range so remove the |
1020 | * bss struct for that AP. | 1042 | * bss struct for that AP. |
1021 | */ | 1043 | */ |
1022 | cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss); | 1044 | ieee80211_remove_auth_bss(local, wk); |
1023 | 1045 | ||
1024 | /* | 1046 | /* |
1025 | * We might have a pending scan which had no chance to run yet | 1047 | * We might have a pending scan which had no chance to run yet |
@@ -1031,14 +1053,14 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | |||
1031 | } | 1053 | } |
1032 | 1054 | ||
1033 | printk(KERN_DEBUG "%s: direct probe to AP %pM (try %d)\n", | 1055 | printk(KERN_DEBUG "%s: direct probe to AP %pM (try %d)\n", |
1034 | sdata->name, wk->bss->cbss.bssid, | 1056 | sdata->name, wk->auth.bssid, wk->auth.tries); |
1035 | wk->tries); | ||
1036 | 1057 | ||
1037 | /* | 1058 | /* |
1038 | * Direct probe is sent to broadcast address as some APs | 1059 | * Direct probe is sent to broadcast address as some APs |
1039 | * will not answer to direct packet in unassociated state. | 1060 | * will not answer to direct packet in unassociated state. |
1040 | */ | 1061 | */ |
1041 | ieee80211_send_probe_req(sdata, NULL, wk->ssid, wk->ssid_len, NULL, 0); | 1062 | ieee80211_send_probe_req(sdata, NULL, wk->auth.ssid, wk->auth.ssid_len, |
1063 | NULL, 0); | ||
1042 | 1064 | ||
1043 | wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; | 1065 | wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; |
1044 | run_again(ifmgd, wk->timeout); | 1066 | run_again(ifmgd, wk->timeout); |
@@ -1049,22 +1071,21 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata, | |||
1049 | 1071 | ||
1050 | static enum rx_mgmt_action __must_check | 1072 | static enum rx_mgmt_action __must_check |
1051 | ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, | 1073 | ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, |
1052 | struct ieee80211_mgd_work *wk) | 1074 | struct ieee80211_work *wk) |
1053 | { | 1075 | { |
1054 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1076 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1055 | struct ieee80211_local *local = sdata->local; | 1077 | struct ieee80211_local *local = sdata->local; |
1056 | 1078 | ||
1057 | wk->tries++; | 1079 | wk->auth.tries++; |
1058 | if (wk->tries > IEEE80211_AUTH_MAX_TRIES) { | 1080 | if (wk->auth.tries > IEEE80211_AUTH_MAX_TRIES) { |
1059 | printk(KERN_DEBUG "%s: authentication with AP %pM" | 1081 | printk(KERN_DEBUG "%s: authentication with AP %pM" |
1060 | " timed out\n", | 1082 | " timed out\n", sdata->name, wk->auth.bssid); |
1061 | sdata->name, wk->bss->cbss.bssid); | ||
1062 | 1083 | ||
1063 | /* | 1084 | /* |
1064 | * Most likely AP is not in the range so remove the | 1085 | * Most likely AP is not in the range so remove the |
1065 | * bss struct for that AP. | 1086 | * bss struct for that AP. |
1066 | */ | 1087 | */ |
1067 | cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss); | 1088 | ieee80211_remove_auth_bss(local, wk); |
1068 | 1089 | ||
1069 | /* | 1090 | /* |
1070 | * We might have a pending scan which had no chance to run yet | 1091 | * We might have a pending scan which had no chance to run yet |
@@ -1076,11 +1097,11 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata, | |||
1076 | } | 1097 | } |
1077 | 1098 | ||
1078 | printk(KERN_DEBUG "%s: authenticate with AP %pM (try %d)\n", | 1099 | printk(KERN_DEBUG "%s: authenticate with AP %pM (try %d)\n", |
1079 | sdata->name, wk->bss->cbss.bssid, wk->tries); | 1100 | sdata->name, wk->auth.bssid, wk->auth.tries); |
1080 | 1101 | ||
1081 | ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len, | 1102 | ieee80211_send_auth(sdata, 1, wk->auth.algorithm, wk->ie, wk->ie_len, |
1082 | wk->bss->cbss.bssid, NULL, 0, 0); | 1103 | wk->auth.bssid, NULL, 0, 0); |
1083 | wk->auth_transaction = 2; | 1104 | wk->auth.transaction = 2; |
1084 | 1105 | ||
1085 | wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; | 1106 | wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; |
1086 | run_again(ifmgd, wk->timeout); | 1107 | run_again(ifmgd, wk->timeout); |
@@ -1176,22 +1197,22 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata) | |||
1176 | 1197 | ||
1177 | static enum rx_mgmt_action __must_check | 1198 | static enum rx_mgmt_action __must_check |
1178 | ieee80211_associate(struct ieee80211_sub_if_data *sdata, | 1199 | ieee80211_associate(struct ieee80211_sub_if_data *sdata, |
1179 | struct ieee80211_mgd_work *wk) | 1200 | struct ieee80211_work *wk) |
1180 | { | 1201 | { |
1181 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1202 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1182 | struct ieee80211_local *local = sdata->local; | 1203 | struct ieee80211_local *local = sdata->local; |
1183 | 1204 | ||
1184 | wk->tries++; | 1205 | wk->assoc.tries++; |
1185 | if (wk->tries > IEEE80211_ASSOC_MAX_TRIES) { | 1206 | if (wk->assoc.tries > IEEE80211_ASSOC_MAX_TRIES) { |
1186 | printk(KERN_DEBUG "%s: association with AP %pM" | 1207 | printk(KERN_DEBUG "%s: association with AP %pM" |
1187 | " timed out\n", | 1208 | " timed out\n", |
1188 | sdata->name, wk->bss->cbss.bssid); | 1209 | sdata->name, wk->assoc.bssid); |
1189 | 1210 | ||
1190 | /* | 1211 | /* |
1191 | * Most likely AP is not in the range so remove the | 1212 | * Most likely AP is not in the range so remove the |
1192 | * bss struct for that AP. | 1213 | * bss struct for that AP. |
1193 | */ | 1214 | */ |
1194 | cfg80211_unlink_bss(local->hw.wiphy, &wk->bss->cbss); | 1215 | cfg80211_unlink_bss(local->hw.wiphy, &wk->assoc.bss->cbss); |
1195 | 1216 | ||
1196 | /* | 1217 | /* |
1197 | * We might have a pending scan which had no chance to run yet | 1218 | * We might have a pending scan which had no chance to run yet |
@@ -1203,7 +1224,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata, | |||
1203 | } | 1224 | } |
1204 | 1225 | ||
1205 | printk(KERN_DEBUG "%s: associate with AP %pM (try %d)\n", | 1226 | printk(KERN_DEBUG "%s: associate with AP %pM (try %d)\n", |
1206 | sdata->name, wk->bss->cbss.bssid, wk->tries); | 1227 | sdata->name, wk->assoc.bssid, wk->assoc.tries); |
1207 | ieee80211_send_assoc(sdata, wk); | 1228 | ieee80211_send_assoc(sdata, wk); |
1208 | 1229 | ||
1209 | wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; | 1230 | wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; |
@@ -1318,7 +1339,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif) | |||
1318 | EXPORT_SYMBOL(ieee80211_beacon_loss); | 1339 | EXPORT_SYMBOL(ieee80211_beacon_loss); |
1319 | 1340 | ||
1320 | static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata, | 1341 | static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata, |
1321 | struct ieee80211_mgd_work *wk) | 1342 | struct ieee80211_work *wk) |
1322 | { | 1343 | { |
1323 | list_del(&wk->list); | 1344 | list_del(&wk->list); |
1324 | kfree(wk); | 1345 | kfree(wk); |
@@ -1327,7 +1348,7 @@ static void ieee80211_auth_completed(struct ieee80211_sub_if_data *sdata, | |||
1327 | 1348 | ||
1328 | 1349 | ||
1329 | static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, | 1350 | static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, |
1330 | struct ieee80211_mgd_work *wk, | 1351 | struct ieee80211_work *wk, |
1331 | struct ieee80211_mgmt *mgmt, | 1352 | struct ieee80211_mgmt *mgmt, |
1332 | size_t len) | 1353 | size_t len) |
1333 | { | 1354 | { |
@@ -1338,38 +1359,38 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, | |||
1338 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 1359 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); |
1339 | if (!elems.challenge) | 1360 | if (!elems.challenge) |
1340 | return; | 1361 | return; |
1341 | ieee80211_send_auth(sdata, 3, wk->auth_alg, | 1362 | ieee80211_send_auth(sdata, 3, wk->auth.algorithm, |
1342 | elems.challenge - 2, elems.challenge_len + 2, | 1363 | elems.challenge - 2, elems.challenge_len + 2, |
1343 | wk->bss->cbss.bssid, | 1364 | wk->auth.bssid, wk->auth.key, wk->auth.key_len, |
1344 | wk->key, wk->key_len, wk->key_idx); | 1365 | wk->auth.key_idx); |
1345 | wk->auth_transaction = 4; | 1366 | wk->auth.transaction = 4; |
1346 | } | 1367 | } |
1347 | 1368 | ||
1348 | static enum rx_mgmt_action __must_check | 1369 | static enum rx_mgmt_action __must_check |
1349 | ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | 1370 | ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, |
1350 | struct ieee80211_mgd_work *wk, | 1371 | struct ieee80211_work *wk, |
1351 | struct ieee80211_mgmt *mgmt, size_t len) | 1372 | struct ieee80211_mgmt *mgmt, size_t len) |
1352 | { | 1373 | { |
1353 | u16 auth_alg, auth_transaction, status_code; | 1374 | u16 auth_alg, auth_transaction, status_code; |
1354 | 1375 | ||
1355 | if (wk->state != IEEE80211_MGD_STATE_AUTH) | 1376 | if (wk->type != IEEE80211_WORK_AUTH) |
1356 | return RX_MGMT_NONE; | 1377 | return RX_MGMT_NONE; |
1357 | 1378 | ||
1358 | if (len < 24 + 6) | 1379 | if (len < 24 + 6) |
1359 | return RX_MGMT_NONE; | 1380 | return RX_MGMT_NONE; |
1360 | 1381 | ||
1361 | if (memcmp(wk->bss->cbss.bssid, mgmt->sa, ETH_ALEN) != 0) | 1382 | if (memcmp(wk->auth.bssid, mgmt->sa, ETH_ALEN) != 0) |
1362 | return RX_MGMT_NONE; | 1383 | return RX_MGMT_NONE; |
1363 | 1384 | ||
1364 | if (memcmp(wk->bss->cbss.bssid, mgmt->bssid, ETH_ALEN) != 0) | 1385 | if (memcmp(wk->auth.bssid, mgmt->bssid, ETH_ALEN) != 0) |
1365 | return RX_MGMT_NONE; | 1386 | return RX_MGMT_NONE; |
1366 | 1387 | ||
1367 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | 1388 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); |
1368 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); | 1389 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); |
1369 | status_code = le16_to_cpu(mgmt->u.auth.status_code); | 1390 | status_code = le16_to_cpu(mgmt->u.auth.status_code); |
1370 | 1391 | ||
1371 | if (auth_alg != wk->auth_alg || | 1392 | if (auth_alg != wk->auth.algorithm || |
1372 | auth_transaction != wk->auth_transaction) | 1393 | auth_transaction != wk->auth.transaction) |
1373 | return RX_MGMT_NONE; | 1394 | return RX_MGMT_NONE; |
1374 | 1395 | ||
1375 | if (status_code != WLAN_STATUS_SUCCESS) { | 1396 | if (status_code != WLAN_STATUS_SUCCESS) { |
@@ -1378,14 +1399,14 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1378 | return RX_MGMT_CFG80211_AUTH; | 1399 | return RX_MGMT_CFG80211_AUTH; |
1379 | } | 1400 | } |
1380 | 1401 | ||
1381 | switch (wk->auth_alg) { | 1402 | switch (wk->auth.algorithm) { |
1382 | case WLAN_AUTH_OPEN: | 1403 | case WLAN_AUTH_OPEN: |
1383 | case WLAN_AUTH_LEAP: | 1404 | case WLAN_AUTH_LEAP: |
1384 | case WLAN_AUTH_FT: | 1405 | case WLAN_AUTH_FT: |
1385 | ieee80211_auth_completed(sdata, wk); | 1406 | ieee80211_auth_completed(sdata, wk); |
1386 | return RX_MGMT_CFG80211_AUTH; | 1407 | return RX_MGMT_CFG80211_AUTH; |
1387 | case WLAN_AUTH_SHARED_KEY: | 1408 | case WLAN_AUTH_SHARED_KEY: |
1388 | if (wk->auth_transaction == 4) { | 1409 | if (wk->auth.transaction == 4) { |
1389 | ieee80211_auth_completed(sdata, wk); | 1410 | ieee80211_auth_completed(sdata, wk); |
1390 | return RX_MGMT_CFG80211_AUTH; | 1411 | return RX_MGMT_CFG80211_AUTH; |
1391 | } else | 1412 | } else |
@@ -1455,7 +1476,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1455 | 1476 | ||
1456 | static enum rx_mgmt_action __must_check | 1477 | static enum rx_mgmt_action __must_check |
1457 | ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | 1478 | ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, |
1458 | struct ieee80211_mgd_work *wk, | 1479 | struct ieee80211_work *wk, |
1459 | struct ieee80211_mgmt *mgmt, size_t len, | 1480 | struct ieee80211_mgmt *mgmt, size_t len, |
1460 | bool reassoc) | 1481 | bool reassoc) |
1461 | { | 1482 | { |
@@ -1463,7 +1484,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
1463 | struct ieee80211_local *local = sdata->local; | 1484 | struct ieee80211_local *local = sdata->local; |
1464 | struct ieee80211_supported_band *sband; | 1485 | struct ieee80211_supported_band *sband; |
1465 | struct sta_info *sta; | 1486 | struct sta_info *sta; |
1466 | struct ieee80211_bss *bss = wk->bss; | 1487 | struct ieee80211_bss *bss = wk->assoc.bss; |
1467 | u32 rates, basic_rates; | 1488 | u32 rates, basic_rates; |
1468 | u16 capab_info, status_code, aid; | 1489 | u16 capab_info, status_code, aid; |
1469 | struct ieee802_11_elems elems; | 1490 | struct ieee802_11_elems elems; |
@@ -1693,7 +1714,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
1693 | 1714 | ||
1694 | 1715 | ||
1695 | static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | 1716 | static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, |
1696 | struct ieee80211_mgd_work *wk, | 1717 | struct ieee80211_work *wk, |
1697 | struct ieee80211_mgmt *mgmt, size_t len, | 1718 | struct ieee80211_mgmt *mgmt, size_t len, |
1698 | struct ieee80211_rx_status *rx_status) | 1719 | struct ieee80211_rx_status *rx_status) |
1699 | { | 1720 | { |
@@ -1718,11 +1739,11 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
1718 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); | 1739 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, false); |
1719 | 1740 | ||
1720 | /* direct probe may be part of the association flow */ | 1741 | /* direct probe may be part of the association flow */ |
1721 | if (wk && wk->state == IEEE80211_MGD_STATE_PROBE) { | 1742 | if (wk && wk->type == IEEE80211_WORK_AUTH_PROBE) { |
1722 | printk(KERN_DEBUG "%s: direct probe responded\n", | 1743 | printk(KERN_DEBUG "%s: direct probe responded\n", |
1723 | sdata->name); | 1744 | sdata->name); |
1724 | wk->tries = 0; | 1745 | wk->auth.tries = 0; |
1725 | wk->state = IEEE80211_MGD_STATE_AUTH; | 1746 | wk->type = IEEE80211_WORK_AUTH; |
1726 | WARN_ON(ieee80211_authenticate(sdata, wk) != RX_MGMT_NONE); | 1747 | WARN_ON(ieee80211_authenticate(sdata, wk) != RX_MGMT_NONE); |
1727 | } | 1748 | } |
1728 | 1749 | ||
@@ -1959,7 +1980,7 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1959 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1980 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1960 | struct ieee80211_rx_status *rx_status; | 1981 | struct ieee80211_rx_status *rx_status; |
1961 | struct ieee80211_mgmt *mgmt; | 1982 | struct ieee80211_mgmt *mgmt; |
1962 | struct ieee80211_mgd_work *wk; | 1983 | struct ieee80211_work *wk; |
1963 | enum rx_mgmt_action rma = RX_MGMT_NONE; | 1984 | enum rx_mgmt_action rma = RX_MGMT_NONE; |
1964 | u16 fc; | 1985 | u16 fc; |
1965 | 1986 | ||
@@ -2013,7 +2034,20 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
2013 | } | 2034 | } |
2014 | 2035 | ||
2015 | list_for_each_entry(wk, &ifmgd->work_list, list) { | 2036 | list_for_each_entry(wk, &ifmgd->work_list, list) { |
2016 | if (memcmp(wk->bss->cbss.bssid, mgmt->bssid, ETH_ALEN) != 0) | 2037 | const u8 *bssid = NULL; |
2038 | |||
2039 | switch (wk->type) { | ||
2040 | case IEEE80211_WORK_AUTH_PROBE: | ||
2041 | case IEEE80211_WORK_AUTH: | ||
2042 | bssid = wk->auth.bssid; | ||
2043 | break; | ||
2044 | case IEEE80211_WORK_ASSOC: | ||
2045 | bssid = wk->assoc.bssid; | ||
2046 | break; | ||
2047 | default: | ||
2048 | continue; | ||
2049 | } | ||
2050 | if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0) | ||
2017 | continue; | 2051 | continue; |
2018 | 2052 | ||
2019 | switch (fc & IEEE80211_FCTL_STYPE) { | 2053 | switch (fc & IEEE80211_FCTL_STYPE) { |
@@ -2108,7 +2142,7 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2108 | struct ieee80211_local *local = sdata->local; | 2142 | struct ieee80211_local *local = sdata->local; |
2109 | struct ieee80211_if_managed *ifmgd; | 2143 | struct ieee80211_if_managed *ifmgd; |
2110 | struct sk_buff *skb; | 2144 | struct sk_buff *skb; |
2111 | struct ieee80211_mgd_work *wk, *tmp; | 2145 | struct ieee80211_work *wk, *tmp; |
2112 | LIST_HEAD(free_work); | 2146 | LIST_HEAD(free_work); |
2113 | enum rx_mgmt_action rma; | 2147 | enum rx_mgmt_action rma; |
2114 | 2148 | ||
@@ -2194,19 +2228,19 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2194 | continue; | 2228 | continue; |
2195 | } | 2229 | } |
2196 | 2230 | ||
2197 | switch (wk->state) { | 2231 | switch (wk->type) { |
2198 | default: | 2232 | default: |
2199 | WARN_ON(1); | 2233 | WARN_ON(1); |
2200 | /* nothing */ | 2234 | /* nothing */ |
2201 | rma = RX_MGMT_NONE; | 2235 | rma = RX_MGMT_NONE; |
2202 | break; | 2236 | break; |
2203 | case IEEE80211_MGD_STATE_PROBE: | 2237 | case IEEE80211_WORK_AUTH_PROBE: |
2204 | rma = ieee80211_direct_probe(sdata, wk); | 2238 | rma = ieee80211_direct_probe(sdata, wk); |
2205 | break; | 2239 | break; |
2206 | case IEEE80211_MGD_STATE_AUTH: | 2240 | case IEEE80211_WORK_AUTH: |
2207 | rma = ieee80211_authenticate(sdata, wk); | 2241 | rma = ieee80211_authenticate(sdata, wk); |
2208 | break; | 2242 | break; |
2209 | case IEEE80211_MGD_STATE_ASSOC: | 2243 | case IEEE80211_WORK_ASSOC: |
2210 | rma = ieee80211_associate(sdata, wk); | 2244 | rma = ieee80211_associate(sdata, wk); |
2211 | break; | 2245 | break; |
2212 | } | 2246 | } |
@@ -2243,12 +2277,11 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
2243 | /* see above how we're using wk->timeout */ | 2277 | /* see above how we're using wk->timeout */ |
2244 | switch (wk->timeout) { | 2278 | switch (wk->timeout) { |
2245 | case RX_MGMT_CFG80211_AUTH_TO: | 2279 | case RX_MGMT_CFG80211_AUTH_TO: |
2246 | cfg80211_send_auth_timeout(sdata->dev, | 2280 | cfg80211_send_auth_timeout(sdata->dev, wk->auth.bssid); |
2247 | wk->bss->cbss.bssid); | ||
2248 | break; | 2281 | break; |
2249 | case RX_MGMT_CFG80211_ASSOC_TO: | 2282 | case RX_MGMT_CFG80211_ASSOC_TO: |
2250 | cfg80211_send_assoc_timeout(sdata->dev, | 2283 | cfg80211_send_assoc_timeout(sdata->dev, |
2251 | wk->bss->cbss.bssid); | 2284 | wk->assoc.bssid); |
2252 | break; | 2285 | break; |
2253 | default: | 2286 | default: |
2254 | WARN(1, "unexpected: %lu", wk->timeout); | 2287 | WARN(1, "unexpected: %lu", wk->timeout); |
@@ -2415,7 +2448,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2415 | { | 2448 | { |
2416 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2449 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2417 | const u8 *ssid; | 2450 | const u8 *ssid; |
2418 | struct ieee80211_mgd_work *wk; | 2451 | struct ieee80211_work *wk; |
2419 | u16 auth_alg; | 2452 | u16 auth_alg; |
2420 | 2453 | ||
2421 | switch (req->auth_type) { | 2454 | switch (req->auth_type) { |
@@ -2439,7 +2472,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2439 | if (!wk) | 2472 | if (!wk) |
2440 | return -ENOMEM; | 2473 | return -ENOMEM; |
2441 | 2474 | ||
2442 | wk->bss = (void *)req->bss; | 2475 | memcpy(wk->auth.bssid, req->bss->bssid, ETH_ALEN);; |
2443 | 2476 | ||
2444 | if (req->ie && req->ie_len) { | 2477 | if (req->ie && req->ie_len) { |
2445 | memcpy(wk->ie, req->ie, req->ie_len); | 2478 | memcpy(wk->ie, req->ie, req->ie_len); |
@@ -2447,22 +2480,27 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2447 | } | 2480 | } |
2448 | 2481 | ||
2449 | if (req->key && req->key_len) { | 2482 | if (req->key && req->key_len) { |
2450 | wk->key_len = req->key_len; | 2483 | wk->auth.key_len = req->key_len; |
2451 | wk->key_idx = req->key_idx; | 2484 | wk->auth.key_idx = req->key_idx; |
2452 | memcpy(wk->key, req->key, req->key_len); | 2485 | memcpy(wk->auth.key, req->key, req->key_len); |
2453 | } | 2486 | } |
2454 | 2487 | ||
2455 | ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); | 2488 | ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); |
2456 | memcpy(wk->ssid, ssid + 2, ssid[1]); | 2489 | memcpy(wk->auth.ssid, ssid + 2, ssid[1]); |
2457 | wk->ssid_len = ssid[1]; | 2490 | wk->auth.ssid_len = ssid[1]; |
2491 | |||
2492 | wk->auth.algorithm = auth_alg; | ||
2493 | wk->auth.privacy = req->bss->capability & WLAN_CAPABILITY_PRIVACY; | ||
2458 | 2494 | ||
2459 | wk->state = IEEE80211_MGD_STATE_PROBE; | 2495 | wk->type = IEEE80211_WORK_AUTH_PROBE; |
2460 | wk->auth_alg = auth_alg; | ||
2461 | wk->timeout = jiffies; /* run right away */ | 2496 | wk->timeout = jiffies; /* run right away */ |
2497 | wk->chan = req->bss->channel; | ||
2462 | 2498 | ||
2463 | /* | 2499 | /* |
2464 | * XXX: if still associated need to tell AP that we're going | 2500 | * XXX: if still associated need to tell AP that we're going |
2465 | * to sleep and then change channel etc. | 2501 | * to sleep and then change channel etc. |
2502 | * For now switch channel here, later will be handled | ||
2503 | * by submitting this as an off-channel work item. | ||
2466 | */ | 2504 | */ |
2467 | sdata->local->oper_channel = req->bss->channel; | 2505 | sdata->local->oper_channel = req->bss->channel; |
2468 | ieee80211_hw_config(sdata->local, 0); | 2506 | ieee80211_hw_config(sdata->local, 0); |
@@ -2479,7 +2517,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2479 | struct cfg80211_assoc_request *req) | 2517 | struct cfg80211_assoc_request *req) |
2480 | { | 2518 | { |
2481 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2519 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2482 | struct ieee80211_mgd_work *wk; | 2520 | struct ieee80211_work *wk; |
2483 | const u8 *ssid; | 2521 | const u8 *ssid; |
2484 | int i, err; | 2522 | int i, err; |
2485 | 2523 | ||
@@ -2506,17 +2544,27 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2506 | } else | 2544 | } else |
2507 | wk->ie_len = 0; | 2545 | wk->ie_len = 0; |
2508 | 2546 | ||
2509 | wk->bss = (void *)req->bss; | 2547 | wk->assoc.bss = (void *)req->bss; |
2548 | |||
2549 | memcpy(wk->assoc.bssid, req->bss->bssid, ETH_ALEN); | ||
2550 | |||
2551 | wk->assoc.capability = req->bss->capability; | ||
2552 | wk->assoc.wmm_used = wk->assoc.bss->wmm_used; | ||
2553 | wk->assoc.supp_rates = wk->assoc.bss->supp_rates; | ||
2554 | wk->assoc.supp_rates_len = wk->assoc.bss->supp_rates_len; | ||
2555 | wk->assoc.ht_information_ie = | ||
2556 | ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION); | ||
2510 | 2557 | ||
2511 | ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); | 2558 | ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); |
2512 | memcpy(wk->ssid, ssid + 2, ssid[1]); | 2559 | memcpy(wk->assoc.ssid, ssid + 2, ssid[1]); |
2513 | wk->ssid_len = ssid[1]; | 2560 | wk->assoc.ssid_len = ssid[1]; |
2514 | 2561 | ||
2515 | if (req->prev_bssid) | 2562 | if (req->prev_bssid) |
2516 | memcpy(wk->prev_bssid, req->prev_bssid, ETH_ALEN); | 2563 | memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); |
2517 | 2564 | ||
2518 | wk->state = IEEE80211_MGD_STATE_ASSOC; | 2565 | wk->type = IEEE80211_WORK_ASSOC; |
2519 | wk->timeout = jiffies; /* run right away */ | 2566 | wk->timeout = jiffies; /* run right away */ |
2567 | wk->chan = req->bss->channel; | ||
2520 | 2568 | ||
2521 | if (req->use_mfp) { | 2569 | if (req->use_mfp) { |
2522 | ifmgd->mfp = IEEE80211_MFP_REQUIRED; | 2570 | ifmgd->mfp = IEEE80211_MFP_REQUIRED; |
@@ -2549,7 +2597,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2549 | void *cookie) | 2597 | void *cookie) |
2550 | { | 2598 | { |
2551 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2599 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2552 | struct ieee80211_mgd_work *wk; | 2600 | struct ieee80211_work *wk; |
2553 | const u8 *bssid = req->bss->bssid; | 2601 | const u8 *bssid = req->bss->bssid; |
2554 | bool not_auth_yet = false; | 2602 | bool not_auth_yet = false; |
2555 | 2603 | ||
@@ -2559,9 +2607,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
2559 | bssid = req->bss->bssid; | 2607 | bssid = req->bss->bssid; |
2560 | ieee80211_set_disassoc(sdata); | 2608 | ieee80211_set_disassoc(sdata); |
2561 | } else list_for_each_entry(wk, &ifmgd->work_list, list) { | 2609 | } else list_for_each_entry(wk, &ifmgd->work_list, list) { |
2562 | if (wk->state != IEEE80211_MGD_STATE_PROBE) | 2610 | if (wk->type != IEEE80211_WORK_AUTH_PROBE) |
2563 | continue; | 2611 | continue; |
2564 | if (req->bss != &wk->bss->cbss) | 2612 | if (memcmp(req->bss->bssid, wk->auth.bssid, ETH_ALEN)) |
2565 | continue; | 2613 | continue; |
2566 | not_auth_yet = true; | 2614 | not_auth_yet = true; |
2567 | list_del(&wk->list); | 2615 | list_del(&wk->list); |