diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-07-29 10:08:55 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-07-29 12:55:00 -0400 |
commit | e5b900d228b76d445a4240d9aeb3cd8f79205a91 (patch) | |
tree | dffa32e827e2d6e5388430ae5ec732f0ca023b11 /net/mac80211/mlme.c | |
parent | d28232b461b8d54b09e59325dbac8b0913ce2049 (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.c | 32 |
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)) |