diff options
author | John W. Linville <linville@tuxdriver.com> | 2011-02-22 15:10:22 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-22 15:10:22 -0500 |
commit | 5db5e44cdcdc5ee9cc821bd4d63445af0bb34bce (patch) | |
tree | b5e5787a6d5c15e589d275c7434ebbf341257234 /net/mac80211 | |
parent | db62983a1e4b2af9e79c97af768f0c8b80bd93f0 (diff) | |
parent | 320d6c1b56de5f461c6062625b9664095f90ee95 (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/Kconfig | 2 | ||||
-rw-r--r-- | net/mac80211/cfg.c | 1 | ||||
-rw-r--r-- | net/mac80211/debugfs.c | 6 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 11 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 2 | ||||
-rw-r--r-- | net/mac80211/main.c | 33 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 8 | ||||
-rw-r--r-- | net/mac80211/rx.c | 12 | ||||
-rw-r--r-- | net/mac80211/scan.c | 15 | ||||
-rw-r--r-- | net/mac80211/tx.c | 1 | ||||
-rw-r--r-- | net/mac80211/util.c | 6 | ||||
-rw-r--r-- | net/mac80211/work.c | 59 |
12 files changed, 113 insertions, 43 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index c766056d0488..dbf5e4006bc1 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -17,7 +17,7 @@ comment "CFG80211 needs to be enabled for MAC80211" | |||
17 | if MAC80211 != n | 17 | if MAC80211 != n |
18 | 18 | ||
19 | config MAC80211_HAS_RC | 19 | config MAC80211_HAS_RC |
20 | def_bool n | 20 | bool |
21 | 21 | ||
22 | config MAC80211_RC_PID | 22 | config MAC80211_RC_PID |
23 | bool "PID controller based rate control algorithm" if EXPERT | 23 | bool "PID controller based rate control algorithm" if EXPERT |
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 2ba3af850dda..140503d4c97a 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -1863,6 +1863,7 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
1863 | 1863 | ||
1864 | wk->type = IEEE80211_WORK_OFFCHANNEL_TX; | 1864 | wk->type = IEEE80211_WORK_OFFCHANNEL_TX; |
1865 | wk->chan = chan; | 1865 | wk->chan = chan; |
1866 | wk->chan_type = channel_type; | ||
1866 | wk->sdata = sdata; | 1867 | wk->sdata = sdata; |
1867 | wk->done = ieee80211_offchan_tx_done; | 1868 | wk->done = ieee80211_offchan_tx_done; |
1868 | wk->offchan_tx.frame = skb; | 1869 | wk->offchan_tx.frame = skb; |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 1f02e599a318..51f0d780dafa 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -60,6 +60,10 @@ static const struct file_operations name## _ops = { \ | |||
60 | debugfs_create_file(#name, mode, phyd, local, &name## _ops); | 60 | debugfs_create_file(#name, mode, phyd, local, &name## _ops); |
61 | 61 | ||
62 | 62 | ||
63 | DEBUGFS_READONLY_FILE(user_power, "%d", | ||
64 | local->user_power_level); | ||
65 | DEBUGFS_READONLY_FILE(power, "%d", | ||
66 | local->hw.conf.power_level); | ||
63 | DEBUGFS_READONLY_FILE(frequency, "%d", | 67 | DEBUGFS_READONLY_FILE(frequency, "%d", |
64 | local->hw.conf.channel->center_freq); | 68 | local->hw.conf.channel->center_freq); |
65 | DEBUGFS_READONLY_FILE(total_ps_buffered, "%d", | 69 | DEBUGFS_READONLY_FILE(total_ps_buffered, "%d", |
@@ -391,6 +395,8 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
391 | DEBUGFS_ADD(uapsd_queues); | 395 | DEBUGFS_ADD(uapsd_queues); |
392 | DEBUGFS_ADD(uapsd_max_sp_len); | 396 | DEBUGFS_ADD(uapsd_max_sp_len); |
393 | DEBUGFS_ADD(channel_type); | 397 | DEBUGFS_ADD(channel_type); |
398 | DEBUGFS_ADD(user_power); | ||
399 | DEBUGFS_ADD(power); | ||
394 | 400 | ||
395 | statsd = debugfs_create_dir("statistics", phyd); | 401 | statsd = debugfs_create_dir("statistics", phyd); |
396 | 402 | ||
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 775fb63471c4..a42aa61269ea 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -664,12 +664,13 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
664 | } | 664 | } |
665 | 665 | ||
666 | static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | 666 | static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, |
667 | struct ieee80211_mgmt *mgmt, | 667 | struct sk_buff *req) |
668 | size_t len) | ||
669 | { | 668 | { |
669 | struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(req); | ||
670 | struct ieee80211_mgmt *mgmt = (void *)req->data; | ||
670 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | 671 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; |
671 | struct ieee80211_local *local = sdata->local; | 672 | struct ieee80211_local *local = sdata->local; |
672 | int tx_last_beacon; | 673 | int tx_last_beacon, len = req->len; |
673 | struct sk_buff *skb; | 674 | struct sk_buff *skb; |
674 | struct ieee80211_mgmt *resp; | 675 | struct ieee80211_mgmt *resp; |
675 | u8 *pos, *end; | 676 | u8 *pos, *end; |
@@ -689,7 +690,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
689 | mgmt->bssid, tx_last_beacon); | 690 | mgmt->bssid, tx_last_beacon); |
690 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 691 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
691 | 692 | ||
692 | if (!tx_last_beacon) | 693 | if (!tx_last_beacon && !(rx_status->rx_flags & IEEE80211_RX_RA_MATCH)) |
693 | return; | 694 | return; |
694 | 695 | ||
695 | if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 && | 696 | if (memcmp(mgmt->bssid, ifibss->bssid, ETH_ALEN) != 0 && |
@@ -786,7 +787,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
786 | 787 | ||
787 | switch (fc & IEEE80211_FCTL_STYPE) { | 788 | switch (fc & IEEE80211_FCTL_STYPE) { |
788 | case IEEE80211_STYPE_PROBE_REQ: | 789 | case IEEE80211_STYPE_PROBE_REQ: |
789 | ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len); | 790 | ieee80211_rx_mgmt_probe_req(sdata, skb); |
790 | break; | 791 | break; |
791 | case IEEE80211_STYPE_PROBE_RESP: | 792 | case IEEE80211_STYPE_PROBE_RESP: |
792 | ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, | 793 | ieee80211_rx_mgmt_probe_resp(sdata, mgmt, skb->len, |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f2ef15d910a5..0a570a111a84 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -1066,8 +1066,6 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
1066 | void ieee80211_configure_filter(struct ieee80211_local *local); | 1066 | void ieee80211_configure_filter(struct ieee80211_local *local); |
1067 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); | 1067 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata); |
1068 | 1068 | ||
1069 | extern bool ieee80211_disable_40mhz_24ghz; | ||
1070 | |||
1071 | /* STA code */ | 1069 | /* STA code */ |
1072 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); | 1070 | void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata); |
1073 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | 1071 | int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index c155c0b69426..2543e48bd813 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -34,7 +34,7 @@ | |||
34 | #include "debugfs.h" | 34 | #include "debugfs.h" |
35 | 35 | ||
36 | 36 | ||
37 | bool ieee80211_disable_40mhz_24ghz; | 37 | static bool ieee80211_disable_40mhz_24ghz; |
38 | module_param(ieee80211_disable_40mhz_24ghz, bool, 0644); | 38 | module_param(ieee80211_disable_40mhz_24ghz, bool, 0644); |
39 | MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz, | 39 | MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz, |
40 | "Disable 40MHz support in the 2.4GHz band"); | 40 | "Disable 40MHz support in the 2.4GHz band"); |
@@ -112,7 +112,13 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) | |||
112 | /* This logic needs to match logic in ieee80211_hw_config */ | 112 | /* This logic needs to match logic in ieee80211_hw_config */ |
113 | if (local->scan_channel) { | 113 | if (local->scan_channel) { |
114 | chan = local->scan_channel; | 114 | chan = local->scan_channel; |
115 | channel_type = NL80211_CHAN_NO_HT; | 115 | /* If scanning on oper channel, use whatever channel-type |
116 | * is currently in use. | ||
117 | */ | ||
118 | if (chan == local->oper_channel) | ||
119 | channel_type = local->_oper_channel_type; | ||
120 | else | ||
121 | channel_type = NL80211_CHAN_NO_HT; | ||
116 | } else if (local->tmp_channel) { | 122 | } else if (local->tmp_channel) { |
117 | chan = scan_chan = local->tmp_channel; | 123 | chan = scan_chan = local->tmp_channel; |
118 | channel_type = local->tmp_channel_type; | 124 | channel_type = local->tmp_channel_type; |
@@ -151,7 +157,13 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
151 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; | 157 | offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; |
152 | if (scan_chan) { | 158 | if (scan_chan) { |
153 | chan = scan_chan; | 159 | chan = scan_chan; |
154 | channel_type = NL80211_CHAN_NO_HT; | 160 | /* If scanning on oper channel, use whatever channel-type |
161 | * is currently in use. | ||
162 | */ | ||
163 | if (chan == local->oper_channel) | ||
164 | channel_type = local->_oper_channel_type; | ||
165 | else | ||
166 | channel_type = NL80211_CHAN_NO_HT; | ||
155 | } else if (local->tmp_channel) { | 167 | } else if (local->tmp_channel) { |
156 | chan = scan_chan = local->tmp_channel; | 168 | chan = scan_chan = local->tmp_channel; |
157 | channel_type = local->tmp_channel_type; | 169 | channel_type = local->tmp_channel_type; |
@@ -187,7 +199,8 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
187 | changed |= IEEE80211_CONF_CHANGE_SMPS; | 199 | changed |= IEEE80211_CONF_CHANGE_SMPS; |
188 | } | 200 | } |
189 | 201 | ||
190 | if (scan_chan) | 202 | if ((local->scanning & SCAN_SW_SCANNING) || |
203 | (local->scanning & SCAN_HW_SCANNING)) | ||
191 | power = chan->max_power; | 204 | power = chan->max_power; |
192 | else | 205 | else |
193 | power = local->power_constr_level ? | 206 | power = local->power_constr_level ? |
@@ -710,6 +723,18 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
710 | } | 723 | } |
711 | channels += sband->n_channels; | 724 | channels += sband->n_channels; |
712 | 725 | ||
726 | /* | ||
727 | * Since ieee80211_disable_40mhz_24ghz is global, we can | ||
728 | * modify the sband's ht data even if the driver uses a | ||
729 | * global structure for that. | ||
730 | */ | ||
731 | if (ieee80211_disable_40mhz_24ghz && | ||
732 | band == IEEE80211_BAND_2GHZ && | ||
733 | sband->ht_cap.ht_supported) { | ||
734 | sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
735 | sband->ht_cap.cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
736 | } | ||
737 | |||
713 | if (max_bitrates < sband->n_bitrates) | 738 | if (max_bitrates < sband->n_bitrates) |
714 | max_bitrates = sband->n_bitrates; | 739 | max_bitrates = sband->n_bitrates; |
715 | supp_ht = supp_ht || sband->ht_cap.ht_supported; | 740 | supp_ht = supp_ht || sband->ht_cap.ht_supported; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index f77adf1a520e..7b3f9df725bd 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1071,6 +1071,12 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata, | |||
1071 | if (is_multicast_ether_addr(hdr->addr1)) | 1071 | if (is_multicast_ether_addr(hdr->addr1)) |
1072 | return; | 1072 | return; |
1073 | 1073 | ||
1074 | /* | ||
1075 | * In case we receive frames after disassociation. | ||
1076 | */ | ||
1077 | if (!sdata->u.mgd.associated) | ||
1078 | return; | ||
1079 | |||
1074 | ieee80211_sta_reset_conn_monitor(sdata); | 1080 | ieee80211_sta_reset_conn_monitor(sdata); |
1075 | } | 1081 | } |
1076 | 1082 | ||
@@ -2294,6 +2300,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
2294 | else | 2300 | else |
2295 | wk->type = IEEE80211_WORK_DIRECT_PROBE; | 2301 | wk->type = IEEE80211_WORK_DIRECT_PROBE; |
2296 | wk->chan = req->bss->channel; | 2302 | wk->chan = req->bss->channel; |
2303 | wk->chan_type = NL80211_CHAN_NO_HT; | ||
2297 | wk->sdata = sdata; | 2304 | wk->sdata = sdata; |
2298 | wk->done = ieee80211_probe_auth_done; | 2305 | wk->done = ieee80211_probe_auth_done; |
2299 | 2306 | ||
@@ -2443,6 +2450,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
2443 | memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); | 2450 | memcpy(wk->assoc.prev_bssid, req->prev_bssid, ETH_ALEN); |
2444 | 2451 | ||
2445 | wk->chan = req->bss->channel; | 2452 | wk->chan = req->bss->channel; |
2453 | wk->chan_type = NL80211_CHAN_NO_HT; | ||
2446 | wk->sdata = sdata; | 2454 | wk->sdata = sdata; |
2447 | wk->done = ieee80211_assoc_done; | 2455 | wk->done = ieee80211_assoc_done; |
2448 | if (!bss->dtim_period && | 2456 | if (!bss->dtim_period && |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 045b2fe4a414..f502634d43af 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -832,18 +832,8 @@ ieee80211_rx_h_check(struct ieee80211_rx_data *rx) | |||
832 | ieee80211_is_pspoll(hdr->frame_control)) && | 832 | ieee80211_is_pspoll(hdr->frame_control)) && |
833 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && | 833 | rx->sdata->vif.type != NL80211_IFTYPE_ADHOC && |
834 | rx->sdata->vif.type != NL80211_IFTYPE_WDS && | 834 | rx->sdata->vif.type != NL80211_IFTYPE_WDS && |
835 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) { | 835 | (!rx->sta || !test_sta_flags(rx->sta, WLAN_STA_ASSOC)))) |
836 | if ((!ieee80211_has_fromds(hdr->frame_control) && | ||
837 | !ieee80211_has_tods(hdr->frame_control) && | ||
838 | ieee80211_is_data(hdr->frame_control)) || | ||
839 | !(status->rx_flags & IEEE80211_RX_RA_MATCH)) { | ||
840 | /* Drop IBSS frames and frames for other hosts | ||
841 | * silently. */ | ||
842 | return RX_DROP_MONITOR; | ||
843 | } | ||
844 | |||
845 | return RX_DROP_MONITOR; | 836 | return RX_DROP_MONITOR; |
846 | } | ||
847 | 837 | ||
848 | return RX_CONTINUE; | 838 | return RX_CONTINUE; |
849 | } | 839 | } |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 0ea6adae3e06..842954509925 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -307,11 +307,15 @@ static void __ieee80211_scan_completed_finish(struct ieee80211_hw *hw, | |||
307 | mutex_lock(&local->mtx); | 307 | mutex_lock(&local->mtx); |
308 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | 308 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); |
309 | 309 | ||
310 | WARN_ON(local->scanning & (SCAN_SW_SCANNING | SCAN_HW_SCANNING)); | ||
311 | |||
310 | if (was_hw_scan || !on_oper_chan) { | 312 | if (was_hw_scan || !on_oper_chan) { |
311 | if (WARN_ON(local->scan_channel)) | 313 | if (WARN_ON(local->scan_channel)) |
312 | local->scan_channel = NULL; | 314 | local->scan_channel = NULL; |
313 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 315 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
314 | } | 316 | } else |
317 | /* Set power back to normal operating levels. */ | ||
318 | ieee80211_hw_config(local, 0); | ||
315 | 319 | ||
316 | if (!was_hw_scan) { | 320 | if (!was_hw_scan) { |
317 | bool on_oper_chan2; | 321 | bool on_oper_chan2; |
@@ -377,6 +381,9 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
377 | 381 | ||
378 | ieee80211_configure_filter(local); | 382 | ieee80211_configure_filter(local); |
379 | 383 | ||
384 | /* We need to set power level at maximum rate for scanning. */ | ||
385 | ieee80211_hw_config(local, 0); | ||
386 | |||
380 | ieee80211_queue_delayed_work(&local->hw, | 387 | ieee80211_queue_delayed_work(&local->hw, |
381 | &local->scan_work, | 388 | &local->scan_work, |
382 | IEEE80211_CHANNEL_TIME); | 389 | IEEE80211_CHANNEL_TIME); |
@@ -517,8 +524,7 @@ static void ieee80211_scan_state_decision(struct ieee80211_local *local, | |||
517 | 524 | ||
518 | if (ieee80211_cfg_on_oper_channel(local)) { | 525 | if (ieee80211_cfg_on_oper_channel(local)) { |
519 | /* We're currently on operating channel. */ | 526 | /* We're currently on operating channel. */ |
520 | if ((next_chan == local->oper_channel) && | 527 | if (next_chan == local->oper_channel) |
521 | (local->_oper_channel_type == NL80211_CHAN_NO_HT)) | ||
522 | /* We don't need to move off of operating channel. */ | 528 | /* We don't need to move off of operating channel. */ |
523 | local->next_scan_state = SCAN_SET_CHANNEL; | 529 | local->next_scan_state = SCAN_SET_CHANNEL; |
524 | else | 530 | else |
@@ -620,8 +626,7 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, | |||
620 | local->scan_channel = chan; | 626 | local->scan_channel = chan; |
621 | 627 | ||
622 | /* Only call hw-config if we really need to change channels. */ | 628 | /* Only call hw-config if we really need to change channels. */ |
623 | if ((chan != local->hw.conf.channel) || | 629 | if (chan != local->hw.conf.channel) |
624 | (local->hw.conf.channel_type != NL80211_CHAN_NO_HT)) | ||
625 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) | 630 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) |
626 | skip = 1; | 631 | skip = 1; |
627 | 632 | ||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 17ef4f4e8602..34edf7f22b0e 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -236,6 +236,7 @@ ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) | |||
236 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 236 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
237 | ieee80211_stop_queues_by_reason(&local->hw, | 237 | ieee80211_stop_queues_by_reason(&local->hw, |
238 | IEEE80211_QUEUE_STOP_REASON_PS); | 238 | IEEE80211_QUEUE_STOP_REASON_PS); |
239 | ifmgd->flags &= ~IEEE80211_STA_NULLFUNC_ACKED; | ||
239 | ieee80211_queue_work(&local->hw, | 240 | ieee80211_queue_work(&local->hw, |
240 | &local->dynamic_ps_disable_work); | 241 | &local->dynamic_ps_disable_work); |
241 | } | 242 | } |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index d036597aabbe..556647a910ac 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -986,12 +986,6 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
986 | u16 cap = sband->ht_cap.cap; | 986 | u16 cap = sband->ht_cap.cap; |
987 | __le16 tmp; | 987 | __le16 tmp; |
988 | 988 | ||
989 | if (ieee80211_disable_40mhz_24ghz && | ||
990 | sband->band == IEEE80211_BAND_2GHZ) { | ||
991 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
992 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
993 | } | ||
994 | |||
995 | *pos++ = WLAN_EID_HT_CAPABILITY; | 989 | *pos++ = WLAN_EID_HT_CAPABILITY; |
996 | *pos++ = sizeof(struct ieee80211_ht_cap); | 990 | *pos++ = sizeof(struct ieee80211_ht_cap); |
997 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); | 991 | memset(pos, 0, sizeof(struct ieee80211_ht_cap)); |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index 6bf787a5b38a..204f0a4db969 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
@@ -126,12 +126,6 @@ static void ieee80211_add_ht_ie(struct sk_buff *skb, const u8 *ht_info_ie, | |||
126 | 126 | ||
127 | /* determine capability flags */ | 127 | /* determine capability flags */ |
128 | 128 | ||
129 | if (ieee80211_disable_40mhz_24ghz && | ||
130 | sband->band == IEEE80211_BAND_2GHZ) { | ||
131 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | ||
132 | cap &= ~IEEE80211_HT_CAP_SGI_40; | ||
133 | } | ||
134 | |||
135 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | 129 | switch (ht_info->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
136 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 130 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
137 | if (flags & IEEE80211_CHAN_NO_HT40PLUS) { | 131 | if (flags & IEEE80211_CHAN_NO_HT40PLUS) { |
@@ -874,6 +868,44 @@ static void ieee80211_work_rx_queued_mgmt(struct ieee80211_local *local, | |||
874 | kfree_skb(skb); | 868 | kfree_skb(skb); |
875 | } | 869 | } |
876 | 870 | ||
871 | static bool ieee80211_work_ct_coexists(enum nl80211_channel_type wk_ct, | ||
872 | enum nl80211_channel_type oper_ct) | ||
873 | { | ||
874 | switch (wk_ct) { | ||
875 | case NL80211_CHAN_NO_HT: | ||
876 | return true; | ||
877 | case NL80211_CHAN_HT20: | ||
878 | if (oper_ct != NL80211_CHAN_NO_HT) | ||
879 | return true; | ||
880 | return false; | ||
881 | case NL80211_CHAN_HT40MINUS: | ||
882 | case NL80211_CHAN_HT40PLUS: | ||
883 | return (wk_ct == oper_ct); | ||
884 | } | ||
885 | WARN_ON(1); /* shouldn't get here */ | ||
886 | return false; | ||
887 | } | ||
888 | |||
889 | static enum nl80211_channel_type | ||
890 | ieee80211_calc_ct(enum nl80211_channel_type wk_ct, | ||
891 | enum nl80211_channel_type oper_ct) | ||
892 | { | ||
893 | switch (wk_ct) { | ||
894 | case NL80211_CHAN_NO_HT: | ||
895 | return oper_ct; | ||
896 | case NL80211_CHAN_HT20: | ||
897 | if (oper_ct != NL80211_CHAN_NO_HT) | ||
898 | return oper_ct; | ||
899 | return wk_ct; | ||
900 | case NL80211_CHAN_HT40MINUS: | ||
901 | case NL80211_CHAN_HT40PLUS: | ||
902 | return wk_ct; | ||
903 | } | ||
904 | WARN_ON(1); /* shouldn't get here */ | ||
905 | return wk_ct; | ||
906 | } | ||
907 | |||
908 | |||
877 | static void ieee80211_work_timer(unsigned long data) | 909 | static void ieee80211_work_timer(unsigned long data) |
878 | { | 910 | { |
879 | struct ieee80211_local *local = (void *) data; | 911 | struct ieee80211_local *local = (void *) data; |
@@ -927,14 +959,22 @@ static void ieee80211_work_work(struct work_struct *work) | |||
927 | bool on_oper_chan; | 959 | bool on_oper_chan; |
928 | bool tmp_chan_changed = false; | 960 | bool tmp_chan_changed = false; |
929 | bool on_oper_chan2; | 961 | bool on_oper_chan2; |
962 | enum nl80211_channel_type wk_ct; | ||
930 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); | 963 | on_oper_chan = ieee80211_cfg_on_oper_channel(local); |
964 | |||
965 | /* Work with existing channel type if possible. */ | ||
966 | wk_ct = wk->chan_type; | ||
967 | if (wk->chan == local->hw.conf.channel) | ||
968 | wk_ct = ieee80211_calc_ct(wk->chan_type, | ||
969 | local->hw.conf.channel_type); | ||
970 | |||
931 | if (local->tmp_channel) | 971 | if (local->tmp_channel) |
932 | if ((local->tmp_channel != wk->chan) || | 972 | if ((local->tmp_channel != wk->chan) || |
933 | (local->tmp_channel_type != wk->chan_type)) | 973 | (local->tmp_channel_type != wk_ct)) |
934 | tmp_chan_changed = true; | 974 | tmp_chan_changed = true; |
935 | 975 | ||
936 | local->tmp_channel = wk->chan; | 976 | local->tmp_channel = wk->chan; |
937 | local->tmp_channel_type = wk->chan_type; | 977 | local->tmp_channel_type = wk_ct; |
938 | /* | 978 | /* |
939 | * Leave the station vifs in awake mode if they | 979 | * Leave the station vifs in awake mode if they |
940 | * happen to be on the same channel as | 980 | * happen to be on the same channel as |
@@ -1031,7 +1071,8 @@ static void ieee80211_work_work(struct work_struct *work) | |||
1031 | continue; | 1071 | continue; |
1032 | if (wk->chan != local->tmp_channel) | 1072 | if (wk->chan != local->tmp_channel) |
1033 | continue; | 1073 | continue; |
1034 | if (wk->chan_type != local->tmp_channel_type) | 1074 | if (ieee80211_work_ct_coexists(wk->chan_type, |
1075 | local->tmp_channel_type)) | ||
1035 | continue; | 1076 | continue; |
1036 | remain_off_channel = true; | 1077 | remain_off_channel = true; |
1037 | } | 1078 | } |