aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-07-29 10:08:55 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-07-29 12:55:00 -0400
commite5b900d228b76d445a4240d9aeb3cd8f79205a91 (patch)
treedffa32e827e2d6e5388430ae5ec732f0ca023b11 /net/mac80211/mlme.c
parentd28232b461b8d54b09e59325dbac8b0913ce2049 (diff)
mac80211: allow drivers to request DTIM period
Some features require knowing the DTIM period before associating. This implements the ability to wait for a beacon in mac80211 before assoc to provide this value. It is optional since most likely not all drivers will need this. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index cf8d72196c65..b6c163ac22da 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -870,6 +870,11 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
870 870
871 ieee80211_led_assoc(local, 1); 871 ieee80211_led_assoc(local, 1);
872 872
873 if (local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
874 bss_conf->dtim_period = bss->dtim_period;
875 else
876 bss_conf->dtim_period = 0;
877
873 bss_conf->assoc = 1; 878 bss_conf->assoc = 1;
874 /* 879 /*
875 * For now just always ask the driver to update the basic rateset 880 * For now just always ask the driver to update the basic rateset
@@ -1751,7 +1756,8 @@ void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1751 if (wk->sdata != sdata) 1756 if (wk->sdata != sdata)
1752 continue; 1757 continue;
1753 1758
1754 if (wk->type != IEEE80211_WORK_ASSOC) 1759 if (wk->type != IEEE80211_WORK_ASSOC &&
1760 wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
1755 continue; 1761 continue;
1756 1762
1757 if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN)) 1763 if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN))
@@ -2086,6 +2092,8 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2086 struct sk_buff *skb) 2092 struct sk_buff *skb)
2087{ 2093{
2088 struct ieee80211_mgmt *mgmt; 2094 struct ieee80211_mgmt *mgmt;
2095 struct ieee80211_rx_status *rx_status;
2096 struct ieee802_11_elems elems;
2089 u16 status; 2097 u16 status;
2090 2098
2091 if (!skb) { 2099 if (!skb) {
@@ -2093,6 +2101,19 @@ static enum work_done_result ieee80211_assoc_done(struct ieee80211_work *wk,
2093 return WORK_DONE_DESTROY; 2101 return WORK_DONE_DESTROY;
2094 } 2102 }
2095 2103
2104 if (wk->type == IEEE80211_WORK_ASSOC_BEACON_WAIT) {
2105 mutex_lock(&wk->sdata->u.mgd.mtx);
2106 rx_status = (void *) skb->cb;
2107 ieee802_11_parse_elems(skb->data + 24 + 12, skb->len - 24 - 12, &elems);
2108 ieee80211_rx_bss_info(wk->sdata, (void *)skb->data, skb->len, rx_status,
2109 &elems, true);
2110 mutex_unlock(&wk->sdata->u.mgd.mtx);
2111
2112 wk->type = IEEE80211_WORK_ASSOC;
2113 /* not really done yet */
2114 return WORK_DONE_REQUEUE;
2115 }
2116
2096 mgmt = (void *)skb->data; 2117 mgmt = (void *)skb->data;
2097 status = le16_to_cpu(mgmt->u.assoc_resp.status_code); 2118 status = le16_to_cpu(mgmt->u.assoc_resp.status_code);
2098 2119
@@ -2206,10 +2227,14 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2206 if (req->prev_bssid) 2227 if (req->prev_bssid)
2207 memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); 2228 memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN);
2208 2229
2209 wk->type = IEEE80211_WORK_ASSOC;
2210 wk->chan = req->bss->channel; 2230 wk->chan = req->bss->channel;
2211 wk->sdata = sdata; 2231 wk->sdata = sdata;
2212 wk->done = ieee80211_assoc_done; 2232 wk->done = ieee80211_assoc_done;
2233 if (!bss->dtim_period &&
2234 sdata->local->hw.flags & IEEE80211_HW_NEED_DTIM_PERIOD)
2235 wk->type = IEEE80211_WORK_ASSOC_BEACON_WAIT;
2236 else
2237 wk->type = IEEE80211_WORK_ASSOC;
2213 2238
2214 if (req->use_mfp) { 2239 if (req->use_mfp) {
2215 ifmgd->mfp = IEEE80211_MFP_REQUIRED; 2240 ifmgd->mfp = IEEE80211_MFP_REQUIRED;
@@ -2257,7 +2282,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2257 2282
2258 if (wk->type != IEEE80211_WORK_DIRECT_PROBE && 2283 if (wk->type != IEEE80211_WORK_DIRECT_PROBE &&
2259 wk->type != IEEE80211_WORK_AUTH && 2284 wk->type != IEEE80211_WORK_AUTH &&
2260 wk->type != IEEE80211_WORK_ASSOC) 2285 wk->type != IEEE80211_WORK_ASSOC &&
2286 wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT)
2261 continue; 2287 continue;
2262 2288
2263 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) 2289 if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN))