Skip to content

Commit

Permalink
mac80211: fix short slot handling
Browse files Browse the repository at this point in the history
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: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Oct 31, 2008
1 parent e87a2fe commit 7a5158e
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 49 deletions.
28 changes: 16 additions & 12 deletions include/net/mac80211.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,8 +180,12 @@ enum ieee80211_bss_change {
* @assoc: association status
* @aid: association ID number, valid only when @assoc is true
* @use_cts_prot: use CTS protection
* @use_short_preamble: use 802.11b short preamble
* @use_short_slot: use short slot time (only relevant for ERP)
* @use_short_preamble: use 802.11b short preamble;
* 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
* @timestamp: beacon timestamp
* @beacon_int: beacon interval
Expand Down Expand Up @@ -442,23 +446,23 @@ struct ieee80211_rx_status {
*
* 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_SUPPORT_HT_MODE: use 802.11n HT capabilities (if supported)
* @IEEE80211_CONF_PS: Enable 802.11 power save mode
*/
enum ieee80211_conf_flags {
/*
* TODO: IEEE80211_CONF_SHORT_SLOT_TIME will be removed once drivers
* have been converted to use bss_info_changed() for slot time
* 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),
IEEE80211_CONF_RADIOTAP = (1<<0),
IEEE80211_CONF_SUPPORT_HT_MODE = (1<<1),
IEEE80211_CONF_PS = (1<<2),
};

/* 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
*
Expand Down
9 changes: 6 additions & 3 deletions net/mac80211/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
sdata->bss_conf.use_cts_prot = 0;
sdata->bss_conf.use_short_preamble = 0;
return BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_ERP_PREAMBLE;
sdata->bss_conf.use_cts_prot = false;
sdata->bss_conf.use_short_preamble = false;
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,
Expand Down
74 changes: 40 additions & 34 deletions net/mac80211/mlme.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
bool use_protection,
bool use_short_preamble)
static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
u16 capab, bool erp_valid, u8 erp)
{
struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
struct ieee80211_if_sta *ifsta = &sdata->u.sta;
#endif
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) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
Expand Down Expand Up @@ -605,30 +617,18 @@ static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
changed |= BSS_CHANGED_ERP_PREAMBLE;
}

return changed;
}

static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
u8 erp_value)
{
bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;

return ieee80211_handle_protect_preamb(sdata,
use_protection, use_short_preamble);
}

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);
if (use_short_slot != bss_conf->use_short_slot) {
#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
if (net_ratelimit()) {
printk(KERN_DEBUG "%s: switched to %s slot"
" (BSSID=%s)\n",
sdata->dev->name,
use_short_slot ? "short" : "long",
ifsta->bssid);
}
#endif
bss_conf->use_short_slot = use_short_slot;
changed |= BSS_CHANGED_ERP_SLOT;
}

return changed;
Expand Down Expand Up @@ -721,7 +721,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
sdata->bss_conf.timestamp = bss->timestamp;
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);
}
Expand Down Expand Up @@ -1657,6 +1658,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
struct ieee80211_local *local = sdata->local;
struct ieee80211_conf *conf = &local->hw.conf;
u32 changed = 0;
bool erp_valid;
u8 erp_value = 0;

/* Process beacon from the current BSS */
baselen = (u8 *) mgmt->u.beacon.variable - (u8 *) mgmt;
Expand All @@ -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,
elems.wmm_param_len);

if (elems.erp_info && elems.erp_info_len >= 1)
changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
else {
u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info);
changed |= ieee80211_handle_protect_preamb(sdata, false,
(capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);

if (elems.erp_info && elems.erp_info_len >= 1) {
erp_valid = true;
erp_value = elems.erp_info[0];
} else {
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 &&
elems.wmm_param && conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
Expand Down

0 comments on commit 7a5158e

Please sign in to comment.