aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c160
1 files changed, 74 insertions, 86 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 353b690900e9..efb22763d56d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -685,7 +685,8 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
685 if (powersave) 685 if (powersave)
686 nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); 686 nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
687 687
688 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 688 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT |
689 IEEE80211_TX_INTFL_OFFCHAN_TX_OK;
689 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 690 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
690 IEEE80211_STA_CONNECTION_POLL)) 691 IEEE80211_STA_CONNECTION_POLL))
691 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE; 692 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_USE_MINRATE;
@@ -951,39 +952,6 @@ static u32 ieee80211_handle_pwr_constr(struct ieee80211_sub_if_data *sdata,
951 return 0; 952 return 0;
952} 953}
953 954
954void ieee80211_enable_dyn_ps(struct ieee80211_vif *vif)
955{
956 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
957 struct ieee80211_local *local = sdata->local;
958 struct ieee80211_conf *conf = &local->hw.conf;
959
960 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
961 !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
962 (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));
963
964 local->disable_dynamic_ps = false;
965 conf->dynamic_ps_timeout = local->dynamic_ps_user_timeout;
966}
967EXPORT_SYMBOL(ieee80211_enable_dyn_ps);
968
969void ieee80211_disable_dyn_ps(struct ieee80211_vif *vif)
970{
971 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
972 struct ieee80211_local *local = sdata->local;
973 struct ieee80211_conf *conf = &local->hw.conf;
974
975 WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION ||
976 !(local->hw.flags & IEEE80211_HW_SUPPORTS_PS) ||
977 (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS));
978
979 local->disable_dynamic_ps = true;
980 conf->dynamic_ps_timeout = 0;
981 del_timer_sync(&local->dynamic_ps_timer);
982 ieee80211_queue_work(&local->hw,
983 &local->dynamic_ps_enable_work);
984}
985EXPORT_SYMBOL(ieee80211_disable_dyn_ps);
986
987/* powersave */ 955/* powersave */
988static void ieee80211_enable_ps(struct ieee80211_local *local, 956static void ieee80211_enable_ps(struct ieee80211_local *local,
989 struct ieee80211_sub_if_data *sdata) 957 struct ieee80211_sub_if_data *sdata)
@@ -1086,7 +1054,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
1086 } 1054 }
1087 1055
1088 if (count == 1 && ieee80211_powersave_allowed(found)) { 1056 if (count == 1 && ieee80211_powersave_allowed(found)) {
1089 struct ieee80211_conf *conf = &local->hw.conf;
1090 s32 beaconint_us; 1057 s32 beaconint_us;
1091 1058
1092 if (latency < 0) 1059 if (latency < 0)
@@ -1110,10 +1077,7 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
1110 else 1077 else
1111 timeout = 100; 1078 timeout = 100;
1112 } 1079 }
1113 local->dynamic_ps_user_timeout = timeout; 1080 local->hw.conf.dynamic_ps_timeout = timeout;
1114 if (!local->disable_dynamic_ps)
1115 conf->dynamic_ps_timeout =
1116 local->dynamic_ps_user_timeout;
1117 1081
1118 if (beaconint_us > latency) { 1082 if (beaconint_us > latency) {
1119 local->ps_sdata = NULL; 1083 local->ps_sdata = NULL;
@@ -1183,8 +1147,7 @@ void ieee80211_dynamic_ps_enable_work(struct work_struct *work)
1183 if (local->hw.conf.flags & IEEE80211_CONF_PS) 1147 if (local->hw.conf.flags & IEEE80211_CONF_PS)
1184 return; 1148 return;
1185 1149
1186 if (!local->disable_dynamic_ps && 1150 if (local->hw.conf.dynamic_ps_timeout > 0) {
1187 local->hw.conf.dynamic_ps_timeout > 0) {
1188 /* don't enter PS if TX frames are pending */ 1151 /* don't enter PS if TX frames are pending */
1189 if (drv_tx_frames_pending(local)) { 1152 if (drv_tx_frames_pending(local)) {
1190 mod_timer(&local->dynamic_ps_timer, jiffies + 1153 mod_timer(&local->dynamic_ps_timer, jiffies +
@@ -1746,7 +1709,7 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1746 1709
1747 if (beacon) 1710 if (beacon)
1748 mlme_dbg_ratelimited(sdata, 1711 mlme_dbg_ratelimited(sdata,
1749 "detected beacon loss from AP - sending probe request\n"); 1712 "detected beacon loss from AP - probing\n");
1750 1713
1751 ieee80211_cqm_rssi_notify(&sdata->vif, 1714 ieee80211_cqm_rssi_notify(&sdata->vif,
1752 NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL); 1715 NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL);
@@ -1830,7 +1793,6 @@ EXPORT_SYMBOL(ieee80211_ap_probereq_get);
1830static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) 1793static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
1831{ 1794{
1832 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1795 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1833 struct ieee80211_local *local = sdata->local;
1834 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 1796 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
1835 1797
1836 mutex_lock(&ifmgd->mtx); 1798 mutex_lock(&ifmgd->mtx);
@@ -1850,10 +1812,6 @@ static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata)
1850 * but that's not a problem. 1812 * but that's not a problem.
1851 */ 1813 */
1852 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 1814 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
1853
1854 mutex_lock(&local->mtx);
1855 ieee80211_recalc_idle(local);
1856 mutex_unlock(&local->mtx);
1857} 1815}
1858 1816
1859static void ieee80211_beacon_connection_loss_work(struct work_struct *work) 1817static void ieee80211_beacon_connection_loss_work(struct work_struct *work)
@@ -1934,7 +1892,7 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
1934 ieee80211_vif_release_channel(sdata); 1892 ieee80211_vif_release_channel(sdata);
1935 } 1893 }
1936 1894
1937 cfg80211_put_bss(auth_data->bss); 1895 cfg80211_put_bss(sdata->local->hw.wiphy, auth_data->bss);
1938 kfree(auth_data); 1896 kfree(auth_data);
1939 sdata->u.mgd.auth_data = NULL; 1897 sdata->u.mgd.auth_data = NULL;
1940} 1898}
@@ -2086,10 +2044,6 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
2086 2044
2087 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2045 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2088 2046
2089 mutex_lock(&sdata->local->mtx);
2090 ieee80211_recalc_idle(sdata->local);
2091 mutex_unlock(&sdata->local->mtx);
2092
2093 return RX_MGMT_CFG80211_DEAUTH; 2047 return RX_MGMT_CFG80211_DEAUTH;
2094} 2048}
2095 2049
@@ -2117,10 +2071,6 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
2117 2071
2118 ieee80211_set_disassoc(sdata, 0, 0, false, NULL); 2072 ieee80211_set_disassoc(sdata, 0, 0, false, NULL);
2119 2073
2120 mutex_lock(&sdata->local->mtx);
2121 ieee80211_recalc_idle(sdata->local);
2122 mutex_unlock(&sdata->local->mtx);
2123
2124 return RX_MGMT_CFG80211_DISASSOC; 2074 return RX_MGMT_CFG80211_DISASSOC;
2125} 2075}
2126 2076
@@ -2263,9 +2213,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata,
2263 if (elems.wmm_param) 2213 if (elems.wmm_param)
2264 set_sta_flag(sta, WLAN_STA_WME); 2214 set_sta_flag(sta, WLAN_STA_WME);
2265 2215
2266 err = sta_info_move_state(sta, IEEE80211_STA_AUTH); 2216 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
2267 if (!err)
2268 err = sta_info_move_state(sta, IEEE80211_STA_ASSOC);
2269 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) 2217 if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
2270 err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); 2218 err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED);
2271 if (err) { 2219 if (err) {
@@ -2387,7 +2335,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2387 if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { 2335 if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) {
2388 /* oops -- internal error -- send timeout for now */ 2336 /* oops -- internal error -- send timeout for now */
2389 ieee80211_destroy_assoc_data(sdata, false); 2337 ieee80211_destroy_assoc_data(sdata, false);
2390 cfg80211_put_bss(*bss); 2338 cfg80211_put_bss(sdata->local->hw.wiphy, *bss);
2391 return RX_MGMT_CFG80211_ASSOC_TIMEOUT; 2339 return RX_MGMT_CFG80211_ASSOC_TIMEOUT;
2392 } 2340 }
2393 sdata_info(sdata, "associated\n"); 2341 sdata_info(sdata, "associated\n");
@@ -2567,6 +2515,17 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2567 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems); 2515 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
2568 ifmgd->assoc_data->have_beacon = true; 2516 ifmgd->assoc_data->have_beacon = true;
2569 ifmgd->assoc_data->need_beacon = false; 2517 ifmgd->assoc_data->need_beacon = false;
2518 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
2519 sdata->vif.bss_conf.sync_tsf =
2520 le64_to_cpu(mgmt->u.beacon.timestamp);
2521 sdata->vif.bss_conf.sync_device_ts =
2522 rx_status->device_timestamp;
2523 if (elems.tim)
2524 sdata->vif.bss_conf.sync_dtim_count =
2525 elems.tim->dtim_count;
2526 else
2527 sdata->vif.bss_conf.sync_dtim_count = 0;
2528 }
2570 /* continue assoc process */ 2529 /* continue assoc process */
2571 ifmgd->assoc_data->timeout = jiffies; 2530 ifmgd->assoc_data->timeout = jiffies;
2572 run_again(ifmgd, ifmgd->assoc_data->timeout); 2531 run_again(ifmgd, ifmgd->assoc_data->timeout);
@@ -2641,7 +2600,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2641 2600
2642 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { 2601 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
2643 mlme_dbg_ratelimited(sdata, 2602 mlme_dbg_ratelimited(sdata,
2644 "cancelling probereq poll due to a received beacon\n"); 2603 "cancelling AP probe due to a received beacon\n");
2645 mutex_lock(&local->mtx); 2604 mutex_lock(&local->mtx);
2646 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; 2605 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
2647 ieee80211_run_deferred_scan(local); 2606 ieee80211_run_deferred_scan(local);
@@ -2725,7 +2684,7 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2725 2684
2726 /* 2685 /*
2727 * If we haven't had a beacon before, tell the driver about the 2686 * If we haven't had a beacon before, tell the driver about the
2728 * DTIM period now. 2687 * DTIM period (and beacon timing if desired) now.
2729 */ 2688 */
2730 if (!bss_conf->dtim_period) { 2689 if (!bss_conf->dtim_period) {
2731 /* a few bogus AP send dtim_period = 0 or no TIM IE */ 2690 /* a few bogus AP send dtim_period = 0 or no TIM IE */
@@ -2733,6 +2692,19 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
2733 bss_conf->dtim_period = elems.tim->dtim_period ?: 1; 2692 bss_conf->dtim_period = elems.tim->dtim_period ?: 1;
2734 else 2693 else
2735 bss_conf->dtim_period = 1; 2694 bss_conf->dtim_period = 1;
2695
2696 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
2697 sdata->vif.bss_conf.sync_tsf =
2698 le64_to_cpu(mgmt->u.beacon.timestamp);
2699 sdata->vif.bss_conf.sync_device_ts =
2700 rx_status->device_timestamp;
2701 if (elems.tim)
2702 sdata->vif.bss_conf.sync_dtim_count =
2703 elems.tim->dtim_count;
2704 else
2705 sdata->vif.bss_conf.sync_dtim_count = 0;
2706 }
2707
2736 changed |= BSS_CHANGED_DTIM_PERIOD; 2708 changed |= BSS_CHANGED_DTIM_PERIOD;
2737 } 2709 }
2738 2710
@@ -2853,7 +2825,6 @@ static void ieee80211_sta_timer(unsigned long data)
2853static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, 2825static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
2854 u8 *bssid, u8 reason, bool tx) 2826 u8 *bssid, u8 reason, bool tx)
2855{ 2827{
2856 struct ieee80211_local *local = sdata->local;
2857 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 2828 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2858 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; 2829 u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN];
2859 2830
@@ -2867,10 +2838,6 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
2867 */ 2838 */
2868 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN); 2839 cfg80211_send_deauth(sdata->dev, frame_buf, IEEE80211_DEAUTH_FRAME_LEN);
2869 2840
2870 mutex_lock(&local->mtx);
2871 ieee80211_recalc_idle(local);
2872 mutex_unlock(&local->mtx);
2873
2874 mutex_lock(&ifmgd->mtx); 2841 mutex_lock(&ifmgd->mtx);
2875} 2842}
2876 2843
@@ -3141,10 +3108,6 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3141 } 3108 }
3142 3109
3143 mutex_unlock(&ifmgd->mtx); 3110 mutex_unlock(&ifmgd->mtx);
3144
3145 mutex_lock(&local->mtx);
3146 ieee80211_recalc_idle(local);
3147 mutex_unlock(&local->mtx);
3148} 3111}
3149 3112
3150static void ieee80211_sta_bcn_mon_timer(unsigned long data) 3113static void ieee80211_sta_bcn_mon_timer(unsigned long data)
@@ -3658,15 +3621,12 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3658 return -ENOMEM; 3621 return -ENOMEM;
3659 } 3622 }
3660 3623
3661 mutex_lock(&local->mtx);
3662 ieee80211_recalc_idle(sdata->local);
3663 mutex_unlock(&local->mtx);
3664
3665 if (new_sta) { 3624 if (new_sta) {
3666 u32 rates = 0, basic_rates = 0; 3625 u32 rates = 0, basic_rates = 0;
3667 bool have_higher_than_11mbit; 3626 bool have_higher_than_11mbit;
3668 int min_rate = INT_MAX, min_rate_index = -1; 3627 int min_rate = INT_MAX, min_rate_index = -1;
3669 struct ieee80211_supported_band *sband; 3628 struct ieee80211_supported_band *sband;
3629 const struct cfg80211_bss_ies *ies;
3670 3630
3671 sband = local->hw.wiphy->bands[cbss->channel->band]; 3631 sband = local->hw.wiphy->bands[cbss->channel->band];
3672 3632
@@ -3710,8 +3670,34 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata,
3710 3670
3711 /* set timing information */ 3671 /* set timing information */
3712 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval; 3672 sdata->vif.bss_conf.beacon_int = cbss->beacon_interval;
3713 sdata->vif.bss_conf.sync_tsf = cbss->tsf; 3673 rcu_read_lock();
3714 sdata->vif.bss_conf.sync_device_ts = bss->device_ts; 3674 ies = rcu_dereference(cbss->beacon_ies);
3675 if (ies) {
3676 const u8 *tim_ie;
3677
3678 sdata->vif.bss_conf.sync_tsf = ies->tsf;
3679 sdata->vif.bss_conf.sync_device_ts =
3680 bss->device_ts_beacon;
3681 tim_ie = cfg80211_find_ie(WLAN_EID_TIM,
3682 ies->data, ies->len);
3683 if (tim_ie && tim_ie[1] >= 2)
3684 sdata->vif.bss_conf.sync_dtim_count = tim_ie[2];
3685 else
3686 sdata->vif.bss_conf.sync_dtim_count = 0;
3687 } else if (!(local->hw.flags &
3688 IEEE80211_HW_TIMING_BEACON_ONLY)) {
3689 ies = rcu_dereference(cbss->proberesp_ies);
3690 /* must be non-NULL since beacon IEs were NULL */
3691 sdata->vif.bss_conf.sync_tsf = ies->tsf;
3692 sdata->vif.bss_conf.sync_device_ts =
3693 bss->device_ts_presp;
3694 sdata->vif.bss_conf.sync_dtim_count = 0;
3695 } else {
3696 sdata->vif.bss_conf.sync_tsf = 0;
3697 sdata->vif.bss_conf.sync_device_ts = 0;
3698 sdata->vif.bss_conf.sync_dtim_count = 0;
3699 }
3700 rcu_read_unlock();
3715 3701
3716 /* tell driver about BSSID, basic rates and timing */ 3702 /* tell driver about BSSID, basic rates and timing */
3717 ieee80211_bss_info_change_notify(sdata, 3703 ieee80211_bss_info_change_notify(sdata,
@@ -3831,7 +3817,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
3831 } 3817 }
3832 3818
3833 /* hold our own reference */ 3819 /* hold our own reference */
3834 cfg80211_ref_bss(auth_data->bss); 3820 cfg80211_ref_bss(local->hw.wiphy, auth_data->bss);
3835 err = 0; 3821 err = 0;
3836 goto out_unlock; 3822 goto out_unlock;
3837 3823
@@ -4037,13 +4023,23 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
4037 const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM, 4023 const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM,
4038 beacon_ies->data, 4024 beacon_ies->data,
4039 beacon_ies->len); 4025 beacon_ies->len);
4026 u8 dtim_count = 0;
4027
4040 if (tim_ie && tim_ie[1] >= sizeof(struct ieee80211_tim_ie)) { 4028 if (tim_ie && tim_ie[1] >= sizeof(struct ieee80211_tim_ie)) {
4041 const struct ieee80211_tim_ie *tim; 4029 const struct ieee80211_tim_ie *tim;
4042 tim = (void *)(tim_ie + 2); 4030 tim = (void *)(tim_ie + 2);
4043 ifmgd->dtim_period = tim->dtim_period; 4031 ifmgd->dtim_period = tim->dtim_period;
4032 dtim_count = tim->dtim_count;
4044 } 4033 }
4045 assoc_data->have_beacon = true; 4034 assoc_data->have_beacon = true;
4046 assoc_data->timeout = jiffies; 4035 assoc_data->timeout = jiffies;
4036
4037 if (local->hw.flags & IEEE80211_HW_TIMING_BEACON_ONLY) {
4038 sdata->vif.bss_conf.sync_tsf = beacon_ies->tsf;
4039 sdata->vif.bss_conf.sync_device_ts =
4040 bss->device_ts_beacon;
4041 sdata->vif.bss_conf.sync_dtim_count = dtim_count;
4042 }
4047 } else { 4043 } else {
4048 assoc_data->timeout = jiffies; 4044 assoc_data->timeout = jiffies;
4049 } 4045 }
@@ -4115,10 +4111,6 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
4115 mutex_unlock(&ifmgd->mtx); 4111 mutex_unlock(&ifmgd->mtx);
4116 4112
4117 out: 4113 out:
4118 mutex_lock(&sdata->local->mtx);
4119 ieee80211_recalc_idle(sdata->local);
4120 mutex_unlock(&sdata->local->mtx);
4121
4122 if (sent_frame) 4114 if (sent_frame)
4123 __cfg80211_send_deauth(sdata->dev, frame_buf, 4115 __cfg80211_send_deauth(sdata->dev, frame_buf,
4124 IEEE80211_DEAUTH_FRAME_LEN); 4116 IEEE80211_DEAUTH_FRAME_LEN);
@@ -4159,10 +4151,6 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
4159 __cfg80211_send_disassoc(sdata->dev, frame_buf, 4151 __cfg80211_send_disassoc(sdata->dev, frame_buf,
4160 IEEE80211_DEAUTH_FRAME_LEN); 4152 IEEE80211_DEAUTH_FRAME_LEN);
4161 4153
4162 mutex_lock(&sdata->local->mtx);
4163 ieee80211_recalc_idle(sdata->local);
4164 mutex_unlock(&sdata->local->mtx);
4165
4166 return 0; 4154 return 0;
4167} 4155}
4168 4156