diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/main.c | 5 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 39 |
3 files changed, 38 insertions, 7 deletions
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index a2e200f..ec59345 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h @@ -82,6 +82,7 @@ struct ieee80211_sta_bss { u8 bssid[ETH_ALEN]; u8 ssid[IEEE80211_MAX_SSID_LEN]; + u8 dtim_period; u16 capability; /* host byte order */ enum ieee80211_band band; int freq; diff --git a/net/mac80211/main.c b/net/mac80211/main.c index a4c5b90..0c02c47 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -1689,6 +1689,11 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) if (local->hw.conf.beacon_int < 10) local->hw.conf.beacon_int = 100; + if (local->hw.max_listen_interval == 0) + local->hw.max_listen_interval = 1; + + local->hw.conf.listen_interval = local->hw.max_listen_interval; + local->wstats_flags |= local->hw.flags & (IEEE80211_HW_SIGNAL_UNSPEC | IEEE80211_HW_SIGNAL_DB | IEEE80211_HW_SIGNAL_DBM) ? diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index acb0413..e1d11c9 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -551,6 +551,7 @@ static void ieee80211_set_associated(struct net_device *dev, /* set timing information */ sdata->bss_conf.beacon_int = bss->beacon_int; sdata->bss_conf.timestamp = bss->timestamp; + sdata->bss_conf.dtim_period = bss->dtim_period; changed |= ieee80211_handle_bss_capability(sdata, bss); @@ -773,7 +774,8 @@ static void ieee80211_send_assoc(struct net_device *dev, mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, IEEE80211_STYPE_REASSOC_REQ); mgmt->u.reassoc_req.capab_info = cpu_to_le16(capab); - mgmt->u.reassoc_req.listen_interval = cpu_to_le16(1); + mgmt->u.reassoc_req.listen_interval = + cpu_to_le16(local->hw.conf.listen_interval); memcpy(mgmt->u.reassoc_req.current_ap, ifsta->prev_bssid, ETH_ALEN); } else { @@ -781,7 +783,8 @@ static void ieee80211_send_assoc(struct net_device *dev, mgmt->frame_control = IEEE80211_FC(IEEE80211_FTYPE_MGMT, IEEE80211_STYPE_ASSOC_REQ); mgmt->u.assoc_req.capab_info = cpu_to_le16(capab); - mgmt->u.assoc_req.listen_interval = cpu_to_le16(1); + mgmt->u.reassoc_req.listen_interval = + cpu_to_le16(local->hw.conf.listen_interval); } /* SSID */ @@ -2688,6 +2691,16 @@ static void ieee80211_rx_bss_info(struct net_device *dev, bss->beacon_int = le16_to_cpu(mgmt->u.beacon.beacon_int); bss->capability = le16_to_cpu(mgmt->u.beacon.capab_info); + if (elems->tim) { + struct ieee80211_tim_ie *tim_ie = + (struct ieee80211_tim_ie *)elems->tim; + bss->dtim_period = tim_ie->dtim_period; + } + + /* set default value for buggy APs */ + if (!elems->tim || bss->dtim_period == 0) + bss->dtim_period = 1; + bss->supp_rates_len = 0; if (elems->supp_rates) { clen = IEEE80211_MAX_SUPP_RATES - bss->supp_rates_len; @@ -3650,11 +3663,21 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, "%s\n", print_mac(mac, bssid), print_mac(mac2, ifsta->bssid)); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ - if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0 && - (bss = ieee80211_rx_bss_get(dev, bssid, - local->hw.conf.channel->center_freq, - ifsta->ssid, ifsta->ssid_len))) { + + if (found && memcmp(ifsta->bssid, bssid, ETH_ALEN) != 0) { int ret; + int search_freq; + + if (ifsta->flags & IEEE80211_STA_AUTO_CHANNEL_SEL) + search_freq = bss->freq; + else + search_freq = local->hw.conf.channel->center_freq; + + bss = ieee80211_rx_bss_get(dev, bssid, search_freq, + ifsta->ssid, ifsta->ssid_len); + if (!bss) + goto dont_join; + printk(KERN_DEBUG "%s: Selected IBSS BSSID %s" " based on configured SSID\n", dev->name, print_mac(mac, bssid)); @@ -3662,6 +3685,8 @@ static int ieee80211_sta_find_ibss(struct net_device *dev, ieee80211_rx_bss_put(local, bss); return ret; } + +dont_join: #ifdef CONFIG_MAC80211_IBSS_DEBUG printk(KERN_DEBUG " did not try to join ibss\n"); #endif /* CONFIG_MAC80211_IBSS_DEBUG */ @@ -3895,7 +3920,7 @@ done: if (sdata->vif.type == IEEE80211_IF_TYPE_IBSS) { struct ieee80211_if_sta *ifsta = &sdata->u.sta; if (!(ifsta->flags & IEEE80211_STA_BSSID_SET) || - (!ifsta->state == IEEE80211_IBSS_JOINED && + (!(ifsta->state == IEEE80211_IBSS_JOINED) && !ieee80211_sta_active_ibss(dev))) ieee80211_sta_find_ibss(dev, ifsta); } |