diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-06-11 14:48:32 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-11 14:48:32 -0400 |
commit | 3899ba90a4ab2f3cab8e0f91a76c14ff131c8293 (patch) | |
tree | ae82b469f8a7ceb42547d11dd1fe5c73abc8635b /net/mac80211 | |
parent | 45203a3b380cee28f570475c0d28c169f908c209 (diff) | |
parent | 8b3e7be437a6b62118d0485ad971e724afe23fdf (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
drivers/net/wireless/ath/ath9k/debug.c
net/mac80211/iface.c
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/aes_ccm.c | 6 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 33 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 15 | ||||
-rw-r--r-- | net/mac80211/driver-ops.h | 3 | ||||
-rw-r--r-- | net/mac80211/ht.c | 4 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 49 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 28 | ||||
-rw-r--r-- | net/mac80211/iface.c | 29 | ||||
-rw-r--r-- | net/mac80211/key.c | 24 | ||||
-rw-r--r-- | net/mac80211/key.h | 15 | ||||
-rw-r--r-- | net/mac80211/main.c | 4 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 38 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 7 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 345 | ||||
-rw-r--r-- | net/mac80211/rx.c | 30 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 2 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 5 | ||||
-rw-r--r-- | net/mac80211/tx.c | 5 | ||||
-rw-r--r-- | net/mac80211/util.c | 36 | ||||
-rw-r--r-- | net/mac80211/wep.c | 48 | ||||
-rw-r--r-- | net/mac80211/wpa.c | 68 |
21 files changed, 370 insertions, 424 deletions
diff --git a/net/mac80211/aes_ccm.c b/net/mac80211/aes_ccm.c index 0785e95c9924..be7614b9ed27 100644 --- a/net/mac80211/aes_ccm.c +++ b/net/mac80211/aes_ccm.c | |||
@@ -85,7 +85,7 @@ void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
85 | *cpos++ = *pos++ ^ e[i]; | 85 | *cpos++ = *pos++ ^ e[i]; |
86 | } | 86 | } |
87 | 87 | ||
88 | for (i = 0; i < CCMP_MIC_LEN; i++) | 88 | for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) |
89 | mic[i] = b[i] ^ s_0[i]; | 89 | mic[i] = b[i] ^ s_0[i]; |
90 | } | 90 | } |
91 | 91 | ||
@@ -123,7 +123,7 @@ int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch, | |||
123 | crypto_cipher_encrypt_one(tfm, a, a); | 123 | crypto_cipher_encrypt_one(tfm, a, a); |
124 | } | 124 | } |
125 | 125 | ||
126 | for (i = 0; i < CCMP_MIC_LEN; i++) { | 126 | for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) { |
127 | if ((mic[i] ^ s_0[i]) != a[i]) | 127 | if ((mic[i] ^ s_0[i]) != a[i]) |
128 | return -1; | 128 | return -1; |
129 | } | 129 | } |
@@ -138,7 +138,7 @@ struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]) | |||
138 | 138 | ||
139 | tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); | 139 | tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC); |
140 | if (!IS_ERR(tfm)) | 140 | if (!IS_ERR(tfm)) |
141 | crypto_cipher_setkey(tfm, key, ALG_CCMP_KEY_LEN); | 141 | crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP); |
142 | 142 | ||
143 | return tfm; | 143 | return tfm; |
144 | } | 144 | } |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 1a89c80e6407..30622101d3b5 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -73,16 +73,19 @@ static int ieee80211_change_iface(struct wiphy *wiphy, | |||
73 | struct ieee80211_local *local = sdata->local; | 73 | struct ieee80211_local *local = sdata->local; |
74 | 74 | ||
75 | if (ieee80211_sdata_running(sdata)) { | 75 | if (ieee80211_sdata_running(sdata)) { |
76 | u32 mask = MONITOR_FLAG_COOK_FRAMES | | ||
77 | MONITOR_FLAG_ACTIVE; | ||
78 | |||
76 | /* | 79 | /* |
77 | * Prohibit MONITOR_FLAG_COOK_FRAMES to be | 80 | * Prohibit MONITOR_FLAG_COOK_FRAMES and |
78 | * changed while the interface is up. | 81 | * MONITOR_FLAG_ACTIVE to be changed while the |
82 | * interface is up. | ||
79 | * Else we would need to add a lot of cruft | 83 | * Else we would need to add a lot of cruft |
80 | * to update everything: | 84 | * to update everything: |
81 | * cooked_mntrs, monitor and all fif_* counters | 85 | * cooked_mntrs, monitor and all fif_* counters |
82 | * reconfigure hardware | 86 | * reconfigure hardware |
83 | */ | 87 | */ |
84 | if ((*flags & MONITOR_FLAG_COOK_FRAMES) != | 88 | if ((*flags & mask) != (sdata->u.mntr_flags & mask)) |
85 | (sdata->u.mntr_flags & MONITOR_FLAG_COOK_FRAMES)) | ||
86 | return -EBUSY; | 89 | return -EBUSY; |
87 | 90 | ||
88 | ieee80211_adjust_monitor_flags(sdata, -1); | 91 | ieee80211_adjust_monitor_flags(sdata, -1); |
@@ -444,7 +447,7 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
444 | struct ieee80211_local *local = sdata->local; | 447 | struct ieee80211_local *local = sdata->local; |
445 | struct timespec uptime; | 448 | struct timespec uptime; |
446 | u64 packets = 0; | 449 | u64 packets = 0; |
447 | int ac; | 450 | int i, ac; |
448 | 451 | ||
449 | sinfo->generation = sdata->local->sta_generation; | 452 | sinfo->generation = sdata->local->sta_generation; |
450 | 453 | ||
@@ -488,6 +491,17 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
488 | sinfo->signal = (s8)sta->last_signal; | 491 | sinfo->signal = (s8)sta->last_signal; |
489 | sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); | 492 | sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); |
490 | } | 493 | } |
494 | if (sta->chains) { | ||
495 | sinfo->filled |= STATION_INFO_CHAIN_SIGNAL | | ||
496 | STATION_INFO_CHAIN_SIGNAL_AVG; | ||
497 | |||
498 | sinfo->chains = sta->chains; | ||
499 | for (i = 0; i < ARRAY_SIZE(sinfo->chain_signal); i++) { | ||
500 | sinfo->chain_signal[i] = sta->chain_signal_last[i]; | ||
501 | sinfo->chain_signal_avg[i] = | ||
502 | (s8) -ewma_read(&sta->chain_signal_avg[i]); | ||
503 | } | ||
504 | } | ||
491 | 505 | ||
492 | sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); | 506 | sta_set_rate_info_tx(sta, &sta->last_tx_rate, &sinfo->txrate); |
493 | sta_set_rate_info_rx(sta, &sinfo->rxrate); | 507 | sta_set_rate_info_rx(sta, &sinfo->rxrate); |
@@ -728,7 +742,7 @@ static void ieee80211_get_et_strings(struct wiphy *wiphy, | |||
728 | 742 | ||
729 | if (sset == ETH_SS_STATS) { | 743 | if (sset == ETH_SS_STATS) { |
730 | sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats); | 744 | sz_sta_stats = sizeof(ieee80211_gstrings_sta_stats); |
731 | memcpy(data, *ieee80211_gstrings_sta_stats, sz_sta_stats); | 745 | memcpy(data, ieee80211_gstrings_sta_stats, sz_sta_stats); |
732 | } | 746 | } |
733 | drv_get_et_strings(sdata, sset, &(data[sz_sta_stats])); | 747 | drv_get_et_strings(sdata, sset, &(data[sz_sta_stats])); |
734 | } | 748 | } |
@@ -1735,6 +1749,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, | |||
1735 | ifmsh->mesh_pp_id = setup->path_sel_proto; | 1749 | ifmsh->mesh_pp_id = setup->path_sel_proto; |
1736 | ifmsh->mesh_pm_id = setup->path_metric; | 1750 | ifmsh->mesh_pm_id = setup->path_metric; |
1737 | ifmsh->user_mpm = setup->user_mpm; | 1751 | ifmsh->user_mpm = setup->user_mpm; |
1752 | ifmsh->mesh_auth_id = setup->auth_id; | ||
1738 | ifmsh->security = IEEE80211_MESH_SEC_NONE; | 1753 | ifmsh->security = IEEE80211_MESH_SEC_NONE; |
1739 | if (setup->is_authenticated) | 1754 | if (setup->is_authenticated) |
1740 | ifmsh->security |= IEEE80211_MESH_SEC_AUTHED; | 1755 | ifmsh->security |= IEEE80211_MESH_SEC_AUTHED; |
@@ -2306,7 +2321,7 @@ int __ieee80211_request_smps(struct ieee80211_sub_if_data *sdata, | |||
2306 | enum ieee80211_smps_mode old_req; | 2321 | enum ieee80211_smps_mode old_req; |
2307 | int err; | 2322 | int err; |
2308 | 2323 | ||
2309 | lockdep_assert_held(&sdata->u.mgd.mtx); | 2324 | lockdep_assert_held(&sdata->wdev.mtx); |
2310 | 2325 | ||
2311 | old_req = sdata->u.mgd.req_smps; | 2326 | old_req = sdata->u.mgd.req_smps; |
2312 | sdata->u.mgd.req_smps = smps_mode; | 2327 | sdata->u.mgd.req_smps = smps_mode; |
@@ -2363,9 +2378,9 @@ static int ieee80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
2363 | local->dynamic_ps_forced_timeout = timeout; | 2378 | local->dynamic_ps_forced_timeout = timeout; |
2364 | 2379 | ||
2365 | /* no change, but if automatic follow powersave */ | 2380 | /* no change, but if automatic follow powersave */ |
2366 | mutex_lock(&sdata->u.mgd.mtx); | 2381 | sdata_lock(sdata); |
2367 | __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps); | 2382 | __ieee80211_request_smps(sdata, sdata->u.mgd.req_smps); |
2368 | mutex_unlock(&sdata->u.mgd.mtx); | 2383 | sdata_unlock(sdata); |
2369 | 2384 | ||
2370 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) | 2385 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) |
2371 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | 2386 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 14abcf44f974..cafe614ef93d 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -228,9 +228,9 @@ static int ieee80211_set_smps(struct ieee80211_sub_if_data *sdata, | |||
228 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 228 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
229 | return -EOPNOTSUPP; | 229 | return -EOPNOTSUPP; |
230 | 230 | ||
231 | mutex_lock(&sdata->u.mgd.mtx); | 231 | sdata_lock(sdata); |
232 | err = __ieee80211_request_smps(sdata, smps_mode); | 232 | err = __ieee80211_request_smps(sdata, smps_mode); |
233 | mutex_unlock(&sdata->u.mgd.mtx); | 233 | sdata_unlock(sdata); |
234 | 234 | ||
235 | return err; | 235 | return err; |
236 | } | 236 | } |
@@ -313,16 +313,16 @@ static ssize_t ieee80211_if_parse_tkip_mic_test( | |||
313 | case NL80211_IFTYPE_STATION: | 313 | case NL80211_IFTYPE_STATION: |
314 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); | 314 | fc |= cpu_to_le16(IEEE80211_FCTL_TODS); |
315 | /* BSSID SA DA */ | 315 | /* BSSID SA DA */ |
316 | mutex_lock(&sdata->u.mgd.mtx); | 316 | sdata_lock(sdata); |
317 | if (!sdata->u.mgd.associated) { | 317 | if (!sdata->u.mgd.associated) { |
318 | mutex_unlock(&sdata->u.mgd.mtx); | 318 | sdata_unlock(sdata); |
319 | dev_kfree_skb(skb); | 319 | dev_kfree_skb(skb); |
320 | return -ENOTCONN; | 320 | return -ENOTCONN; |
321 | } | 321 | } |
322 | memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN); | 322 | memcpy(hdr->addr1, sdata->u.mgd.associated->bssid, ETH_ALEN); |
323 | memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); | 323 | memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); |
324 | memcpy(hdr->addr3, addr, ETH_ALEN); | 324 | memcpy(hdr->addr3, addr, ETH_ALEN); |
325 | mutex_unlock(&sdata->u.mgd.mtx); | 325 | sdata_unlock(sdata); |
326 | break; | 326 | break; |
327 | default: | 327 | default: |
328 | dev_kfree_skb(skb); | 328 | dev_kfree_skb(skb); |
@@ -471,6 +471,8 @@ __IEEE80211_IF_FILE_W(tsf); | |||
471 | IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC); | 471 | IEEE80211_IF_FILE(peer, u.wds.remote_addr, MAC); |
472 | 472 | ||
473 | #ifdef CONFIG_MAC80211_MESH | 473 | #ifdef CONFIG_MAC80211_MESH |
474 | IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC); | ||
475 | |||
474 | /* Mesh stats attributes */ | 476 | /* Mesh stats attributes */ |
475 | IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC); | 477 | IEEE80211_IF_FILE(fwded_mcast, u.mesh.mshstats.fwded_mcast, DEC); |
476 | IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC); | 478 | IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC); |
@@ -480,7 +482,6 @@ IEEE80211_IF_FILE(dropped_frames_congestion, | |||
480 | u.mesh.mshstats.dropped_frames_congestion, DEC); | 482 | u.mesh.mshstats.dropped_frames_congestion, DEC); |
481 | IEEE80211_IF_FILE(dropped_frames_no_route, | 483 | IEEE80211_IF_FILE(dropped_frames_no_route, |
482 | u.mesh.mshstats.dropped_frames_no_route, DEC); | 484 | u.mesh.mshstats.dropped_frames_no_route, DEC); |
483 | IEEE80211_IF_FILE(estab_plinks, u.mesh.estab_plinks, ATOMIC); | ||
484 | 485 | ||
485 | /* Mesh parameters */ | 486 | /* Mesh parameters */ |
486 | IEEE80211_IF_FILE(dot11MeshMaxRetries, | 487 | IEEE80211_IF_FILE(dot11MeshMaxRetries, |
@@ -583,6 +584,7 @@ static void add_wds_files(struct ieee80211_sub_if_data *sdata) | |||
583 | static void add_mesh_files(struct ieee80211_sub_if_data *sdata) | 584 | static void add_mesh_files(struct ieee80211_sub_if_data *sdata) |
584 | { | 585 | { |
585 | DEBUGFS_ADD_MODE(tsf, 0600); | 586 | DEBUGFS_ADD_MODE(tsf, 0600); |
587 | DEBUGFS_ADD_MODE(estab_plinks, 0400); | ||
586 | } | 588 | } |
587 | 589 | ||
588 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) | 590 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) |
@@ -598,7 +600,6 @@ static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) | |||
598 | MESHSTATS_ADD(dropped_frames_ttl); | 600 | MESHSTATS_ADD(dropped_frames_ttl); |
599 | MESHSTATS_ADD(dropped_frames_no_route); | 601 | MESHSTATS_ADD(dropped_frames_no_route); |
600 | MESHSTATS_ADD(dropped_frames_congestion); | 602 | MESHSTATS_ADD(dropped_frames_congestion); |
601 | MESHSTATS_ADD(estab_plinks); | ||
602 | #undef MESHSTATS_ADD | 603 | #undef MESHSTATS_ADD |
603 | } | 604 | } |
604 | 605 | ||
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 169664c122e2..b931c96a596f 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -146,7 +146,8 @@ static inline int drv_add_interface(struct ieee80211_local *local, | |||
146 | 146 | ||
147 | if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || | 147 | if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
148 | (sdata->vif.type == NL80211_IFTYPE_MONITOR && | 148 | (sdata->vif.type == NL80211_IFTYPE_MONITOR && |
149 | !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)))) | 149 | !(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF) && |
150 | !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)))) | ||
150 | return -EINVAL; | 151 | return -EINVAL; |
151 | 152 | ||
152 | trace_drv_add_interface(local, sdata); | 153 | trace_drv_add_interface(local, sdata); |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index af8cee06e4f3..75dff338f581 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -429,9 +429,9 @@ void ieee80211_request_smps_work(struct work_struct *work) | |||
429 | container_of(work, struct ieee80211_sub_if_data, | 429 | container_of(work, struct ieee80211_sub_if_data, |
430 | u.mgd.request_smps_work); | 430 | u.mgd.request_smps_work); |
431 | 431 | ||
432 | mutex_lock(&sdata->u.mgd.mtx); | 432 | sdata_lock(sdata); |
433 | __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode); | 433 | __ieee80211_request_smps(sdata, sdata->u.mgd.driver_smps_mode); |
434 | mutex_unlock(&sdata->u.mgd.mtx); | 434 | sdata_unlock(sdata); |
435 | } | 435 | } |
436 | 436 | ||
437 | void ieee80211_request_smps(struct ieee80211_vif *vif, | 437 | void ieee80211_request_smps(struct ieee80211_vif *vif, |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 170f9a7fa319..caa4b4f7f6e4 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -54,7 +54,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
54 | struct beacon_data *presp; | 54 | struct beacon_data *presp; |
55 | int frame_len; | 55 | int frame_len; |
56 | 56 | ||
57 | lockdep_assert_held(&ifibss->mtx); | 57 | sdata_assert_lock(sdata); |
58 | 58 | ||
59 | /* Reset own TSF to allow time synchronization work. */ | 59 | /* Reset own TSF to allow time synchronization work. */ |
60 | drv_reset_tsf(local, sdata); | 60 | drv_reset_tsf(local, sdata); |
@@ -74,7 +74,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
74 | } | 74 | } |
75 | 75 | ||
76 | presp = rcu_dereference_protected(ifibss->presp, | 76 | presp = rcu_dereference_protected(ifibss->presp, |
77 | lockdep_is_held(&ifibss->mtx)); | 77 | lockdep_is_held(&sdata->wdev.mtx)); |
78 | rcu_assign_pointer(ifibss->presp, NULL); | 78 | rcu_assign_pointer(ifibss->presp, NULL); |
79 | if (presp) | 79 | if (presp) |
80 | kfree_rcu(presp, rcu_head); | 80 | kfree_rcu(presp, rcu_head); |
@@ -263,7 +263,7 @@ static void ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
263 | const struct cfg80211_bss_ies *ies; | 263 | const struct cfg80211_bss_ies *ies; |
264 | u64 tsf; | 264 | u64 tsf; |
265 | 265 | ||
266 | lockdep_assert_held(&sdata->u.ibss.mtx); | 266 | sdata_assert_lock(sdata); |
267 | 267 | ||
268 | if (beacon_int < 10) | 268 | if (beacon_int < 10) |
269 | beacon_int = 10; | 269 | beacon_int = 10; |
@@ -341,6 +341,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
341 | struct ieee80211_local *local = sdata->local; | 341 | struct ieee80211_local *local = sdata->local; |
342 | struct sta_info *sta; | 342 | struct sta_info *sta; |
343 | struct ieee80211_chanctx_conf *chanctx_conf; | 343 | struct ieee80211_chanctx_conf *chanctx_conf; |
344 | struct ieee80211_supported_band *sband; | ||
344 | int band; | 345 | int band; |
345 | 346 | ||
346 | /* | 347 | /* |
@@ -380,8 +381,9 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
380 | sta->last_rx = jiffies; | 381 | sta->last_rx = jiffies; |
381 | 382 | ||
382 | /* make sure mandatory rates are always added */ | 383 | /* make sure mandatory rates are always added */ |
384 | sband = local->hw.wiphy->bands[band]; | ||
383 | sta->sta.supp_rates[band] = supp_rates | | 385 | sta->sta.supp_rates[band] = supp_rates | |
384 | ieee80211_mandatory_rates(local, band); | 386 | ieee80211_mandatory_rates(sband); |
385 | 387 | ||
386 | return ieee80211_ibss_finish_sta(sta, auth); | 388 | return ieee80211_ibss_finish_sta(sta, auth); |
387 | } | 389 | } |
@@ -408,7 +410,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
408 | struct sta_info *sta; | 410 | struct sta_info *sta; |
409 | u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 411 | u8 deauth_frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
410 | 412 | ||
411 | lockdep_assert_held(&sdata->u.ibss.mtx); | 413 | sdata_assert_lock(sdata); |
412 | 414 | ||
413 | if (len < 24 + 6) | 415 | if (len < 24 + 6) |
414 | return; | 416 | return; |
@@ -492,7 +494,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
492 | prev_rates = sta->sta.supp_rates[band]; | 494 | prev_rates = sta->sta.supp_rates[band]; |
493 | /* make sure mandatory rates are always added */ | 495 | /* make sure mandatory rates are always added */ |
494 | sta->sta.supp_rates[band] = supp_rates | | 496 | sta->sta.supp_rates[band] = supp_rates | |
495 | ieee80211_mandatory_rates(local, band); | 497 | ieee80211_mandatory_rates(sband); |
496 | 498 | ||
497 | if (sta->sta.supp_rates[band] != prev_rates) { | 499 | if (sta->sta.supp_rates[band] != prev_rates) { |
498 | ibss_dbg(sdata, | 500 | ibss_dbg(sdata, |
@@ -624,6 +626,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, | |||
624 | struct ieee80211_local *local = sdata->local; | 626 | struct ieee80211_local *local = sdata->local; |
625 | struct sta_info *sta; | 627 | struct sta_info *sta; |
626 | struct ieee80211_chanctx_conf *chanctx_conf; | 628 | struct ieee80211_chanctx_conf *chanctx_conf; |
629 | struct ieee80211_supported_band *sband; | ||
627 | int band; | 630 | int band; |
628 | 631 | ||
629 | /* | 632 | /* |
@@ -658,8 +661,9 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, | |||
658 | sta->last_rx = jiffies; | 661 | sta->last_rx = jiffies; |
659 | 662 | ||
660 | /* make sure mandatory rates are always added */ | 663 | /* make sure mandatory rates are always added */ |
664 | sband = local->hw.wiphy->bands[band]; | ||
661 | sta->sta.supp_rates[band] = supp_rates | | 665 | sta->sta.supp_rates[band] = supp_rates | |
662 | ieee80211_mandatory_rates(local, band); | 666 | ieee80211_mandatory_rates(sband); |
663 | 667 | ||
664 | spin_lock(&ifibss->incomplete_lock); | 668 | spin_lock(&ifibss->incomplete_lock); |
665 | list_add(&sta->list, &ifibss->incomplete_stations); | 669 | list_add(&sta->list, &ifibss->incomplete_stations); |
@@ -673,7 +677,7 @@ static int ieee80211_sta_active_ibss(struct ieee80211_sub_if_data *sdata) | |||
673 | int active = 0; | 677 | int active = 0; |
674 | struct sta_info *sta; | 678 | struct sta_info *sta; |
675 | 679 | ||
676 | lockdep_assert_held(&sdata->u.ibss.mtx); | 680 | sdata_assert_lock(sdata); |
677 | 681 | ||
678 | rcu_read_lock(); | 682 | rcu_read_lock(); |
679 | 683 | ||
@@ -699,7 +703,7 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
699 | { | 703 | { |
700 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 704 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
701 | 705 | ||
702 | lockdep_assert_held(&ifibss->mtx); | 706 | sdata_assert_lock(sdata); |
703 | 707 | ||
704 | mod_timer(&ifibss->timer, | 708 | mod_timer(&ifibss->timer, |
705 | round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); | 709 | round_jiffies(jiffies + IEEE80211_IBSS_MERGE_INTERVAL)); |
@@ -730,7 +734,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
730 | u16 capability; | 734 | u16 capability; |
731 | int i; | 735 | int i; |
732 | 736 | ||
733 | lockdep_assert_held(&ifibss->mtx); | 737 | sdata_assert_lock(sdata); |
734 | 738 | ||
735 | if (ifibss->fixed_bssid) { | 739 | if (ifibss->fixed_bssid) { |
736 | memcpy(bssid, ifibss->bssid, ETH_ALEN); | 740 | memcpy(bssid, ifibss->bssid, ETH_ALEN); |
@@ -773,7 +777,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
773 | int active_ibss; | 777 | int active_ibss; |
774 | u16 capability; | 778 | u16 capability; |
775 | 779 | ||
776 | lockdep_assert_held(&ifibss->mtx); | 780 | sdata_assert_lock(sdata); |
777 | 781 | ||
778 | active_ibss = ieee80211_sta_active_ibss(sdata); | 782 | active_ibss = ieee80211_sta_active_ibss(sdata); |
779 | ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss); | 783 | ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss); |
@@ -843,10 +847,10 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
843 | struct beacon_data *presp; | 847 | struct beacon_data *presp; |
844 | u8 *pos, *end; | 848 | u8 *pos, *end; |
845 | 849 | ||
846 | lockdep_assert_held(&ifibss->mtx); | 850 | sdata_assert_lock(sdata); |
847 | 851 | ||
848 | presp = rcu_dereference_protected(ifibss->presp, | 852 | presp = rcu_dereference_protected(ifibss->presp, |
849 | lockdep_is_held(&ifibss->mtx)); | 853 | lockdep_is_held(&sdata->wdev.mtx)); |
850 | 854 | ||
851 | if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || | 855 | if (ifibss->state != IEEE80211_IBSS_MLME_JOINED || |
852 | len < 24 + 2 || !presp) | 856 | len < 24 + 2 || !presp) |
@@ -930,7 +934,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
930 | mgmt = (struct ieee80211_mgmt *) skb->data; | 934 | mgmt = (struct ieee80211_mgmt *) skb->data; |
931 | fc = le16_to_cpu(mgmt->frame_control); | 935 | fc = le16_to_cpu(mgmt->frame_control); |
932 | 936 | ||
933 | mutex_lock(&sdata->u.ibss.mtx); | 937 | sdata_lock(sdata); |
934 | 938 | ||
935 | if (!sdata->u.ibss.ssid_len) | 939 | if (!sdata->u.ibss.ssid_len) |
936 | goto mgmt_out; /* not ready to merge yet */ | 940 | goto mgmt_out; /* not ready to merge yet */ |
@@ -953,7 +957,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
953 | } | 957 | } |
954 | 958 | ||
955 | mgmt_out: | 959 | mgmt_out: |
956 | mutex_unlock(&sdata->u.ibss.mtx); | 960 | sdata_unlock(sdata); |
957 | } | 961 | } |
958 | 962 | ||
959 | void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) | 963 | void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) |
@@ -961,7 +965,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) | |||
961 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 965 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
962 | struct sta_info *sta; | 966 | struct sta_info *sta; |
963 | 967 | ||
964 | mutex_lock(&ifibss->mtx); | 968 | sdata_lock(sdata); |
965 | 969 | ||
966 | /* | 970 | /* |
967 | * Work could be scheduled after scan or similar | 971 | * Work could be scheduled after scan or similar |
@@ -997,7 +1001,7 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata) | |||
997 | } | 1001 | } |
998 | 1002 | ||
999 | out: | 1003 | out: |
1000 | mutex_unlock(&ifibss->mtx); | 1004 | sdata_unlock(sdata); |
1001 | } | 1005 | } |
1002 | 1006 | ||
1003 | static void ieee80211_ibss_timer(unsigned long data) | 1007 | static void ieee80211_ibss_timer(unsigned long data) |
@@ -1014,7 +1018,6 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
1014 | 1018 | ||
1015 | setup_timer(&ifibss->timer, ieee80211_ibss_timer, | 1019 | setup_timer(&ifibss->timer, ieee80211_ibss_timer, |
1016 | (unsigned long) sdata); | 1020 | (unsigned long) sdata); |
1017 | mutex_init(&ifibss->mtx); | ||
1018 | INIT_LIST_HEAD(&ifibss->incomplete_stations); | 1021 | INIT_LIST_HEAD(&ifibss->incomplete_stations); |
1019 | spin_lock_init(&ifibss->incomplete_lock); | 1022 | spin_lock_init(&ifibss->incomplete_lock); |
1020 | } | 1023 | } |
@@ -1041,8 +1044,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1041 | { | 1044 | { |
1042 | u32 changed = 0; | 1045 | u32 changed = 0; |
1043 | 1046 | ||
1044 | mutex_lock(&sdata->u.ibss.mtx); | ||
1045 | |||
1046 | if (params->bssid) { | 1047 | if (params->bssid) { |
1047 | memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN); | 1048 | memcpy(sdata->u.ibss.bssid, params->bssid, ETH_ALEN); |
1048 | sdata->u.ibss.fixed_bssid = true; | 1049 | sdata->u.ibss.fixed_bssid = true; |
@@ -1075,8 +1076,6 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata, | |||
1075 | memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); | 1076 | memcpy(sdata->u.ibss.ssid, params->ssid, params->ssid_len); |
1076 | sdata->u.ibss.ssid_len = params->ssid_len; | 1077 | sdata->u.ibss.ssid_len = params->ssid_len; |
1077 | 1078 | ||
1078 | mutex_unlock(&sdata->u.ibss.mtx); | ||
1079 | |||
1080 | /* | 1079 | /* |
1081 | * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is | 1080 | * 802.11n-2009 9.13.3.1: In an IBSS, the HT Protection field is |
1082 | * reserved, but an HT STA shall protect HT transmissions as though | 1081 | * reserved, but an HT STA shall protect HT transmissions as though |
@@ -1112,8 +1111,6 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1112 | struct sta_info *sta; | 1111 | struct sta_info *sta; |
1113 | struct beacon_data *presp; | 1112 | struct beacon_data *presp; |
1114 | 1113 | ||
1115 | mutex_lock(&sdata->u.ibss.mtx); | ||
1116 | |||
1117 | active_ibss = ieee80211_sta_active_ibss(sdata); | 1114 | active_ibss = ieee80211_sta_active_ibss(sdata); |
1118 | 1115 | ||
1119 | if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { | 1116 | if (!active_ibss && !is_zero_ether_addr(ifibss->bssid)) { |
@@ -1157,7 +1154,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1157 | /* remove beacon */ | 1154 | /* remove beacon */ |
1158 | kfree(sdata->u.ibss.ie); | 1155 | kfree(sdata->u.ibss.ie); |
1159 | presp = rcu_dereference_protected(ifibss->presp, | 1156 | presp = rcu_dereference_protected(ifibss->presp, |
1160 | lockdep_is_held(&sdata->u.ibss.mtx)); | 1157 | lockdep_is_held(&sdata->wdev.mtx)); |
1161 | RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); | 1158 | RCU_INIT_POINTER(sdata->u.ibss.presp, NULL); |
1162 | sdata->vif.bss_conf.ibss_joined = false; | 1159 | sdata->vif.bss_conf.ibss_joined = false; |
1163 | sdata->vif.bss_conf.ibss_creator = false; | 1160 | sdata->vif.bss_conf.ibss_creator = false; |
@@ -1173,7 +1170,5 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
1173 | 1170 | ||
1174 | del_timer_sync(&sdata->u.ibss.timer); | 1171 | del_timer_sync(&sdata->u.ibss.timer); |
1175 | 1172 | ||
1176 | mutex_unlock(&sdata->u.ibss.mtx); | ||
1177 | |||
1178 | return 0; | 1173 | return 0; |
1179 | } | 1174 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 44be28cfc6c4..9eed6f1d1614 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -394,7 +394,6 @@ struct ieee80211_if_managed { | |||
394 | bool nullfunc_failed; | 394 | bool nullfunc_failed; |
395 | bool connection_loss; | 395 | bool connection_loss; |
396 | 396 | ||
397 | struct mutex mtx; | ||
398 | struct cfg80211_bss *associated; | 397 | struct cfg80211_bss *associated; |
399 | struct ieee80211_mgd_auth_data *auth_data; | 398 | struct ieee80211_mgd_auth_data *auth_data; |
400 | struct ieee80211_mgd_assoc_data *assoc_data; | 399 | struct ieee80211_mgd_assoc_data *assoc_data; |
@@ -488,8 +487,6 @@ struct ieee80211_if_managed { | |||
488 | struct ieee80211_if_ibss { | 487 | struct ieee80211_if_ibss { |
489 | struct timer_list timer; | 488 | struct timer_list timer; |
490 | 489 | ||
491 | struct mutex mtx; | ||
492 | |||
493 | unsigned long last_scan_completed; | 490 | unsigned long last_scan_completed; |
494 | 491 | ||
495 | u32 basic_rates; | 492 | u32 basic_rates; |
@@ -580,8 +577,6 @@ struct ieee80211_if_mesh { | |||
580 | bool accepting_plinks; | 577 | bool accepting_plinks; |
581 | int num_gates; | 578 | int num_gates; |
582 | struct beacon_data __rcu *beacon; | 579 | struct beacon_data __rcu *beacon; |
583 | /* just protects beacon updates for now */ | ||
584 | struct mutex mtx; | ||
585 | const u8 *ie; | 580 | const u8 *ie; |
586 | u8 ie_len; | 581 | u8 ie_len; |
587 | enum { | 582 | enum { |
@@ -778,6 +773,26 @@ struct ieee80211_sub_if_data *vif_to_sdata(struct ieee80211_vif *p) | |||
778 | return container_of(p, struct ieee80211_sub_if_data, vif); | 773 | return container_of(p, struct ieee80211_sub_if_data, vif); |
779 | } | 774 | } |
780 | 775 | ||
776 | static inline void sdata_lock(struct ieee80211_sub_if_data *sdata) | ||
777 | __acquires(&sdata->wdev.mtx) | ||
778 | { | ||
779 | mutex_lock(&sdata->wdev.mtx); | ||
780 | __acquire(&sdata->wdev.mtx); | ||
781 | } | ||
782 | |||
783 | static inline void sdata_unlock(struct ieee80211_sub_if_data *sdata) | ||
784 | __releases(&sdata->wdev.mtx) | ||
785 | { | ||
786 | mutex_unlock(&sdata->wdev.mtx); | ||
787 | __release(&sdata->wdev.mtx); | ||
788 | } | ||
789 | |||
790 | static inline void | ||
791 | sdata_assert_lock(struct ieee80211_sub_if_data *sdata) | ||
792 | { | ||
793 | lockdep_assert_held(&sdata->wdev.mtx); | ||
794 | } | ||
795 | |||
781 | static inline enum ieee80211_band | 796 | static inline enum ieee80211_band |
782 | ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata) | 797 | ieee80211_get_sdata_band(struct ieee80211_sub_if_data *sdata) |
783 | { | 798 | { |
@@ -1506,9 +1521,6 @@ static inline void ieee802_11_parse_elems(u8 *start, size_t len, bool action, | |||
1506 | ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); | 1521 | ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0); |
1507 | } | 1522 | } |
1508 | 1523 | ||
1509 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | ||
1510 | enum ieee80211_band band); | ||
1511 | |||
1512 | void ieee80211_dynamic_ps_enable_work(struct work_struct *work); | 1524 | void ieee80211_dynamic_ps_enable_work(struct work_struct *work); |
1513 | void ieee80211_dynamic_ps_disable_work(struct work_struct *work); | 1525 | void ieee80211_dynamic_ps_disable_work(struct work_struct *work); |
1514 | void ieee80211_dynamic_ps_timer(unsigned long data); | 1526 | void ieee80211_dynamic_ps_timer(unsigned long data); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 7c3ba8628d4e..cc117591f678 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -159,7 +159,8 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | |||
159 | return 0; | 159 | return 0; |
160 | } | 160 | } |
161 | 161 | ||
162 | static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr) | 162 | static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr, |
163 | bool check_dup) | ||
163 | { | 164 | { |
164 | struct ieee80211_local *local = sdata->local; | 165 | struct ieee80211_local *local = sdata->local; |
165 | struct ieee80211_sub_if_data *iter; | 166 | struct ieee80211_sub_if_data *iter; |
@@ -180,13 +181,16 @@ static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr) | |||
180 | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | | 181 | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | |
181 | ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); | 182 | ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); |
182 | 183 | ||
184 | if (!check_dup) | ||
185 | return ret; | ||
183 | 186 | ||
184 | mutex_lock(&local->iflist_mtx); | 187 | mutex_lock(&local->iflist_mtx); |
185 | list_for_each_entry(iter, &local->interfaces, list) { | 188 | list_for_each_entry(iter, &local->interfaces, list) { |
186 | if (iter == sdata) | 189 | if (iter == sdata) |
187 | continue; | 190 | continue; |
188 | 191 | ||
189 | if (iter->vif.type == NL80211_IFTYPE_MONITOR) | 192 | if (iter->vif.type == NL80211_IFTYPE_MONITOR && |
193 | !(iter->u.mntr_flags & MONITOR_FLAG_ACTIVE)) | ||
190 | continue; | 194 | continue; |
191 | 195 | ||
192 | m = iter->vif.addr; | 196 | m = iter->vif.addr; |
@@ -208,12 +212,17 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr) | |||
208 | { | 212 | { |
209 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 213 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
210 | struct sockaddr *sa = addr; | 214 | struct sockaddr *sa = addr; |
215 | bool check_dup = true; | ||
211 | int ret; | 216 | int ret; |
212 | 217 | ||
213 | if (ieee80211_sdata_running(sdata)) | 218 | if (ieee80211_sdata_running(sdata)) |
214 | return -EBUSY; | 219 | return -EBUSY; |
215 | 220 | ||
216 | ret = ieee80211_verify_mac(sdata, sa->sa_data); | 221 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR && |
222 | !(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) | ||
223 | check_dup = false; | ||
224 | |||
225 | ret = ieee80211_verify_mac(sdata, sa->sa_data, check_dup); | ||
217 | if (ret) | 226 | if (ret) |
218 | return ret; | 227 | return ret; |
219 | 228 | ||
@@ -545,7 +554,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
545 | break; | 554 | break; |
546 | } | 555 | } |
547 | 556 | ||
548 | if (local->monitors == 0 && local->open_count == 0) { | 557 | if (sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE) { |
558 | res = drv_add_interface(local, sdata); | ||
559 | if (res) | ||
560 | goto err_stop; | ||
561 | } else if (local->monitors == 0 && local->open_count == 0) { | ||
549 | res = ieee80211_add_virtual_monitor(local); | 562 | res = ieee80211_add_virtual_monitor(local); |
550 | if (res) | 563 | if (res) |
551 | goto err_stop; | 564 | goto err_stop; |
@@ -923,7 +936,11 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
923 | mutex_lock(&local->mtx); | 936 | mutex_lock(&local->mtx); |
924 | ieee80211_recalc_idle(local); | 937 | ieee80211_recalc_idle(local); |
925 | mutex_unlock(&local->mtx); | 938 | mutex_unlock(&local->mtx); |
926 | break; | 939 | |
940 | if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) | ||
941 | break; | ||
942 | |||
943 | /* fall through */ | ||
927 | default: | 944 | default: |
928 | if (going_down) | 945 | if (going_down) |
929 | drv_remove_interface(local, sdata); | 946 | drv_remove_interface(local, sdata); |
@@ -1072,7 +1089,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = { | |||
1072 | .ndo_start_xmit = ieee80211_monitor_start_xmit, | 1089 | .ndo_start_xmit = ieee80211_monitor_start_xmit, |
1073 | .ndo_set_rx_mode = ieee80211_set_multicast_list, | 1090 | .ndo_set_rx_mode = ieee80211_set_multicast_list, |
1074 | .ndo_change_mtu = ieee80211_change_mtu, | 1091 | .ndo_change_mtu = ieee80211_change_mtu, |
1075 | .ndo_set_mac_address = eth_mac_addr, | 1092 | .ndo_set_mac_address = ieee80211_change_mac, |
1076 | .ndo_select_queue = ieee80211_monitor_select_queue, | 1093 | .ndo_select_queue = ieee80211_monitor_select_queue, |
1077 | }; | 1094 | }; |
1078 | 1095 | ||
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 67059b88fea5..e39cc91d0cf1 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -335,12 +335,12 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, | |||
335 | switch (cipher) { | 335 | switch (cipher) { |
336 | case WLAN_CIPHER_SUITE_WEP40: | 336 | case WLAN_CIPHER_SUITE_WEP40: |
337 | case WLAN_CIPHER_SUITE_WEP104: | 337 | case WLAN_CIPHER_SUITE_WEP104: |
338 | key->conf.iv_len = WEP_IV_LEN; | 338 | key->conf.iv_len = IEEE80211_WEP_IV_LEN; |
339 | key->conf.icv_len = WEP_ICV_LEN; | 339 | key->conf.icv_len = IEEE80211_WEP_ICV_LEN; |
340 | break; | 340 | break; |
341 | case WLAN_CIPHER_SUITE_TKIP: | 341 | case WLAN_CIPHER_SUITE_TKIP: |
342 | key->conf.iv_len = TKIP_IV_LEN; | 342 | key->conf.iv_len = IEEE80211_TKIP_IV_LEN; |
343 | key->conf.icv_len = TKIP_ICV_LEN; | 343 | key->conf.icv_len = IEEE80211_TKIP_ICV_LEN; |
344 | if (seq) { | 344 | if (seq) { |
345 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | 345 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { |
346 | key->u.tkip.rx[i].iv32 = | 346 | key->u.tkip.rx[i].iv32 = |
@@ -352,13 +352,13 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, | |||
352 | spin_lock_init(&key->u.tkip.txlock); | 352 | spin_lock_init(&key->u.tkip.txlock); |
353 | break; | 353 | break; |
354 | case WLAN_CIPHER_SUITE_CCMP: | 354 | case WLAN_CIPHER_SUITE_CCMP: |
355 | key->conf.iv_len = CCMP_HDR_LEN; | 355 | key->conf.iv_len = IEEE80211_CCMP_HDR_LEN; |
356 | key->conf.icv_len = CCMP_MIC_LEN; | 356 | key->conf.icv_len = IEEE80211_CCMP_MIC_LEN; |
357 | if (seq) { | 357 | if (seq) { |
358 | for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) | 358 | for (i = 0; i < IEEE80211_NUM_TIDS + 1; i++) |
359 | for (j = 0; j < CCMP_PN_LEN; j++) | 359 | for (j = 0; j < IEEE80211_CCMP_PN_LEN; j++) |
360 | key->u.ccmp.rx_pn[i][j] = | 360 | key->u.ccmp.rx_pn[i][j] = |
361 | seq[CCMP_PN_LEN - j - 1]; | 361 | seq[IEEE80211_CCMP_PN_LEN - j - 1]; |
362 | } | 362 | } |
363 | /* | 363 | /* |
364 | * Initialize AES key state here as an optimization so that | 364 | * Initialize AES key state here as an optimization so that |
@@ -375,9 +375,9 @@ struct ieee80211_key *ieee80211_key_alloc(u32 cipher, int idx, size_t key_len, | |||
375 | key->conf.iv_len = 0; | 375 | key->conf.iv_len = 0; |
376 | key->conf.icv_len = sizeof(struct ieee80211_mmie); | 376 | key->conf.icv_len = sizeof(struct ieee80211_mmie); |
377 | if (seq) | 377 | if (seq) |
378 | for (j = 0; j < CMAC_PN_LEN; j++) | 378 | for (j = 0; j < IEEE80211_CMAC_PN_LEN; j++) |
379 | key->u.aes_cmac.rx_pn[j] = | 379 | key->u.aes_cmac.rx_pn[j] = |
380 | seq[CMAC_PN_LEN - j - 1]; | 380 | seq[IEEE80211_CMAC_PN_LEN - j - 1]; |
381 | /* | 381 | /* |
382 | * Initialize AES key state here as an optimization so that | 382 | * Initialize AES key state here as an optimization so that |
383 | * it does not need to be initialized for every packet. | 383 | * it does not need to be initialized for every packet. |
@@ -740,13 +740,13 @@ void ieee80211_get_key_rx_seq(struct ieee80211_key_conf *keyconf, | |||
740 | pn = key->u.ccmp.rx_pn[IEEE80211_NUM_TIDS]; | 740 | pn = key->u.ccmp.rx_pn[IEEE80211_NUM_TIDS]; |
741 | else | 741 | else |
742 | pn = key->u.ccmp.rx_pn[tid]; | 742 | pn = key->u.ccmp.rx_pn[tid]; |
743 | memcpy(seq->ccmp.pn, pn, CCMP_PN_LEN); | 743 | memcpy(seq->ccmp.pn, pn, IEEE80211_CCMP_PN_LEN); |
744 | break; | 744 | break; |
745 | case WLAN_CIPHER_SUITE_AES_CMAC: | 745 | case WLAN_CIPHER_SUITE_AES_CMAC: |
746 | if (WARN_ON(tid != 0)) | 746 | if (WARN_ON(tid != 0)) |
747 | return; | 747 | return; |
748 | pn = key->u.aes_cmac.rx_pn; | 748 | pn = key->u.aes_cmac.rx_pn; |
749 | memcpy(seq->aes_cmac.pn, pn, CMAC_PN_LEN); | 749 | memcpy(seq->aes_cmac.pn, pn, IEEE80211_CMAC_PN_LEN); |
750 | break; | 750 | break; |
751 | } | 751 | } |
752 | } | 752 | } |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index e8de3e6d7804..036d57e76a5e 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -19,17 +19,6 @@ | |||
19 | #define NUM_DEFAULT_KEYS 4 | 19 | #define NUM_DEFAULT_KEYS 4 |
20 | #define NUM_DEFAULT_MGMT_KEYS 2 | 20 | #define NUM_DEFAULT_MGMT_KEYS 2 |
21 | 21 | ||
22 | #define WEP_IV_LEN 4 | ||
23 | #define WEP_ICV_LEN 4 | ||
24 | #define ALG_CCMP_KEY_LEN 16 | ||
25 | #define CCMP_HDR_LEN 8 | ||
26 | #define CCMP_MIC_LEN 8 | ||
27 | #define CCMP_TK_LEN 16 | ||
28 | #define CCMP_PN_LEN 6 | ||
29 | #define TKIP_IV_LEN 8 | ||
30 | #define TKIP_ICV_LEN 4 | ||
31 | #define CMAC_PN_LEN 6 | ||
32 | |||
33 | struct ieee80211_local; | 22 | struct ieee80211_local; |
34 | struct ieee80211_sub_if_data; | 23 | struct ieee80211_sub_if_data; |
35 | struct sta_info; | 24 | struct sta_info; |
@@ -93,13 +82,13 @@ struct ieee80211_key { | |||
93 | * frames and the last counter is used with Robust | 82 | * frames and the last counter is used with Robust |
94 | * Management frames. | 83 | * Management frames. |
95 | */ | 84 | */ |
96 | u8 rx_pn[IEEE80211_NUM_TIDS + 1][CCMP_PN_LEN]; | 85 | u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; |
97 | struct crypto_cipher *tfm; | 86 | struct crypto_cipher *tfm; |
98 | u32 replays; /* dot11RSNAStatsCCMPReplays */ | 87 | u32 replays; /* dot11RSNAStatsCCMPReplays */ |
99 | } ccmp; | 88 | } ccmp; |
100 | struct { | 89 | struct { |
101 | atomic64_t tx_pn; | 90 | atomic64_t tx_pn; |
102 | u8 rx_pn[CMAC_PN_LEN]; | 91 | u8 rx_pn[IEEE80211_CMAC_PN_LEN]; |
103 | struct crypto_cipher *tfm; | 92 | struct crypto_cipher *tfm; |
104 | u32 replays; /* dot11RSNAStatsCMACReplays */ | 93 | u32 replays; /* dot11RSNAStatsCMACReplays */ |
105 | u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ | 94 | u32 icverrors; /* dot11RSNAStatsCMACICVErrors */ |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 8a7bfc47d577..1998f1475267 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -331,7 +331,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, | |||
331 | return NOTIFY_DONE; | 331 | return NOTIFY_DONE; |
332 | 332 | ||
333 | ifmgd = &sdata->u.mgd; | 333 | ifmgd = &sdata->u.mgd; |
334 | mutex_lock(&ifmgd->mtx); | 334 | sdata_lock(sdata); |
335 | 335 | ||
336 | /* Copy the addresses to the bss_conf list */ | 336 | /* Copy the addresses to the bss_conf list */ |
337 | ifa = idev->ifa_list; | 337 | ifa = idev->ifa_list; |
@@ -349,7 +349,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, | |||
349 | ieee80211_bss_info_change_notify(sdata, | 349 | ieee80211_bss_info_change_notify(sdata, |
350 | BSS_CHANGED_ARP_FILTER); | 350 | BSS_CHANGED_ARP_FILTER); |
351 | 351 | ||
352 | mutex_unlock(&ifmgd->mtx); | 352 | sdata_unlock(sdata); |
353 | 353 | ||
354 | return NOTIFY_DONE; | 354 | return NOTIFY_DONE; |
355 | } | 355 | } |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 6952760881c8..b3d1fdd46368 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -161,8 +161,11 @@ void mesh_sta_cleanup(struct sta_info *sta) | |||
161 | del_timer_sync(&sta->plink_timer); | 161 | del_timer_sync(&sta->plink_timer); |
162 | } | 162 | } |
163 | 163 | ||
164 | if (changed) | 164 | if (changed) { |
165 | sdata_lock(sdata); | ||
165 | ieee80211_mbss_info_change_notify(sdata, changed); | 166 | ieee80211_mbss_info_change_notify(sdata, changed); |
167 | sdata_unlock(sdata); | ||
168 | } | ||
166 | } | 169 | } |
167 | 170 | ||
168 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) | 171 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata) |
@@ -577,7 +580,9 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata) | |||
577 | mesh_path_expire(sdata); | 580 | mesh_path_expire(sdata); |
578 | 581 | ||
579 | changed = mesh_accept_plinks_update(sdata); | 582 | changed = mesh_accept_plinks_update(sdata); |
583 | sdata_lock(sdata); | ||
580 | ieee80211_mbss_info_change_notify(sdata, changed); | 584 | ieee80211_mbss_info_change_notify(sdata, changed); |
585 | sdata_unlock(sdata); | ||
581 | 586 | ||
582 | mod_timer(&ifmsh->housekeeping_timer, | 587 | mod_timer(&ifmsh->housekeeping_timer, |
583 | round_jiffies(jiffies + | 588 | round_jiffies(jiffies + |
@@ -697,25 +702,21 @@ out_free: | |||
697 | } | 702 | } |
698 | 703 | ||
699 | static int | 704 | static int |
700 | ieee80211_mesh_rebuild_beacon(struct ieee80211_if_mesh *ifmsh) | 705 | ieee80211_mesh_rebuild_beacon(struct ieee80211_sub_if_data *sdata) |
701 | { | 706 | { |
702 | struct beacon_data *old_bcn; | 707 | struct beacon_data *old_bcn; |
703 | int ret; | 708 | int ret; |
704 | 709 | ||
705 | mutex_lock(&ifmsh->mtx); | 710 | old_bcn = rcu_dereference_protected(sdata->u.mesh.beacon, |
706 | 711 | lockdep_is_held(&sdata->wdev.mtx)); | |
707 | old_bcn = rcu_dereference_protected(ifmsh->beacon, | 712 | ret = ieee80211_mesh_build_beacon(&sdata->u.mesh); |
708 | lockdep_is_held(&ifmsh->mtx)); | ||
709 | ret = ieee80211_mesh_build_beacon(ifmsh); | ||
710 | if (ret) | 713 | if (ret) |
711 | /* just reuse old beacon */ | 714 | /* just reuse old beacon */ |
712 | goto out; | 715 | return ret; |
713 | 716 | ||
714 | if (old_bcn) | 717 | if (old_bcn) |
715 | kfree_rcu(old_bcn, rcu_head); | 718 | kfree_rcu(old_bcn, rcu_head); |
716 | out: | 719 | return 0; |
717 | mutex_unlock(&ifmsh->mtx); | ||
718 | return ret; | ||
719 | } | 720 | } |
720 | 721 | ||
721 | void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, | 722 | void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, |
@@ -726,7 +727,7 @@ void ieee80211_mbss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
726 | BSS_CHANGED_HT | | 727 | BSS_CHANGED_HT | |
727 | BSS_CHANGED_BASIC_RATES | | 728 | BSS_CHANGED_BASIC_RATES | |
728 | BSS_CHANGED_BEACON_INT))) | 729 | BSS_CHANGED_BEACON_INT))) |
729 | if (ieee80211_mesh_rebuild_beacon(&sdata->u.mesh)) | 730 | if (ieee80211_mesh_rebuild_beacon(sdata)) |
730 | return; | 731 | return; |
731 | ieee80211_bss_info_change_notify(sdata, changed); | 732 | ieee80211_bss_info_change_notify(sdata, changed); |
732 | } | 733 | } |
@@ -741,6 +742,8 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
741 | BSS_CHANGED_BASIC_RATES | | 742 | BSS_CHANGED_BASIC_RATES | |
742 | BSS_CHANGED_BEACON_INT; | 743 | BSS_CHANGED_BEACON_INT; |
743 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); | 744 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); |
745 | struct ieee80211_supported_band *sband = | ||
746 | sdata->local->hw.wiphy->bands[band]; | ||
744 | 747 | ||
745 | local->fif_other_bss++; | 748 | local->fif_other_bss++; |
746 | /* mesh ifaces must set allmulti to forward mcast traffic */ | 749 | /* mesh ifaces must set allmulti to forward mcast traffic */ |
@@ -748,7 +751,6 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
748 | ieee80211_configure_filter(local); | 751 | ieee80211_configure_filter(local); |
749 | 752 | ||
750 | ifmsh->mesh_cc_id = 0; /* Disabled */ | 753 | ifmsh->mesh_cc_id = 0; /* Disabled */ |
751 | ifmsh->mesh_auth_id = 0; /* Disabled */ | ||
752 | /* register sync ops from extensible synchronization framework */ | 754 | /* register sync ops from extensible synchronization framework */ |
753 | ifmsh->sync_ops = ieee80211_mesh_sync_ops_get(ifmsh->mesh_sp_id); | 755 | ifmsh->sync_ops = ieee80211_mesh_sync_ops_get(ifmsh->mesh_sp_id); |
754 | ifmsh->adjusting_tbtt = false; | 756 | ifmsh->adjusting_tbtt = false; |
@@ -759,8 +761,7 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
759 | sdata->vif.bss_conf.ht_operation_mode = | 761 | sdata->vif.bss_conf.ht_operation_mode = |
760 | ifmsh->mshcfg.ht_opmode; | 762 | ifmsh->mshcfg.ht_opmode; |
761 | sdata->vif.bss_conf.enable_beacon = true; | 763 | sdata->vif.bss_conf.enable_beacon = true; |
762 | sdata->vif.bss_conf.basic_rates = | 764 | sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sband); |
763 | ieee80211_mandatory_rates(local, band); | ||
764 | 765 | ||
765 | changed |= ieee80211_mps_local_status_update(sdata); | 766 | changed |= ieee80211_mps_local_status_update(sdata); |
766 | 767 | ||
@@ -788,12 +789,12 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | |||
788 | sdata->vif.bss_conf.enable_beacon = false; | 789 | sdata->vif.bss_conf.enable_beacon = false; |
789 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); | 790 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); |
790 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 791 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
791 | mutex_lock(&ifmsh->mtx); | 792 | sdata_lock(sdata); |
792 | bcn = rcu_dereference_protected(ifmsh->beacon, | 793 | bcn = rcu_dereference_protected(ifmsh->beacon, |
793 | lockdep_is_held(&ifmsh->mtx)); | 794 | lockdep_is_held(&sdata->wdev.mtx)); |
794 | rcu_assign_pointer(ifmsh->beacon, NULL); | 795 | rcu_assign_pointer(ifmsh->beacon, NULL); |
795 | kfree_rcu(bcn, rcu_head); | 796 | kfree_rcu(bcn, rcu_head); |
796 | mutex_unlock(&ifmsh->mtx); | 797 | sdata_unlock(sdata); |
797 | 798 | ||
798 | /* flush STAs and mpaths on this iface */ | 799 | /* flush STAs and mpaths on this iface */ |
799 | sta_info_flush(sdata); | 800 | sta_info_flush(sdata); |
@@ -1041,7 +1042,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) | |||
1041 | spin_lock_init(&ifmsh->mesh_preq_queue_lock); | 1042 | spin_lock_init(&ifmsh->mesh_preq_queue_lock); |
1042 | spin_lock_init(&ifmsh->sync_offset_lock); | 1043 | spin_lock_init(&ifmsh->sync_offset_lock); |
1043 | RCU_INIT_POINTER(ifmsh->beacon, NULL); | 1044 | RCU_INIT_POINTER(ifmsh->beacon, NULL); |
1044 | mutex_init(&ifmsh->mtx); | ||
1045 | 1045 | ||
1046 | sdata->vif.bss_conf.bssid = zero_addr; | 1046 | sdata->vif.bss_conf.bssid = zero_addr; |
1047 | } | 1047 | } |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 09bebed99416..6c4da99bc4fb 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -517,7 +517,9 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata, | |||
517 | ieee80211_mps_frame_release(sta, elems); | 517 | ieee80211_mps_frame_release(sta, elems); |
518 | out: | 518 | out: |
519 | rcu_read_unlock(); | 519 | rcu_read_unlock(); |
520 | sdata_lock(sdata); | ||
520 | ieee80211_mbss_info_change_notify(sdata, changed); | 521 | ieee80211_mbss_info_change_notify(sdata, changed); |
522 | sdata_unlock(sdata); | ||
521 | } | 523 | } |
522 | 524 | ||
523 | static void mesh_plink_timer(unsigned long data) | 525 | static void mesh_plink_timer(unsigned long data) |
@@ -1068,6 +1070,9 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, | |||
1068 | 1070 | ||
1069 | rcu_read_unlock(); | 1071 | rcu_read_unlock(); |
1070 | 1072 | ||
1071 | if (changed) | 1073 | if (changed) { |
1074 | sdata_lock(sdata); | ||
1072 | ieee80211_mbss_info_change_notify(sdata, changed); | 1075 | ieee80211_mbss_info_change_notify(sdata, changed); |
1076 | sdata_unlock(sdata); | ||
1077 | } | ||
1073 | } | 1078 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a8c2130c8ba4..f44f4caa69ee 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -91,41 +91,6 @@ MODULE_PARM_DESC(probe_wait_ms, | |||
91 | #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 | 91 | #define IEEE80211_SIGNAL_AVE_MIN_COUNT 4 |
92 | 92 | ||
93 | /* | 93 | /* |
94 | * All cfg80211 functions have to be called outside a locked | ||
95 | * section so that they can acquire a lock themselves... This | ||
96 | * is much simpler than queuing up things in cfg80211, but we | ||
97 | * do need some indirection for that here. | ||
98 | */ | ||
99 | enum rx_mgmt_action { | ||
100 | /* no action required */ | ||
101 | RX_MGMT_NONE, | ||
102 | |||
103 | /* caller must call cfg80211_send_deauth() */ | ||
104 | RX_MGMT_CFG80211_DEAUTH, | ||
105 | |||
106 | /* caller must call cfg80211_send_disassoc() */ | ||
107 | RX_MGMT_CFG80211_DISASSOC, | ||
108 | |||
109 | /* caller must call cfg80211_send_rx_auth() */ | ||
110 | RX_MGMT_CFG80211_RX_AUTH, | ||
111 | |||
112 | /* caller must call cfg80211_send_rx_assoc() */ | ||
113 | RX_MGMT_CFG80211_RX_ASSOC, | ||
114 | |||
115 | /* caller must call cfg80211_send_assoc_timeout() */ | ||
116 | RX_MGMT_CFG80211_ASSOC_TIMEOUT, | ||
117 | |||
118 | /* used when a processed beacon causes a deauth */ | ||
119 | RX_MGMT_CFG80211_TX_DEAUTH, | ||
120 | }; | ||
121 | |||
122 | /* utils */ | ||
123 | static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd) | ||
124 | { | ||
125 | lockdep_assert_held(&ifmgd->mtx); | ||
126 | } | ||
127 | |||
128 | /* | ||
129 | * We can have multiple work items (and connection probing) | 94 | * We can have multiple work items (and connection probing) |
130 | * scheduling this timer, but we need to take care to only | 95 | * scheduling this timer, but we need to take care to only |
131 | * reschedule it when it should fire _earlier_ than it was | 96 | * reschedule it when it should fire _earlier_ than it was |
@@ -135,13 +100,14 @@ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd) | |||
135 | * has happened -- the work that runs from this timer will | 100 | * has happened -- the work that runs from this timer will |
136 | * do that. | 101 | * do that. |
137 | */ | 102 | */ |
138 | static void run_again(struct ieee80211_if_managed *ifmgd, unsigned long timeout) | 103 | static void run_again(struct ieee80211_sub_if_data *sdata, |
104 | unsigned long timeout) | ||
139 | { | 105 | { |
140 | ASSERT_MGD_MTX(ifmgd); | 106 | sdata_assert_lock(sdata); |
141 | 107 | ||
142 | if (!timer_pending(&ifmgd->timer) || | 108 | if (!timer_pending(&sdata->u.mgd.timer) || |
143 | time_before(timeout, ifmgd->timer.expires)) | 109 | time_before(timeout, sdata->u.mgd.timer.expires)) |
144 | mod_timer(&ifmgd->timer, timeout); | 110 | mod_timer(&sdata->u.mgd.timer, timeout); |
145 | } | 111 | } |
146 | 112 | ||
147 | void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) | 113 | void ieee80211_sta_reset_beacon_monitor(struct ieee80211_sub_if_data *sdata) |
@@ -652,7 +618,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
652 | struct ieee80211_channel *chan; | 618 | struct ieee80211_channel *chan; |
653 | u32 rates = 0; | 619 | u32 rates = 0; |
654 | 620 | ||
655 | lockdep_assert_held(&ifmgd->mtx); | 621 | sdata_assert_lock(sdata); |
656 | 622 | ||
657 | rcu_read_lock(); | 623 | rcu_read_lock(); |
658 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | 624 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
@@ -962,7 +928,7 @@ static void ieee80211_chswitch_work(struct work_struct *work) | |||
962 | if (!ieee80211_sdata_running(sdata)) | 928 | if (!ieee80211_sdata_running(sdata)) |
963 | return; | 929 | return; |
964 | 930 | ||
965 | mutex_lock(&ifmgd->mtx); | 931 | sdata_lock(sdata); |
966 | if (!ifmgd->associated) | 932 | if (!ifmgd->associated) |
967 | goto out; | 933 | goto out; |
968 | 934 | ||
@@ -985,7 +951,7 @@ static void ieee80211_chswitch_work(struct work_struct *work) | |||
985 | IEEE80211_QUEUE_STOP_REASON_CSA); | 951 | IEEE80211_QUEUE_STOP_REASON_CSA); |
986 | out: | 952 | out: |
987 | ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; | 953 | ifmgd->flags &= ~IEEE80211_STA_CSA_RECEIVED; |
988 | mutex_unlock(&ifmgd->mtx); | 954 | sdata_unlock(sdata); |
989 | } | 955 | } |
990 | 956 | ||
991 | void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) | 957 | void ieee80211_chswitch_done(struct ieee80211_vif *vif, bool success) |
@@ -1036,7 +1002,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
1036 | const struct ieee80211_ht_operation *ht_oper; | 1002 | const struct ieee80211_ht_operation *ht_oper; |
1037 | int secondary_channel_offset = -1; | 1003 | int secondary_channel_offset = -1; |
1038 | 1004 | ||
1039 | ASSERT_MGD_MTX(ifmgd); | 1005 | sdata_assert_lock(sdata); |
1040 | 1006 | ||
1041 | if (!cbss) | 1007 | if (!cbss) |
1042 | return; | 1008 | return; |
@@ -1390,6 +1356,9 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) | |||
1390 | IEEE80211_STA_CONNECTION_POLL)) | 1356 | IEEE80211_STA_CONNECTION_POLL)) |
1391 | return false; | 1357 | return false; |
1392 | 1358 | ||
1359 | if (!sdata->vif.bss_conf.dtim_period) | ||
1360 | return false; | ||
1361 | |||
1393 | rcu_read_lock(); | 1362 | rcu_read_lock(); |
1394 | sta = sta_info_get(sdata, mgd->bssid); | 1363 | sta = sta_info_get(sdata, mgd->bssid); |
1395 | if (sta) | 1364 | if (sta) |
@@ -1842,7 +1811,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1842 | struct ieee80211_local *local = sdata->local; | 1811 | struct ieee80211_local *local = sdata->local; |
1843 | u32 changed = 0; | 1812 | u32 changed = 0; |
1844 | 1813 | ||
1845 | ASSERT_MGD_MTX(ifmgd); | 1814 | sdata_assert_lock(sdata); |
1846 | 1815 | ||
1847 | if (WARN_ON_ONCE(tx && !frame_buf)) | 1816 | if (WARN_ON_ONCE(tx && !frame_buf)) |
1848 | return; | 1817 | return; |
@@ -2051,7 +2020,7 @@ static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata) | |||
2051 | } | 2020 | } |
2052 | 2021 | ||
2053 | ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); | 2022 | ifmgd->probe_timeout = jiffies + msecs_to_jiffies(probe_wait_ms); |
2054 | run_again(ifmgd, ifmgd->probe_timeout); | 2023 | run_again(sdata, ifmgd->probe_timeout); |
2055 | if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | 2024 | if (sdata->local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) |
2056 | ieee80211_flush_queues(sdata->local, sdata); | 2025 | ieee80211_flush_queues(sdata->local, sdata); |
2057 | } | 2026 | } |
@@ -2065,7 +2034,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
2065 | if (!ieee80211_sdata_running(sdata)) | 2034 | if (!ieee80211_sdata_running(sdata)) |
2066 | return; | 2035 | return; |
2067 | 2036 | ||
2068 | mutex_lock(&ifmgd->mtx); | 2037 | sdata_lock(sdata); |
2069 | 2038 | ||
2070 | if (!ifmgd->associated) | 2039 | if (!ifmgd->associated) |
2071 | goto out; | 2040 | goto out; |
@@ -2119,7 +2088,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
2119 | ifmgd->probe_send_count = 0; | 2088 | ifmgd->probe_send_count = 0; |
2120 | ieee80211_mgd_probe_ap_send(sdata); | 2089 | ieee80211_mgd_probe_ap_send(sdata); |
2121 | out: | 2090 | out: |
2122 | mutex_unlock(&ifmgd->mtx); | 2091 | sdata_unlock(sdata); |
2123 | } | 2092 | } |
2124 | 2093 | ||
2125 | struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, | 2094 | struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, |
@@ -2135,7 +2104,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, | |||
2135 | if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) | 2104 | if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) |
2136 | return NULL; | 2105 | return NULL; |
2137 | 2106 | ||
2138 | ASSERT_MGD_MTX(ifmgd); | 2107 | sdata_assert_lock(sdata); |
2139 | 2108 | ||
2140 | if (ifmgd->associated) | 2109 | if (ifmgd->associated) |
2141 | cbss = ifmgd->associated; | 2110 | cbss = ifmgd->associated; |
@@ -2168,9 +2137,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) | |||
2168 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2137 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2169 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 2138 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
2170 | 2139 | ||
2171 | mutex_lock(&ifmgd->mtx); | 2140 | sdata_lock(sdata); |
2172 | if (!ifmgd->associated) { | 2141 | if (!ifmgd->associated) { |
2173 | mutex_unlock(&ifmgd->mtx); | 2142 | sdata_unlock(sdata); |
2174 | return; | 2143 | return; |
2175 | } | 2144 | } |
2176 | 2145 | ||
@@ -2181,13 +2150,9 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) | |||
2181 | ieee80211_wake_queues_by_reason(&sdata->local->hw, | 2150 | ieee80211_wake_queues_by_reason(&sdata->local->hw, |
2182 | IEEE80211_MAX_QUEUE_MAP, | 2151 | IEEE80211_MAX_QUEUE_MAP, |
2183 | IEEE80211_QUEUE_STOP_REASON_CSA); | 2152 | IEEE80211_QUEUE_STOP_REASON_CSA); |
2184 | mutex_unlock(&ifmgd->mtx); | ||
2185 | 2153 | ||
2186 | /* | ||
2187 | * must be outside lock due to cfg80211, | ||
2188 | * but that's not a problem. | ||
2189 | */ | ||
2190 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); | 2154 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); |
2155 | sdata_unlock(sdata); | ||
2191 | } | 2156 | } |
2192 | 2157 | ||
2193 | static void ieee80211_beacon_connection_loss_work(struct work_struct *work) | 2158 | static void ieee80211_beacon_connection_loss_work(struct work_struct *work) |
@@ -2254,7 +2219,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata, | |||
2254 | { | 2219 | { |
2255 | struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data; | 2220 | struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data; |
2256 | 2221 | ||
2257 | lockdep_assert_held(&sdata->u.mgd.mtx); | 2222 | sdata_assert_lock(sdata); |
2258 | 2223 | ||
2259 | if (!assoc) { | 2224 | if (!assoc) { |
2260 | sta_info_destroy_addr(sdata, auth_data->bss->bssid); | 2225 | sta_info_destroy_addr(sdata, auth_data->bss->bssid); |
@@ -2295,27 +2260,26 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, | |||
2295 | auth_data->key_idx, tx_flags); | 2260 | auth_data->key_idx, tx_flags); |
2296 | } | 2261 | } |
2297 | 2262 | ||
2298 | static enum rx_mgmt_action __must_check | 2263 | static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, |
2299 | ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | 2264 | struct ieee80211_mgmt *mgmt, size_t len) |
2300 | struct ieee80211_mgmt *mgmt, size_t len) | ||
2301 | { | 2265 | { |
2302 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2266 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2303 | u8 bssid[ETH_ALEN]; | 2267 | u8 bssid[ETH_ALEN]; |
2304 | u16 auth_alg, auth_transaction, status_code; | 2268 | u16 auth_alg, auth_transaction, status_code; |
2305 | struct sta_info *sta; | 2269 | struct sta_info *sta; |
2306 | 2270 | ||
2307 | lockdep_assert_held(&ifmgd->mtx); | 2271 | sdata_assert_lock(sdata); |
2308 | 2272 | ||
2309 | if (len < 24 + 6) | 2273 | if (len < 24 + 6) |
2310 | return RX_MGMT_NONE; | 2274 | return; |
2311 | 2275 | ||
2312 | if (!ifmgd->auth_data || ifmgd->auth_data->done) | 2276 | if (!ifmgd->auth_data || ifmgd->auth_data->done) |
2313 | return RX_MGMT_NONE; | 2277 | return; |
2314 | 2278 | ||
2315 | memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); | 2279 | memcpy(bssid, ifmgd->auth_data->bss->bssid, ETH_ALEN); |
2316 | 2280 | ||
2317 | if (!ether_addr_equal(bssid, mgmt->bssid)) | 2281 | if (!ether_addr_equal(bssid, mgmt->bssid)) |
2318 | return RX_MGMT_NONE; | 2282 | return; |
2319 | 2283 | ||
2320 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); | 2284 | auth_alg = le16_to_cpu(mgmt->u.auth.auth_alg); |
2321 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); | 2285 | auth_transaction = le16_to_cpu(mgmt->u.auth.auth_transaction); |
@@ -2327,14 +2291,15 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2327 | mgmt->sa, auth_alg, ifmgd->auth_data->algorithm, | 2291 | mgmt->sa, auth_alg, ifmgd->auth_data->algorithm, |
2328 | auth_transaction, | 2292 | auth_transaction, |
2329 | ifmgd->auth_data->expected_transaction); | 2293 | ifmgd->auth_data->expected_transaction); |
2330 | return RX_MGMT_NONE; | 2294 | return; |
2331 | } | 2295 | } |
2332 | 2296 | ||
2333 | if (status_code != WLAN_STATUS_SUCCESS) { | 2297 | if (status_code != WLAN_STATUS_SUCCESS) { |
2334 | sdata_info(sdata, "%pM denied authentication (status %d)\n", | 2298 | sdata_info(sdata, "%pM denied authentication (status %d)\n", |
2335 | mgmt->sa, status_code); | 2299 | mgmt->sa, status_code); |
2336 | ieee80211_destroy_auth_data(sdata, false); | 2300 | ieee80211_destroy_auth_data(sdata, false); |
2337 | return RX_MGMT_CFG80211_RX_AUTH; | 2301 | cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); |
2302 | return; | ||
2338 | } | 2303 | } |
2339 | 2304 | ||
2340 | switch (ifmgd->auth_data->algorithm) { | 2305 | switch (ifmgd->auth_data->algorithm) { |
@@ -2347,20 +2312,20 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2347 | if (ifmgd->auth_data->expected_transaction != 4) { | 2312 | if (ifmgd->auth_data->expected_transaction != 4) { |
2348 | ieee80211_auth_challenge(sdata, mgmt, len); | 2313 | ieee80211_auth_challenge(sdata, mgmt, len); |
2349 | /* need another frame */ | 2314 | /* need another frame */ |
2350 | return RX_MGMT_NONE; | 2315 | return; |
2351 | } | 2316 | } |
2352 | break; | 2317 | break; |
2353 | default: | 2318 | default: |
2354 | WARN_ONCE(1, "invalid auth alg %d", | 2319 | WARN_ONCE(1, "invalid auth alg %d", |
2355 | ifmgd->auth_data->algorithm); | 2320 | ifmgd->auth_data->algorithm); |
2356 | return RX_MGMT_NONE; | 2321 | return; |
2357 | } | 2322 | } |
2358 | 2323 | ||
2359 | sdata_info(sdata, "authenticated\n"); | 2324 | sdata_info(sdata, "authenticated\n"); |
2360 | ifmgd->auth_data->done = true; | 2325 | ifmgd->auth_data->done = true; |
2361 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; | 2326 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; |
2362 | ifmgd->auth_data->timeout_started = true; | 2327 | ifmgd->auth_data->timeout_started = true; |
2363 | run_again(ifmgd, ifmgd->auth_data->timeout); | 2328 | run_again(sdata, ifmgd->auth_data->timeout); |
2364 | 2329 | ||
2365 | if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && | 2330 | if (ifmgd->auth_data->algorithm == WLAN_AUTH_SAE && |
2366 | ifmgd->auth_data->expected_transaction != 2) { | 2331 | ifmgd->auth_data->expected_transaction != 2) { |
@@ -2368,7 +2333,8 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2368 | * Report auth frame to user space for processing since another | 2333 | * Report auth frame to user space for processing since another |
2369 | * round of Authentication frames is still needed. | 2334 | * round of Authentication frames is still needed. |
2370 | */ | 2335 | */ |
2371 | return RX_MGMT_CFG80211_RX_AUTH; | 2336 | cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); |
2337 | return; | ||
2372 | } | 2338 | } |
2373 | 2339 | ||
2374 | /* move station state to auth */ | 2340 | /* move station state to auth */ |
@@ -2384,30 +2350,29 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2384 | } | 2350 | } |
2385 | mutex_unlock(&sdata->local->sta_mtx); | 2351 | mutex_unlock(&sdata->local->sta_mtx); |
2386 | 2352 | ||
2387 | return RX_MGMT_CFG80211_RX_AUTH; | 2353 | cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); |
2354 | return; | ||
2388 | out_err: | 2355 | out_err: |
2389 | mutex_unlock(&sdata->local->sta_mtx); | 2356 | mutex_unlock(&sdata->local->sta_mtx); |
2390 | /* ignore frame -- wait for timeout */ | 2357 | /* ignore frame -- wait for timeout */ |
2391 | return RX_MGMT_NONE; | ||
2392 | } | 2358 | } |
2393 | 2359 | ||
2394 | 2360 | ||
2395 | static enum rx_mgmt_action __must_check | 2361 | static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, |
2396 | ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | 2362 | struct ieee80211_mgmt *mgmt, size_t len) |
2397 | struct ieee80211_mgmt *mgmt, size_t len) | ||
2398 | { | 2363 | { |
2399 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2364 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2400 | const u8 *bssid = NULL; | 2365 | const u8 *bssid = NULL; |
2401 | u16 reason_code; | 2366 | u16 reason_code; |
2402 | 2367 | ||
2403 | lockdep_assert_held(&ifmgd->mtx); | 2368 | sdata_assert_lock(sdata); |
2404 | 2369 | ||
2405 | if (len < 24 + 2) | 2370 | if (len < 24 + 2) |
2406 | return RX_MGMT_NONE; | 2371 | return; |
2407 | 2372 | ||
2408 | if (!ifmgd->associated || | 2373 | if (!ifmgd->associated || |
2409 | !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) | 2374 | !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) |
2410 | return RX_MGMT_NONE; | 2375 | return; |
2411 | 2376 | ||
2412 | bssid = ifmgd->associated->bssid; | 2377 | bssid = ifmgd->associated->bssid; |
2413 | 2378 | ||
@@ -2418,25 +2383,24 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
2418 | 2383 | ||
2419 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 2384 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
2420 | 2385 | ||
2421 | return RX_MGMT_CFG80211_DEAUTH; | 2386 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, len); |
2422 | } | 2387 | } |
2423 | 2388 | ||
2424 | 2389 | ||
2425 | static enum rx_mgmt_action __must_check | 2390 | static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, |
2426 | ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | 2391 | struct ieee80211_mgmt *mgmt, size_t len) |
2427 | struct ieee80211_mgmt *mgmt, size_t len) | ||
2428 | { | 2392 | { |
2429 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2393 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2430 | u16 reason_code; | 2394 | u16 reason_code; |
2431 | 2395 | ||
2432 | lockdep_assert_held(&ifmgd->mtx); | 2396 | sdata_assert_lock(sdata); |
2433 | 2397 | ||
2434 | if (len < 24 + 2) | 2398 | if (len < 24 + 2) |
2435 | return RX_MGMT_NONE; | 2399 | return; |
2436 | 2400 | ||
2437 | if (!ifmgd->associated || | 2401 | if (!ifmgd->associated || |
2438 | !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) | 2402 | !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) |
2439 | return RX_MGMT_NONE; | 2403 | return; |
2440 | 2404 | ||
2441 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 2405 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
2442 | 2406 | ||
@@ -2445,7 +2409,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2445 | 2409 | ||
2446 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 2410 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
2447 | 2411 | ||
2448 | return RX_MGMT_CFG80211_DISASSOC; | 2412 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, len); |
2449 | } | 2413 | } |
2450 | 2414 | ||
2451 | static void ieee80211_get_rates(struct ieee80211_supported_band *sband, | 2415 | static void ieee80211_get_rates(struct ieee80211_supported_band *sband, |
@@ -2495,7 +2459,7 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata, | |||
2495 | { | 2459 | { |
2496 | struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data; | 2460 | struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data; |
2497 | 2461 | ||
2498 | lockdep_assert_held(&sdata->u.mgd.mtx); | 2462 | sdata_assert_lock(sdata); |
2499 | 2463 | ||
2500 | if (!assoc) { | 2464 | if (!assoc) { |
2501 | sta_info_destroy_addr(sdata, assoc_data->bss->bssid); | 2465 | sta_info_destroy_addr(sdata, assoc_data->bss->bssid); |
@@ -2676,10 +2640,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2676 | return true; | 2640 | return true; |
2677 | } | 2641 | } |
2678 | 2642 | ||
2679 | static enum rx_mgmt_action __must_check | 2643 | static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, |
2680 | ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | 2644 | struct ieee80211_mgmt *mgmt, |
2681 | struct ieee80211_mgmt *mgmt, size_t len, | 2645 | size_t len) |
2682 | struct cfg80211_bss **bss) | ||
2683 | { | 2646 | { |
2684 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2647 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2685 | struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; | 2648 | struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data; |
@@ -2687,13 +2650,14 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2687 | struct ieee802_11_elems elems; | 2650 | struct ieee802_11_elems elems; |
2688 | u8 *pos; | 2651 | u8 *pos; |
2689 | bool reassoc; | 2652 | bool reassoc; |
2653 | struct cfg80211_bss *bss; | ||
2690 | 2654 | ||
2691 | lockdep_assert_held(&ifmgd->mtx); | 2655 | sdata_assert_lock(sdata); |
2692 | 2656 | ||
2693 | if (!assoc_data) | 2657 | if (!assoc_data) |
2694 | return RX_MGMT_NONE; | 2658 | return; |
2695 | if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid)) | 2659 | if (!ether_addr_equal(assoc_data->bss->bssid, mgmt->bssid)) |
2696 | return RX_MGMT_NONE; | 2660 | return; |
2697 | 2661 | ||
2698 | /* | 2662 | /* |
2699 | * AssocResp and ReassocResp have identical structure, so process both | 2663 | * AssocResp and ReassocResp have identical structure, so process both |
@@ -2701,7 +2665,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2701 | */ | 2665 | */ |
2702 | 2666 | ||
2703 | if (len < 24 + 6) | 2667 | if (len < 24 + 6) |
2704 | return RX_MGMT_NONE; | 2668 | return; |
2705 | 2669 | ||
2706 | reassoc = ieee80211_is_reassoc_req(mgmt->frame_control); | 2670 | reassoc = ieee80211_is_reassoc_req(mgmt->frame_control); |
2707 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); | 2671 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); |
@@ -2728,22 +2692,23 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2728 | assoc_data->timeout = jiffies + msecs_to_jiffies(ms); | 2692 | assoc_data->timeout = jiffies + msecs_to_jiffies(ms); |
2729 | assoc_data->timeout_started = true; | 2693 | assoc_data->timeout_started = true; |
2730 | if (ms > IEEE80211_ASSOC_TIMEOUT) | 2694 | if (ms > IEEE80211_ASSOC_TIMEOUT) |
2731 | run_again(ifmgd, assoc_data->timeout); | 2695 | run_again(sdata, assoc_data->timeout); |
2732 | return RX_MGMT_NONE; | 2696 | return; |
2733 | } | 2697 | } |
2734 | 2698 | ||
2735 | *bss = assoc_data->bss; | 2699 | bss = assoc_data->bss; |
2736 | 2700 | ||
2737 | if (status_code != WLAN_STATUS_SUCCESS) { | 2701 | if (status_code != WLAN_STATUS_SUCCESS) { |
2738 | sdata_info(sdata, "%pM denied association (code=%d)\n", | 2702 | sdata_info(sdata, "%pM denied association (code=%d)\n", |
2739 | mgmt->sa, status_code); | 2703 | mgmt->sa, status_code); |
2740 | ieee80211_destroy_assoc_data(sdata, false); | 2704 | ieee80211_destroy_assoc_data(sdata, false); |
2741 | } else { | 2705 | } else { |
2742 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { | 2706 | if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) { |
2743 | /* oops -- internal error -- send timeout for now */ | 2707 | /* oops -- internal error -- send timeout for now */ |
2744 | ieee80211_destroy_assoc_data(sdata, false); | 2708 | ieee80211_destroy_assoc_data(sdata, false); |
2745 | cfg80211_put_bss(sdata->local->hw.wiphy, *bss); | 2709 | cfg80211_put_bss(sdata->local->hw.wiphy, bss); |
2746 | return RX_MGMT_CFG80211_ASSOC_TIMEOUT; | 2710 | cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid); |
2711 | return; | ||
2747 | } | 2712 | } |
2748 | sdata_info(sdata, "associated\n"); | 2713 | sdata_info(sdata, "associated\n"); |
2749 | 2714 | ||
@@ -2755,7 +2720,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2755 | ieee80211_destroy_assoc_data(sdata, true); | 2720 | ieee80211_destroy_assoc_data(sdata, true); |
2756 | } | 2721 | } |
2757 | 2722 | ||
2758 | return RX_MGMT_CFG80211_RX_ASSOC; | 2723 | cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, len); |
2759 | } | 2724 | } |
2760 | 2725 | ||
2761 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 2726 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, |
@@ -2769,7 +2734,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
2769 | struct ieee80211_channel *channel; | 2734 | struct ieee80211_channel *channel; |
2770 | bool need_ps = false; | 2735 | bool need_ps = false; |
2771 | 2736 | ||
2772 | lockdep_assert_held(&sdata->u.mgd.mtx); | 2737 | sdata_assert_lock(sdata); |
2773 | 2738 | ||
2774 | if ((sdata->u.mgd.associated && | 2739 | if ((sdata->u.mgd.associated && |
2775 | ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) || | 2740 | ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) || |
@@ -2828,7 +2793,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
2828 | 2793 | ||
2829 | ifmgd = &sdata->u.mgd; | 2794 | ifmgd = &sdata->u.mgd; |
2830 | 2795 | ||
2831 | ASSERT_MGD_MTX(ifmgd); | 2796 | sdata_assert_lock(sdata); |
2832 | 2797 | ||
2833 | if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) | 2798 | if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) |
2834 | return; /* ignore ProbeResp to foreign address */ | 2799 | return; /* ignore ProbeResp to foreign address */ |
@@ -2853,7 +2818,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
2853 | ifmgd->auth_data->tries = 0; | 2818 | ifmgd->auth_data->tries = 0; |
2854 | ifmgd->auth_data->timeout = jiffies; | 2819 | ifmgd->auth_data->timeout = jiffies; |
2855 | ifmgd->auth_data->timeout_started = true; | 2820 | ifmgd->auth_data->timeout_started = true; |
2856 | run_again(ifmgd, ifmgd->auth_data->timeout); | 2821 | run_again(sdata, ifmgd->auth_data->timeout); |
2857 | } | 2822 | } |
2858 | } | 2823 | } |
2859 | 2824 | ||
@@ -2878,10 +2843,9 @@ static const u64 care_about_ies = | |||
2878 | (1ULL << WLAN_EID_HT_CAPABILITY) | | 2843 | (1ULL << WLAN_EID_HT_CAPABILITY) | |
2879 | (1ULL << WLAN_EID_HT_OPERATION); | 2844 | (1ULL << WLAN_EID_HT_OPERATION); |
2880 | 2845 | ||
2881 | static enum rx_mgmt_action | 2846 | static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, |
2882 | ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | 2847 | struct ieee80211_mgmt *mgmt, size_t len, |
2883 | struct ieee80211_mgmt *mgmt, size_t len, | 2848 | struct ieee80211_rx_status *rx_status) |
2884 | u8 *deauth_buf, struct ieee80211_rx_status *rx_status) | ||
2885 | { | 2849 | { |
2886 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 2850 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
2887 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 2851 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
@@ -2896,24 +2860,25 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2896 | u8 erp_value = 0; | 2860 | u8 erp_value = 0; |
2897 | u32 ncrc; | 2861 | u32 ncrc; |
2898 | u8 *bssid; | 2862 | u8 *bssid; |
2863 | u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN]; | ||
2899 | 2864 | ||
2900 | lockdep_assert_held(&ifmgd->mtx); | 2865 | sdata_assert_lock(sdata); |
2901 | 2866 | ||
2902 | /* Process beacon from the current BSS */ | 2867 | /* Process beacon from the current BSS */ |
2903 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; | 2868 | baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; |
2904 | if (baselen > len) | 2869 | if (baselen > len) |
2905 | return RX_MGMT_NONE; | 2870 | return; |
2906 | 2871 | ||
2907 | rcu_read_lock(); | 2872 | rcu_read_lock(); |
2908 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | 2873 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
2909 | if (!chanctx_conf) { | 2874 | if (!chanctx_conf) { |
2910 | rcu_read_unlock(); | 2875 | rcu_read_unlock(); |
2911 | return RX_MGMT_NONE; | 2876 | return; |
2912 | } | 2877 | } |
2913 | 2878 | ||
2914 | if (rx_status->freq != chanctx_conf->def.chan->center_freq) { | 2879 | if (rx_status->freq != chanctx_conf->def.chan->center_freq) { |
2915 | rcu_read_unlock(); | 2880 | rcu_read_unlock(); |
2916 | return RX_MGMT_NONE; | 2881 | return; |
2917 | } | 2882 | } |
2918 | chan = chanctx_conf->def.chan; | 2883 | chan = chanctx_conf->def.chan; |
2919 | rcu_read_unlock(); | 2884 | rcu_read_unlock(); |
@@ -2940,13 +2905,13 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2940 | /* continue assoc process */ | 2905 | /* continue assoc process */ |
2941 | ifmgd->assoc_data->timeout = jiffies; | 2906 | ifmgd->assoc_data->timeout = jiffies; |
2942 | ifmgd->assoc_data->timeout_started = true; | 2907 | ifmgd->assoc_data->timeout_started = true; |
2943 | run_again(ifmgd, ifmgd->assoc_data->timeout); | 2908 | run_again(sdata, ifmgd->assoc_data->timeout); |
2944 | return RX_MGMT_NONE; | 2909 | return; |
2945 | } | 2910 | } |
2946 | 2911 | ||
2947 | if (!ifmgd->associated || | 2912 | if (!ifmgd->associated || |
2948 | !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) | 2913 | !ether_addr_equal(mgmt->bssid, ifmgd->associated->bssid)) |
2949 | return RX_MGMT_NONE; | 2914 | return; |
2950 | bssid = ifmgd->associated->bssid; | 2915 | bssid = ifmgd->associated->bssid; |
2951 | 2916 | ||
2952 | /* Track average RSSI from the Beacon frames of the current AP */ | 2917 | /* Track average RSSI from the Beacon frames of the current AP */ |
@@ -3092,7 +3057,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3092 | } | 3057 | } |
3093 | 3058 | ||
3094 | if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) | 3059 | if (ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) |
3095 | return RX_MGMT_NONE; | 3060 | return; |
3096 | ifmgd->beacon_crc = ncrc; | 3061 | ifmgd->beacon_crc = ncrc; |
3097 | ifmgd->beacon_crc_valid = true; | 3062 | ifmgd->beacon_crc_valid = true; |
3098 | 3063 | ||
@@ -3126,6 +3091,7 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3126 | } | 3091 | } |
3127 | 3092 | ||
3128 | changed |= BSS_CHANGED_DTIM_PERIOD; | 3093 | changed |= BSS_CHANGED_DTIM_PERIOD; |
3094 | ieee80211_recalc_ps_vif(sdata); | ||
3129 | } | 3095 | } |
3130 | 3096 | ||
3131 | if (elems.erp_info) { | 3097 | if (elems.erp_info) { |
@@ -3147,7 +3113,9 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3147 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 3113 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
3148 | WLAN_REASON_DEAUTH_LEAVING, | 3114 | WLAN_REASON_DEAUTH_LEAVING, |
3149 | true, deauth_buf); | 3115 | true, deauth_buf); |
3150 | return RX_MGMT_CFG80211_TX_DEAUTH; | 3116 | cfg80211_send_deauth(sdata->dev, deauth_buf, |
3117 | sizeof(deauth_buf)); | ||
3118 | return; | ||
3151 | } | 3119 | } |
3152 | 3120 | ||
3153 | if (sta && elems.opmode_notif) | 3121 | if (sta && elems.opmode_notif) |
@@ -3164,19 +3132,13 @@ ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3164 | elems.pwr_constr_elem); | 3132 | elems.pwr_constr_elem); |
3165 | 3133 | ||
3166 | ieee80211_bss_info_change_notify(sdata, changed); | 3134 | ieee80211_bss_info_change_notify(sdata, changed); |
3167 | |||
3168 | return RX_MGMT_NONE; | ||
3169 | } | 3135 | } |
3170 | 3136 | ||
3171 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | 3137 | void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, |
3172 | struct sk_buff *skb) | 3138 | struct sk_buff *skb) |
3173 | { | 3139 | { |
3174 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
3175 | struct ieee80211_rx_status *rx_status; | 3140 | struct ieee80211_rx_status *rx_status; |
3176 | struct ieee80211_mgmt *mgmt; | 3141 | struct ieee80211_mgmt *mgmt; |
3177 | struct cfg80211_bss *bss = NULL; | ||
3178 | enum rx_mgmt_action rma = RX_MGMT_NONE; | ||
3179 | u8 deauth_buf[IEEE80211_DEAUTH_FRAME_LEN]; | ||
3180 | u16 fc; | 3142 | u16 fc; |
3181 | struct ieee802_11_elems elems; | 3143 | struct ieee802_11_elems elems; |
3182 | int ies_len; | 3144 | int ies_len; |
@@ -3185,28 +3147,27 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
3185 | mgmt = (struct ieee80211_mgmt *) skb->data; | 3147 | mgmt = (struct ieee80211_mgmt *) skb->data; |
3186 | fc = le16_to_cpu(mgmt->frame_control); | 3148 | fc = le16_to_cpu(mgmt->frame_control); |
3187 | 3149 | ||
3188 | mutex_lock(&ifmgd->mtx); | 3150 | sdata_lock(sdata); |
3189 | 3151 | ||
3190 | switch (fc & IEEE80211_FCTL_STYPE) { | 3152 | switch (fc & IEEE80211_FCTL_STYPE) { |
3191 | case IEEE80211_STYPE_BEACON: | 3153 | case IEEE80211_STYPE_BEACON: |
3192 | rma = ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, | 3154 | ieee80211_rx_mgmt_beacon(sdata, mgmt, skb->len, rx_status); |
3193 | deauth_buf, rx_status); | ||
3194 | break; | 3155 | break; |
3195 | case IEEE80211_STYPE_PROBE_RESP: | 3156 | case IEEE80211_STYPE_PROBE_RESP: |
3196 | ieee80211_rx_mgmt_probe_resp(sdata, skb); | 3157 | ieee80211_rx_mgmt_probe_resp(sdata, skb); |
3197 | break; | 3158 | break; |
3198 | case IEEE80211_STYPE_AUTH: | 3159 | case IEEE80211_STYPE_AUTH: |
3199 | rma = ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len); | 3160 | ieee80211_rx_mgmt_auth(sdata, mgmt, skb->len); |
3200 | break; | 3161 | break; |
3201 | case IEEE80211_STYPE_DEAUTH: | 3162 | case IEEE80211_STYPE_DEAUTH: |
3202 | rma = ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len); | 3163 | ieee80211_rx_mgmt_deauth(sdata, mgmt, skb->len); |
3203 | break; | 3164 | break; |
3204 | case IEEE80211_STYPE_DISASSOC: | 3165 | case IEEE80211_STYPE_DISASSOC: |
3205 | rma = ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); | 3166 | ieee80211_rx_mgmt_disassoc(sdata, mgmt, skb->len); |
3206 | break; | 3167 | break; |
3207 | case IEEE80211_STYPE_ASSOC_RESP: | 3168 | case IEEE80211_STYPE_ASSOC_RESP: |
3208 | case IEEE80211_STYPE_REASSOC_RESP: | 3169 | case IEEE80211_STYPE_REASSOC_RESP: |
3209 | rma = ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len, &bss); | 3170 | ieee80211_rx_mgmt_assoc_resp(sdata, mgmt, skb->len); |
3210 | break; | 3171 | break; |
3211 | case IEEE80211_STYPE_ACTION: | 3172 | case IEEE80211_STYPE_ACTION: |
3212 | if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) { | 3173 | if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) { |
@@ -3252,34 +3213,7 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
3252 | } | 3213 | } |
3253 | break; | 3214 | break; |
3254 | } | 3215 | } |
3255 | mutex_unlock(&ifmgd->mtx); | 3216 | sdata_unlock(sdata); |
3256 | |||
3257 | switch (rma) { | ||
3258 | case RX_MGMT_NONE: | ||
3259 | /* no action */ | ||
3260 | break; | ||
3261 | case RX_MGMT_CFG80211_DEAUTH: | ||
3262 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); | ||
3263 | break; | ||
3264 | case RX_MGMT_CFG80211_DISASSOC: | ||
3265 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, skb->len); | ||
3266 | break; | ||
3267 | case RX_MGMT_CFG80211_RX_AUTH: | ||
3268 | cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, skb->len); | ||
3269 | break; | ||
3270 | case RX_MGMT_CFG80211_RX_ASSOC: | ||
3271 | cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, skb->len); | ||
3272 | break; | ||
3273 | case RX_MGMT_CFG80211_ASSOC_TIMEOUT: | ||
3274 | cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid); | ||
3275 | break; | ||
3276 | case RX_MGMT_CFG80211_TX_DEAUTH: | ||
3277 | cfg80211_send_deauth(sdata->dev, deauth_buf, | ||
3278 | sizeof(deauth_buf)); | ||
3279 | break; | ||
3280 | default: | ||
3281 | WARN(1, "unexpected: %d", rma); | ||
3282 | } | ||
3283 | } | 3217 | } |
3284 | 3218 | ||
3285 | static void ieee80211_sta_timer(unsigned long data) | 3219 | static void ieee80211_sta_timer(unsigned long data) |
@@ -3293,20 +3227,12 @@ static void ieee80211_sta_timer(unsigned long data) | |||
3293 | static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | 3227 | static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, |
3294 | u8 *bssid, u8 reason, bool tx) | 3228 | u8 *bssid, u8 reason, bool tx) |
3295 | { | 3229 | { |
3296 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | ||
3297 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 3230 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
3298 | 3231 | ||
3299 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, | 3232 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, |
3300 | tx, frame_buf); | 3233 | tx, frame_buf); |
3301 | mutex_unlock(&ifmgd->mtx); | ||
3302 | 3234 | ||
3303 | /* | ||
3304 | * must be outside lock due to cfg80211, | ||
3305 | * but that's not a problem. | ||
3306 | */ | ||
3307 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); | 3235 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); |
3308 | |||
3309 | mutex_lock(&ifmgd->mtx); | ||
3310 | } | 3236 | } |
3311 | 3237 | ||
3312 | static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | 3238 | static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) |
@@ -3316,7 +3242,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
3316 | struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data; | 3242 | struct ieee80211_mgd_auth_data *auth_data = ifmgd->auth_data; |
3317 | u32 tx_flags = 0; | 3243 | u32 tx_flags = 0; |
3318 | 3244 | ||
3319 | lockdep_assert_held(&ifmgd->mtx); | 3245 | sdata_assert_lock(sdata); |
3320 | 3246 | ||
3321 | if (WARN_ON_ONCE(!auth_data)) | 3247 | if (WARN_ON_ONCE(!auth_data)) |
3322 | return -EINVAL; | 3248 | return -EINVAL; |
@@ -3389,7 +3315,7 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
3389 | if (tx_flags == 0) { | 3315 | if (tx_flags == 0) { |
3390 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; | 3316 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; |
3391 | ifmgd->auth_data->timeout_started = true; | 3317 | ifmgd->auth_data->timeout_started = true; |
3392 | run_again(ifmgd, auth_data->timeout); | 3318 | run_again(sdata, auth_data->timeout); |
3393 | } else { | 3319 | } else { |
3394 | auth_data->timeout_started = false; | 3320 | auth_data->timeout_started = false; |
3395 | } | 3321 | } |
@@ -3402,7 +3328,7 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) | |||
3402 | struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data; | 3328 | struct ieee80211_mgd_assoc_data *assoc_data = sdata->u.mgd.assoc_data; |
3403 | struct ieee80211_local *local = sdata->local; | 3329 | struct ieee80211_local *local = sdata->local; |
3404 | 3330 | ||
3405 | lockdep_assert_held(&sdata->u.mgd.mtx); | 3331 | sdata_assert_lock(sdata); |
3406 | 3332 | ||
3407 | assoc_data->tries++; | 3333 | assoc_data->tries++; |
3408 | if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { | 3334 | if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { |
@@ -3426,7 +3352,7 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) | |||
3426 | if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { | 3352 | if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { |
3427 | assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; | 3353 | assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; |
3428 | assoc_data->timeout_started = true; | 3354 | assoc_data->timeout_started = true; |
3429 | run_again(&sdata->u.mgd, assoc_data->timeout); | 3355 | run_again(sdata, assoc_data->timeout); |
3430 | } else { | 3356 | } else { |
3431 | assoc_data->timeout_started = false; | 3357 | assoc_data->timeout_started = false; |
3432 | } | 3358 | } |
@@ -3451,7 +3377,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3451 | struct ieee80211_local *local = sdata->local; | 3377 | struct ieee80211_local *local = sdata->local; |
3452 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3378 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3453 | 3379 | ||
3454 | mutex_lock(&ifmgd->mtx); | 3380 | sdata_lock(sdata); |
3455 | 3381 | ||
3456 | if (ifmgd->status_received) { | 3382 | if (ifmgd->status_received) { |
3457 | __le16 fc = ifmgd->status_fc; | 3383 | __le16 fc = ifmgd->status_fc; |
@@ -3463,7 +3389,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3463 | if (status_acked) { | 3389 | if (status_acked) { |
3464 | ifmgd->auth_data->timeout = | 3390 | ifmgd->auth_data->timeout = |
3465 | jiffies + IEEE80211_AUTH_TIMEOUT_SHORT; | 3391 | jiffies + IEEE80211_AUTH_TIMEOUT_SHORT; |
3466 | run_again(ifmgd, ifmgd->auth_data->timeout); | 3392 | run_again(sdata, ifmgd->auth_data->timeout); |
3467 | } else { | 3393 | } else { |
3468 | ifmgd->auth_data->timeout = jiffies - 1; | 3394 | ifmgd->auth_data->timeout = jiffies - 1; |
3469 | } | 3395 | } |
@@ -3474,7 +3400,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3474 | if (status_acked) { | 3400 | if (status_acked) { |
3475 | ifmgd->assoc_data->timeout = | 3401 | ifmgd->assoc_data->timeout = |
3476 | jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT; | 3402 | jiffies + IEEE80211_ASSOC_TIMEOUT_SHORT; |
3477 | run_again(ifmgd, ifmgd->assoc_data->timeout); | 3403 | run_again(sdata, ifmgd->assoc_data->timeout); |
3478 | } else { | 3404 | } else { |
3479 | ifmgd->assoc_data->timeout = jiffies - 1; | 3405 | ifmgd->assoc_data->timeout = jiffies - 1; |
3480 | } | 3406 | } |
@@ -3497,12 +3423,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3497 | 3423 | ||
3498 | ieee80211_destroy_auth_data(sdata, false); | 3424 | ieee80211_destroy_auth_data(sdata, false); |
3499 | 3425 | ||
3500 | mutex_unlock(&ifmgd->mtx); | ||
3501 | cfg80211_send_auth_timeout(sdata->dev, bssid); | 3426 | cfg80211_send_auth_timeout(sdata->dev, bssid); |
3502 | mutex_lock(&ifmgd->mtx); | ||
3503 | } | 3427 | } |
3504 | } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) | 3428 | } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) |
3505 | run_again(ifmgd, ifmgd->auth_data->timeout); | 3429 | run_again(sdata, ifmgd->auth_data->timeout); |
3506 | 3430 | ||
3507 | if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && | 3431 | if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && |
3508 | time_after(jiffies, ifmgd->assoc_data->timeout)) { | 3432 | time_after(jiffies, ifmgd->assoc_data->timeout)) { |
@@ -3515,12 +3439,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3515 | 3439 | ||
3516 | ieee80211_destroy_assoc_data(sdata, false); | 3440 | ieee80211_destroy_assoc_data(sdata, false); |
3517 | 3441 | ||
3518 | mutex_unlock(&ifmgd->mtx); | ||
3519 | cfg80211_send_assoc_timeout(sdata->dev, bssid); | 3442 | cfg80211_send_assoc_timeout(sdata->dev, bssid); |
3520 | mutex_lock(&ifmgd->mtx); | ||
3521 | } | 3443 | } |
3522 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) | 3444 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) |
3523 | run_again(ifmgd, ifmgd->assoc_data->timeout); | 3445 | run_again(sdata, ifmgd->assoc_data->timeout); |
3524 | 3446 | ||
3525 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | 3447 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | |
3526 | IEEE80211_STA_CONNECTION_POLL) && | 3448 | IEEE80211_STA_CONNECTION_POLL) && |
@@ -3554,7 +3476,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3554 | false); | 3476 | false); |
3555 | } | 3477 | } |
3556 | } else if (time_is_after_jiffies(ifmgd->probe_timeout)) | 3478 | } else if (time_is_after_jiffies(ifmgd->probe_timeout)) |
3557 | run_again(ifmgd, ifmgd->probe_timeout); | 3479 | run_again(sdata, ifmgd->probe_timeout); |
3558 | else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { | 3480 | else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { |
3559 | mlme_dbg(sdata, | 3481 | mlme_dbg(sdata, |
3560 | "Failed to send nullfunc to AP %pM after %dms, disconnecting\n", | 3482 | "Failed to send nullfunc to AP %pM after %dms, disconnecting\n", |
@@ -3583,7 +3505,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3583 | } | 3505 | } |
3584 | } | 3506 | } |
3585 | 3507 | ||
3586 | mutex_unlock(&ifmgd->mtx); | 3508 | sdata_unlock(sdata); |
3587 | } | 3509 | } |
3588 | 3510 | ||
3589 | static void ieee80211_sta_bcn_mon_timer(unsigned long data) | 3511 | static void ieee80211_sta_bcn_mon_timer(unsigned long data) |
@@ -3644,9 +3566,9 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | |||
3644 | { | 3566 | { |
3645 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3567 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3646 | 3568 | ||
3647 | mutex_lock(&ifmgd->mtx); | 3569 | sdata_lock(sdata); |
3648 | if (!ifmgd->associated) { | 3570 | if (!ifmgd->associated) { |
3649 | mutex_unlock(&ifmgd->mtx); | 3571 | sdata_unlock(sdata); |
3650 | return; | 3572 | return; |
3651 | } | 3573 | } |
3652 | 3574 | ||
@@ -3657,10 +3579,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | |||
3657 | ifmgd->associated->bssid, | 3579 | ifmgd->associated->bssid, |
3658 | WLAN_REASON_UNSPECIFIED, | 3580 | WLAN_REASON_UNSPECIFIED, |
3659 | true); | 3581 | true); |
3660 | mutex_unlock(&ifmgd->mtx); | 3582 | sdata_unlock(sdata); |
3661 | return; | 3583 | return; |
3662 | } | 3584 | } |
3663 | mutex_unlock(&ifmgd->mtx); | 3585 | sdata_unlock(sdata); |
3664 | } | 3586 | } |
3665 | #endif | 3587 | #endif |
3666 | 3588 | ||
@@ -3692,8 +3614,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
3692 | ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len; | 3614 | ifmgd->uapsd_max_sp_len = sdata->local->hw.uapsd_max_sp_len; |
3693 | ifmgd->p2p_noa_index = -1; | 3615 | ifmgd->p2p_noa_index = -1; |
3694 | 3616 | ||
3695 | mutex_init(&ifmgd->mtx); | ||
3696 | |||
3697 | if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) | 3617 | if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS) |
3698 | ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC; | 3618 | ifmgd->req_smps = IEEE80211_SMPS_AUTOMATIC; |
3699 | else | 3619 | else |
@@ -4049,8 +3969,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
4049 | 3969 | ||
4050 | /* try to authenticate/probe */ | 3970 | /* try to authenticate/probe */ |
4051 | 3971 | ||
4052 | mutex_lock(&ifmgd->mtx); | ||
4053 | |||
4054 | if ((ifmgd->auth_data && !ifmgd->auth_data->done) || | 3972 | if ((ifmgd->auth_data && !ifmgd->auth_data->done) || |
4055 | ifmgd->assoc_data) { | 3973 | ifmgd->assoc_data) { |
4056 | err = -EBUSY; | 3974 | err = -EBUSY; |
@@ -4070,8 +3988,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
4070 | WLAN_REASON_UNSPECIFIED, | 3988 | WLAN_REASON_UNSPECIFIED, |
4071 | false, frame_buf); | 3989 | false, frame_buf); |
4072 | 3990 | ||
4073 | __cfg80211_send_deauth(sdata->dev, frame_buf, | 3991 | cfg80211_send_deauth(sdata->dev, frame_buf, |
4074 | sizeof(frame_buf)); | 3992 | sizeof(frame_buf)); |
4075 | } | 3993 | } |
4076 | 3994 | ||
4077 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); | 3995 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); |
@@ -4088,8 +4006,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
4088 | 4006 | ||
4089 | /* hold our own reference */ | 4007 | /* hold our own reference */ |
4090 | cfg80211_ref_bss(local->hw.wiphy, auth_data->bss); | 4008 | cfg80211_ref_bss(local->hw.wiphy, auth_data->bss); |
4091 | err = 0; | 4009 | return 0; |
4092 | goto out_unlock; | ||
4093 | 4010 | ||
4094 | err_clear: | 4011 | err_clear: |
4095 | memset(ifmgd->bssid, 0, ETH_ALEN); | 4012 | memset(ifmgd->bssid, 0, ETH_ALEN); |
@@ -4097,9 +4014,6 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
4097 | ifmgd->auth_data = NULL; | 4014 | ifmgd->auth_data = NULL; |
4098 | err_free: | 4015 | err_free: |
4099 | kfree(auth_data); | 4016 | kfree(auth_data); |
4100 | out_unlock: | ||
4101 | mutex_unlock(&ifmgd->mtx); | ||
4102 | |||
4103 | return err; | 4017 | return err; |
4104 | } | 4018 | } |
4105 | 4019 | ||
@@ -4130,8 +4044,6 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4130 | assoc_data->ssid_len = ssidie[1]; | 4044 | assoc_data->ssid_len = ssidie[1]; |
4131 | rcu_read_unlock(); | 4045 | rcu_read_unlock(); |
4132 | 4046 | ||
4133 | mutex_lock(&ifmgd->mtx); | ||
4134 | |||
4135 | if (ifmgd->associated) { | 4047 | if (ifmgd->associated) { |
4136 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 4048 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
4137 | 4049 | ||
@@ -4139,8 +4051,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4139 | WLAN_REASON_UNSPECIFIED, | 4051 | WLAN_REASON_UNSPECIFIED, |
4140 | false, frame_buf); | 4052 | false, frame_buf); |
4141 | 4053 | ||
4142 | __cfg80211_send_deauth(sdata->dev, frame_buf, | 4054 | cfg80211_send_deauth(sdata->dev, frame_buf, |
4143 | sizeof(frame_buf)); | 4055 | sizeof(frame_buf)); |
4144 | } | 4056 | } |
4145 | 4057 | ||
4146 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { | 4058 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { |
@@ -4334,7 +4246,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4334 | } | 4246 | } |
4335 | rcu_read_unlock(); | 4247 | rcu_read_unlock(); |
4336 | 4248 | ||
4337 | run_again(ifmgd, assoc_data->timeout); | 4249 | run_again(sdata, assoc_data->timeout); |
4338 | 4250 | ||
4339 | if (bss->corrupt_data) { | 4251 | if (bss->corrupt_data) { |
4340 | char *corrupt_type = "data"; | 4252 | char *corrupt_type = "data"; |
@@ -4350,17 +4262,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4350 | corrupt_type); | 4262 | corrupt_type); |
4351 | } | 4263 | } |
4352 | 4264 | ||
4353 | err = 0; | 4265 | return 0; |
4354 | goto out; | ||
4355 | err_clear: | 4266 | err_clear: |
4356 | memset(ifmgd->bssid, 0, ETH_ALEN); | 4267 | memset(ifmgd->bssid, 0, ETH_ALEN); |
4357 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); | 4268 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BSSID); |
4358 | ifmgd->assoc_data = NULL; | 4269 | ifmgd->assoc_data = NULL; |
4359 | err_free: | 4270 | err_free: |
4360 | kfree(assoc_data); | 4271 | kfree(assoc_data); |
4361 | out: | ||
4362 | mutex_unlock(&ifmgd->mtx); | ||
4363 | |||
4364 | return err; | 4272 | return err; |
4365 | } | 4273 | } |
4366 | 4274 | ||
@@ -4372,8 +4280,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4372 | bool tx = !req->local_state_change; | 4280 | bool tx = !req->local_state_change; |
4373 | bool report_frame = false; | 4281 | bool report_frame = false; |
4374 | 4282 | ||
4375 | mutex_lock(&ifmgd->mtx); | ||
4376 | |||
4377 | sdata_info(sdata, | 4283 | sdata_info(sdata, |
4378 | "deauthenticating from %pM by local choice (reason=%d)\n", | 4284 | "deauthenticating from %pM by local choice (reason=%d)\n", |
4379 | req->bssid, req->reason_code); | 4285 | req->bssid, req->reason_code); |
@@ -4385,7 +4291,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4385 | req->reason_code, tx, | 4291 | req->reason_code, tx, |
4386 | frame_buf); | 4292 | frame_buf); |
4387 | ieee80211_destroy_auth_data(sdata, false); | 4293 | ieee80211_destroy_auth_data(sdata, false); |
4388 | mutex_unlock(&ifmgd->mtx); | ||
4389 | 4294 | ||
4390 | report_frame = true; | 4295 | report_frame = true; |
4391 | goto out; | 4296 | goto out; |
@@ -4397,12 +4302,11 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4397 | req->reason_code, tx, frame_buf); | 4302 | req->reason_code, tx, frame_buf); |
4398 | report_frame = true; | 4303 | report_frame = true; |
4399 | } | 4304 | } |
4400 | mutex_unlock(&ifmgd->mtx); | ||
4401 | 4305 | ||
4402 | out: | 4306 | out: |
4403 | if (report_frame) | 4307 | if (report_frame) |
4404 | __cfg80211_send_deauth(sdata->dev, frame_buf, | 4308 | cfg80211_send_deauth(sdata->dev, frame_buf, |
4405 | IEEE80211_DEAUTH_FRAME_LEN); | 4309 | IEEE80211_DEAUTH_FRAME_LEN); |
4406 | 4310 | ||
4407 | return 0; | 4311 | return 0; |
4408 | } | 4312 | } |
@@ -4414,18 +4318,14 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
4414 | u8 bssid[ETH_ALEN]; | 4318 | u8 bssid[ETH_ALEN]; |
4415 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; | 4319 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
4416 | 4320 | ||
4417 | mutex_lock(&ifmgd->mtx); | ||
4418 | |||
4419 | /* | 4321 | /* |
4420 | * cfg80211 should catch this ... but it's racy since | 4322 | * cfg80211 should catch this ... but it's racy since |
4421 | * we can receive a disassoc frame, process it, hand it | 4323 | * we can receive a disassoc frame, process it, hand it |
4422 | * to cfg80211 while that's in a locked section already | 4324 | * to cfg80211 while that's in a locked section already |
4423 | * trying to tell us that the user wants to disconnect. | 4325 | * trying to tell us that the user wants to disconnect. |
4424 | */ | 4326 | */ |
4425 | if (ifmgd->associated != req->bss) { | 4327 | if (ifmgd->associated != req->bss) |
4426 | mutex_unlock(&ifmgd->mtx); | ||
4427 | return -ENOLINK; | 4328 | return -ENOLINK; |
4428 | } | ||
4429 | 4329 | ||
4430 | sdata_info(sdata, | 4330 | sdata_info(sdata, |
4431 | "disassociating from %pM by local choice (reason=%d)\n", | 4331 | "disassociating from %pM by local choice (reason=%d)\n", |
@@ -4435,10 +4335,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
4435 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, | 4335 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, |
4436 | req->reason_code, !req->local_state_change, | 4336 | req->reason_code, !req->local_state_change, |
4437 | frame_buf); | 4337 | frame_buf); |
4438 | mutex_unlock(&ifmgd->mtx); | ||
4439 | 4338 | ||
4440 | __cfg80211_send_disassoc(sdata->dev, frame_buf, | 4339 | cfg80211_send_disassoc(sdata->dev, frame_buf, |
4441 | IEEE80211_DEAUTH_FRAME_LEN); | 4340 | IEEE80211_DEAUTH_FRAME_LEN); |
4442 | 4341 | ||
4443 | return 0; | 4342 | return 0; |
4444 | } | 4343 | } |
@@ -4458,13 +4357,13 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata) | |||
4458 | cancel_work_sync(&ifmgd->csa_connection_drop_work); | 4357 | cancel_work_sync(&ifmgd->csa_connection_drop_work); |
4459 | cancel_work_sync(&ifmgd->chswitch_work); | 4358 | cancel_work_sync(&ifmgd->chswitch_work); |
4460 | 4359 | ||
4461 | mutex_lock(&ifmgd->mtx); | 4360 | sdata_lock(sdata); |
4462 | if (ifmgd->assoc_data) | 4361 | if (ifmgd->assoc_data) |
4463 | ieee80211_destroy_assoc_data(sdata, false); | 4362 | ieee80211_destroy_assoc_data(sdata, false); |
4464 | if (ifmgd->auth_data) | 4363 | if (ifmgd->auth_data) |
4465 | ieee80211_destroy_auth_data(sdata, false); | 4364 | ieee80211_destroy_auth_data(sdata, false); |
4466 | del_timer_sync(&ifmgd->timer); | 4365 | del_timer_sync(&ifmgd->timer); |
4467 | mutex_unlock(&ifmgd->mtx); | 4366 | sdata_unlock(sdata); |
4468 | } | 4367 | } |
4469 | 4368 | ||
4470 | void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | 4369 | void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 8e2952620256..bdd7b4a719e9 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -258,6 +258,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
258 | pos += 2; | 258 | pos += 2; |
259 | 259 | ||
260 | if (status->flag & RX_FLAG_HT) { | 260 | if (status->flag & RX_FLAG_HT) { |
261 | unsigned int stbc; | ||
262 | |||
261 | rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS); | 263 | rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_MCS); |
262 | *pos++ = local->hw.radiotap_mcs_details; | 264 | *pos++ = local->hw.radiotap_mcs_details; |
263 | *pos = 0; | 265 | *pos = 0; |
@@ -267,6 +269,8 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
267 | *pos |= IEEE80211_RADIOTAP_MCS_BW_40; | 269 | *pos |= IEEE80211_RADIOTAP_MCS_BW_40; |
268 | if (status->flag & RX_FLAG_HT_GF) | 270 | if (status->flag & RX_FLAG_HT_GF) |
269 | *pos |= IEEE80211_RADIOTAP_MCS_FMT_GF; | 271 | *pos |= IEEE80211_RADIOTAP_MCS_FMT_GF; |
272 | stbc = (status->flag & RX_FLAG_STBC_MASK) >> RX_FLAG_STBC_SHIFT; | ||
273 | *pos |= stbc << IEEE80211_RADIOTAP_MCS_STBC_SHIFT; | ||
270 | pos++; | 274 | pos++; |
271 | *pos++ = status->rate_idx; | 275 | *pos++ = status->rate_idx; |
272 | } | 276 | } |
@@ -1372,6 +1376,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1372 | struct sk_buff *skb = rx->skb; | 1376 | struct sk_buff *skb = rx->skb; |
1373 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 1377 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
1374 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 1378 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
1379 | int i; | ||
1375 | 1380 | ||
1376 | if (!sta) | 1381 | if (!sta) |
1377 | return RX_CONTINUE; | 1382 | return RX_CONTINUE; |
@@ -1422,6 +1427,19 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
1422 | ewma_add(&sta->avg_signal, -status->signal); | 1427 | ewma_add(&sta->avg_signal, -status->signal); |
1423 | } | 1428 | } |
1424 | 1429 | ||
1430 | if (status->chains) { | ||
1431 | sta->chains = status->chains; | ||
1432 | for (i = 0; i < ARRAY_SIZE(status->chain_signal); i++) { | ||
1433 | int signal = status->chain_signal[i]; | ||
1434 | |||
1435 | if (!(status->chains & BIT(i))) | ||
1436 | continue; | ||
1437 | |||
1438 | sta->chain_signal_last[i] = signal; | ||
1439 | ewma_add(&sta->chain_signal_avg[i], -signal); | ||
1440 | } | ||
1441 | } | ||
1442 | |||
1425 | /* | 1443 | /* |
1426 | * Change STA power saving mode only at the end of a frame | 1444 | * Change STA power saving mode only at the end of a frame |
1427 | * exchange sequence. | 1445 | * exchange sequence. |
@@ -1608,7 +1626,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1608 | entry->ccmp = 1; | 1626 | entry->ccmp = 1; |
1609 | memcpy(entry->last_pn, | 1627 | memcpy(entry->last_pn, |
1610 | rx->key->u.ccmp.rx_pn[queue], | 1628 | rx->key->u.ccmp.rx_pn[queue], |
1611 | CCMP_PN_LEN); | 1629 | IEEE80211_CCMP_PN_LEN); |
1612 | } | 1630 | } |
1613 | return RX_QUEUED; | 1631 | return RX_QUEUED; |
1614 | } | 1632 | } |
@@ -1627,21 +1645,21 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1627 | * (IEEE 802.11i, 8.3.3.4.5) */ | 1645 | * (IEEE 802.11i, 8.3.3.4.5) */ |
1628 | if (entry->ccmp) { | 1646 | if (entry->ccmp) { |
1629 | int i; | 1647 | int i; |
1630 | u8 pn[CCMP_PN_LEN], *rpn; | 1648 | u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; |
1631 | int queue; | 1649 | int queue; |
1632 | if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP) | 1650 | if (!rx->key || rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP) |
1633 | return RX_DROP_UNUSABLE; | 1651 | return RX_DROP_UNUSABLE; |
1634 | memcpy(pn, entry->last_pn, CCMP_PN_LEN); | 1652 | memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); |
1635 | for (i = CCMP_PN_LEN - 1; i >= 0; i--) { | 1653 | for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { |
1636 | pn[i]++; | 1654 | pn[i]++; |
1637 | if (pn[i]) | 1655 | if (pn[i]) |
1638 | break; | 1656 | break; |
1639 | } | 1657 | } |
1640 | queue = rx->security_idx; | 1658 | queue = rx->security_idx; |
1641 | rpn = rx->key->u.ccmp.rx_pn[queue]; | 1659 | rpn = rx->key->u.ccmp.rx_pn[queue]; |
1642 | if (memcmp(pn, rpn, CCMP_PN_LEN)) | 1660 | if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN)) |
1643 | return RX_DROP_UNUSABLE; | 1661 | return RX_DROP_UNUSABLE; |
1644 | memcpy(entry->last_pn, pn, CCMP_PN_LEN); | 1662 | memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN); |
1645 | } | 1663 | } |
1646 | 1664 | ||
1647 | skb_pull(rx->skb, ieee80211_hdrlen(fc)); | 1665 | skb_pull(rx->skb, ieee80211_hdrlen(fc)); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 11216bc13b27..a04c5671d7fd 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -358,6 +358,8 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
358 | do_posix_clock_monotonic_gettime(&uptime); | 358 | do_posix_clock_monotonic_gettime(&uptime); |
359 | sta->last_connected = uptime.tv_sec; | 359 | sta->last_connected = uptime.tv_sec; |
360 | ewma_init(&sta->avg_signal, 1024, 8); | 360 | ewma_init(&sta->avg_signal, 1024, 8); |
361 | for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++) | ||
362 | ewma_init(&sta->chain_signal_avg[i], 1024, 8); | ||
361 | 363 | ||
362 | if (sta_prepare_rate_control(local, sta, gfp)) { | 364 | if (sta_prepare_rate_control(local, sta, gfp)) { |
363 | kfree(sta); | 365 | kfree(sta); |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index adc30045f99e..41c28b977f7c 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -344,6 +344,11 @@ struct sta_info { | |||
344 | int last_signal; | 344 | int last_signal; |
345 | struct ewma avg_signal; | 345 | struct ewma avg_signal; |
346 | int last_ack_signal; | 346 | int last_ack_signal; |
347 | |||
348 | u8 chains; | ||
349 | s8 chain_signal_last[IEEE80211_MAX_CHAINS]; | ||
350 | struct ewma chain_signal_avg[IEEE80211_MAX_CHAINS]; | ||
351 | |||
347 | /* Plus 1 for non-QoS frames */ | 352 | /* Plus 1 for non-QoS frames */ |
348 | __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1]; | 353 | __le16 last_seq_ctrl[IEEE80211_NUM_TIDS + 1]; |
349 | 354 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 9972e07a2f96..34be9336b5d1 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -398,13 +398,14 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
398 | if (ieee80211_has_order(hdr->frame_control)) | 398 | if (ieee80211_has_order(hdr->frame_control)) |
399 | return TX_CONTINUE; | 399 | return TX_CONTINUE; |
400 | 400 | ||
401 | if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) | ||
402 | info->hw_queue = tx->sdata->vif.cab_queue; | ||
403 | |||
401 | /* no stations in PS mode */ | 404 | /* no stations in PS mode */ |
402 | if (!atomic_read(&ps->num_sta_ps)) | 405 | if (!atomic_read(&ps->num_sta_ps)) |
403 | return TX_CONTINUE; | 406 | return TX_CONTINUE; |
404 | 407 | ||
405 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; | 408 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; |
406 | if (tx->local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) | ||
407 | info->hw_queue = tx->sdata->vif.cab_queue; | ||
408 | 409 | ||
409 | /* device releases frame after DTIM beacon */ | 410 | /* device releases frame after DTIM beacon */ |
410 | if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)) | 411 | if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)) |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 27e07150eb46..89a83770d152 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -560,6 +560,9 @@ void ieee80211_iterate_active_interfaces( | |||
560 | list_for_each_entry(sdata, &local->interfaces, list) { | 560 | list_for_each_entry(sdata, &local->interfaces, list) { |
561 | switch (sdata->vif.type) { | 561 | switch (sdata->vif.type) { |
562 | case NL80211_IFTYPE_MONITOR: | 562 | case NL80211_IFTYPE_MONITOR: |
563 | if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) | ||
564 | continue; | ||
565 | break; | ||
563 | case NL80211_IFTYPE_AP_VLAN: | 566 | case NL80211_IFTYPE_AP_VLAN: |
564 | continue; | 567 | continue; |
565 | default: | 568 | default: |
@@ -598,6 +601,9 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
598 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 601 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
599 | switch (sdata->vif.type) { | 602 | switch (sdata->vif.type) { |
600 | case NL80211_IFTYPE_MONITOR: | 603 | case NL80211_IFTYPE_MONITOR: |
604 | if (!(sdata->u.mntr_flags & MONITOR_FLAG_ACTIVE)) | ||
605 | continue; | ||
606 | break; | ||
601 | case NL80211_IFTYPE_AP_VLAN: | 607 | case NL80211_IFTYPE_AP_VLAN: |
602 | continue; | 608 | continue; |
603 | default: | 609 | default: |
@@ -1072,32 +1078,6 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | |||
1072 | ieee80211_set_wmm_default(sdata, true); | 1078 | ieee80211_set_wmm_default(sdata, true); |
1073 | } | 1079 | } |
1074 | 1080 | ||
1075 | u32 ieee80211_mandatory_rates(struct ieee80211_local *local, | ||
1076 | enum ieee80211_band band) | ||
1077 | { | ||
1078 | struct ieee80211_supported_band *sband; | ||
1079 | struct ieee80211_rate *bitrates; | ||
1080 | u32 mandatory_rates; | ||
1081 | enum ieee80211_rate_flags mandatory_flag; | ||
1082 | int i; | ||
1083 | |||
1084 | sband = local->hw.wiphy->bands[band]; | ||
1085 | if (WARN_ON(!sband)) | ||
1086 | return 1; | ||
1087 | |||
1088 | if (band == IEEE80211_BAND_2GHZ) | ||
1089 | mandatory_flag = IEEE80211_RATE_MANDATORY_B; | ||
1090 | else | ||
1091 | mandatory_flag = IEEE80211_RATE_MANDATORY_A; | ||
1092 | |||
1093 | bitrates = sband->bitrates; | ||
1094 | mandatory_rates = 0; | ||
1095 | for (i = 0; i < sband->n_bitrates; i++) | ||
1096 | if (bitrates[i].flags & mandatory_flag) | ||
1097 | mandatory_rates |= BIT(i); | ||
1098 | return mandatory_rates; | ||
1099 | } | ||
1100 | |||
1101 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | 1081 | void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, |
1102 | u16 transaction, u16 auth_alg, u16 status, | 1082 | u16 transaction, u16 auth_alg, u16 status, |
1103 | const u8 *extra, size_t extra_len, const u8 *da, | 1083 | const u8 *extra, size_t extra_len, const u8 *da, |
@@ -1607,9 +1587,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1607 | if (sdata->u.mgd.dtim_period) | 1587 | if (sdata->u.mgd.dtim_period) |
1608 | changed |= BSS_CHANGED_DTIM_PERIOD; | 1588 | changed |= BSS_CHANGED_DTIM_PERIOD; |
1609 | 1589 | ||
1610 | mutex_lock(&sdata->u.mgd.mtx); | 1590 | sdata_lock(sdata); |
1611 | ieee80211_bss_info_change_notify(sdata, changed); | 1591 | ieee80211_bss_info_change_notify(sdata, changed); |
1612 | mutex_unlock(&sdata->u.mgd.mtx); | 1592 | sdata_unlock(sdata); |
1613 | break; | 1593 | break; |
1614 | case NL80211_IFTYPE_ADHOC: | 1594 | case NL80211_IFTYPE_ADHOC: |
1615 | changed |= BSS_CHANGED_IBSS; | 1595 | changed |= BSS_CHANGED_IBSS; |
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c index c04d401dae92..6ee2b5863572 100644 --- a/net/mac80211/wep.c +++ b/net/mac80211/wep.c | |||
@@ -28,7 +28,7 @@ | |||
28 | int ieee80211_wep_init(struct ieee80211_local *local) | 28 | int ieee80211_wep_init(struct ieee80211_local *local) |
29 | { | 29 | { |
30 | /* start WEP IV from a random value */ | 30 | /* start WEP IV from a random value */ |
31 | get_random_bytes(&local->wep_iv, WEP_IV_LEN); | 31 | get_random_bytes(&local->wep_iv, IEEE80211_WEP_IV_LEN); |
32 | 32 | ||
33 | local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC); | 33 | local->wep_tx_tfm = crypto_alloc_cipher("arc4", 0, CRYPTO_ALG_ASYNC); |
34 | if (IS_ERR(local->wep_tx_tfm)) { | 34 | if (IS_ERR(local->wep_tx_tfm)) { |
@@ -98,20 +98,21 @@ static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, | |||
98 | 98 | ||
99 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); | 99 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
100 | 100 | ||
101 | if (WARN_ON(skb_tailroom(skb) < WEP_ICV_LEN || | 101 | if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN || |
102 | skb_headroom(skb) < WEP_IV_LEN)) | 102 | skb_headroom(skb) < IEEE80211_WEP_IV_LEN)) |
103 | return NULL; | 103 | return NULL; |
104 | 104 | ||
105 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 105 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
106 | newhdr = skb_push(skb, WEP_IV_LEN); | 106 | newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN); |
107 | memmove(newhdr, newhdr + WEP_IV_LEN, hdrlen); | 107 | memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen); |
108 | 108 | ||
109 | /* the HW only needs room for the IV, but not the actual IV */ | 109 | /* the HW only needs room for the IV, but not the actual IV */ |
110 | if (info->control.hw_key && | 110 | if (info->control.hw_key && |
111 | (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) | 111 | (info->control.hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) |
112 | return newhdr + hdrlen; | 112 | return newhdr + hdrlen; |
113 | 113 | ||
114 | skb_set_network_header(skb, skb_network_offset(skb) + WEP_IV_LEN); | 114 | skb_set_network_header(skb, skb_network_offset(skb) + |
115 | IEEE80211_WEP_IV_LEN); | ||
115 | ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); | 116 | ieee80211_wep_get_iv(local, keylen, keyidx, newhdr + hdrlen); |
116 | return newhdr + hdrlen; | 117 | return newhdr + hdrlen; |
117 | } | 118 | } |
@@ -125,8 +126,8 @@ static void ieee80211_wep_remove_iv(struct ieee80211_local *local, | |||
125 | unsigned int hdrlen; | 126 | unsigned int hdrlen; |
126 | 127 | ||
127 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 128 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
128 | memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); | 129 | memmove(skb->data + IEEE80211_WEP_IV_LEN, skb->data, hdrlen); |
129 | skb_pull(skb, WEP_IV_LEN); | 130 | skb_pull(skb, IEEE80211_WEP_IV_LEN); |
130 | } | 131 | } |
131 | 132 | ||
132 | 133 | ||
@@ -146,7 +147,7 @@ int ieee80211_wep_encrypt_data(struct crypto_cipher *tfm, u8 *rc4key, | |||
146 | put_unaligned(icv, (__le32 *)(data + data_len)); | 147 | put_unaligned(icv, (__le32 *)(data + data_len)); |
147 | 148 | ||
148 | crypto_cipher_setkey(tfm, rc4key, klen); | 149 | crypto_cipher_setkey(tfm, rc4key, klen); |
149 | for (i = 0; i < data_len + WEP_ICV_LEN; i++) | 150 | for (i = 0; i < data_len + IEEE80211_WEP_ICV_LEN; i++) |
150 | crypto_cipher_encrypt_one(tfm, data + i, data + i); | 151 | crypto_cipher_encrypt_one(tfm, data + i, data + i); |
151 | 152 | ||
152 | return 0; | 153 | return 0; |
@@ -172,7 +173,7 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, | |||
172 | if (!iv) | 173 | if (!iv) |
173 | return -1; | 174 | return -1; |
174 | 175 | ||
175 | len = skb->len - (iv + WEP_IV_LEN - skb->data); | 176 | len = skb->len - (iv + IEEE80211_WEP_IV_LEN - skb->data); |
176 | 177 | ||
177 | /* Prepend 24-bit IV to RC4 key */ | 178 | /* Prepend 24-bit IV to RC4 key */ |
178 | memcpy(rc4key, iv, 3); | 179 | memcpy(rc4key, iv, 3); |
@@ -181,10 +182,10 @@ int ieee80211_wep_encrypt(struct ieee80211_local *local, | |||
181 | memcpy(rc4key + 3, key, keylen); | 182 | memcpy(rc4key + 3, key, keylen); |
182 | 183 | ||
183 | /* Add room for ICV */ | 184 | /* Add room for ICV */ |
184 | skb_put(skb, WEP_ICV_LEN); | 185 | skb_put(skb, IEEE80211_WEP_ICV_LEN); |
185 | 186 | ||
186 | return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, | 187 | return ieee80211_wep_encrypt_data(local->wep_tx_tfm, rc4key, keylen + 3, |
187 | iv + WEP_IV_LEN, len); | 188 | iv + IEEE80211_WEP_IV_LEN, len); |
188 | } | 189 | } |
189 | 190 | ||
190 | 191 | ||
@@ -201,11 +202,11 @@ int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, | |||
201 | return -1; | 202 | return -1; |
202 | 203 | ||
203 | crypto_cipher_setkey(tfm, rc4key, klen); | 204 | crypto_cipher_setkey(tfm, rc4key, klen); |
204 | for (i = 0; i < data_len + WEP_ICV_LEN; i++) | 205 | for (i = 0; i < data_len + IEEE80211_WEP_ICV_LEN; i++) |
205 | crypto_cipher_decrypt_one(tfm, data + i, data + i); | 206 | crypto_cipher_decrypt_one(tfm, data + i, data + i); |
206 | 207 | ||
207 | crc = cpu_to_le32(~crc32_le(~0, data, data_len)); | 208 | crc = cpu_to_le32(~crc32_le(~0, data, data_len)); |
208 | if (memcmp(&crc, data + data_len, WEP_ICV_LEN) != 0) | 209 | if (memcmp(&crc, data + data_len, IEEE80211_WEP_ICV_LEN) != 0) |
209 | /* ICV mismatch */ | 210 | /* ICV mismatch */ |
210 | return -1; | 211 | return -1; |
211 | 212 | ||
@@ -237,10 +238,10 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, | |||
237 | return -1; | 238 | return -1; |
238 | 239 | ||
239 | hdrlen = ieee80211_hdrlen(hdr->frame_control); | 240 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
240 | if (skb->len < hdrlen + WEP_IV_LEN + WEP_ICV_LEN) | 241 | if (skb->len < hdrlen + IEEE80211_WEP_IV_LEN + IEEE80211_WEP_ICV_LEN) |
241 | return -1; | 242 | return -1; |
242 | 243 | ||
243 | len = skb->len - hdrlen - WEP_IV_LEN - WEP_ICV_LEN; | 244 | len = skb->len - hdrlen - IEEE80211_WEP_IV_LEN - IEEE80211_WEP_ICV_LEN; |
244 | 245 | ||
245 | keyidx = skb->data[hdrlen + 3] >> 6; | 246 | keyidx = skb->data[hdrlen + 3] >> 6; |
246 | 247 | ||
@@ -256,16 +257,16 @@ static int ieee80211_wep_decrypt(struct ieee80211_local *local, | |||
256 | memcpy(rc4key + 3, key->conf.key, key->conf.keylen); | 257 | memcpy(rc4key + 3, key->conf.key, key->conf.keylen); |
257 | 258 | ||
258 | if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, | 259 | if (ieee80211_wep_decrypt_data(local->wep_rx_tfm, rc4key, klen, |
259 | skb->data + hdrlen + WEP_IV_LEN, | 260 | skb->data + hdrlen + |
260 | len)) | 261 | IEEE80211_WEP_IV_LEN, len)) |
261 | ret = -1; | 262 | ret = -1; |
262 | 263 | ||
263 | /* Trim ICV */ | 264 | /* Trim ICV */ |
264 | skb_trim(skb, skb->len - WEP_ICV_LEN); | 265 | skb_trim(skb, skb->len - IEEE80211_WEP_ICV_LEN); |
265 | 266 | ||
266 | /* Remove IV */ | 267 | /* Remove IV */ |
267 | memmove(skb->data + WEP_IV_LEN, skb->data, hdrlen); | 268 | memmove(skb->data + IEEE80211_WEP_IV_LEN, skb->data, hdrlen); |
268 | skb_pull(skb, WEP_IV_LEN); | 269 | skb_pull(skb, IEEE80211_WEP_IV_LEN); |
269 | 270 | ||
270 | return ret; | 271 | return ret; |
271 | } | 272 | } |
@@ -305,13 +306,14 @@ ieee80211_crypto_wep_decrypt(struct ieee80211_rx_data *rx) | |||
305 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) | 306 | if (ieee80211_wep_decrypt(rx->local, rx->skb, rx->key)) |
306 | return RX_DROP_UNUSABLE; | 307 | return RX_DROP_UNUSABLE; |
307 | } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { | 308 | } else if (!(status->flag & RX_FLAG_IV_STRIPPED)) { |
308 | if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + WEP_IV_LEN)) | 309 | if (!pskb_may_pull(rx->skb, ieee80211_hdrlen(fc) + |
310 | IEEE80211_WEP_IV_LEN)) | ||
309 | return RX_DROP_UNUSABLE; | 311 | return RX_DROP_UNUSABLE; |
310 | if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) | 312 | if (rx->sta && ieee80211_wep_is_weak_iv(rx->skb, rx->key)) |
311 | rx->sta->wep_weak_iv_count++; | 313 | rx->sta->wep_weak_iv_count++; |
312 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); | 314 | ieee80211_wep_remove_iv(rx->local, rx->skb, rx->key); |
313 | /* remove ICV */ | 315 | /* remove ICV */ |
314 | if (pskb_trim(rx->skb, rx->skb->len - WEP_ICV_LEN)) | 316 | if (pskb_trim(rx->skb, rx->skb->len - IEEE80211_WEP_ICV_LEN)) |
315 | return RX_DROP_UNUSABLE; | 317 | return RX_DROP_UNUSABLE; |
316 | } | 318 | } |
317 | 319 | ||
diff --git a/net/mac80211/wpa.c b/net/mac80211/wpa.c index c7c6d644486f..c9edfcb7a13b 100644 --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c | |||
@@ -62,10 +62,10 @@ ieee80211_tx_h_michael_mic_add(struct ieee80211_tx_data *tx) | |||
62 | 62 | ||
63 | tail = MICHAEL_MIC_LEN; | 63 | tail = MICHAEL_MIC_LEN; |
64 | if (!info->control.hw_key) | 64 | if (!info->control.hw_key) |
65 | tail += TKIP_ICV_LEN; | 65 | tail += IEEE80211_TKIP_ICV_LEN; |
66 | 66 | ||
67 | if (WARN_ON(skb_tailroom(skb) < tail || | 67 | if (WARN_ON(skb_tailroom(skb) < tail || |
68 | skb_headroom(skb) < TKIP_IV_LEN)) | 68 | skb_headroom(skb) < IEEE80211_TKIP_IV_LEN)) |
69 | return TX_DROP; | 69 | return TX_DROP; |
70 | 70 | ||
71 | key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY]; | 71 | key = &tx->key->conf.key[NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY]; |
@@ -198,15 +198,16 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
198 | if (info->control.hw_key) | 198 | if (info->control.hw_key) |
199 | tail = 0; | 199 | tail = 0; |
200 | else | 200 | else |
201 | tail = TKIP_ICV_LEN; | 201 | tail = IEEE80211_TKIP_ICV_LEN; |
202 | 202 | ||
203 | if (WARN_ON(skb_tailroom(skb) < tail || | 203 | if (WARN_ON(skb_tailroom(skb) < tail || |
204 | skb_headroom(skb) < TKIP_IV_LEN)) | 204 | skb_headroom(skb) < IEEE80211_TKIP_IV_LEN)) |
205 | return -1; | 205 | return -1; |
206 | 206 | ||
207 | pos = skb_push(skb, TKIP_IV_LEN); | 207 | pos = skb_push(skb, IEEE80211_TKIP_IV_LEN); |
208 | memmove(pos, pos + TKIP_IV_LEN, hdrlen); | 208 | memmove(pos, pos + IEEE80211_TKIP_IV_LEN, hdrlen); |
209 | skb_set_network_header(skb, skb_network_offset(skb) + TKIP_IV_LEN); | 209 | skb_set_network_header(skb, skb_network_offset(skb) + |
210 | IEEE80211_TKIP_IV_LEN); | ||
210 | pos += hdrlen; | 211 | pos += hdrlen; |
211 | 212 | ||
212 | /* the HW only needs room for the IV, but not the actual IV */ | 213 | /* the HW only needs room for the IV, but not the actual IV */ |
@@ -227,7 +228,7 @@ static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
227 | return 0; | 228 | return 0; |
228 | 229 | ||
229 | /* Add room for ICV */ | 230 | /* Add room for ICV */ |
230 | skb_put(skb, TKIP_ICV_LEN); | 231 | skb_put(skb, IEEE80211_TKIP_ICV_LEN); |
231 | 232 | ||
232 | return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, | 233 | return ieee80211_tkip_encrypt_data(tx->local->wep_tx_tfm, |
233 | key, skb, pos, len); | 234 | key, skb, pos, len); |
@@ -290,11 +291,11 @@ ieee80211_crypto_tkip_decrypt(struct ieee80211_rx_data *rx) | |||
290 | return RX_DROP_UNUSABLE; | 291 | return RX_DROP_UNUSABLE; |
291 | 292 | ||
292 | /* Trim ICV */ | 293 | /* Trim ICV */ |
293 | skb_trim(skb, skb->len - TKIP_ICV_LEN); | 294 | skb_trim(skb, skb->len - IEEE80211_TKIP_ICV_LEN); |
294 | 295 | ||
295 | /* Remove IV */ | 296 | /* Remove IV */ |
296 | memmove(skb->data + TKIP_IV_LEN, skb->data, hdrlen); | 297 | memmove(skb->data + IEEE80211_TKIP_IV_LEN, skb->data, hdrlen); |
297 | skb_pull(skb, TKIP_IV_LEN); | 298 | skb_pull(skb, IEEE80211_TKIP_IV_LEN); |
298 | 299 | ||
299 | return RX_CONTINUE; | 300 | return RX_CONTINUE; |
300 | } | 301 | } |
@@ -337,9 +338,9 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, | |||
337 | else | 338 | else |
338 | qos_tid = 0; | 339 | qos_tid = 0; |
339 | 340 | ||
340 | data_len = skb->len - hdrlen - CCMP_HDR_LEN; | 341 | data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN; |
341 | if (encrypted) | 342 | if (encrypted) |
342 | data_len -= CCMP_MIC_LEN; | 343 | data_len -= IEEE80211_CCMP_MIC_LEN; |
343 | 344 | ||
344 | /* First block, b_0 */ | 345 | /* First block, b_0 */ |
345 | b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ | 346 | b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */ |
@@ -348,7 +349,7 @@ static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch, | |||
348 | */ | 349 | */ |
349 | b_0[1] = qos_tid | (mgmt << 4); | 350 | b_0[1] = qos_tid | (mgmt << 4); |
350 | memcpy(&b_0[2], hdr->addr2, ETH_ALEN); | 351 | memcpy(&b_0[2], hdr->addr2, ETH_ALEN); |
351 | memcpy(&b_0[8], pn, CCMP_PN_LEN); | 352 | memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); |
352 | /* l(m) */ | 353 | /* l(m) */ |
353 | put_unaligned_be16(data_len, &b_0[14]); | 354 | put_unaligned_be16(data_len, &b_0[14]); |
354 | 355 | ||
@@ -424,15 +425,16 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
424 | if (info->control.hw_key) | 425 | if (info->control.hw_key) |
425 | tail = 0; | 426 | tail = 0; |
426 | else | 427 | else |
427 | tail = CCMP_MIC_LEN; | 428 | tail = IEEE80211_CCMP_MIC_LEN; |
428 | 429 | ||
429 | if (WARN_ON(skb_tailroom(skb) < tail || | 430 | if (WARN_ON(skb_tailroom(skb) < tail || |
430 | skb_headroom(skb) < CCMP_HDR_LEN)) | 431 | skb_headroom(skb) < IEEE80211_CCMP_HDR_LEN)) |
431 | return -1; | 432 | return -1; |
432 | 433 | ||
433 | pos = skb_push(skb, CCMP_HDR_LEN); | 434 | pos = skb_push(skb, IEEE80211_CCMP_HDR_LEN); |
434 | memmove(pos, pos + CCMP_HDR_LEN, hdrlen); | 435 | memmove(pos, pos + IEEE80211_CCMP_HDR_LEN, hdrlen); |
435 | skb_set_network_header(skb, skb_network_offset(skb) + CCMP_HDR_LEN); | 436 | skb_set_network_header(skb, skb_network_offset(skb) + |
437 | IEEE80211_CCMP_HDR_LEN); | ||
436 | 438 | ||
437 | /* the HW only needs room for the IV, but not the actual IV */ | 439 | /* the HW only needs room for the IV, but not the actual IV */ |
438 | if (info->control.hw_key && | 440 | if (info->control.hw_key && |
@@ -457,10 +459,10 @@ static int ccmp_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) | |||
457 | if (info->control.hw_key) | 459 | if (info->control.hw_key) |
458 | return 0; | 460 | return 0; |
459 | 461 | ||
460 | pos += CCMP_HDR_LEN; | 462 | pos += IEEE80211_CCMP_HDR_LEN; |
461 | ccmp_special_blocks(skb, pn, scratch, 0); | 463 | ccmp_special_blocks(skb, pn, scratch, 0); |
462 | ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len, | 464 | ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len, |
463 | pos, skb_put(skb, CCMP_MIC_LEN)); | 465 | pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN)); |
464 | 466 | ||
465 | return 0; | 467 | return 0; |
466 | } | 468 | } |
@@ -490,7 +492,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
490 | struct ieee80211_key *key = rx->key; | 492 | struct ieee80211_key *key = rx->key; |
491 | struct sk_buff *skb = rx->skb; | 493 | struct sk_buff *skb = rx->skb; |
492 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 494 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
493 | u8 pn[CCMP_PN_LEN]; | 495 | u8 pn[IEEE80211_CCMP_PN_LEN]; |
494 | int data_len; | 496 | int data_len; |
495 | int queue; | 497 | int queue; |
496 | 498 | ||
@@ -500,12 +502,13 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
500 | !ieee80211_is_robust_mgmt_frame(hdr)) | 502 | !ieee80211_is_robust_mgmt_frame(hdr)) |
501 | return RX_CONTINUE; | 503 | return RX_CONTINUE; |
502 | 504 | ||
503 | data_len = skb->len - hdrlen - CCMP_HDR_LEN - CCMP_MIC_LEN; | 505 | data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN - |
506 | IEEE80211_CCMP_MIC_LEN; | ||
504 | if (!rx->sta || data_len < 0) | 507 | if (!rx->sta || data_len < 0) |
505 | return RX_DROP_UNUSABLE; | 508 | return RX_DROP_UNUSABLE; |
506 | 509 | ||
507 | if (status->flag & RX_FLAG_DECRYPTED) { | 510 | if (status->flag & RX_FLAG_DECRYPTED) { |
508 | if (!pskb_may_pull(rx->skb, hdrlen + CCMP_HDR_LEN)) | 511 | if (!pskb_may_pull(rx->skb, hdrlen + IEEE80211_CCMP_HDR_LEN)) |
509 | return RX_DROP_UNUSABLE; | 512 | return RX_DROP_UNUSABLE; |
510 | } else { | 513 | } else { |
511 | if (skb_linearize(rx->skb)) | 514 | if (skb_linearize(rx->skb)) |
@@ -516,7 +519,7 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
516 | 519 | ||
517 | queue = rx->security_idx; | 520 | queue = rx->security_idx; |
518 | 521 | ||
519 | if (memcmp(pn, key->u.ccmp.rx_pn[queue], CCMP_PN_LEN) <= 0) { | 522 | if (memcmp(pn, key->u.ccmp.rx_pn[queue], IEEE80211_CCMP_PN_LEN) <= 0) { |
520 | key->u.ccmp.replays++; | 523 | key->u.ccmp.replays++; |
521 | return RX_DROP_UNUSABLE; | 524 | return RX_DROP_UNUSABLE; |
522 | } | 525 | } |
@@ -528,19 +531,20 @@ ieee80211_crypto_ccmp_decrypt(struct ieee80211_rx_data *rx) | |||
528 | 531 | ||
529 | if (ieee80211_aes_ccm_decrypt( | 532 | if (ieee80211_aes_ccm_decrypt( |
530 | key->u.ccmp.tfm, scratch, | 533 | key->u.ccmp.tfm, scratch, |
531 | skb->data + hdrlen + CCMP_HDR_LEN, data_len, | 534 | skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN, |
532 | skb->data + skb->len - CCMP_MIC_LEN, | 535 | data_len, |
533 | skb->data + hdrlen + CCMP_HDR_LEN)) | 536 | skb->data + skb->len - IEEE80211_CCMP_MIC_LEN, |
537 | skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN)) | ||
534 | return RX_DROP_UNUSABLE; | 538 | return RX_DROP_UNUSABLE; |
535 | } | 539 | } |
536 | 540 | ||
537 | memcpy(key->u.ccmp.rx_pn[queue], pn, CCMP_PN_LEN); | 541 | memcpy(key->u.ccmp.rx_pn[queue], pn, IEEE80211_CCMP_PN_LEN); |
538 | 542 | ||
539 | /* Remove CCMP header and MIC */ | 543 | /* Remove CCMP header and MIC */ |
540 | if (pskb_trim(skb, skb->len - CCMP_MIC_LEN)) | 544 | if (pskb_trim(skb, skb->len - IEEE80211_CCMP_MIC_LEN)) |
541 | return RX_DROP_UNUSABLE; | 545 | return RX_DROP_UNUSABLE; |
542 | memmove(skb->data + CCMP_HDR_LEN, skb->data, hdrlen); | 546 | memmove(skb->data + IEEE80211_CCMP_HDR_LEN, skb->data, hdrlen); |
543 | skb_pull(skb, CCMP_HDR_LEN); | 547 | skb_pull(skb, IEEE80211_CCMP_HDR_LEN); |
544 | 548 | ||
545 | return RX_CONTINUE; | 549 | return RX_CONTINUE; |
546 | } | 550 | } |