diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-06-21 15:42:30 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-21 15:42:30 -0400 |
commit | 7d2a47aab2a511c87a96238977e04e6378969d45 (patch) | |
tree | e3765af6d4b292d8f3c013a5962324eab683a931 /net/mac80211 | |
parent | fedaf4ffc224a194e2d13a3ec2abe5df0bc94258 (diff) | |
parent | b887664d882ee4f6a67e0bf05e5f141d32fcc067 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next into for-davem
Conflicts:
net/wireless/nl80211.c
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 20 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 38 | ||||
-rw-r--r-- | net/mac80211/mesh.h | 5 | ||||
-rw-r--r-- | net/mac80211/mesh_plink.c | 7 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 98 | ||||
-rw-r--r-- | net/mac80211/rx.c | 26 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 4 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 3 | ||||
-rw-r--r-- | net/mac80211/tx.c | 6 | ||||
-rw-r--r-- | net/mac80211/util.c | 5 |
12 files changed, 108 insertions, 110 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index a1c6e1ceede8..082f270b5912 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1765,6 +1765,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, | |||
1765 | /* mcast rate setting in Mesh Node */ | 1765 | /* mcast rate setting in Mesh Node */ |
1766 | memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate, | 1766 | memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate, |
1767 | sizeof(setup->mcast_rate)); | 1767 | sizeof(setup->mcast_rate)); |
1768 | sdata->vif.bss_conf.basic_rates = setup->basic_rates; | ||
1768 | 1769 | ||
1769 | sdata->vif.bss_conf.beacon_int = setup->beacon_interval; | 1770 | sdata->vif.bss_conf.beacon_int = setup->beacon_interval; |
1770 | sdata->vif.bss_conf.dtim_period = setup->dtim_period; | 1771 | sdata->vif.bss_conf.dtim_period = setup->dtim_period; |
@@ -1877,6 +1878,8 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, | |||
1877 | if (_chg_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask)) | 1878 | if (_chg_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask)) |
1878 | conf->dot11MeshAwakeWindowDuration = | 1879 | conf->dot11MeshAwakeWindowDuration = |
1879 | nconf->dot11MeshAwakeWindowDuration; | 1880 | nconf->dot11MeshAwakeWindowDuration; |
1881 | if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask)) | ||
1882 | conf->plink_timeout = nconf->plink_timeout; | ||
1880 | ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); | 1883 | ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); |
1881 | return 0; | 1884 | return 0; |
1882 | } | 1885 | } |
@@ -2844,6 +2847,12 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
2844 | return -EOPNOTSUPP; | 2847 | return -EOPNOTSUPP; |
2845 | } | 2848 | } |
2846 | 2849 | ||
2850 | /* configurations requiring offchan cannot work if no channel has been | ||
2851 | * specified | ||
2852 | */ | ||
2853 | if (need_offchan && !chan) | ||
2854 | return -EINVAL; | ||
2855 | |||
2847 | mutex_lock(&local->mtx); | 2856 | mutex_lock(&local->mtx); |
2848 | 2857 | ||
2849 | /* Check if the operating channel is the requested channel */ | 2858 | /* Check if the operating channel is the requested channel */ |
@@ -2853,10 +2862,15 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
2853 | rcu_read_lock(); | 2862 | rcu_read_lock(); |
2854 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | 2863 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
2855 | 2864 | ||
2856 | if (chanctx_conf) | 2865 | if (chanctx_conf) { |
2857 | need_offchan = chan != chanctx_conf->def.chan; | 2866 | need_offchan = chan && (chan != chanctx_conf->def.chan); |
2858 | else | 2867 | } else if (!chan) { |
2868 | ret = -EINVAL; | ||
2869 | rcu_read_unlock(); | ||
2870 | goto out_unlock; | ||
2871 | } else { | ||
2859 | need_offchan = true; | 2872 | need_offchan = true; |
2873 | } | ||
2860 | rcu_read_unlock(); | 2874 | rcu_read_unlock(); |
2861 | } | 2875 | } |
2862 | 2876 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 923e1772e8f3..f97cd9d9105f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -366,7 +366,7 @@ struct ieee80211_mgd_assoc_data { | |||
366 | u8 ssid_len; | 366 | u8 ssid_len; |
367 | u8 supp_rates_len; | 367 | u8 supp_rates_len; |
368 | bool wmm, uapsd; | 368 | bool wmm, uapsd; |
369 | bool have_beacon, need_beacon; | 369 | bool need_beacon; |
370 | bool synced; | 370 | bool synced; |
371 | bool timeout_started; | 371 | bool timeout_started; |
372 | 372 | ||
@@ -404,6 +404,7 @@ struct ieee80211_if_managed { | |||
404 | 404 | ||
405 | bool powersave; /* powersave requested for this iface */ | 405 | bool powersave; /* powersave requested for this iface */ |
406 | bool broken_ap; /* AP is broken -- turn off powersave */ | 406 | bool broken_ap; /* AP is broken -- turn off powersave */ |
407 | bool have_beacon; | ||
407 | u8 dtim_period; | 408 | u8 dtim_period; |
408 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ | 409 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ |
409 | driver_smps_mode; /* smps mode request */ | 410 | driver_smps_mode; /* smps mode request */ |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 1998f1475267..626c83c042d7 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -686,8 +686,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
686 | return -EINVAL; | 686 | return -EINVAL; |
687 | 687 | ||
688 | #ifdef CONFIG_PM | 688 | #ifdef CONFIG_PM |
689 | if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) && | 689 | if (hw->wiphy->wowlan && (!local->ops->suspend || !local->ops->resume)) |
690 | (!local->ops->suspend || !local->ops->resume)) | ||
691 | return -EINVAL; | 690 | return -EINVAL; |
692 | #endif | 691 | #endif |
693 | 692 | ||
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index b3d1fdd46368..6c33af482df4 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -274,8 +274,7 @@ int mesh_add_meshconf_ie(struct ieee80211_sub_if_data *sdata, | |||
274 | *pos++ = ifmsh->mesh_auth_id; | 274 | *pos++ = ifmsh->mesh_auth_id; |
275 | /* Mesh Formation Info - number of neighbors */ | 275 | /* Mesh Formation Info - number of neighbors */ |
276 | neighbors = atomic_read(&ifmsh->estab_plinks); | 276 | neighbors = atomic_read(&ifmsh->estab_plinks); |
277 | /* Number of neighbor mesh STAs or 15 whichever is smaller */ | 277 | neighbors = min_t(int, neighbors, IEEE80211_MAX_MESH_PEERINGS); |
278 | neighbors = (neighbors > 15) ? 15 : neighbors; | ||
279 | *pos++ = neighbors << 1; | 278 | *pos++ = neighbors << 1; |
280 | /* Mesh capability */ | 279 | /* Mesh capability */ |
281 | *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING; | 280 | *pos = IEEE80211_MESHCONF_CAPAB_FORWARDING; |
@@ -576,13 +575,11 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata) | |||
576 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 575 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
577 | u32 changed; | 576 | u32 changed; |
578 | 577 | ||
579 | ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); | 578 | ieee80211_sta_expire(sdata, ifmsh->mshcfg.plink_timeout * HZ); |
580 | mesh_path_expire(sdata); | 579 | mesh_path_expire(sdata); |
581 | 580 | ||
582 | changed = mesh_accept_plinks_update(sdata); | 581 | changed = mesh_accept_plinks_update(sdata); |
583 | sdata_lock(sdata); | ||
584 | ieee80211_mbss_info_change_notify(sdata, changed); | 582 | ieee80211_mbss_info_change_notify(sdata, changed); |
585 | sdata_unlock(sdata); | ||
586 | 583 | ||
587 | mod_timer(&ifmsh->housekeeping_timer, | 584 | mod_timer(&ifmsh->housekeeping_timer, |
588 | round_jiffies(jiffies + | 585 | round_jiffies(jiffies + |
@@ -741,9 +738,6 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
741 | BSS_CHANGED_HT | | 738 | BSS_CHANGED_HT | |
742 | BSS_CHANGED_BASIC_RATES | | 739 | BSS_CHANGED_BASIC_RATES | |
743 | BSS_CHANGED_BEACON_INT; | 740 | BSS_CHANGED_BEACON_INT; |
744 | enum ieee80211_band band = ieee80211_get_sdata_band(sdata); | ||
745 | struct ieee80211_supported_band *sband = | ||
746 | sdata->local->hw.wiphy->bands[band]; | ||
747 | 741 | ||
748 | local->fif_other_bss++; | 742 | local->fif_other_bss++; |
749 | /* mesh ifaces must set allmulti to forward mcast traffic */ | 743 | /* mesh ifaces must set allmulti to forward mcast traffic */ |
@@ -761,7 +755,6 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata) | |||
761 | sdata->vif.bss_conf.ht_operation_mode = | 755 | sdata->vif.bss_conf.ht_operation_mode = |
762 | ifmsh->mshcfg.ht_opmode; | 756 | ifmsh->mshcfg.ht_opmode; |
763 | sdata->vif.bss_conf.enable_beacon = true; | 757 | sdata->vif.bss_conf.enable_beacon = true; |
764 | sdata->vif.bss_conf.basic_rates = ieee80211_mandatory_rates(sband); | ||
765 | 758 | ||
766 | changed |= ieee80211_mps_local_status_update(sdata); | 759 | changed |= ieee80211_mps_local_status_update(sdata); |
767 | 760 | ||
@@ -789,12 +782,10 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | |||
789 | sdata->vif.bss_conf.enable_beacon = false; | 782 | sdata->vif.bss_conf.enable_beacon = false; |
790 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); | 783 | clear_bit(SDATA_STATE_OFFCHANNEL_BEACON_STOPPED, &sdata->state); |
791 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 784 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
792 | sdata_lock(sdata); | ||
793 | bcn = rcu_dereference_protected(ifmsh->beacon, | 785 | bcn = rcu_dereference_protected(ifmsh->beacon, |
794 | lockdep_is_held(&sdata->wdev.mtx)); | 786 | lockdep_is_held(&sdata->wdev.mtx)); |
795 | rcu_assign_pointer(ifmsh->beacon, NULL); | 787 | rcu_assign_pointer(ifmsh->beacon, NULL); |
796 | kfree_rcu(bcn, rcu_head); | 788 | kfree_rcu(bcn, rcu_head); |
797 | sdata_unlock(sdata); | ||
798 | 789 | ||
799 | /* flush STAs and mpaths on this iface */ | 790 | /* flush STAs and mpaths on this iface */ |
800 | sta_info_flush(sdata); | 791 | sta_info_flush(sdata); |
@@ -807,14 +798,6 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | |||
807 | del_timer_sync(&sdata->u.mesh.housekeeping_timer); | 798 | del_timer_sync(&sdata->u.mesh.housekeeping_timer); |
808 | del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); | 799 | del_timer_sync(&sdata->u.mesh.mesh_path_root_timer); |
809 | del_timer_sync(&sdata->u.mesh.mesh_path_timer); | 800 | del_timer_sync(&sdata->u.mesh.mesh_path_timer); |
810 | /* | ||
811 | * If the timer fired while we waited for it, it will have | ||
812 | * requeued the work. Now the work will be running again | ||
813 | * but will not rearm the timer again because it checks | ||
814 | * whether the interface is running, which, at this point, | ||
815 | * it no longer is. | ||
816 | */ | ||
817 | cancel_work_sync(&sdata->work); | ||
818 | 801 | ||
819 | local->fif_other_bss--; | 802 | local->fif_other_bss--; |
820 | atomic_dec(&local->iff_allmultis); | 803 | atomic_dec(&local->iff_allmultis); |
@@ -955,6 +938,12 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
955 | struct ieee80211_mgmt *mgmt; | 938 | struct ieee80211_mgmt *mgmt; |
956 | u16 stype; | 939 | u16 stype; |
957 | 940 | ||
941 | sdata_lock(sdata); | ||
942 | |||
943 | /* mesh already went down */ | ||
944 | if (!sdata->wdev.mesh_id_len) | ||
945 | goto out; | ||
946 | |||
958 | rx_status = IEEE80211_SKB_RXCB(skb); | 947 | rx_status = IEEE80211_SKB_RXCB(skb); |
959 | mgmt = (struct ieee80211_mgmt *) skb->data; | 948 | mgmt = (struct ieee80211_mgmt *) skb->data; |
960 | stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; | 949 | stype = le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE; |
@@ -972,12 +961,20 @@ void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
972 | ieee80211_mesh_rx_mgmt_action(sdata, mgmt, skb->len, rx_status); | 961 | ieee80211_mesh_rx_mgmt_action(sdata, mgmt, skb->len, rx_status); |
973 | break; | 962 | break; |
974 | } | 963 | } |
964 | out: | ||
965 | sdata_unlock(sdata); | ||
975 | } | 966 | } |
976 | 967 | ||
977 | void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) | 968 | void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) |
978 | { | 969 | { |
979 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 970 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
980 | 971 | ||
972 | sdata_lock(sdata); | ||
973 | |||
974 | /* mesh already went down */ | ||
975 | if (!sdata->wdev.mesh_id_len) | ||
976 | goto out; | ||
977 | |||
981 | if (ifmsh->preq_queue_len && | 978 | if (ifmsh->preq_queue_len && |
982 | time_after(jiffies, | 979 | time_after(jiffies, |
983 | ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) | 980 | ifmsh->last_preq + msecs_to_jiffies(ifmsh->mshcfg.dot11MeshHWMPpreqMinInterval))) |
@@ -997,6 +994,9 @@ void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata) | |||
997 | 994 | ||
998 | if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags)) | 995 | if (test_and_clear_bit(MESH_WORK_DRIFT_ADJUST, &ifmsh->wrkq_flags)) |
999 | mesh_sync_adjust_tbtt(sdata); | 996 | mesh_sync_adjust_tbtt(sdata); |
997 | |||
998 | out: | ||
999 | sdata_unlock(sdata); | ||
1000 | } | 1000 | } |
1001 | 1001 | ||
1002 | void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) | 1002 | void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local) |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index da158774eebb..01a28bca6e9b 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -188,7 +188,6 @@ struct mesh_rmc { | |||
188 | u32 idx_mask; | 188 | u32 idx_mask; |
189 | }; | 189 | }; |
190 | 190 | ||
191 | #define IEEE80211_MESH_PEER_INACTIVITY_LIMIT (1800 * HZ) | ||
192 | #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) | 191 | #define IEEE80211_MESH_HOUSEKEEPING_INTERVAL (60 * HZ) |
193 | 192 | ||
194 | #define MESH_PATH_EXPIRE (600 * HZ) | 193 | #define MESH_PATH_EXPIRE (600 * HZ) |
@@ -324,14 +323,14 @@ static inline | |||
324 | u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) | 323 | u32 mesh_plink_inc_estab_count(struct ieee80211_sub_if_data *sdata) |
325 | { | 324 | { |
326 | atomic_inc(&sdata->u.mesh.estab_plinks); | 325 | atomic_inc(&sdata->u.mesh.estab_plinks); |
327 | return mesh_accept_plinks_update(sdata); | 326 | return mesh_accept_plinks_update(sdata) | BSS_CHANGED_BEACON; |
328 | } | 327 | } |
329 | 328 | ||
330 | static inline | 329 | static inline |
331 | u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) | 330 | u32 mesh_plink_dec_estab_count(struct ieee80211_sub_if_data *sdata) |
332 | { | 331 | { |
333 | atomic_dec(&sdata->u.mesh.estab_plinks); | 332 | atomic_dec(&sdata->u.mesh.estab_plinks); |
334 | return mesh_accept_plinks_update(sdata); | 333 | return mesh_accept_plinks_update(sdata) | BSS_CHANGED_BEACON; |
335 | } | 334 | } |
336 | 335 | ||
337 | static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) | 336 | static inline int mesh_plink_free_count(struct ieee80211_sub_if_data *sdata) |
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 6c4da99bc4fb..09bebed99416 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -517,9 +517,7 @@ 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); | ||
521 | ieee80211_mbss_info_change_notify(sdata, changed); | 520 | ieee80211_mbss_info_change_notify(sdata, changed); |
522 | sdata_unlock(sdata); | ||
523 | } | 521 | } |
524 | 522 | ||
525 | static void mesh_plink_timer(unsigned long data) | 523 | static void mesh_plink_timer(unsigned long data) |
@@ -1070,9 +1068,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, | |||
1070 | 1068 | ||
1071 | rcu_read_unlock(); | 1069 | rcu_read_unlock(); |
1072 | 1070 | ||
1073 | if (changed) { | 1071 | if (changed) |
1074 | sdata_lock(sdata); | ||
1075 | ieee80211_mbss_info_change_notify(sdata, changed); | 1072 | ieee80211_mbss_info_change_notify(sdata, changed); |
1076 | sdata_unlock(sdata); | ||
1077 | } | ||
1078 | } | 1073 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 118540b16729..9e49f557fa5c 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -880,6 +880,10 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local, | |||
880 | 880 | ||
881 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | | 881 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | |
882 | IEEE80211_TX_INTFL_OFFCHAN_TX_OK; | 882 | IEEE80211_TX_INTFL_OFFCHAN_TX_OK; |
883 | |||
884 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | ||
885 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
886 | |||
883 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | | 887 | if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | |
884 | IEEE80211_STA_CONNECTION_POLL)) | 888 | IEEE80211_STA_CONNECTION_POLL)) |
885 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE; | 889 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE; |
@@ -1356,7 +1360,7 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) | |||
1356 | IEEE80211_STA_CONNECTION_POLL)) | 1360 | IEEE80211_STA_CONNECTION_POLL)) |
1357 | return false; | 1361 | return false; |
1358 | 1362 | ||
1359 | if (!sdata->vif.bss_conf.dtim_period) | 1363 | if (!mgd->have_beacon) |
1360 | return false; | 1364 | return false; |
1361 | 1365 | ||
1362 | rcu_read_lock(); | 1366 | rcu_read_lock(); |
@@ -1767,7 +1771,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1767 | 1771 | ||
1768 | ieee80211_led_assoc(local, 1); | 1772 | ieee80211_led_assoc(local, 1); |
1769 | 1773 | ||
1770 | if (sdata->u.mgd.assoc_data->have_beacon) { | 1774 | if (sdata->u.mgd.have_beacon) { |
1771 | /* | 1775 | /* |
1772 | * If the AP is buggy we may get here with no DTIM period | 1776 | * If the AP is buggy we may get here with no DTIM period |
1773 | * known, so assume it's 1 which is the only safe assumption | 1777 | * known, so assume it's 1 which is the only safe assumption |
@@ -1775,7 +1779,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1775 | * probably just won't work at all. | 1779 | * probably just won't work at all. |
1776 | */ | 1780 | */ |
1777 | bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1; | 1781 | bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1; |
1778 | bss_info_changed |= BSS_CHANGED_DTIM_PERIOD; | 1782 | bss_info_changed |= BSS_CHANGED_BEACON_INFO; |
1779 | } else { | 1783 | } else { |
1780 | bss_conf->dtim_period = 0; | 1784 | bss_conf->dtim_period = 0; |
1781 | } | 1785 | } |
@@ -1899,6 +1903,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1899 | del_timer_sync(&sdata->u.mgd.chswitch_timer); | 1903 | del_timer_sync(&sdata->u.mgd.chswitch_timer); |
1900 | 1904 | ||
1901 | sdata->vif.bss_conf.dtim_period = 0; | 1905 | sdata->vif.bss_conf.dtim_period = 0; |
1906 | ifmgd->have_beacon = false; | ||
1902 | 1907 | ||
1903 | ifmgd->flags = 0; | 1908 | ifmgd->flags = 0; |
1904 | ieee80211_vif_release_channel(sdata); | 1909 | ieee80211_vif_release_channel(sdata); |
@@ -2151,7 +2156,8 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) | |||
2151 | IEEE80211_MAX_QUEUE_MAP, | 2156 | IEEE80211_MAX_QUEUE_MAP, |
2152 | IEEE80211_QUEUE_STOP_REASON_CSA); | 2157 | IEEE80211_QUEUE_STOP_REASON_CSA); |
2153 | 2158 | ||
2154 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); | 2159 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
2160 | IEEE80211_DEAUTH_FRAME_LEN); | ||
2155 | sdata_unlock(sdata); | 2161 | sdata_unlock(sdata); |
2156 | } | 2162 | } |
2157 | 2163 | ||
@@ -2298,7 +2304,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2298 | sdata_info(sdata, "%pM denied authentication (status %d)\n", | 2304 | sdata_info(sdata, "%pM denied authentication (status %d)\n", |
2299 | mgmt->sa, status_code); | 2305 | mgmt->sa, status_code); |
2300 | ieee80211_destroy_auth_data(sdata, false); | 2306 | ieee80211_destroy_auth_data(sdata, false); |
2301 | cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); | 2307 | cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); |
2302 | return; | 2308 | return; |
2303 | } | 2309 | } |
2304 | 2310 | ||
@@ -2333,7 +2339,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2333 | * Report auth frame to user space for processing since another | 2339 | * Report auth frame to user space for processing since another |
2334 | * round of Authentication frames is still needed. | 2340 | * round of Authentication frames is still needed. |
2335 | */ | 2341 | */ |
2336 | cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); | 2342 | cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); |
2337 | return; | 2343 | return; |
2338 | } | 2344 | } |
2339 | 2345 | ||
@@ -2350,7 +2356,7 @@ static void ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
2350 | } | 2356 | } |
2351 | mutex_unlock(&sdata->local->sta_mtx); | 2357 | mutex_unlock(&sdata->local->sta_mtx); |
2352 | 2358 | ||
2353 | cfg80211_send_rx_auth(sdata->dev, (u8 *)mgmt, len); | 2359 | cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); |
2354 | return; | 2360 | return; |
2355 | out_err: | 2361 | out_err: |
2356 | mutex_unlock(&sdata->local->sta_mtx); | 2362 | mutex_unlock(&sdata->local->sta_mtx); |
@@ -2383,7 +2389,7 @@ static void ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
2383 | 2389 | ||
2384 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 2390 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
2385 | 2391 | ||
2386 | cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, len); | 2392 | cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); |
2387 | } | 2393 | } |
2388 | 2394 | ||
2389 | 2395 | ||
@@ -2409,7 +2415,7 @@ static void ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
2409 | 2415 | ||
2410 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 2416 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
2411 | 2417 | ||
2412 | cfg80211_send_disassoc(sdata->dev, (u8 *)mgmt, len); | 2418 | cfg80211_rx_mlme_mgmt(sdata->dev, (u8 *)mgmt, len); |
2413 | } | 2419 | } |
2414 | 2420 | ||
2415 | static void ieee80211_get_rates(struct ieee80211_supported_band *sband, | 2421 | static void ieee80211_get_rates(struct ieee80211_supported_band *sband, |
@@ -2780,7 +2786,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2780 | /* oops -- internal error -- send timeout for now */ | 2786 | /* oops -- internal error -- send timeout for now */ |
2781 | ieee80211_destroy_assoc_data(sdata, false); | 2787 | ieee80211_destroy_assoc_data(sdata, false); |
2782 | cfg80211_put_bss(sdata->local->hw.wiphy, bss); | 2788 | cfg80211_put_bss(sdata->local->hw.wiphy, bss); |
2783 | cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid); | 2789 | cfg80211_assoc_timeout(sdata->dev, mgmt->bssid); |
2784 | return; | 2790 | return; |
2785 | } | 2791 | } |
2786 | sdata_info(sdata, "associated\n"); | 2792 | sdata_info(sdata, "associated\n"); |
@@ -2793,7 +2799,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2793 | ieee80211_destroy_assoc_data(sdata, true); | 2799 | ieee80211_destroy_assoc_data(sdata, true); |
2794 | } | 2800 | } |
2795 | 2801 | ||
2796 | cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, len); | 2802 | cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len); |
2797 | } | 2803 | } |
2798 | 2804 | ||
2799 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 2805 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, |
@@ -2805,24 +2811,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
2805 | int freq; | 2811 | int freq; |
2806 | struct ieee80211_bss *bss; | 2812 | struct ieee80211_bss *bss; |
2807 | struct ieee80211_channel *channel; | 2813 | struct ieee80211_channel *channel; |
2808 | bool need_ps = false; | ||
2809 | 2814 | ||
2810 | sdata_assert_lock(sdata); | 2815 | sdata_assert_lock(sdata); |
2811 | 2816 | ||
2812 | if ((sdata->u.mgd.associated && | ||
2813 | ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) || | ||
2814 | (sdata->u.mgd.assoc_data && | ||
2815 | ether_addr_equal(mgmt->bssid, | ||
2816 | sdata->u.mgd.assoc_data->bss->bssid))) { | ||
2817 | /* not previously set so we may need to recalc */ | ||
2818 | need_ps = sdata->u.mgd.associated && !sdata->u.mgd.dtim_period; | ||
2819 | |||
2820 | if (elems->tim && !elems->parse_error) { | ||
2821 | const struct ieee80211_tim_ie *tim_ie = elems->tim; | ||
2822 | sdata->u.mgd.dtim_period = tim_ie->dtim_period; | ||
2823 | } | ||
2824 | } | ||
2825 | |||
2826 | if (elems->ds_params) | 2817 | if (elems->ds_params) |
2827 | freq = ieee80211_channel_to_frequency(elems->ds_params[0], | 2818 | freq = ieee80211_channel_to_frequency(elems->ds_params[0], |
2828 | rx_status->band); | 2819 | rx_status->band); |
@@ -2843,12 +2834,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
2843 | !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) | 2834 | !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) |
2844 | return; | 2835 | return; |
2845 | 2836 | ||
2846 | if (need_ps) { | ||
2847 | mutex_lock(&local->iflist_mtx); | ||
2848 | ieee80211_recalc_ps(local, -1); | ||
2849 | mutex_unlock(&local->iflist_mtx); | ||
2850 | } | ||
2851 | |||
2852 | ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, | 2837 | ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, |
2853 | elems, true); | 2838 | elems, true); |
2854 | 2839 | ||
@@ -2962,7 +2947,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2962 | len - baselen, false, &elems); | 2947 | len - baselen, false, &elems); |
2963 | 2948 | ||
2964 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); | 2949 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); |
2965 | ifmgd->assoc_data->have_beacon = true; | 2950 | if (elems.tim && !elems.parse_error) { |
2951 | const struct ieee80211_tim_ie *tim_ie = elems.tim; | ||
2952 | ifmgd->dtim_period = tim_ie->dtim_period; | ||
2953 | } | ||
2954 | ifmgd->have_beacon = true; | ||
2966 | ifmgd->assoc_data->need_beacon = false; | 2955 | ifmgd->assoc_data->need_beacon = false; |
2967 | if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) { | 2956 | if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) { |
2968 | sdata->vif.bss_conf.sync_tsf = | 2957 | sdata->vif.bss_conf.sync_tsf = |
@@ -3144,7 +3133,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3144 | * If we haven't had a beacon before, tell the driver about the | 3133 | * If we haven't had a beacon before, tell the driver about the |
3145 | * DTIM period (and beacon timing if desired) now. | 3134 | * DTIM period (and beacon timing if desired) now. |
3146 | */ | 3135 | */ |
3147 | if (!bss_conf->dtim_period) { | 3136 | if (!ifmgd->have_beacon) { |
3148 | /* a few bogus AP send dtim_period = 0 or no TIM IE */ | 3137 | /* a few bogus AP send dtim_period = 0 or no TIM IE */ |
3149 | if (elems.tim) | 3138 | if (elems.tim) |
3150 | bss_conf->dtim_period = elems.tim->dtim_period ?: 1; | 3139 | bss_conf->dtim_period = elems.tim->dtim_period ?: 1; |
@@ -3163,7 +3152,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3163 | sdata->vif.bss_conf.sync_dtim_count = 0; | 3152 | sdata->vif.bss_conf.sync_dtim_count = 0; |
3164 | } | 3153 | } |
3165 | 3154 | ||
3166 | changed |= BSS_CHANGED_DTIM_PERIOD; | 3155 | changed |= BSS_CHANGED_BEACON_INFO; |
3156 | ifmgd->have_beacon = true; | ||
3157 | |||
3158 | mutex_lock(&local->iflist_mtx); | ||
3159 | ieee80211_recalc_ps(local, -1); | ||
3160 | mutex_unlock(&local->iflist_mtx); | ||
3161 | |||
3167 | ieee80211_recalc_ps_vif(sdata); | 3162 | ieee80211_recalc_ps_vif(sdata); |
3168 | } | 3163 | } |
3169 | 3164 | ||
@@ -3186,8 +3181,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3186 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 3181 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
3187 | WLAN_REASON_DEAUTH_LEAVING, | 3182 | WLAN_REASON_DEAUTH_LEAVING, |
3188 | true, deauth_buf); | 3183 | true, deauth_buf); |
3189 | cfg80211_send_deauth(sdata->dev, deauth_buf, | 3184 | cfg80211_tx_mlme_mgmt(sdata->dev, deauth_buf, |
3190 | sizeof(deauth_buf)); | 3185 | sizeof(deauth_buf)); |
3191 | return; | 3186 | return; |
3192 | } | 3187 | } |
3193 | 3188 | ||
@@ -3305,7 +3300,8 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | |||
3305 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, | 3300 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, |
3306 | tx, frame_buf); | 3301 | tx, frame_buf); |
3307 | 3302 | ||
3308 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); | 3303 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
3304 | IEEE80211_DEAUTH_FRAME_LEN); | ||
3309 | } | 3305 | } |
3310 | 3306 | ||
3311 | static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | 3307 | static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) |
@@ -3496,15 +3492,14 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3496 | 3492 | ||
3497 | ieee80211_destroy_auth_data(sdata, false); | 3493 | ieee80211_destroy_auth_data(sdata, false); |
3498 | 3494 | ||
3499 | cfg80211_send_auth_timeout(sdata->dev, bssid); | 3495 | cfg80211_auth_timeout(sdata->dev, bssid); |
3500 | } | 3496 | } |
3501 | } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) | 3497 | } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) |
3502 | run_again(sdata, ifmgd->auth_data->timeout); | 3498 | run_again(sdata, ifmgd->auth_data->timeout); |
3503 | 3499 | ||
3504 | if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && | 3500 | if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && |
3505 | time_after(jiffies, ifmgd->assoc_data->timeout)) { | 3501 | time_after(jiffies, ifmgd->assoc_data->timeout)) { |
3506 | if ((ifmgd->assoc_data->need_beacon && | 3502 | if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) || |
3507 | !ifmgd->assoc_data->have_beacon) || | ||
3508 | ieee80211_do_assoc(sdata)) { | 3503 | ieee80211_do_assoc(sdata)) { |
3509 | u8 bssid[ETH_ALEN]; | 3504 | u8 bssid[ETH_ALEN]; |
3510 | 3505 | ||
@@ -3512,7 +3507,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3512 | 3507 | ||
3513 | ieee80211_destroy_assoc_data(sdata, false); | 3508 | ieee80211_destroy_assoc_data(sdata, false); |
3514 | 3509 | ||
3515 | cfg80211_send_assoc_timeout(sdata->dev, bssid); | 3510 | cfg80211_assoc_timeout(sdata->dev, bssid); |
3516 | } | 3511 | } |
3517 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) | 3512 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) |
3518 | run_again(sdata, ifmgd->assoc_data->timeout); | 3513 | run_again(sdata, ifmgd->assoc_data->timeout); |
@@ -4061,8 +4056,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
4061 | WLAN_REASON_UNSPECIFIED, | 4056 | WLAN_REASON_UNSPECIFIED, |
4062 | false, frame_buf); | 4057 | false, frame_buf); |
4063 | 4058 | ||
4064 | cfg80211_send_deauth(sdata->dev, frame_buf, | 4059 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
4065 | sizeof(frame_buf)); | 4060 | sizeof(frame_buf)); |
4066 | } | 4061 | } |
4067 | 4062 | ||
4068 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); | 4063 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); |
@@ -4124,8 +4119,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4124 | WLAN_REASON_UNSPECIFIED, | 4119 | WLAN_REASON_UNSPECIFIED, |
4125 | false, frame_buf); | 4120 | false, frame_buf); |
4126 | 4121 | ||
4127 | cfg80211_send_deauth(sdata->dev, frame_buf, | 4122 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
4128 | sizeof(frame_buf)); | 4123 | sizeof(frame_buf)); |
4129 | } | 4124 | } |
4130 | 4125 | ||
4131 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { | 4126 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { |
@@ -4272,6 +4267,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4272 | 4267 | ||
4273 | ifmgd->assoc_data = assoc_data; | 4268 | ifmgd->assoc_data = assoc_data; |
4274 | ifmgd->dtim_period = 0; | 4269 | ifmgd->dtim_period = 0; |
4270 | ifmgd->have_beacon = false; | ||
4275 | 4271 | ||
4276 | err = ieee80211_prep_connection(sdata, req->bss, true); | 4272 | err = ieee80211_prep_connection(sdata, req->bss, true); |
4277 | if (err) | 4273 | if (err) |
@@ -4303,7 +4299,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4303 | ifmgd->dtim_period = tim->dtim_period; | 4299 | ifmgd->dtim_period = tim->dtim_period; |
4304 | dtim_count = tim->dtim_count; | 4300 | dtim_count = tim->dtim_count; |
4305 | } | 4301 | } |
4306 | assoc_data->have_beacon = true; | 4302 | ifmgd->have_beacon = true; |
4307 | assoc_data->timeout = jiffies; | 4303 | assoc_data->timeout = jiffies; |
4308 | assoc_data->timeout_started = true; | 4304 | assoc_data->timeout_started = true; |
4309 | 4305 | ||
@@ -4378,8 +4374,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4378 | 4374 | ||
4379 | out: | 4375 | out: |
4380 | if (report_frame) | 4376 | if (report_frame) |
4381 | cfg80211_send_deauth(sdata->dev, frame_buf, | 4377 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
4382 | IEEE80211_DEAUTH_FRAME_LEN); | 4378 | IEEE80211_DEAUTH_FRAME_LEN); |
4383 | 4379 | ||
4384 | return 0; | 4380 | return 0; |
4385 | } | 4381 | } |
@@ -4409,8 +4405,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
4409 | req->reason_code, !req->local_state_change, | 4405 | req->reason_code, !req->local_state_change, |
4410 | frame_buf); | 4406 | frame_buf); |
4411 | 4407 | ||
4412 | cfg80211_send_disassoc(sdata->dev, frame_buf, | 4408 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
4413 | IEEE80211_DEAUTH_FRAME_LEN); | 4409 | IEEE80211_DEAUTH_FRAME_LEN); |
4414 | 4410 | ||
4415 | return 0; | 4411 | return 0; |
4416 | } | 4412 | } |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index bdd7b4a719e9..23dbcfc69b3b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1747,27 +1747,21 @@ static int ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx) | |||
1747 | if (unlikely(!ieee80211_has_protected(fc) && | 1747 | if (unlikely(!ieee80211_has_protected(fc) && |
1748 | ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && | 1748 | ieee80211_is_unicast_robust_mgmt_frame(rx->skb) && |
1749 | rx->key)) { | 1749 | rx->key)) { |
1750 | if (ieee80211_is_deauth(fc)) | 1750 | if (ieee80211_is_deauth(fc) || |
1751 | cfg80211_send_unprot_deauth(rx->sdata->dev, | 1751 | ieee80211_is_disassoc(fc)) |
1752 | rx->skb->data, | 1752 | cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, |
1753 | rx->skb->len); | 1753 | rx->skb->data, |
1754 | else if (ieee80211_is_disassoc(fc)) | 1754 | rx->skb->len); |
1755 | cfg80211_send_unprot_disassoc(rx->sdata->dev, | ||
1756 | rx->skb->data, | ||
1757 | rx->skb->len); | ||
1758 | return -EACCES; | 1755 | return -EACCES; |
1759 | } | 1756 | } |
1760 | /* BIP does not use Protected field, so need to check MMIE */ | 1757 | /* BIP does not use Protected field, so need to check MMIE */ |
1761 | if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && | 1758 | if (unlikely(ieee80211_is_multicast_robust_mgmt_frame(rx->skb) && |
1762 | ieee80211_get_mmie_keyidx(rx->skb) < 0)) { | 1759 | ieee80211_get_mmie_keyidx(rx->skb) < 0)) { |
1763 | if (ieee80211_is_deauth(fc)) | 1760 | if (ieee80211_is_deauth(fc) || |
1764 | cfg80211_send_unprot_deauth(rx->sdata->dev, | 1761 | ieee80211_is_disassoc(fc)) |
1765 | rx->skb->data, | 1762 | cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev, |
1766 | rx->skb->len); | 1763 | rx->skb->data, |
1767 | else if (ieee80211_is_disassoc(fc)) | 1764 | rx->skb->len); |
1768 | cfg80211_send_unprot_disassoc(rx->sdata->dev, | ||
1769 | rx->skb->data, | ||
1770 | rx->skb->len); | ||
1771 | return -EACCES; | 1765 | return -EACCES; |
1772 | } | 1766 | } |
1773 | /* | 1767 | /* |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index a04c5671d7fd..b4297982d34a 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -1132,6 +1132,7 @@ static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | |||
1132 | * ends the poll/service period. | 1132 | * ends the poll/service period. |
1133 | */ | 1133 | */ |
1134 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | | 1134 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | |
1135 | IEEE80211_TX_CTL_PS_RESPONSE | | ||
1135 | IEEE80211_TX_STATUS_EOSP | | 1136 | IEEE80211_TX_STATUS_EOSP | |
1136 | IEEE80211_TX_CTL_REQ_TX_STATUS; | 1137 | IEEE80211_TX_CTL_REQ_TX_STATUS; |
1137 | 1138 | ||
@@ -1269,7 +1270,8 @@ ieee80211_sta_ps_deliver_response(struct sta_info *sta, | |||
1269 | * STA may still remain is PS mode after this frame | 1270 | * STA may still remain is PS mode after this frame |
1270 | * exchange. | 1271 | * exchange. |
1271 | */ | 1272 | */ |
1272 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER; | 1273 | info->flags |= IEEE80211_TX_CTL_NO_PS_BUFFER | |
1274 | IEEE80211_TX_CTL_PS_RESPONSE; | ||
1273 | 1275 | ||
1274 | /* | 1276 | /* |
1275 | * Use MoreData flag to indicate whether there are | 1277 | * Use MoreData flag to indicate whether there are |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 41c28b977f7c..bd12fc54266c 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -297,6 +297,9 @@ struct sta_ampdu_mlme { | |||
297 | * @rcu_head: RCU head used for freeing this station struct | 297 | * @rcu_head: RCU head used for freeing this station struct |
298 | * @cur_max_bandwidth: maximum bandwidth to use for TX to the station, | 298 | * @cur_max_bandwidth: maximum bandwidth to use for TX to the station, |
299 | * taken from HT/VHT capabilities or VHT operating mode notification | 299 | * taken from HT/VHT capabilities or VHT operating mode notification |
300 | * @chains: chains ever used for RX from this station | ||
301 | * @chain_signal_last: last signal (per chain) | ||
302 | * @chain_signal_avg: signal average (per chain) | ||
300 | */ | 303 | */ |
301 | struct sta_info { | 304 | struct sta_info { |
302 | /* General information, mostly static */ | 305 | /* General information, mostly static */ |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 34be9336b5d1..4105d0ca963e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -1790,12 +1790,6 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1790 | break; | 1790 | break; |
1791 | #ifdef CONFIG_MAC80211_MESH | 1791 | #ifdef CONFIG_MAC80211_MESH |
1792 | case NL80211_IFTYPE_MESH_POINT: | 1792 | case NL80211_IFTYPE_MESH_POINT: |
1793 | if (!sdata->u.mesh.mshcfg.dot11MeshTTL) { | ||
1794 | /* Do not send frames with mesh_ttl == 0 */ | ||
1795 | sdata->u.mesh.mshstats.dropped_frames_ttl++; | ||
1796 | goto fail_rcu; | ||
1797 | } | ||
1798 | |||
1799 | if (!is_multicast_ether_addr(skb->data)) { | 1793 | if (!is_multicast_ether_addr(skb->data)) { |
1800 | struct sta_info *next_hop; | 1794 | struct sta_info *next_hop; |
1801 | bool mpp_lookup = true; | 1795 | bool mpp_lookup = true; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index c75d3db2a31c..22654452a561 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -1584,8 +1584,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1584 | BSS_CHANGED_ARP_FILTER | | 1584 | BSS_CHANGED_ARP_FILTER | |
1585 | BSS_CHANGED_PS; | 1585 | BSS_CHANGED_PS; |
1586 | 1586 | ||
1587 | if (sdata->u.mgd.dtim_period) | 1587 | /* Re-send beacon info report to the driver */ |
1588 | changed |= BSS_CHANGED_DTIM_PERIOD; | 1588 | if (sdata->u.mgd.have_beacon) |
1589 | changed |= BSS_CHANGED_BEACON_INFO; | ||
1589 | 1590 | ||
1590 | sdata_lock(sdata); | 1591 | sdata_lock(sdata); |
1591 | ieee80211_bss_info_change_notify(sdata, changed); | 1592 | ieee80211_bss_info_change_notify(sdata, changed); |