aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2014-09-04 13:41:33 -0400
committerJohn W. Linville <linville@tuxdriver.com>2014-09-04 13:41:33 -0400
commitef4ead3f29256ed83991cd77b39334aadd25672a (patch)
treea164b021488a7b1dc869c093886cada1ff07fde4 /net
parent6a5d088a923854569e20eac4f3f569926d5911ec (diff)
parentd0616613d9cf17919fbd46fa0274db4b0084ad62 (diff)
Merge tag 'mac80211-next-for-john-2014-08-29' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Johannes Berg <johannes@sipsolutions.net> says: "Not that much content this time. Some RCU cleanups, crypto performance improvements, and various patches all over, rather than listing them one might as well look into the git log instead." Signed-off-by: John W. Linville <linville@tuxdriver.com> Conflicts: drivers/net/wireless/ath/wil6210/wmi.c
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/cfg.c13
-rw-r--r--net/mac80211/chan.c191
-rw-r--r--net/mac80211/debugfs_sta.c3
-rw-r--r--net/mac80211/ibss.c2
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/key.c12
-rw-r--r--net/mac80211/mesh_pathtbl.c4
-rw-r--r--net/mac80211/mesh_plink.c14
-rw-r--r--net/mac80211/mlme.c33
-rw-r--r--net/mac80211/rx.c2
-rw-r--r--net/mac80211/scan.c2
-rw-r--r--net/mac80211/sta_info.c4
-rw-r--r--net/mac80211/sta_info.h2
-rw-r--r--net/mac80211/tdls.c3
-rw-r--r--net/mac80211/tx.c11
-rw-r--r--net/mac80211/wme.c4
-rw-r--r--net/rfkill/rfkill-gpio.c1
-rw-r--r--net/wireless/core.c6
-rw-r--r--net/wireless/mlme.c4
-rw-r--r--net/wireless/nl80211.c16
-rw-r--r--net/wireless/scan.c21
21 files changed, 179 insertions, 170 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 927b4ea0128b..4d8989b87960 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1011,15 +1011,8 @@ static int sta_apply_parameters(struct ieee80211_local *local,
1011 clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE); 1011 clear_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE);
1012 } 1012 }
1013 1013
1014 if (mask & BIT(NL80211_STA_FLAG_WME)) { 1014 if (mask & BIT(NL80211_STA_FLAG_WME))
1015 if (set & BIT(NL80211_STA_FLAG_WME)) { 1015 sta->sta.wme = set & BIT(NL80211_STA_FLAG_WME);
1016 set_sta_flag(sta, WLAN_STA_WME);
1017 sta->sta.wme = true;
1018 } else {
1019 clear_sta_flag(sta, WLAN_STA_WME);
1020 sta->sta.wme = false;
1021 }
1022 }
1023 1016
1024 if (mask & BIT(NL80211_STA_FLAG_MFP)) { 1017 if (mask & BIT(NL80211_STA_FLAG_MFP)) {
1025 if (set & BIT(NL80211_STA_FLAG_MFP)) 1018 if (set & BIT(NL80211_STA_FLAG_MFP))
@@ -3352,7 +3345,7 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev,
3352 band = chanctx_conf->def.chan->band; 3345 band = chanctx_conf->def.chan->band;
3353 sta = sta_info_get_bss(sdata, peer); 3346 sta = sta_info_get_bss(sdata, peer);
3354 if (sta) { 3347 if (sta) {
3355 qos = test_sta_flag(sta, WLAN_STA_WME); 3348 qos = sta->sta.wme;
3356 } else { 3349 } else {
3357 rcu_read_unlock(); 3350 rcu_read_unlock();
3358 return -ENOLINK; 3351 return -ENOLINK;
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 0375009ddc0d..0da6f3a027e7 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -547,12 +547,12 @@ static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
547 547
548 compat = cfg80211_chandef_compatible( 548 compat = cfg80211_chandef_compatible(
549 &sdata->vif.bss_conf.chandef, compat); 549 &sdata->vif.bss_conf.chandef, compat);
550 if (!compat) 550 if (WARN_ON_ONCE(!compat))
551 break; 551 break;
552 } 552 }
553 rcu_read_unlock(); 553 rcu_read_unlock();
554 554
555 if (WARN_ON_ONCE(!compat)) 555 if (!compat)
556 return; 556 return;
557 557
558 ieee80211_change_chanctx(local, ctx, compat); 558 ieee80211_change_chanctx(local, ctx, compat);
@@ -637,41 +637,6 @@ out:
637 return ret; 637 return ret;
638} 638}
639 639
640static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
641{
642 struct ieee80211_local *local = sdata->local;
643 struct ieee80211_chanctx_conf *conf;
644 struct ieee80211_chanctx *ctx;
645 bool use_reserved_switch = false;
646
647 lockdep_assert_held(&local->chanctx_mtx);
648
649 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
650 lockdep_is_held(&local->chanctx_mtx));
651 if (!conf)
652 return;
653
654 ctx = container_of(conf, struct ieee80211_chanctx, conf);
655
656 if (sdata->reserved_chanctx) {
657 if (sdata->reserved_chanctx->replace_state ==
658 IEEE80211_CHANCTX_REPLACES_OTHER &&
659 ieee80211_chanctx_num_reserved(local,
660 sdata->reserved_chanctx) > 1)
661 use_reserved_switch = true;
662
663 ieee80211_vif_unreserve_chanctx(sdata);
664 }
665
666 ieee80211_assign_vif_chanctx(sdata, NULL);
667 if (ieee80211_chanctx_refcount(local, ctx) == 0)
668 ieee80211_free_chanctx(local, ctx);
669
670 /* Unreserving may ready an in-place reservation. */
671 if (use_reserved_switch)
672 ieee80211_vif_use_reserved_switch(local);
673}
674
675void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local, 640void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
676 struct ieee80211_chanctx *chanctx) 641 struct ieee80211_chanctx *chanctx)
677{ 642{
@@ -762,63 +727,6 @@ void ieee80211_recalc_smps_chanctx(struct ieee80211_local *local,
762 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS); 727 drv_change_chanctx(local, chanctx, IEEE80211_CHANCTX_CHANGE_RX_CHAINS);
763} 728}
764 729
765int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
766 const struct cfg80211_chan_def *chandef,
767 enum ieee80211_chanctx_mode mode)
768{
769 struct ieee80211_local *local = sdata->local;
770 struct ieee80211_chanctx *ctx;
771 u8 radar_detect_width = 0;
772 int ret;
773
774 lockdep_assert_held(&local->mtx);
775
776 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
777
778 mutex_lock(&local->chanctx_mtx);
779
780 ret = cfg80211_chandef_dfs_required(local->hw.wiphy,
781 chandef,
782 sdata->wdev.iftype);
783 if (ret < 0)
784 goto out;
785 if (ret > 0)
786 radar_detect_width = BIT(chandef->width);
787
788 sdata->radar_required = ret;
789
790 ret = ieee80211_check_combinations(sdata, chandef, mode,
791 radar_detect_width);
792 if (ret < 0)
793 goto out;
794
795 __ieee80211_vif_release_channel(sdata);
796
797 ctx = ieee80211_find_chanctx(local, chandef, mode);
798 if (!ctx)
799 ctx = ieee80211_new_chanctx(local, chandef, mode);
800 if (IS_ERR(ctx)) {
801 ret = PTR_ERR(ctx);
802 goto out;
803 }
804
805 sdata->vif.bss_conf.chandef = *chandef;
806
807 ret = ieee80211_assign_vif_chanctx(sdata, ctx);
808 if (ret) {
809 /* if assign fails refcount stays the same */
810 if (ieee80211_chanctx_refcount(local, ctx) == 0)
811 ieee80211_free_chanctx(local, ctx);
812 goto out;
813 }
814
815 ieee80211_recalc_smps_chanctx(local, ctx);
816 ieee80211_recalc_radar_chanctx(local, ctx);
817 out:
818 mutex_unlock(&local->chanctx_mtx);
819 return ret;
820}
821
822static void 730static void
823__ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata, 731__ieee80211_vif_copy_chanctx_to_vlans(struct ieee80211_sub_if_data *sdata,
824 bool clear) 732 bool clear)
@@ -1267,8 +1175,7 @@ err:
1267 return err; 1175 return err;
1268} 1176}
1269 1177
1270int 1178static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
1271ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)
1272{ 1179{
1273 struct ieee80211_sub_if_data *sdata, *sdata_tmp; 1180 struct ieee80211_sub_if_data *sdata, *sdata_tmp;
1274 struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx; 1181 struct ieee80211_chanctx *ctx, *ctx_tmp, *old_ctx;
@@ -1520,6 +1427,98 @@ err:
1520 return err; 1427 return err;
1521} 1428}
1522 1429
1430static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata)
1431{
1432 struct ieee80211_local *local = sdata->local;
1433 struct ieee80211_chanctx_conf *conf;
1434 struct ieee80211_chanctx *ctx;
1435 bool use_reserved_switch = false;
1436
1437 lockdep_assert_held(&local->chanctx_mtx);
1438
1439 conf = rcu_dereference_protected(sdata->vif.chanctx_conf,
1440 lockdep_is_held(&local->chanctx_mtx));
1441 if (!conf)
1442 return;
1443
1444 ctx = container_of(conf, struct ieee80211_chanctx, conf);
1445
1446 if (sdata->reserved_chanctx) {
1447 if (sdata->reserved_chanctx->replace_state ==
1448 IEEE80211_CHANCTX_REPLACES_OTHER &&
1449 ieee80211_chanctx_num_reserved(local,
1450 sdata->reserved_chanctx) > 1)
1451 use_reserved_switch = true;
1452
1453 ieee80211_vif_unreserve_chanctx(sdata);
1454 }
1455
1456 ieee80211_assign_vif_chanctx(sdata, NULL);
1457 if (ieee80211_chanctx_refcount(local, ctx) == 0)
1458 ieee80211_free_chanctx(local, ctx);
1459
1460 /* Unreserving may ready an in-place reservation. */
1461 if (use_reserved_switch)
1462 ieee80211_vif_use_reserved_switch(local);
1463}
1464
1465int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata,
1466 const struct cfg80211_chan_def *chandef,
1467 enum ieee80211_chanctx_mode mode)
1468{
1469 struct ieee80211_local *local = sdata->local;
1470 struct ieee80211_chanctx *ctx;
1471 u8 radar_detect_width = 0;
1472 int ret;
1473
1474 lockdep_assert_held(&local->mtx);
1475
1476 WARN_ON(sdata->dev && netif_carrier_ok(sdata->dev));
1477
1478 mutex_lock(&local->chanctx_mtx);
1479
1480 ret = cfg80211_chandef_dfs_required(local->hw.wiphy,
1481 chandef,
1482 sdata->wdev.iftype);
1483 if (ret < 0)
1484 goto out;
1485 if (ret > 0)
1486 radar_detect_width = BIT(chandef->width);
1487
1488 sdata->radar_required = ret;
1489
1490 ret = ieee80211_check_combinations(sdata, chandef, mode,
1491 radar_detect_width);
1492 if (ret < 0)
1493 goto out;
1494
1495 __ieee80211_vif_release_channel(sdata);
1496
1497 ctx = ieee80211_find_chanctx(local, chandef, mode);
1498 if (!ctx)
1499 ctx = ieee80211_new_chanctx(local, chandef, mode);
1500 if (IS_ERR(ctx)) {
1501 ret = PTR_ERR(ctx);
1502 goto out;
1503 }
1504
1505 sdata->vif.bss_conf.chandef = *chandef;
1506
1507 ret = ieee80211_assign_vif_chanctx(sdata, ctx);
1508 if (ret) {
1509 /* if assign fails refcount stays the same */
1510 if (ieee80211_chanctx_refcount(local, ctx) == 0)
1511 ieee80211_free_chanctx(local, ctx);
1512 goto out;
1513 }
1514
1515 ieee80211_recalc_smps_chanctx(local, ctx);
1516 ieee80211_recalc_radar_chanctx(local, ctx);
1517 out:
1518 mutex_unlock(&local->chanctx_mtx);
1519 return ret;
1520}
1521
1523int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata) 1522int ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata)
1524{ 1523{
1525 struct ieee80211_local *local = sdata->local; 1524 struct ieee80211_local *local = sdata->local;
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c
index 3db96648b45a..4a20fb8f1e23 100644
--- a/net/mac80211/debugfs_sta.c
+++ b/net/mac80211/debugfs_sta.c
@@ -77,7 +77,8 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf,
77 TEST(AUTH), TEST(ASSOC), TEST(PS_STA), 77 TEST(AUTH), TEST(ASSOC), TEST(PS_STA),
78 TEST(PS_DRIVER), TEST(AUTHORIZED), 78 TEST(PS_DRIVER), TEST(AUTHORIZED),
79 TEST(SHORT_PREAMBLE), 79 TEST(SHORT_PREAMBLE),
80 TEST(WME), TEST(WDS), TEST(CLEAR_PS_FILT), 80 sta->sta.wme ? "WME\n" : "",
81 TEST(WDS), TEST(CLEAR_PS_FILT),
81 TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL), 82 TEST(MFP), TEST(BLOCK_BA), TEST(PSPOLL),
82 TEST(UAPSD), TEST(SP), TEST(TDLS_PEER), 83 TEST(UAPSD), TEST(SP), TEST(TDLS_PEER),
83 TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT), 84 TEST(TDLS_PEER_AUTH), TEST(4ADDR_EVENT),
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 9713dc54ea4b..5f9654d31a8d 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1038,7 +1038,7 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
1038 } 1038 }
1039 1039
1040 if (sta && elems->wmm_info) 1040 if (sta && elems->wmm_info)
1041 set_sta_flag(sta, WLAN_STA_WME); 1041 sta->sta.wme = true;
1042 1042
1043 if (sta && elems->ht_operation && elems->ht_cap_elem && 1043 if (sta && elems->ht_operation && elems->ht_cap_elem &&
1044 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT && 1044 sdata->u.ibss.chandef.width != NL80211_CHAN_WIDTH_20_NOHT &&
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index ef7a089ac546..ffb20e5e6cf3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1869,7 +1869,6 @@ ieee80211_vif_reserve_chanctx(struct ieee80211_sub_if_data *sdata,
1869int __must_check 1869int __must_check
1870ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata); 1870ieee80211_vif_use_reserved_context(struct ieee80211_sub_if_data *sdata);
1871int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata); 1871int ieee80211_vif_unreserve_chanctx(struct ieee80211_sub_if_data *sdata);
1872int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local);
1873 1872
1874int __must_check 1873int __must_check
1875ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata, 1874ieee80211_vif_change_bandwidth(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index d808cff80153..6429d0e1d4a1 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -130,9 +130,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key)
130 if (!ret) { 130 if (!ret) {
131 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE; 131 key->flags |= KEY_FLAG_UPLOADED_TO_HARDWARE;
132 132
133 if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || 133 if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
134 (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
135 (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
136 sdata->crypto_tx_tailroom_needed_cnt--; 134 sdata->crypto_tx_tailroom_needed_cnt--;
137 135
138 WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) && 136 WARN_ON((key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE) &&
@@ -180,9 +178,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key)
180 sta = key->sta; 178 sta = key->sta;
181 sdata = key->sdata; 179 sdata = key->sdata;
182 180
183 if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || 181 if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
184 (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
185 (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
186 increment_tailroom_need_count(sdata); 182 increment_tailroom_need_count(sdata);
187 183
188 ret = drv_set_key(key->local, DISABLE_KEY, sdata, 184 ret = drv_set_key(key->local, DISABLE_KEY, sdata,
@@ -878,9 +874,7 @@ void ieee80211_remove_key(struct ieee80211_key_conf *keyconf)
878 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) { 874 if (key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE) {
879 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; 875 key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE;
880 876
881 if (!((key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC) || 877 if (!(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIC))
882 (key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV) ||
883 (key->conf.flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)))
884 increment_tailroom_need_count(key->sdata); 878 increment_tailroom_need_count(key->sdata);
885 } 879 }
886 880
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index cf032a8db9d7..a6699dceae7c 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -729,7 +729,7 @@ void mesh_plink_broken(struct sta_info *sta)
729 tbl = rcu_dereference(mesh_paths); 729 tbl = rcu_dereference(mesh_paths);
730 for_each_mesh_entry(tbl, node, i) { 730 for_each_mesh_entry(tbl, node, i) {
731 mpath = node->mpath; 731 mpath = node->mpath;
732 if (rcu_dereference(mpath->next_hop) == sta && 732 if (rcu_access_pointer(mpath->next_hop) == sta &&
733 mpath->flags & MESH_PATH_ACTIVE && 733 mpath->flags & MESH_PATH_ACTIVE &&
734 !(mpath->flags & MESH_PATH_FIXED)) { 734 !(mpath->flags & MESH_PATH_FIXED)) {
735 spin_lock_bh(&mpath->state_lock); 735 spin_lock_bh(&mpath->state_lock);
@@ -794,7 +794,7 @@ void mesh_path_flush_by_nexthop(struct sta_info *sta)
794 tbl = resize_dereference_mesh_paths(); 794 tbl = resize_dereference_mesh_paths();
795 for_each_mesh_entry(tbl, node, i) { 795 for_each_mesh_entry(tbl, node, i) {
796 mpath = node->mpath; 796 mpath = node->mpath;
797 if (rcu_dereference(mpath->next_hop) == sta) { 797 if (rcu_access_pointer(mpath->next_hop) == sta) {
798 spin_lock(&tbl->hashwlock[i]); 798 spin_lock(&tbl->hashwlock[i]);
799 __mesh_path_del(tbl, node); 799 __mesh_path_del(tbl, node);
800 spin_unlock(&tbl->hashwlock[i]); 800 spin_unlock(&tbl->hashwlock[i]);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index 63b874101b27..8f0887fc7128 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -431,14 +431,12 @@ __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr)
431 return NULL; 431 return NULL;
432 432
433 sta->plink_state = NL80211_PLINK_LISTEN; 433 sta->plink_state = NL80211_PLINK_LISTEN;
434 sta->sta.wme = true;
434 435
435 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); 436 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
436 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); 437 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
437 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED); 438 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
438 439
439 set_sta_flag(sta, WLAN_STA_WME);
440 sta->sta.wme = true;
441
442 return sta; 440 return sta;
443} 441}
444 442
@@ -1003,7 +1001,6 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
1003 enum ieee80211_self_protected_actioncode ftype; 1001 enum ieee80211_self_protected_actioncode ftype;
1004 u32 changed = 0; 1002 u32 changed = 0;
1005 u8 ie_len = elems->peering_len; 1003 u8 ie_len = elems->peering_len;
1006 __le16 _plid, _llid;
1007 u16 plid, llid = 0; 1004 u16 plid, llid = 0;
1008 1005
1009 if (!elems->peering) { 1006 if (!elems->peering) {
@@ -1038,13 +1035,10 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
1038 /* Note the lines below are correct, the llid in the frame is the plid 1035 /* Note the lines below are correct, the llid in the frame is the plid
1039 * from the point of view of this host. 1036 * from the point of view of this host.
1040 */ 1037 */
1041 memcpy(&_plid, PLINK_GET_LLID(elems->peering), sizeof(__le16)); 1038 plid = get_unaligned_le16(PLINK_GET_LLID(elems->peering));
1042 plid = le16_to_cpu(_plid);
1043 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM || 1039 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
1044 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8)) { 1040 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
1045 memcpy(&_llid, PLINK_GET_PLID(elems->peering), sizeof(__le16)); 1041 llid = get_unaligned_le16(PLINK_GET_PLID(elems->peering));
1046 llid = le16_to_cpu(_llid);
1047 }
1048 1042
1049 /* WARNING: Only for sta pointer, is dropped & re-acquired */ 1043 /* WARNING: Only for sta pointer, is dropped & re-acquired */
1050 rcu_read_lock(); 1044 rcu_read_lock();
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 31a8afaf7332..29fe91d6a094 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -149,6 +149,7 @@ static u32
149ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, 149ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
150 struct ieee80211_supported_band *sband, 150 struct ieee80211_supported_band *sband,
151 struct ieee80211_channel *channel, 151 struct ieee80211_channel *channel,
152 const struct ieee80211_ht_cap *ht_cap,
152 const struct ieee80211_ht_operation *ht_oper, 153 const struct ieee80211_ht_operation *ht_oper,
153 const struct ieee80211_vht_operation *vht_oper, 154 const struct ieee80211_vht_operation *vht_oper,
154 struct cfg80211_chan_def *chandef, bool tracking) 155 struct cfg80211_chan_def *chandef, bool tracking)
@@ -162,13 +163,19 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata,
162 chandef->center_freq1 = channel->center_freq; 163 chandef->center_freq1 = channel->center_freq;
163 chandef->center_freq2 = 0; 164 chandef->center_freq2 = 0;
164 165
165 if (!ht_oper || !sband->ht_cap.ht_supported) { 166 if (!ht_cap || !ht_oper || !sband->ht_cap.ht_supported) {
166 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT; 167 ret = IEEE80211_STA_DISABLE_HT | IEEE80211_STA_DISABLE_VHT;
167 goto out; 168 goto out;
168 } 169 }
169 170
170 chandef->width = NL80211_CHAN_WIDTH_20; 171 chandef->width = NL80211_CHAN_WIDTH_20;
171 172
173 if (!(ht_cap->cap_info &
174 cpu_to_le16(IEEE80211_HT_CAP_SUP_WIDTH_20_40))) {
175 ret = IEEE80211_STA_DISABLE_40MHZ | IEEE80211_STA_DISABLE_VHT;
176 goto out;
177 }
178
172 ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan, 179 ht_cfreq = ieee80211_channel_to_frequency(ht_oper->primary_chan,
173 channel->band); 180 channel->band);
174 /* check that channel matches the right operating channel */ 181 /* check that channel matches the right operating channel */
@@ -328,6 +335,7 @@ out:
328 335
329static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata, 336static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
330 struct sta_info *sta, 337 struct sta_info *sta,
338 const struct ieee80211_ht_cap *ht_cap,
331 const struct ieee80211_ht_operation *ht_oper, 339 const struct ieee80211_ht_operation *ht_oper,
332 const struct ieee80211_vht_operation *vht_oper, 340 const struct ieee80211_vht_operation *vht_oper,
333 const u8 *bssid, u32 *changed) 341 const u8 *bssid, u32 *changed)
@@ -367,8 +375,9 @@ static int ieee80211_config_bw(struct ieee80211_sub_if_data *sdata,
367 sband = local->hw.wiphy->bands[chan->band]; 375 sband = local->hw.wiphy->bands[chan->band];
368 376
369 /* calculate new channel (type) based on HT/VHT operation IEs */ 377 /* calculate new channel (type) based on HT/VHT operation IEs */
370 flags = ieee80211_determine_chantype(sdata, sband, chan, ht_oper, 378 flags = ieee80211_determine_chantype(sdata, sband, chan,
371 vht_oper, &chandef, true); 379 ht_cap, ht_oper, vht_oper,
380 &chandef, true);
372 381
373 /* 382 /*
374 * Downgrade the new channel if we associated with restricted 383 * Downgrade the new channel if we associated with restricted
@@ -2677,8 +2686,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2677 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED) 2686 if (ifmgd->flags & IEEE80211_STA_MFP_ENABLED)
2678 set_sta_flag(sta, WLAN_STA_MFP); 2687 set_sta_flag(sta, WLAN_STA_MFP);
2679 2688
2680 if (elems.wmm_param) 2689 sta->sta.wme = elems.wmm_param;
2681 set_sta_flag(sta, WLAN_STA_WME);
2682 2690
2683 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC); 2691 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
2684 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) 2692 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
@@ -3174,7 +3182,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
3174 mutex_lock(&local->sta_mtx); 3182 mutex_lock(&local->sta_mtx);
3175 sta = sta_info_get(sdata, bssid); 3183 sta = sta_info_get(sdata, bssid);
3176 3184
3177 if (ieee80211_config_bw(sdata, sta, elems.ht_operation, 3185 if (ieee80211_config_bw(sdata, sta,
3186 elems.ht_cap_elem, elems.ht_operation,
3178 elems.vht_operation, bssid, &changed)) { 3187 elems.vht_operation, bssid, &changed)) {
3179 mutex_unlock(&local->sta_mtx); 3188 mutex_unlock(&local->sta_mtx);
3180 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, 3189 ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH,
@@ -3808,6 +3817,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3808{ 3817{
3809 struct ieee80211_local *local = sdata->local; 3818 struct ieee80211_local *local = sdata->local;
3810 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 3819 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
3820 const struct ieee80211_ht_cap *ht_cap = NULL;
3811 const struct ieee80211_ht_operation *ht_oper = NULL; 3821 const struct ieee80211_ht_operation *ht_oper = NULL;
3812 const struct ieee80211_vht_operation *vht_oper = NULL; 3822 const struct ieee80211_vht_operation *vht_oper = NULL;
3813 struct ieee80211_supported_band *sband; 3823 struct ieee80211_supported_band *sband;
@@ -3824,14 +3834,17 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3824 3834
3825 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) && 3835 if (!(ifmgd->flags & IEEE80211_STA_DISABLE_HT) &&
3826 sband->ht_cap.ht_supported) { 3836 sband->ht_cap.ht_supported) {
3827 const u8 *ht_oper_ie, *ht_cap; 3837 const u8 *ht_oper_ie, *ht_cap_ie;
3828 3838
3829 ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION); 3839 ht_oper_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_OPERATION);
3830 if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper)) 3840 if (ht_oper_ie && ht_oper_ie[1] >= sizeof(*ht_oper))
3831 ht_oper = (void *)(ht_oper_ie + 2); 3841 ht_oper = (void *)(ht_oper_ie + 2);
3832 3842
3833 ht_cap = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY); 3843 ht_cap_ie = ieee80211_bss_get_ie(cbss, WLAN_EID_HT_CAPABILITY);
3834 if (!ht_cap || ht_cap[1] < sizeof(struct ieee80211_ht_cap)) { 3844 if (ht_cap_ie && ht_cap_ie[1] >= sizeof(*ht_cap))
3845 ht_cap = (void *)(ht_cap_ie + 2);
3846
3847 if (!ht_cap) {
3835 ifmgd->flags |= IEEE80211_STA_DISABLE_HT; 3848 ifmgd->flags |= IEEE80211_STA_DISABLE_HT;
3836 ht_oper = NULL; 3849 ht_oper = NULL;
3837 } 3850 }
@@ -3862,7 +3875,7 @@ static int ieee80211_prep_channel(struct ieee80211_sub_if_data *sdata,
3862 3875
3863 ifmgd->flags |= ieee80211_determine_chantype(sdata, sband, 3876 ifmgd->flags |= ieee80211_determine_chantype(sdata, sband,
3864 cbss->channel, 3877 cbss->channel,
3865 ht_oper, vht_oper, 3878 ht_cap, ht_oper, vht_oper,
3866 &chandef, false); 3879 &chandef, false);
3867 3880
3868 sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss), 3881 sdata->needed_rx_chains = min(ieee80211_ht_vht_rx_chains(sdata, cbss),
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index bd2c9b22c945..a8d862f9183c 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2725,7 +2725,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx)
2725 sig = status->signal; 2725 sig = status->signal;
2726 2726
2727 if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, 2727 if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig,
2728 rx->skb->data, rx->skb->len, 0, GFP_ATOMIC)) { 2728 rx->skb->data, rx->skb->len, 0)) {
2729 if (rx->sta) 2729 if (rx->sta)
2730 rx->sta->rx_packets++; 2730 rx->sta->rx_packets++;
2731 dev_kfree_skb(rx->skb); 2731 dev_kfree_skb(rx->skb);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index a0a938145dcc..a9bb6eb8c3e0 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -1094,7 +1094,7 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata)
1094 if (rcu_access_pointer(local->sched_scan_sdata)) { 1094 if (rcu_access_pointer(local->sched_scan_sdata)) {
1095 ret = drv_sched_scan_stop(local, sdata); 1095 ret = drv_sched_scan_stop(local, sdata);
1096 if (!ret) 1096 if (!ret)
1097 rcu_assign_pointer(local->sched_scan_sdata, NULL); 1097 RCU_INIT_POINTER(local->sched_scan_sdata, NULL);
1098 } 1098 }
1099out: 1099out:
1100 mutex_unlock(&local->mtx); 1100 mutex_unlock(&local->mtx);
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index c6ee2139fbc5..e1f957d5935e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -1179,7 +1179,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,
1179 struct sk_buff *skb; 1179 struct sk_buff *skb;
1180 int size = sizeof(*nullfunc); 1180 int size = sizeof(*nullfunc);
1181 __le16 fc; 1181 __le16 fc;
1182 bool qos = test_sta_flag(sta, WLAN_STA_WME); 1182 bool qos = sta->sta.wme;
1183 struct ieee80211_tx_info *info; 1183 struct ieee80211_tx_info *info;
1184 struct ieee80211_chanctx_conf *chanctx_conf; 1184 struct ieee80211_chanctx_conf *chanctx_conf;
1185 1185
@@ -1834,7 +1834,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
1834 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED); 1834 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
1835 if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE)) 1835 if (test_sta_flag(sta, WLAN_STA_SHORT_PREAMBLE))
1836 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE); 1836 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_SHORT_PREAMBLE);
1837 if (test_sta_flag(sta, WLAN_STA_WME)) 1837 if (sta->sta.wme)
1838 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME); 1838 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_WME);
1839 if (test_sta_flag(sta, WLAN_STA_MFP)) 1839 if (test_sta_flag(sta, WLAN_STA_MFP))
1840 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP); 1840 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_MFP);
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index d411bcc8ef08..89c40d5c0633 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -31,7 +31,6 @@
31 * when virtual port control is not in use. 31 * when virtual port control is not in use.
32 * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble 32 * @WLAN_STA_SHORT_PREAMBLE: Station is capable of receiving short-preamble
33 * frames. 33 * frames.
34 * @WLAN_STA_WME: Station is a QoS-STA.
35 * @WLAN_STA_WDS: Station is one of our WDS peers. 34 * @WLAN_STA_WDS: Station is one of our WDS peers.
36 * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the 35 * @WLAN_STA_CLEAR_PS_FILT: Clear PS filter in hardware (using the
37 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next 36 * IEEE80211_TX_CTL_CLEAR_PS_FILT control flag) when the next
@@ -69,7 +68,6 @@ enum ieee80211_sta_info_flags {
69 WLAN_STA_PS_STA, 68 WLAN_STA_PS_STA,
70 WLAN_STA_AUTHORIZED, 69 WLAN_STA_AUTHORIZED,
71 WLAN_STA_SHORT_PREAMBLE, 70 WLAN_STA_SHORT_PREAMBLE,
72 WLAN_STA_WME,
73 WLAN_STA_WDS, 71 WLAN_STA_WDS,
74 WLAN_STA_CLEAR_PS_FILT, 72 WLAN_STA_CLEAR_PS_FILT,
75 WLAN_STA_MFP, 73 WLAN_STA_MFP,
diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c
index 1b21050be174..f2cb3b6c1871 100644
--- a/net/mac80211/tdls.c
+++ b/net/mac80211/tdls.c
@@ -316,8 +316,7 @@ ieee80211_tdls_add_setup_cfm_ies(struct ieee80211_sub_if_data *sdata,
316 } 316 }
317 317
318 /* add the QoS param IE if both the peer and we support it */ 318 /* add the QoS param IE if both the peer and we support it */
319 if (local->hw.queues >= IEEE80211_NUM_ACS && 319 if (local->hw.queues >= IEEE80211_NUM_ACS && sta->sta.wme)
320 test_sta_flag(sta, WLAN_STA_WME))
321 ieee80211_tdls_add_wmm_param_ie(sdata, skb); 320 ieee80211_tdls_add_wmm_param_ie(sdata, skb);
322 321
323 /* add any custom IEs that go before HT operation */ 322 /* add any custom IEs that go before HT operation */
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 464106c023d8..925c39f4099e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1478,7 +1478,10 @@ static int ieee80211_skb_resize(struct ieee80211_sub_if_data *sdata,
1478 tail_need = max_t(int, tail_need, 0); 1478 tail_need = max_t(int, tail_need, 0);
1479 } 1479 }
1480 1480
1481 if (skb_cloned(skb)) 1481 if (skb_cloned(skb) &&
1482 (!(local->hw.flags & IEEE80211_HW_SUPPORTS_CLONED_SKBS) ||
1483 !skb_clone_writable(skb, ETH_HLEN) ||
1484 sdata->crypto_tx_tailroom_needed_cnt))
1482 I802_DEBUG_INC(local->tx_expand_skb_head_cloned); 1485 I802_DEBUG_INC(local->tx_expand_skb_head_cloned);
1483 else if (head_need || tail_need) 1486 else if (head_need || tail_need)
1484 I802_DEBUG_INC(local->tx_expand_skb_head); 1487 I802_DEBUG_INC(local->tx_expand_skb_head);
@@ -1844,7 +1847,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1844 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN); 1847 memcpy(hdr.addr4, skb->data + ETH_ALEN, ETH_ALEN);
1845 hdrlen = 30; 1848 hdrlen = 30;
1846 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); 1849 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
1847 wme_sta = test_sta_flag(sta, WLAN_STA_WME); 1850 wme_sta = sta->sta.wme;
1848 } 1851 }
1849 ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data, 1852 ap_sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
1850 u.ap); 1853 u.ap);
@@ -1957,7 +1960,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
1957 if (sta) { 1960 if (sta) {
1958 authorized = test_sta_flag(sta, 1961 authorized = test_sta_flag(sta,
1959 WLAN_STA_AUTHORIZED); 1962 WLAN_STA_AUTHORIZED);
1960 wme_sta = test_sta_flag(sta, WLAN_STA_WME); 1963 wme_sta = sta->sta.wme;
1961 tdls_peer = test_sta_flag(sta, 1964 tdls_peer = test_sta_flag(sta,
1962 WLAN_STA_TDLS_PEER); 1965 WLAN_STA_TDLS_PEER);
1963 tdls_auth = test_sta_flag(sta, 1966 tdls_auth = test_sta_flag(sta,
@@ -2035,7 +2038,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
2035 sta = sta_info_get(sdata, hdr.addr1); 2038 sta = sta_info_get(sdata, hdr.addr1);
2036 if (sta) { 2039 if (sta) {
2037 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED); 2040 authorized = test_sta_flag(sta, WLAN_STA_AUTHORIZED);
2038 wme_sta = test_sta_flag(sta, WLAN_STA_WME); 2041 wme_sta = sta->sta.wme;
2039 } 2042 }
2040 } 2043 }
2041 2044
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index d51422c778de..6459946f0b74 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -118,7 +118,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
118 case NL80211_IFTYPE_AP_VLAN: 118 case NL80211_IFTYPE_AP_VLAN:
119 sta = rcu_dereference(sdata->u.vlan.sta); 119 sta = rcu_dereference(sdata->u.vlan.sta);
120 if (sta) { 120 if (sta) {
121 qos = test_sta_flag(sta, WLAN_STA_WME); 121 qos = sta->sta.wme;
122 break; 122 break;
123 } 123 }
124 case NL80211_IFTYPE_AP: 124 case NL80211_IFTYPE_AP:
@@ -145,7 +145,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
145 if (!sta && ra && !is_multicast_ether_addr(ra)) { 145 if (!sta && ra && !is_multicast_ether_addr(ra)) {
146 sta = sta_info_get(sdata, ra); 146 sta = sta_info_get(sdata, ra);
147 if (sta) 147 if (sta)
148 qos = test_sta_flag(sta, WLAN_STA_WME); 148 qos = sta->sta.wme;
149 } 149 }
150 rcu_read_unlock(); 150 rcu_read_unlock();
151 151
diff --git a/net/rfkill/rfkill-gpio.c b/net/rfkill/rfkill-gpio.c
index 14c98e48f261..02a86a27fd84 100644
--- a/net/rfkill/rfkill-gpio.c
+++ b/net/rfkill/rfkill-gpio.c
@@ -158,6 +158,7 @@ static const struct acpi_device_id rfkill_acpi_match[] = {
158 { "BCM2E1A", RFKILL_TYPE_BLUETOOTH }, 158 { "BCM2E1A", RFKILL_TYPE_BLUETOOTH },
159 { "BCM2E39", RFKILL_TYPE_BLUETOOTH }, 159 { "BCM2E39", RFKILL_TYPE_BLUETOOTH },
160 { "BCM2E3D", RFKILL_TYPE_BLUETOOTH }, 160 { "BCM2E3D", RFKILL_TYPE_BLUETOOTH },
161 { "BCM2E64", RFKILL_TYPE_BLUETOOTH },
161 { "BCM4752", RFKILL_TYPE_GPS }, 162 { "BCM4752", RFKILL_TYPE_GPS },
162 { "LNV4752", RFKILL_TYPE_GPS }, 163 { "LNV4752", RFKILL_TYPE_GPS },
163 { }, 164 { },
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 682babde4aa5..c6620aa679e0 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -492,12 +492,6 @@ int wiphy_register(struct wiphy *wiphy)
492 int i; 492 int i;
493 u16 ifmodes = wiphy->interface_modes; 493 u16 ifmodes = wiphy->interface_modes;
494 494
495 /*
496 * There are major locking problems in nl80211/mac80211 for CSA,
497 * disable for all drivers until this has been reworked.
498 */
499 wiphy->flags &= ~WIPHY_FLAG_HAS_CHANNEL_SWITCH;
500
501#ifdef CONFIG_PM 495#ifdef CONFIG_PM
502 if (WARN_ON(wiphy->wowlan && 496 if (WARN_ON(wiphy->wowlan &&
503 (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) && 497 (wiphy->wowlan->flags & WIPHY_WOWLAN_GTK_REKEY_FAILURE) &&
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 266766b8d80b..369fc334fdad 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -605,7 +605,7 @@ int cfg80211_mlme_mgmt_tx(struct cfg80211_registered_device *rdev,
605} 605}
606 606
607bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm, 607bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
608 const u8 *buf, size_t len, u32 flags, gfp_t gfp) 608 const u8 *buf, size_t len, u32 flags)
609{ 609{
610 struct wiphy *wiphy = wdev->wiphy; 610 struct wiphy *wiphy = wdev->wiphy;
611 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy); 611 struct cfg80211_registered_device *rdev = wiphy_to_rdev(wiphy);
@@ -648,7 +648,7 @@ bool cfg80211_rx_mgmt(struct wireless_dev *wdev, int freq, int sig_mbm,
648 /* Indicate the received Action frame to user space */ 648 /* Indicate the received Action frame to user space */
649 if (nl80211_send_mgmt(rdev, wdev, reg->nlportid, 649 if (nl80211_send_mgmt(rdev, wdev, reg->nlportid,
650 freq, sig_mbm, 650 freq, sig_mbm,
651 buf, len, flags, gfp)) 651 buf, len, flags, GFP_ATOMIC))
652 continue; 652 continue;
653 653
654 result = true; 654 result = true;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index df7b1332a1ec..3011401f52c0 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -6033,7 +6033,6 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
6033 const struct cfg80211_bss_ies *ies; 6033 const struct cfg80211_bss_ies *ies;
6034 void *hdr; 6034 void *hdr;
6035 struct nlattr *bss; 6035 struct nlattr *bss;
6036 bool tsf = false;
6037 6036
6038 ASSERT_WDEV_LOCK(wdev); 6037 ASSERT_WDEV_LOCK(wdev);
6039 6038
@@ -6060,18 +6059,27 @@ static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
6060 goto nla_put_failure; 6059 goto nla_put_failure;
6061 6060
6062 rcu_read_lock(); 6061 rcu_read_lock();
6062 /* indicate whether we have probe response data or not */
6063 if (rcu_access_pointer(res->proberesp_ies) &&
6064 nla_put_flag(msg, NL80211_BSS_PRESP_DATA))
6065 goto fail_unlock_rcu;
6066
6067 /* this pointer prefers to be pointed to probe response data
6068 * but is always valid
6069 */
6063 ies = rcu_dereference(res->ies); 6070 ies = rcu_dereference(res->ies);
6064 if (ies) { 6071 if (ies) {
6065 if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf)) 6072 if (nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf))
6066 goto fail_unlock_rcu; 6073 goto fail_unlock_rcu;
6067 tsf = true;
6068 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS, 6074 if (ies->len && nla_put(msg, NL80211_BSS_INFORMATION_ELEMENTS,
6069 ies->len, ies->data)) 6075 ies->len, ies->data))
6070 goto fail_unlock_rcu; 6076 goto fail_unlock_rcu;
6071 } 6077 }
6078
6079 /* and this pointer is always (unless driver didn't know) beacon data */
6072 ies = rcu_dereference(res->beacon_ies); 6080 ies = rcu_dereference(res->beacon_ies);
6073 if (ies) { 6081 if (ies && ies->from_beacon) {
6074 if (!tsf && nla_put_u64(msg, NL80211_BSS_TSF, ies->tsf)) 6082 if (nla_put_u64(msg, NL80211_BSS_BEACON_TSF, ies->tsf))
6075 goto fail_unlock_rcu; 6083 goto fail_unlock_rcu;
6076 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES, 6084 if (ies->len && nla_put(msg, NL80211_BSS_BEACON_IES,
6077 ies->len, ies->data)) 6085 ies->len, ies->data))
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 0798c62e6085..620a4b40d466 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -884,6 +884,7 @@ struct cfg80211_bss*
884cfg80211_inform_bss_width(struct wiphy *wiphy, 884cfg80211_inform_bss_width(struct wiphy *wiphy,
885 struct ieee80211_channel *rx_channel, 885 struct ieee80211_channel *rx_channel,
886 enum nl80211_bss_scan_width scan_width, 886 enum nl80211_bss_scan_width scan_width,
887 enum cfg80211_bss_frame_type ftype,
887 const u8 *bssid, u64 tsf, u16 capability, 888 const u8 *bssid, u64 tsf, u16 capability,
888 u16 beacon_interval, const u8 *ie, size_t ielen, 889 u16 beacon_interval, const u8 *ie, size_t ielen,
889 s32 signal, gfp_t gfp) 890 s32 signal, gfp_t gfp)
@@ -911,21 +912,32 @@ cfg80211_inform_bss_width(struct wiphy *wiphy,
911 tmp.pub.beacon_interval = beacon_interval; 912 tmp.pub.beacon_interval = beacon_interval;
912 tmp.pub.capability = capability; 913 tmp.pub.capability = capability;
913 /* 914 /*
914 * Since we do not know here whether the IEs are from a Beacon or Probe 915 * If we do not know here whether the IEs are from a Beacon or Probe
915 * Response frame, we need to pick one of the options and only use it 916 * Response frame, we need to pick one of the options and only use it
916 * with the driver that does not provide the full Beacon/Probe Response 917 * with the driver that does not provide the full Beacon/Probe Response
917 * frame. Use Beacon frame pointer to avoid indicating that this should 918 * frame. Use Beacon frame pointer to avoid indicating that this should
918 * override the IEs pointer should we have received an earlier 919 * override the IEs pointer should we have received an earlier
919 * indication of Probe Response data. 920 * indication of Probe Response data.
920 */ 921 */
921 ies = kmalloc(sizeof(*ies) + ielen, gfp); 922 ies = kzalloc(sizeof(*ies) + ielen, gfp);
922 if (!ies) 923 if (!ies)
923 return NULL; 924 return NULL;
924 ies->len = ielen; 925 ies->len = ielen;
925 ies->tsf = tsf; 926 ies->tsf = tsf;
927 ies->from_beacon = false;
926 memcpy(ies->data, ie, ielen); 928 memcpy(ies->data, ie, ielen);
927 929
928 rcu_assign_pointer(tmp.pub.beacon_ies, ies); 930 switch (ftype) {
931 case CFG80211_BSS_FTYPE_BEACON:
932 ies->from_beacon = true;
933 /* fall through to assign */
934 case CFG80211_BSS_FTYPE_UNKNOWN:
935 rcu_assign_pointer(tmp.pub.beacon_ies, ies);
936 break;
937 case CFG80211_BSS_FTYPE_PRESP:
938 rcu_assign_pointer(tmp.pub.proberesp_ies, ies);
939 break;
940 }
929 rcu_assign_pointer(tmp.pub.ies, ies); 941 rcu_assign_pointer(tmp.pub.ies, ies);
930 942
931 signal_valid = abs(rx_channel->center_freq - channel->center_freq) <= 943 signal_valid = abs(rx_channel->center_freq - channel->center_freq) <=
@@ -982,11 +994,12 @@ cfg80211_inform_bss_width_frame(struct wiphy *wiphy,
982 if (!channel) 994 if (!channel)
983 return NULL; 995 return NULL;
984 996
985 ies = kmalloc(sizeof(*ies) + ielen, gfp); 997 ies = kzalloc(sizeof(*ies) + ielen, gfp);
986 if (!ies) 998 if (!ies)
987 return NULL; 999 return NULL;
988 ies->len = ielen; 1000 ies->len = ielen;
989 ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); 1001 ies->tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
1002 ies->from_beacon = ieee80211_is_beacon(mgmt->frame_control);
990 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen); 1003 memcpy(ies->data, mgmt->u.probe_resp.variable, ielen);
991 1004
992 if (ieee80211_is_probe_resp(mgmt->frame_control)) 1005 if (ieee80211_is_probe_resp(mgmt->frame_control))