aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/mlme.c75
-rw-r--r--net/mac80211/scan.c12
3 files changed, 55 insertions, 37 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 2fcd274877d7..8563b9a5cac3 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -92,8 +92,6 @@ struct ieee80211_bss {
92 92
93 u32 device_ts; 93 u32 device_ts;
94 94
95 u8 dtim_period;
96
97 bool wmm_used; 95 bool wmm_used;
98 bool uapsd_supported; 96 bool uapsd_supported;
99 97
@@ -140,7 +138,6 @@ enum ieee80211_bss_corrupt_data_flags {
140 138
141/** 139/**
142 * enum ieee80211_valid_data_flags - BSS valid data flags 140 * enum ieee80211_valid_data_flags - BSS valid data flags
143 * @IEEE80211_BSS_VALID_DTIM: DTIM data was gathered from non-corrupt IE
144 * @IEEE80211_BSS_VALID_WMM: WMM/UAPSD data was gathered from non-corrupt IE 141 * @IEEE80211_BSS_VALID_WMM: WMM/UAPSD data was gathered from non-corrupt IE
145 * @IEEE80211_BSS_VALID_RATES: Supported rates were gathered from non-corrupt IE 142 * @IEEE80211_BSS_VALID_RATES: Supported rates were gathered from non-corrupt IE
146 * @IEEE80211_BSS_VALID_ERP: ERP flag was gathered from non-corrupt IE 143 * @IEEE80211_BSS_VALID_ERP: ERP flag was gathered from non-corrupt IE
@@ -151,7 +148,6 @@ enum ieee80211_bss_corrupt_data_flags {
151 * beacon/probe response. 148 * beacon/probe response.
152 */ 149 */
153enum ieee80211_bss_valid_data_flags { 150enum ieee80211_bss_valid_data_flags {
154 IEEE80211_BSS_VALID_DTIM = BIT(0),
155 IEEE80211_BSS_VALID_WMM = BIT(1), 151 IEEE80211_BSS_VALID_WMM = BIT(1),
156 IEEE80211_BSS_VALID_RATES = BIT(2), 152 IEEE80211_BSS_VALID_RATES = BIT(2),
157 IEEE80211_BSS_VALID_ERP = BIT(3) 153 IEEE80211_BSS_VALID_ERP = BIT(3)
@@ -440,6 +436,7 @@ struct ieee80211_if_managed {
440 unsigned long timers_running; /* used for quiesce/restart */ 436 unsigned long timers_running; /* used for quiesce/restart */
441 bool powersave; /* powersave requested for this iface */ 437 bool powersave; /* powersave requested for this iface */
442 bool broken_ap; /* AP is broken -- turn off powersave */ 438 bool broken_ap; /* AP is broken -- turn off powersave */
439 u8 dtim_period;
443 enum ieee80211_smps_mode req_smps, /* requested smps mode */ 440 enum ieee80211_smps_mode req_smps, /* requested smps mode */
444 driver_smps_mode; /* smps mode request */ 441 driver_smps_mode; /* smps mode request */
445 442
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 7753a9ca98a6..a3552929a21d 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1074,12 +1074,8 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
1074 if (beaconint_us > latency) { 1074 if (beaconint_us > latency) {
1075 local->ps_sdata = NULL; 1075 local->ps_sdata = NULL;
1076 } else { 1076 } else {
1077 struct ieee80211_bss *bss;
1078 int maxslp = 1; 1077 int maxslp = 1;
1079 u8 dtimper; 1078 u8 dtimper = found->u.mgd.dtim_period;
1080
1081 bss = (void *)found->u.mgd.associated->priv;
1082 dtimper = bss->dtim_period;
1083 1079
1084 /* If the TIM IE is invalid, pretend the value is 1 */ 1080 /* If the TIM IE is invalid, pretend the value is 1 */
1085 if (!dtimper) 1081 if (!dtimper)
@@ -1410,10 +1406,17 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
1410 1406
1411 ieee80211_led_assoc(local, 1); 1407 ieee80211_led_assoc(local, 1);
1412 1408
1413 if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) 1409 if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {
1414 bss_conf->dtim_period = bss->dtim_period; 1410 /*
1415 else 1411 * If the AP is buggy we may get here with no DTIM period
1412 * known, so assume it's 1 which is the only safe assumption
1413 * in that case, although if the TIM IE is broken powersave
1414 * probably just won't work at all.
1415 */
1416 bss_conf->dtim_period = sdata->u.mgd.dtim_period ?: 1;
1417 } else {
1416 bss_conf->dtim_period = 0; 1418 bss_conf->dtim_period = 0;
1419 }
1417 1420
1418 bss_conf->assoc = 1; 1421 bss_conf->assoc = 1;
1419 1422
@@ -1562,6 +1565,8 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata,
1562 1565
1563 sdata->u.mgd.timers_running = 0; 1566 sdata->u.mgd.timers_running = 0;
1564 1567
1568 sdata->vif.bss_conf.dtim_period = 0;
1569
1565 ifmgd->flags = 0; 1570 ifmgd->flags = 0;
1566 ieee80211_vif_release_channel(sdata); 1571 ieee80211_vif_release_channel(sdata);
1567} 1572}
@@ -2373,11 +2378,18 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
2373 struct ieee80211_channel *channel; 2378 struct ieee80211_channel *channel;
2374 bool need_ps = false; 2379 bool need_ps = false;
2375 2380
2376 if (sdata->u.mgd.associated && 2381 if ((sdata->u.mgd.associated &&
2377 ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) { 2382 ether_addr_equal(mgmt->bssid, sdata->u.mgd.associated->bssid)) ||
2378 bss = (void *)sdata->u.mgd.associated->priv; 2383 (sdata->u.mgd.assoc_data &&
2384 ether_addr_equal(mgmt->bssid,
2385 sdata->u.mgd.assoc_data->bss->bssid))) {
2379 /* not previously set so we may need to recalc */ 2386 /* not previously set so we may need to recalc */
2380 need_ps = !bss->dtim_period; 2387 need_ps = sdata->u.mgd.associated && !sdata->u.mgd.dtim_period;
2388
2389 if (elems->tim && !elems->parse_error) {
2390 struct ieee80211_tim_ie *tim_ie = elems->tim;
2391 sdata->u.mgd.dtim_period = tim_ie->dtim_period;
2392 }
2381 } 2393 }
2382 2394
2383 if (elems->ds_params && elems->ds_params_len == 1) 2395 if (elems->ds_params && elems->ds_params_len == 1)
@@ -3896,20 +3908,41 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
3896 /* kick off associate process */ 3908 /* kick off associate process */
3897 3909
3898 ifmgd->assoc_data = assoc_data; 3910 ifmgd->assoc_data = assoc_data;
3911 ifmgd->dtim_period = 0;
3899 3912
3900 err = ieee80211_prep_connection(sdata, req->bss, true); 3913 err = ieee80211_prep_connection(sdata, req->bss, true);
3901 if (err) 3914 if (err)
3902 goto err_clear; 3915 goto err_clear;
3903 3916
3904 if (!bss->dtim_period && 3917 if (sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) {
3905 sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD) { 3918 const struct cfg80211_bss_ies *beacon_ies;
3906 /* 3919
3907 * Wait up to one beacon interval ... 3920 rcu_read_lock();
3908 * should this be more if we miss one? 3921 beacon_ies = rcu_dereference(req->bss->beacon_ies);
3909 */ 3922 if (!beacon_ies) {
3910 sdata_info(sdata, "waiting for beacon from %pM\n", 3923 /*
3911 ifmgd->bssid); 3924 * Wait up to one beacon interval ...
3912 assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); 3925 * should this be more if we miss one?
3926 */
3927 sdata_info(sdata, "waiting for beacon from %pM\n",
3928 ifmgd->bssid);
3929 assoc_data->timeout =
3930 TU_TO_EXP_TIME(req->bss->beacon_interval);
3931 } else {
3932 const u8 *tim_ie = cfg80211_find_ie(WLAN_EID_TIM,
3933 beacon_ies->data,
3934 beacon_ies->len);
3935 if (tim_ie && tim_ie[1] >=
3936 sizeof(struct ieee80211_tim_ie)) {
3937 const struct ieee80211_tim_ie *tim;
3938 tim = (void *)(tim_ie + 2);
3939 ifmgd->dtim_period = tim->dtim_period;
3940 }
3941 assoc_data->have_beacon = true;
3942 assoc_data->sent_assoc = false;
3943 assoc_data->timeout = jiffies;
3944 }
3945 rcu_read_unlock();
3913 } else { 3946 } else {
3914 assoc_data->have_beacon = true; 3947 assoc_data->have_beacon = true;
3915 assoc_data->sent_assoc = false; 3948 assoc_data->sent_assoc = false;
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index de3532d18df1..d59fc6818b1c 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -113,18 +113,6 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
113 bss->valid_data |= IEEE80211_BSS_VALID_ERP; 113 bss->valid_data |= IEEE80211_BSS_VALID_ERP;
114 } 114 }
115 115
116 if (elems->tim && (!elems->parse_error ||
117 !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) {
118 struct ieee80211_tim_ie *tim_ie = elems->tim;
119 bss->dtim_period = tim_ie->dtim_period;
120 if (!elems->parse_error)
121 bss->valid_data |= IEEE80211_BSS_VALID_DTIM;
122 }
123
124 /* If the beacon had no TIM IE, or it was invalid, use 1 */
125 if (beacon && !bss->dtim_period)
126 bss->dtim_period = 1;
127
128 /* replace old supported rates if we get new values */ 116 /* replace old supported rates if we get new values */
129 if (!elems->parse_error || 117 if (!elems->parse_error ||
130 !(bss->valid_data & IEEE80211_BSS_VALID_RATES)) { 118 !(bss->valid_data & IEEE80211_BSS_VALID_RATES)) {