summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/ieee80211_i.h1
-rw-r--r--net/mac80211/main.c5
-rw-r--r--net/mac80211/mlme.c39
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);
}
OpenPOWER on IntegriCloud