diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-07-29 14:47:07 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-07-29 14:47:07 -0400 |
commit | ae3568adf42d5d3bb3cfa505b94351c5d1ce4924 (patch) | |
tree | 112865a6e6b1e4ddf70362f3efb295c495ec85b9 /net/mac80211 | |
parent | 7f3e01fee41a322747db2d7574516d9fbd3785c0 (diff) | |
parent | b7753c8cd51dce67a0b152efb456a21ff1cc241b (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'net/mac80211')
-rw-r--r-- | net/mac80211/cfg.c | 13 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 1 | ||||
-rw-r--r-- | net/mac80211/key.c | 13 | ||||
-rw-r--r-- | net/mac80211/key.h | 3 | ||||
-rw-r--r-- | net/mac80211/main.c | 3 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 32 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel.c | 1 | ||||
-rw-r--r-- | net/mac80211/rc80211_minstrel_ht.c | 4 | ||||
-rw-r--r-- | net/mac80211/scan.c | 8 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 2 | ||||
-rw-r--r-- | net/mac80211/tx.c | 19 | ||||
-rw-r--r-- | net/mac80211/util.c | 8 | ||||
-rw-r--r-- | net/mac80211/work.c | 43 |
13 files changed, 110 insertions, 40 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index db4d9340c846..29ac8e1a509e 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -158,7 +158,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev, | |||
158 | if (mac_addr) { | 158 | if (mac_addr) { |
159 | sta = sta_info_get_bss(sdata, mac_addr); | 159 | sta = sta_info_get_bss(sdata, mac_addr); |
160 | if (!sta) { | 160 | if (!sta) { |
161 | ieee80211_key_free(key); | 161 | ieee80211_key_free(sdata->local, key); |
162 | err = -ENOENT; | 162 | err = -ENOENT; |
163 | goto out_unlock; | 163 | goto out_unlock; |
164 | } | 164 | } |
@@ -192,7 +192,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
192 | goto out_unlock; | 192 | goto out_unlock; |
193 | 193 | ||
194 | if (sta->key) { | 194 | if (sta->key) { |
195 | ieee80211_key_free(sta->key); | 195 | ieee80211_key_free(sdata->local, sta->key); |
196 | WARN_ON(sta->key); | 196 | WARN_ON(sta->key); |
197 | ret = 0; | 197 | ret = 0; |
198 | } | 198 | } |
@@ -205,7 +205,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, | |||
205 | goto out_unlock; | 205 | goto out_unlock; |
206 | } | 206 | } |
207 | 207 | ||
208 | ieee80211_key_free(sdata->keys[key_idx]); | 208 | ieee80211_key_free(sdata->local, sdata->keys[key_idx]); |
209 | WARN_ON(sdata->keys[key_idx]); | 209 | WARN_ON(sdata->keys[key_idx]); |
210 | 210 | ||
211 | ret = 0; | 211 | ret = 0; |
@@ -324,15 +324,10 @@ static int ieee80211_config_default_mgmt_key(struct wiphy *wiphy, | |||
324 | struct net_device *dev, | 324 | struct net_device *dev, |
325 | u8 key_idx) | 325 | u8 key_idx) |
326 | { | 326 | { |
327 | struct ieee80211_sub_if_data *sdata; | 327 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
328 | |||
329 | rcu_read_lock(); | ||
330 | 328 | ||
331 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | ||
332 | ieee80211_set_default_mgmt_key(sdata, key_idx); | 329 | ieee80211_set_default_mgmt_key(sdata, key_idx); |
333 | 330 | ||
334 | rcu_read_unlock(); | ||
335 | |||
336 | return 0; | 331 | return 0; |
337 | } | 332 | } |
338 | 333 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index ef470064b154..65e0ed6c2975 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -238,6 +238,7 @@ enum ieee80211_work_type { | |||
238 | IEEE80211_WORK_ABORT, | 238 | IEEE80211_WORK_ABORT, |
239 | IEEE80211_WORK_DIRECT_PROBE, | 239 | IEEE80211_WORK_DIRECT_PROBE, |
240 | IEEE80211_WORK_AUTH, | 240 | IEEE80211_WORK_AUTH, |
241 | IEEE80211_WORK_ASSOC_BEACON_WAIT, | ||
241 | IEEE80211_WORK_ASSOC, | 242 | IEEE80211_WORK_ASSOC, |
242 | IEEE80211_WORK_REMAIN_ON_CHANNEL, | 243 | IEEE80211_WORK_REMAIN_ON_CHANNEL, |
243 | }; | 244 | }; |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 50d1cff23d8e..1b9d87ed143a 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -323,13 +323,15 @@ static void __ieee80211_key_destroy(struct ieee80211_key *key) | |||
323 | if (!key) | 323 | if (!key) |
324 | return; | 324 | return; |
325 | 325 | ||
326 | ieee80211_key_disable_hw_accel(key); | 326 | if (key->local) |
327 | ieee80211_key_disable_hw_accel(key); | ||
327 | 328 | ||
328 | if (key->conf.alg == ALG_CCMP) | 329 | if (key->conf.alg == ALG_CCMP) |
329 | ieee80211_aes_key_free(key->u.ccmp.tfm); | 330 | ieee80211_aes_key_free(key->u.ccmp.tfm); |
330 | if (key->conf.alg == ALG_AES_CMAC) | 331 | if (key->conf.alg == ALG_AES_CMAC) |
331 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); | 332 | ieee80211_aes_cmac_key_free(key->u.aes_cmac.tfm); |
332 | ieee80211_debugfs_key_remove(key); | 333 | if (key->local) |
334 | ieee80211_debugfs_key_remove(key); | ||
333 | 335 | ||
334 | kfree(key); | 336 | kfree(key); |
335 | } | 337 | } |
@@ -410,15 +412,12 @@ static void __ieee80211_key_free(struct ieee80211_key *key) | |||
410 | __ieee80211_key_destroy(key); | 412 | __ieee80211_key_destroy(key); |
411 | } | 413 | } |
412 | 414 | ||
413 | void ieee80211_key_free(struct ieee80211_key *key) | 415 | void ieee80211_key_free(struct ieee80211_local *local, |
416 | struct ieee80211_key *key) | ||
414 | { | 417 | { |
415 | struct ieee80211_local *local; | ||
416 | |||
417 | if (!key) | 418 | if (!key) |
418 | return; | 419 | return; |
419 | 420 | ||
420 | local = key->sdata->local; | ||
421 | |||
422 | mutex_lock(&local->key_mtx); | 421 | mutex_lock(&local->key_mtx); |
423 | __ieee80211_key_free(key); | 422 | __ieee80211_key_free(key); |
424 | mutex_unlock(&local->key_mtx); | 423 | mutex_unlock(&local->key_mtx); |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index a3849fa3fce8..b665bbb7a471 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -135,7 +135,8 @@ struct ieee80211_key *ieee80211_key_alloc(enum ieee80211_key_alg alg, | |||
135 | void ieee80211_key_link(struct ieee80211_key *key, | 135 | void ieee80211_key_link(struct ieee80211_key *key, |
136 | struct ieee80211_sub_if_data *sdata, | 136 | struct ieee80211_sub_if_data *sdata, |
137 | struct sta_info *sta); | 137 | struct sta_info *sta); |
138 | void ieee80211_key_free(struct ieee80211_key *key); | 138 | void ieee80211_key_free(struct ieee80211_local *local, |
139 | struct ieee80211_key *key); | ||
139 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); | 140 | void ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, int idx); |
140 | void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, | 141 | void ieee80211_set_default_mgmt_key(struct ieee80211_sub_if_data *sdata, |
141 | int idx); | 142 | int idx); |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 0e95c750ded9..7cc4f913a431 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -107,12 +107,15 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
107 | if (scan_chan) { | 107 | if (scan_chan) { |
108 | chan = scan_chan; | 108 | chan = scan_chan; |
109 | channel_type = NL80211_CHAN_NO_HT; | 109 | channel_type = NL80211_CHAN_NO_HT; |
110 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | ||
110 | } else if (local->tmp_channel) { | 111 | } else if (local->tmp_channel) { |
111 | chan = scan_chan = local->tmp_channel; | 112 | chan = scan_chan = local->tmp_channel; |
112 | channel_type = local->tmp_channel_type; | 113 | channel_type = local->tmp_channel_type; |
114 | local->hw.conf.flags |= IEEE80211_CONF_OFFCHANNEL; | ||
113 | } else { | 115 | } else { |
114 | chan = local->oper_channel; | 116 | chan = local->oper_channel; |
115 | channel_type = local->_oper_channel_type; | 117 | channel_type = local->_oper_channel_type; |
118 | local->hw.conf.flags &= ~IEEE80211_CONF_OFFCHANNEL; | ||
116 | } | 119 | } |
117 | 120 | ||
118 | if (chan != local->hw.conf.channel || | 121 | if (chan != local->hw.conf.channel || |
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)) |
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index f65ce6dcc8e2..778c604d7939 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -67,7 +67,6 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix) | |||
67 | for (i = rix; i >= 0; i--) | 67 | for (i = rix; i >= 0; i--) |
68 | if (mi->r[i].rix == rix) | 68 | if (mi->r[i].rix == rix) |
69 | break; | 69 | break; |
70 | WARN_ON(i < 0); | ||
71 | return i; | 70 | return i; |
72 | } | 71 | } |
73 | 72 | ||
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index b5ace243546c..c5b465904e3b 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -636,7 +636,7 @@ minstrel_ht_update_caps(void *priv, struct ieee80211_supported_band *sband, | |||
636 | int i; | 636 | int i; |
637 | 637 | ||
638 | /* fall back to the old minstrel for legacy stations */ | 638 | /* fall back to the old minstrel for legacy stations */ |
639 | if (sta && !sta->ht_cap.ht_supported) { | 639 | if (!sta->ht_cap.ht_supported) { |
640 | msp->is_ht = false; | 640 | msp->is_ht = false; |
641 | memset(&msp->legacy, 0, sizeof(msp->legacy)); | 641 | memset(&msp->legacy, 0, sizeof(msp->legacy)); |
642 | msp->legacy.r = msp->ratelist; | 642 | msp->legacy.r = msp->ratelist; |
@@ -748,7 +748,7 @@ minstrel_ht_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) | |||
748 | return msp; | 748 | return msp; |
749 | 749 | ||
750 | error1: | 750 | error1: |
751 | kfree(msp->sample_table); | 751 | kfree(msp->ratelist); |
752 | error: | 752 | error: |
753 | kfree(msp); | 753 | kfree(msp); |
754 | return NULL; | 754 | return NULL; |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 439c98d93a79..41f20fb7e670 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -114,6 +114,10 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
114 | bss->dtim_period = tim_ie->dtim_period; | 114 | bss->dtim_period = tim_ie->dtim_period; |
115 | } | 115 | } |
116 | 116 | ||
117 | /* If the beacon had no TIM IE, or it was invalid, use 1 */ | ||
118 | if (beacon && !bss->dtim_period) | ||
119 | bss->dtim_period = 1; | ||
120 | |||
117 | /* replace old supported rates if we get new values */ | 121 | /* replace old supported rates if we get new values */ |
118 | srlen = 0; | 122 | srlen = 0; |
119 | if (elems->supp_rates) { | 123 | if (elems->supp_rates) { |
@@ -286,8 +290,6 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
286 | local->scanning = 0; | 290 | local->scanning = 0; |
287 | local->scan_channel = NULL; | 291 | local->scan_channel = NULL; |
288 | 292 | ||
289 | drv_sw_scan_complete(local); | ||
290 | |||
291 | /* we only have to protect scan_req and hw/sw scan */ | 293 | /* we only have to protect scan_req and hw/sw scan */ |
292 | mutex_unlock(&local->scan_mtx); | 294 | mutex_unlock(&local->scan_mtx); |
293 | 295 | ||
@@ -297,6 +299,8 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
297 | 299 | ||
298 | ieee80211_configure_filter(local); | 300 | ieee80211_configure_filter(local); |
299 | 301 | ||
302 | drv_sw_scan_complete(local); | ||
303 | |||
300 | ieee80211_offchannel_return(local, true); | 304 | ieee80211_offchannel_return(local, true); |
301 | 305 | ||
302 | done: | 306 | done: |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 67656cbf2b15..6d86f0c1ad04 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -647,7 +647,7 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
647 | return ret; | 647 | return ret; |
648 | 648 | ||
649 | if (sta->key) { | 649 | if (sta->key) { |
650 | ieee80211_key_free(sta->key); | 650 | ieee80211_key_free(local, sta->key); |
651 | WARN_ON(sta->key); | 651 | WARN_ON(sta->key); |
652 | } | 652 | } |
653 | 653 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 698d4718b1a4..c54db966926b 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -576,17 +576,6 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
576 | } | 576 | } |
577 | 577 | ||
578 | static ieee80211_tx_result debug_noinline | 578 | static ieee80211_tx_result debug_noinline |
579 | ieee80211_tx_h_sta(struct ieee80211_tx_data *tx) | ||
580 | { | ||
581 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | ||
582 | |||
583 | if (tx->sta && tx->sta->uploaded) | ||
584 | info->control.sta = &tx->sta->sta; | ||
585 | |||
586 | return TX_CONTINUE; | ||
587 | } | ||
588 | |||
589 | static ieee80211_tx_result debug_noinline | ||
590 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) | 579 | ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx) |
591 | { | 580 | { |
592 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 581 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
@@ -1307,6 +1296,11 @@ static int __ieee80211_tx(struct ieee80211_local *local, | |||
1307 | break; | 1296 | break; |
1308 | } | 1297 | } |
1309 | 1298 | ||
1299 | if (sta && sta->uploaded) | ||
1300 | info->control.sta = &sta->sta; | ||
1301 | else | ||
1302 | info->control.sta = NULL; | ||
1303 | |||
1310 | ret = drv_tx(local, skb); | 1304 | ret = drv_tx(local, skb); |
1311 | if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { | 1305 | if (WARN_ON(ret != NETDEV_TX_OK && skb->len != len)) { |
1312 | dev_kfree_skb(skb); | 1306 | dev_kfree_skb(skb); |
@@ -1346,7 +1340,6 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1346 | CALL_TXH(ieee80211_tx_h_check_assoc); | 1340 | CALL_TXH(ieee80211_tx_h_check_assoc); |
1347 | CALL_TXH(ieee80211_tx_h_ps_buf); | 1341 | CALL_TXH(ieee80211_tx_h_ps_buf); |
1348 | CALL_TXH(ieee80211_tx_h_select_key); | 1342 | CALL_TXH(ieee80211_tx_h_select_key); |
1349 | CALL_TXH(ieee80211_tx_h_sta); | ||
1350 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) | 1343 | if (!(tx->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)) |
1351 | CALL_TXH(ieee80211_tx_h_rate_ctrl); | 1344 | CALL_TXH(ieee80211_tx_h_rate_ctrl); |
1352 | 1345 | ||
@@ -1942,11 +1935,13 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1942 | h_pos += encaps_len; | 1935 | h_pos += encaps_len; |
1943 | } | 1936 | } |
1944 | 1937 | ||
1938 | #ifdef CONFIG_MAC80211_MESH | ||
1945 | if (meshhdrlen > 0) { | 1939 | if (meshhdrlen > 0) { |
1946 | memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); | 1940 | memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); |
1947 | nh_pos += meshhdrlen; | 1941 | nh_pos += meshhdrlen; |
1948 | h_pos += meshhdrlen; | 1942 | h_pos += meshhdrlen; |
1949 | } | 1943 | } |
1944 | #endif | ||
1950 | 1945 | ||
1951 | if (ieee80211_is_data_qos(fc)) { | 1946 | if (ieee80211_is_data_qos(fc)) { |
1952 | __le16 *qos_control; | 1947 | __le16 *qos_control; |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 794792177376..748387d45bc0 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -803,8 +803,12 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata) | |||
803 | 803 | ||
804 | /* after reinitialize QoS TX queues setting to default, | 804 | /* after reinitialize QoS TX queues setting to default, |
805 | * disable QoS at all */ | 805 | * disable QoS at all */ |
806 | sdata->vif.bss_conf.qos = sdata->vif.type != NL80211_IFTYPE_STATION; | 806 | |
807 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); | 807 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
808 | sdata->vif.bss_conf.qos = | ||
809 | sdata->vif.type != NL80211_IFTYPE_STATION; | ||
810 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); | ||
811 | } | ||
808 | } | 812 | } |
809 | 813 | ||
810 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, | 814 | void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index c22a71c5cb45..81d4ad64184a 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -560,6 +560,22 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk) | |||
560 | return WORK_ACT_TIMEOUT; | 560 | return WORK_ACT_TIMEOUT; |
561 | } | 561 | } |
562 | 562 | ||
563 | static enum work_action __must_check | ||
564 | ieee80211_assoc_beacon_wait(struct ieee80211_work *wk) | ||
565 | { | ||
566 | if (wk->started) | ||
567 | return WORK_ACT_TIMEOUT; | ||
568 | |||
569 | /* | ||
570 | * Wait up to one beacon interval ... | ||
571 | * should this be more if we miss one? | ||
572 | */ | ||
573 | printk(KERN_DEBUG "%s: waiting for beacon from %pM\n", | ||
574 | wk->sdata->name, wk->filter_ta); | ||
575 | wk->timeout = TU_TO_EXP_TIME(wk->assoc.bss->beacon_interval); | ||
576 | return WORK_ACT_NONE; | ||
577 | } | ||
578 | |||
563 | static void ieee80211_auth_challenge(struct ieee80211_work *wk, | 579 | static void ieee80211_auth_challenge(struct ieee80211_work *wk, |
564 | struct ieee80211_mgmt *mgmt, | 580 | struct ieee80211_mgmt *mgmt, |
565 | size_t len) | 581 | size_t len) |
@@ -709,6 +725,25 @@ ieee80211_rx_mgmt_probe_resp(struct ieee80211_work *wk, | |||
709 | return WORK_ACT_DONE; | 725 | return WORK_ACT_DONE; |
710 | } | 726 | } |
711 | 727 | ||
728 | static enum work_action __must_check | ||
729 | ieee80211_rx_mgmt_beacon(struct ieee80211_work *wk, | ||
730 | struct ieee80211_mgmt *mgmt, size_t len) | ||
731 | { | ||
732 | struct ieee80211_sub_if_data *sdata = wk->sdata; | ||
733 | struct ieee80211_local *local = sdata->local; | ||
734 | |||
735 | ASSERT_WORK_MTX(local); | ||
736 | |||
737 | if (wk->type != IEEE80211_WORK_ASSOC_BEACON_WAIT) | ||
738 | return WORK_ACT_MISMATCH; | ||
739 | |||
740 | if (len < 24 + 12) | ||
741 | return WORK_ACT_NONE; | ||
742 | |||
743 | printk(KERN_DEBUG "%s: beacon received\n", sdata->name); | ||
744 | return WORK_ACT_DONE; | ||
745 | } | ||
746 | |||
712 | static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | 747 | static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, |
713 | struct sk_buff *skb) | 748 | struct sk_buff *skb) |
714 | { | 749 | { |
@@ -731,6 +766,7 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
731 | case IEEE80211_WORK_DIRECT_PROBE: | 766 | case IEEE80211_WORK_DIRECT_PROBE: |
732 | case IEEE80211_WORK_AUTH: | 767 | case IEEE80211_WORK_AUTH: |
733 | case IEEE80211_WORK_ASSOC: | 768 | case IEEE80211_WORK_ASSOC: |
769 | case IEEE80211_WORK_ASSOC_BEACON_WAIT: | ||
734 | bssid = wk->filter_ta; | 770 | bssid = wk->filter_ta; |
735 | break; | 771 | break; |
736 | default: | 772 | default: |
@@ -745,6 +781,9 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
745 | continue; | 781 | continue; |
746 | 782 | ||
747 | switch (fc & IEEE80211_FCTL_STYPE) { | 783 | switch (fc & IEEE80211_FCTL_STYPE) { |
784 | case IEEE80211_STYPE_BEACON: | ||
785 | rma = ieee80211_rx_mgmt_beacon(wk, mgmt, skb->len); | ||
786 | break; | ||
748 | case IEEE80211_STYPE_PROBE_RESP: | 787 | case IEEE80211_STYPE_PROBE_RESP: |
749 | rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len, | 788 | rma = ieee80211_rx_mgmt_probe_resp(wk, mgmt, skb->len, |
750 | rx_status); | 789 | rx_status); |
@@ -916,6 +955,9 @@ static void ieee80211_work_work(struct work_struct *work) | |||
916 | case IEEE80211_WORK_REMAIN_ON_CHANNEL: | 955 | case IEEE80211_WORK_REMAIN_ON_CHANNEL: |
917 | rma = ieee80211_remain_on_channel_timeout(wk); | 956 | rma = ieee80211_remain_on_channel_timeout(wk); |
918 | break; | 957 | break; |
958 | case IEEE80211_WORK_ASSOC_BEACON_WAIT: | ||
959 | rma = ieee80211_assoc_beacon_wait(wk); | ||
960 | break; | ||
919 | } | 961 | } |
920 | 962 | ||
921 | wk->started = started; | 963 | wk->started = started; |
@@ -1065,6 +1107,7 @@ ieee80211_rx_result ieee80211_work_rx_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1065 | case IEEE80211_STYPE_PROBE_RESP: | 1107 | case IEEE80211_STYPE_PROBE_RESP: |
1066 | case IEEE80211_STYPE_ASSOC_RESP: | 1108 | case IEEE80211_STYPE_ASSOC_RESP: |
1067 | case IEEE80211_STYPE_REASSOC_RESP: | 1109 | case IEEE80211_STYPE_REASSOC_RESP: |
1110 | case IEEE80211_STYPE_BEACON: | ||
1068 | skb_queue_tail(&local->work_skb_queue, skb); | 1111 | skb_queue_tail(&local->work_skb_queue, skb); |
1069 | ieee80211_queue_work(&local->hw, &local->work_work); | 1112 | ieee80211_queue_work(&local->hw, &local->work_work); |
1070 | return RX_QUEUED; | 1113 | return RX_QUEUED; |