diff options
-rw-r--r-- | net/mac80211/ieee80211_i.h | 5 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 75 | ||||
-rw-r--r-- | net/mac80211/scan.c | 12 |
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 | */ |
153 | enum ieee80211_bss_valid_data_flags { | 150 | enum 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)) { |