Commit 7a5158ef authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville

mac80211: fix short slot handling

This patch makes mac80211 handle short slot requests from the AP
properly. Also warn about uses of IEEE80211_CONF_SHORT_SLOT_TIME
and optimise out the code since it cannot ever be hit anyway.
Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent e87a2fee
...@@ -180,8 +180,12 @@ enum ieee80211_bss_change { ...@@ -180,8 +180,12 @@ enum ieee80211_bss_change {
* @assoc: association status * @assoc: association status
* @aid: association ID number, valid only when @assoc is true * @aid: association ID number, valid only when @assoc is true
* @use_cts_prot: use CTS protection * @use_cts_prot: use CTS protection
* @use_short_preamble: use 802.11b short preamble * @use_short_preamble: use 802.11b short preamble;
* @use_short_slot: use short slot time (only relevant for ERP) * if the hardware cannot handle this it must set the
* IEEE80211_HW_2GHZ_SHORT_PREAMBLE_INCAPABLE hardware flag
* @use_short_slot: use short slot time (only relevant for ERP);
* if the hardware cannot handle this it must set the
* IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE hardware flag
* @dtim_period: num of beacons before the next DTIM, for PSM * @dtim_period: num of beacons before the next DTIM, for PSM
* @timestamp: beacon timestamp * @timestamp: beacon timestamp
* @beacon_int: beacon interval * @beacon_int: beacon interval
...@@ -442,23 +446,23 @@ struct ieee80211_rx_status { ...@@ -442,23 +446,23 @@ struct ieee80211_rx_status {
* *
* Flags to define PHY configuration options * Flags to define PHY configuration options
* *
* @IEEE80211_CONF_SHORT_SLOT_TIME: use 802.11g short slot time
* @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported) * @IEEE80211_CONF_RADIOTAP: add radiotap header at receive time (if supported)
* @IEEE80211_CONF_SUPPORT_HT_MODE: use 802.11n HT capabilities (if supported) * @IEEE80211_CONF_SUPPORT_HT_MODE: use 802.11n HT capabilities (if supported)
* @IEEE80211_CONF_PS: Enable 802.11 power save mode * @IEEE80211_CONF_PS: Enable 802.11 power save mode
*/ */
enum ieee80211_conf_flags { enum ieee80211_conf_flags {
/* IEEE80211_CONF_RADIOTAP = (1<<0),
* TODO: IEEE80211_CONF_SHORT_SLOT_TIME will be removed once drivers IEEE80211_CONF_SUPPORT_HT_MODE = (1<<1),
* have been converted to use bss_info_changed() for slot time IEEE80211_CONF_PS = (1<<2),
* configuration
*/
IEEE80211_CONF_SHORT_SLOT_TIME = (1<<0),
IEEE80211_CONF_RADIOTAP = (1<<1),
IEEE80211_CONF_SUPPORT_HT_MODE = (1<<2),
IEEE80211_CONF_PS = (1<<3),
}; };
/* XXX: remove all this once drivers stop trying to use it */
static inline int __deprecated __IEEE80211_CONF_SHORT_SLOT_TIME(void)
{
return 0;
}
#define IEEE80211_CONF_SHORT_SLOT_TIME (__IEEE80211_CONF_SHORT_SLOT_TIME())
/** /**
* struct ieee80211_conf - configuration of the device * struct ieee80211_conf - configuration of the device
* *
......
...@@ -346,9 +346,12 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, ...@@ -346,9 +346,12 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata)
{ {
sdata->bss_conf.use_cts_prot = 0; sdata->bss_conf.use_cts_prot = false;
sdata->bss_conf.use_short_preamble = 0; sdata->bss_conf.use_short_preamble = false;
return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE; sdata->bss_conf.use_short_slot = false;
return BSS_CHANGED_ERP_CTS_PROT |
BSS_CHANGED_ERP_PREAMBLE |
BSS_CHANGED_ERP_SLOT;
} }
void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
......
...@@ -568,15 +568,27 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, ...@@ -568,15 +568,27 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
} }
} }
static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
bool use_protection, u16 capab, bool erp_valid, u8 erp)
bool use_short_preamble)
{ {
struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf; struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
struct ieee80211_if_sta *ifsta = &sdata->u.sta; struct ieee80211_if_sta *ifsta = &sdata->u.sta;
#endif #endif
u32 changed = 0; u32 changed = 0;
bool use_protection;
bool use_short_preamble;
bool use_short_slot;
if (erp_valid) {
use_protection = (erp & WLAN_ERP_USE_PROTECTION) != 0;
use_short_preamble = (erp & WLAN_ERP_BARKER_PREAMBLE) == 0;
} else {
use_protection = false;
use_short_preamble = !!(capab & WLAN_CAPABILITY_SHORT_PREAMBLE);
}
use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
if (use_protection != bss_conf->use_cts_prot) { if (use_protection != bss_conf->use_cts_prot) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
...@@ -605,30 +617,18 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata, ...@@ -605,30 +617,18 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
changed |= BSS_CHANGED_ERP_PREAMBLE; changed |= BSS_CHANGED_ERP_PREAMBLE;
} }
return changed; if (use_short_slot != bss_conf->use_short_slot) {
} #ifdef CONFIG_MAC80211_VERBOSE_DEBUG
if (net_ratelimit()) {
static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata, printk(KERN_DEBUG "%s: switched to %s slot"
u8 erp_value) " (BSSID=%s)\n",
{ sdata->dev->name,
bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0; use_short_slot ? "short" : "long",
bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0; ifsta->bssid);
}
return ieee80211_handle_protect_preamb(sdata, #endif
use_protection, use_short_preamble); bss_conf->use_short_slot = use_short_slot;
} changed |= BSS_CHANGED_ERP_SLOT;
static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
struct ieee80211_bss *bss)
{
u32 changed = 0;
if (bss->has_erp_value)
changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value);
else {
u16 capab = bss->capability;
changed |= ieee80211_handle_protect_preamb(sdata, false,
(capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
} }
return changed; return changed;
...@@ -721,7 +721,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, ...@@ -721,7 +721,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
sdata->bss_conf.timestamp = bss->timestamp; sdata->bss_conf.timestamp = bss->timestamp;
sdata->bss_conf.dtim_period = bss->dtim_period; sdata->bss_conf.dtim_period = bss->dtim_period;
changed |= ieee80211_handle_bss_capability(sdata, bss); changed |= ieee80211_handle_bss_capability(sdata,
bss->capability, bss->has_erp_value, bss->erp_value);
ieee80211_rx_bss_put(local, bss); ieee80211_rx_bss_put(local, bss);
} }
...@@ -1657,6 +1658,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ...@@ -1657,6 +1658,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local; struct ieee80211_local *local = sdata->local;
struct ieee80211_conf *conf = &local->hw.conf; struct ieee80211_conf *conf = &local->hw.conf;
u32 changed = 0; u32 changed = 0;
bool erp_valid;
u8 erp_value = 0;
/* Process beacon from the current BSS */ /* Process beacon from the current BSS */
baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt; baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
...@@ -1678,13 +1681,16 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, ...@@ -1678,13 +1681,16 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param, ieee80211_sta_wmm_params(local, ifsta, elems.wmm_param,
elems.wmm_param_len); elems.wmm_param_len);
if (elems.erp_info && elems.erp_info_len >= 1)
changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]); if (elems.erp_info && elems.erp_info_len >= 1) {
else { erp_valid = true;
u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info); erp_value = elems.erp_info[0];
changed |= ieee80211_handle_protect_preamb(sdata, false, } else {
(capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0); erp_valid = false;
} }
changed |= ieee80211_handle_bss_capability(sdata,
le16_to_cpu(mgmt->u.beacon.capab_info),
erp_valid, erp_value);
if (elems.ht_cap_elem && elems.ht_info_elem && if (elems.ht_cap_elem && elems.ht_info_elem &&
elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) { elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment