diff options
author | John W. Linville <linville@tuxdriver.com> | 2013-06-12 15:39:05 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-06-12 15:39:05 -0400 |
commit | 812fd645968118c35a3f4d0d18dd3f4d07221df0 (patch) | |
tree | b68ee223f22a811e9743b193872052cd264fe2d0 /net/mac80211 | |
parent | cb180840a0c6bff7c0787373c23cefdf20417a27 (diff) | |
parent | 940d0ac9dbe3fb9d4806e96f006286c2e476deed (diff) |
Merge branch 'for-john' of git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next
Conflicts:
drivers/net/wireless/iwlwifi/mvm/mac80211.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 30622101d3b5..64cf294c2b96 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1759,6 +1759,7 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh, | |||
1759 | /* mcast rate setting in Mesh Node */ | 1759 | /* mcast rate setting in Mesh Node */ |
1760 | memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate, | 1760 | memcpy(sdata->vif.bss_conf.mcast_rate, setup->mcast_rate, |
1761 | sizeof(setup->mcast_rate)); | 1761 | sizeof(setup->mcast_rate)); |
1762 | sdata->vif.bss_conf.basic_rates = setup->basic_rates; | ||
1762 | 1763 | ||
1763 | sdata->vif.bss_conf.beacon_int = setup->beacon_interval; | 1764 | sdata->vif.bss_conf.beacon_int = setup->beacon_interval; |
1764 | sdata->vif.bss_conf.dtim_period = setup->dtim_period; | 1765 | sdata->vif.bss_conf.dtim_period = setup->dtim_period; |
@@ -1871,6 +1872,8 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, | |||
1871 | if (_chg_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask)) | 1872 | if (_chg_mesh_attr(NL80211_MESHCONF_AWAKE_WINDOW, mask)) |
1872 | conf->dot11MeshAwakeWindowDuration = | 1873 | conf->dot11MeshAwakeWindowDuration = |
1873 | nconf->dot11MeshAwakeWindowDuration; | 1874 | nconf->dot11MeshAwakeWindowDuration; |
1875 | if (_chg_mesh_attr(NL80211_MESHCONF_PLINK_TIMEOUT, mask)) | ||
1876 | conf->plink_timeout = nconf->plink_timeout; | ||
1874 | ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); | 1877 | ieee80211_mbss_info_change_notify(sdata, BSS_CHANGED_BEACON); |
1875 | return 0; | 1878 | return 0; |
1876 | } | 1879 | } |
@@ -2838,6 +2841,12 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
2838 | return -EOPNOTSUPP; | 2841 | return -EOPNOTSUPP; |
2839 | } | 2842 | } |
2840 | 2843 | ||
2844 | /* configurations requiring offchan cannot work if no channel has been | ||
2845 | * specified | ||
2846 | */ | ||
2847 | if (need_offchan && !chan) | ||
2848 | return -EINVAL; | ||
2849 | |||
2841 | mutex_lock(&local->mtx); | 2850 | mutex_lock(&local->mtx); |
2842 | 2851 | ||
2843 | /* Check if the operating channel is the requested channel */ | 2852 | /* Check if the operating channel is the requested channel */ |
@@ -2847,10 +2856,15 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, | |||
2847 | rcu_read_lock(); | 2856 | rcu_read_lock(); |
2848 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | 2857 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
2849 | 2858 | ||
2850 | if (chanctx_conf) | 2859 | if (chanctx_conf) { |
2851 | need_offchan = chan != chanctx_conf->def.chan; | 2860 | need_offchan = chan && (chan != chanctx_conf->def.chan); |
2852 | else | 2861 | } else if (!chan) { |
2862 | ret = -EINVAL; | ||
2863 | rcu_read_unlock(); | ||
2864 | goto out_unlock; | ||
2865 | } else { | ||
2853 | need_offchan = true; | 2866 | need_offchan = true; |
2867 | } | ||
2854 | rcu_read_unlock(); | 2868 | rcu_read_unlock(); |
2855 | } | 2869 | } |
2856 | 2870 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 9eed6f1d1614..7a6f1a0207ec 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 f44f4caa69ee..ad9bb9e10cbb 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, |
@@ -2707,7 +2713,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2707 | /* oops -- internal error -- send timeout for now */ | 2713 | /* oops -- internal error -- send timeout for now */ |
2708 | ieee80211_destroy_assoc_data(sdata, false); | 2714 | ieee80211_destroy_assoc_data(sdata, false); |
2709 | cfg80211_put_bss(sdata->local->hw.wiphy, bss); | 2715 | cfg80211_put_bss(sdata->local->hw.wiphy, bss); |
2710 | cfg80211_send_assoc_timeout(sdata->dev, mgmt->bssid); | 2716 | cfg80211_assoc_timeout(sdata->dev, mgmt->bssid); |
2711 | return; | 2717 | return; |
2712 | } | 2718 | } |
2713 | sdata_info(sdata, "associated\n"); | 2719 | sdata_info(sdata, "associated\n"); |
@@ -2720,7 +2726,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2720 | ieee80211_destroy_assoc_data(sdata, true); | 2726 | ieee80211_destroy_assoc_data(sdata, true); |
2721 | } | 2727 | } |
2722 | 2728 | ||
2723 | cfg80211_send_rx_assoc(sdata->dev, bss, (u8 *)mgmt, len); | 2729 | cfg80211_rx_assoc_resp(sdata->dev, bss, (u8 *)mgmt, len); |
2724 | } | 2730 | } |
2725 | 2731 | ||
2726 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | 2732 | static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, |
@@ -2732,24 +2738,9 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
2732 | int freq; | 2738 | int freq; |
2733 | struct ieee80211_bss *bss; | 2739 | struct ieee80211_bss *bss; |
2734 | struct ieee80211_channel *channel; | 2740 | struct ieee80211_channel *channel; |
2735 | bool need_ps = false; | ||
2736 | 2741 | ||
2737 | sdata_assert_lock(sdata); | 2742 | sdata_assert_lock(sdata); |
2738 | 2743 | ||
2739 | if ((sdata->u.mgd.associated && | ||
2740 | ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) || | ||
2741 | (sdata->u.mgd.assoc_data && | ||
2742 | ether_addr_equal(mgmt->bssid, | ||
2743 | sdata->u.mgd.assoc_data->bss->bssid))) { | ||
2744 | /* not previously set so we may need to recalc */ | ||
2745 | need_ps = sdata->u.mgd.associated && !sdata->u.mgd.dtim_period; | ||
2746 | |||
2747 | if (elems->tim && !elems->parse_error) { | ||
2748 | const struct ieee80211_tim_ie *tim_ie = elems->tim; | ||
2749 | sdata->u.mgd.dtim_period = tim_ie->dtim_period; | ||
2750 | } | ||
2751 | } | ||
2752 | |||
2753 | if (elems->ds_params) | 2744 | if (elems->ds_params) |
2754 | freq = ieee80211_channel_to_frequency(elems->ds_params[0], | 2745 | freq = ieee80211_channel_to_frequency(elems->ds_params[0], |
2755 | rx_status->band); | 2746 | rx_status->band); |
@@ -2770,12 +2761,6 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
2770 | !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) | 2761 | !ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) |
2771 | return; | 2762 | return; |
2772 | 2763 | ||
2773 | if (need_ps) { | ||
2774 | mutex_lock(&local->iflist_mtx); | ||
2775 | ieee80211_recalc_ps(local, -1); | ||
2776 | mutex_unlock(&local->iflist_mtx); | ||
2777 | } | ||
2778 | |||
2779 | ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, | 2764 | ieee80211_sta_process_chanswitch(sdata, rx_status->mactime, |
2780 | elems, true); | 2765 | elems, true); |
2781 | 2766 | ||
@@ -2889,7 +2874,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2889 | len - baselen, false, &elems); | 2874 | len - baselen, false, &elems); |
2890 | 2875 | ||
2891 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); | 2876 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); |
2892 | ifmgd->assoc_data->have_beacon = true; | 2877 | if (elems.tim && !elems.parse_error) { |
2878 | const struct ieee80211_tim_ie *tim_ie = elems.tim; | ||
2879 | ifmgd->dtim_period = tim_ie->dtim_period; | ||
2880 | } | ||
2881 | ifmgd->have_beacon = true; | ||
2893 | ifmgd->assoc_data->need_beacon = false; | 2882 | ifmgd->assoc_data->need_beacon = false; |
2894 | if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) { | 2883 | if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) { |
2895 | sdata->vif.bss_conf.sync_tsf = | 2884 | sdata->vif.bss_conf.sync_tsf = |
@@ -3071,7 +3060,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3071 | * If we haven't had a beacon before, tell the driver about the | 3060 | * If we haven't had a beacon before, tell the driver about the |
3072 | * DTIM period (and beacon timing if desired) now. | 3061 | * DTIM period (and beacon timing if desired) now. |
3073 | */ | 3062 | */ |
3074 | if (!bss_conf->dtim_period) { | 3063 | if (!ifmgd->have_beacon) { |
3075 | /* a few bogus AP send dtim_period = 0 or no TIM IE */ | 3064 | /* a few bogus AP send dtim_period = 0 or no TIM IE */ |
3076 | if (elems.tim) | 3065 | if (elems.tim) |
3077 | bss_conf->dtim_period = elems.tim->dtim_period ?: 1; | 3066 | bss_conf->dtim_period = elems.tim->dtim_period ?: 1; |
@@ -3090,7 +3079,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3090 | sdata->vif.bss_conf.sync_dtim_count = 0; | 3079 | sdata->vif.bss_conf.sync_dtim_count = 0; |
3091 | } | 3080 | } |
3092 | 3081 | ||
3093 | changed |= BSS_CHANGED_DTIM_PERIOD; | 3082 | changed |= BSS_CHANGED_BEACON_INFO; |
3083 | ifmgd->have_beacon = true; | ||
3084 | |||
3085 | mutex_lock(&local->iflist_mtx); | ||
3086 | ieee80211_recalc_ps(local, -1); | ||
3087 | mutex_unlock(&local->iflist_mtx); | ||
3088 | |||
3094 | ieee80211_recalc_ps_vif(sdata); | 3089 | ieee80211_recalc_ps_vif(sdata); |
3095 | } | 3090 | } |
3096 | 3091 | ||
@@ -3113,8 +3108,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
3113 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 3108 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
3114 | WLAN_REASON_DEAUTH_LEAVING, | 3109 | WLAN_REASON_DEAUTH_LEAVING, |
3115 | true, deauth_buf); | 3110 | true, deauth_buf); |
3116 | cfg80211_send_deauth(sdata->dev, deauth_buf, | 3111 | cfg80211_tx_mlme_mgmt(sdata->dev, deauth_buf, |
3117 | sizeof(deauth_buf)); | 3112 | sizeof(deauth_buf)); |
3118 | return; | 3113 | return; |
3119 | } | 3114 | } |
3120 | 3115 | ||
@@ -3232,7 +3227,8 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | |||
3232 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, | 3227 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason, |
3233 | tx, frame_buf); | 3228 | tx, frame_buf); |
3234 | 3229 | ||
3235 | cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); | 3230 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
3231 | IEEE80211_DEAUTH_FRAME_LEN); | ||
3236 | } | 3232 | } |
3237 | 3233 | ||
3238 | static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | 3234 | static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) |
@@ -3423,15 +3419,14 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3423 | 3419 | ||
3424 | ieee80211_destroy_auth_data(sdata, false); | 3420 | ieee80211_destroy_auth_data(sdata, false); |
3425 | 3421 | ||
3426 | cfg80211_send_auth_timeout(sdata->dev, bssid); | 3422 | cfg80211_auth_timeout(sdata->dev, bssid); |
3427 | } | 3423 | } |
3428 | } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) | 3424 | } else if (ifmgd->auth_data && ifmgd->auth_data->timeout_started) |
3429 | run_again(sdata, ifmgd->auth_data->timeout); | 3425 | run_again(sdata, ifmgd->auth_data->timeout); |
3430 | 3426 | ||
3431 | if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && | 3427 | if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started && |
3432 | time_after(jiffies, ifmgd->assoc_data->timeout)) { | 3428 | time_after(jiffies, ifmgd->assoc_data->timeout)) { |
3433 | if ((ifmgd->assoc_data->need_beacon && | 3429 | if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) || |
3434 | !ifmgd->assoc_data->have_beacon) || | ||
3435 | ieee80211_do_assoc(sdata)) { | 3430 | ieee80211_do_assoc(sdata)) { |
3436 | u8 bssid[ETH_ALEN]; | 3431 | u8 bssid[ETH_ALEN]; |
3437 | 3432 | ||
@@ -3439,7 +3434,7 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
3439 | 3434 | ||
3440 | ieee80211_destroy_assoc_data(sdata, false); | 3435 | ieee80211_destroy_assoc_data(sdata, false); |
3441 | 3436 | ||
3442 | cfg80211_send_assoc_timeout(sdata->dev, bssid); | 3437 | cfg80211_assoc_timeout(sdata->dev, bssid); |
3443 | } | 3438 | } |
3444 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) | 3439 | } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) |
3445 | run_again(sdata, ifmgd->assoc_data->timeout); | 3440 | run_again(sdata, ifmgd->assoc_data->timeout); |
@@ -3988,8 +3983,8 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3988 | WLAN_REASON_UNSPECIFIED, | 3983 | WLAN_REASON_UNSPECIFIED, |
3989 | false, frame_buf); | 3984 | false, frame_buf); |
3990 | 3985 | ||
3991 | cfg80211_send_deauth(sdata->dev, frame_buf, | 3986 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
3992 | sizeof(frame_buf)); | 3987 | sizeof(frame_buf)); |
3993 | } | 3988 | } |
3994 | 3989 | ||
3995 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); | 3990 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); |
@@ -4051,8 +4046,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4051 | WLAN_REASON_UNSPECIFIED, | 4046 | WLAN_REASON_UNSPECIFIED, |
4052 | false, frame_buf); | 4047 | false, frame_buf); |
4053 | 4048 | ||
4054 | cfg80211_send_deauth(sdata->dev, frame_buf, | 4049 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
4055 | sizeof(frame_buf)); | 4050 | sizeof(frame_buf)); |
4056 | } | 4051 | } |
4057 | 4052 | ||
4058 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { | 4053 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { |
@@ -4199,6 +4194,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4199 | 4194 | ||
4200 | ifmgd->assoc_data = assoc_data; | 4195 | ifmgd->assoc_data = assoc_data; |
4201 | ifmgd->dtim_period = 0; | 4196 | ifmgd->dtim_period = 0; |
4197 | ifmgd->have_beacon = false; | ||
4202 | 4198 | ||
4203 | err = ieee80211_prep_connection(sdata, req->bss, true); | 4199 | err = ieee80211_prep_connection(sdata, req->bss, true); |
4204 | if (err) | 4200 | if (err) |
@@ -4230,7 +4226,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
4230 | ifmgd->dtim_period = tim->dtim_period; | 4226 | ifmgd->dtim_period = tim->dtim_period; |
4231 | dtim_count = tim->dtim_count; | 4227 | dtim_count = tim->dtim_count; |
4232 | } | 4228 | } |
4233 | assoc_data->have_beacon = true; | 4229 | ifmgd->have_beacon = true; |
4234 | assoc_data->timeout = jiffies; | 4230 | assoc_data->timeout = jiffies; |
4235 | assoc_data->timeout_started = true; | 4231 | assoc_data->timeout_started = true; |
4236 | 4232 | ||
@@ -4305,8 +4301,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
4305 | 4301 | ||
4306 | out: | 4302 | out: |
4307 | if (report_frame) | 4303 | if (report_frame) |
4308 | cfg80211_send_deauth(sdata->dev, frame_buf, | 4304 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
4309 | IEEE80211_DEAUTH_FRAME_LEN); | 4305 | IEEE80211_DEAUTH_FRAME_LEN); |
4310 | 4306 | ||
4311 | return 0; | 4307 | return 0; |
4312 | } | 4308 | } |
@@ -4336,8 +4332,8 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
4336 | req->reason_code, !req->local_state_change, | 4332 | req->reason_code, !req->local_state_change, |
4337 | frame_buf); | 4333 | frame_buf); |
4338 | 4334 | ||
4339 | cfg80211_send_disassoc(sdata->dev, frame_buf, | 4335 | cfg80211_tx_mlme_mgmt(sdata->dev, frame_buf, |
4340 | IEEE80211_DEAUTH_FRAME_LEN); | 4336 | IEEE80211_DEAUTH_FRAME_LEN); |
4341 | 4337 | ||
4342 | return 0; | 4338 | return 0; |
4343 | } | 4339 | } |
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 89a83770d152..5a6c1351d1d3 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); |