diff options
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r-- | net/mac80211/mlme.c | 160 |
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 | ||
954 | void 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 | } | ||
967 | EXPORT_SYMBOL(ieee80211_enable_dyn_ps); | ||
968 | |||
969 | void 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 | } | ||
985 | EXPORT_SYMBOL(ieee80211_disable_dyn_ps); | ||
986 | |||
987 | /* powersave */ | 955 | /* powersave */ |
988 | static void ieee80211_enable_ps(struct ieee80211_local *local, | 956 | static 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); | |||
1830 | static void __ieee80211_disconnect(struct ieee80211_sub_if_data *sdata) | 1793 | static 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 | ||
1859 | static void ieee80211_beacon_connection_loss_work(struct work_struct *work) | 1817 | static 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) | |||
2853 | static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata, | 2825 | static 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 | ||
3150 | static void ieee80211_sta_bcn_mon_timer(unsigned long data) | 3113 | static 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 | ||