aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r--net/mac80211/main.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d999bf3b84e1..e323d4e6647b 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -100,7 +100,7 @@ static void ieee80211_reconfig_filter(struct work_struct *work)
100 */ 100 */
101bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local) 101bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local)
102{ 102{
103 struct ieee80211_channel *chan, *scan_chan; 103 struct ieee80211_channel *chan;
104 enum nl80211_channel_type channel_type; 104 enum nl80211_channel_type channel_type;
105 105
106 /* This logic needs to match logic in ieee80211_hw_config */ 106 /* This logic needs to match logic in ieee80211_hw_config */
@@ -114,7 +114,7 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local)
114 else 114 else
115 channel_type = NL80211_CHAN_NO_HT; 115 channel_type = NL80211_CHAN_NO_HT;
116 } else if (local->tmp_channel) { 116 } else if (local->tmp_channel) {
117 chan = scan_chan = local->tmp_channel; 117 chan = local->tmp_channel;
118 channel_type = local->tmp_channel_type; 118 channel_type = local->tmp_channel_type;
119 } else { 119 } else {
120 chan = local->oper_channel; 120 chan = local->oper_channel;
@@ -126,8 +126,8 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local)
126 return false; 126 return false;
127 127
128 /* Check current hardware-config against oper_channel. */ 128 /* Check current hardware-config against oper_channel. */
129 if ((local->oper_channel != local->hw.conf.channel) || 129 if (local->oper_channel != local->hw.conf.channel ||
130 (local->_oper_channel_type != local->hw.conf.channel_type)) 130 local->_oper_channel_type != local->hw.conf.channel_type)
131 return false; 131 return false;
132 132
133 return true; 133 return true;
@@ -135,7 +135,7 @@ bool ieee80211_cfg_on_oper_channel(struct ieee80211_local *local)
135 135
136int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 136int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
137{ 137{
138 struct ieee80211_channel *chan, *scan_chan; 138 struct ieee80211_channel *chan;
139 int ret = 0; 139 int ret = 0;
140 int power; 140 int power;
141 enum nl80211_channel_type channel_type; 141 enum nl80211_channel_type channel_type;
@@ -143,14 +143,12 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
143 143
144 might_sleep(); 144 might_sleep();
145 145
146 scan_chan = local->scan_channel;
147
148 /* If this off-channel logic ever changes, ieee80211_on_oper_channel 146 /* If this off-channel logic ever changes, ieee80211_on_oper_channel
149 * may need to change as well. 147 * may need to change as well.
150 */ 148 */
151 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; 149 offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
152 if (scan_chan) { 150 if (local->scan_channel) {
153 chan = scan_chan; 151 chan = local->scan_channel;
154 /* If scanning on oper channel, use whatever channel-type 152 /* If scanning on oper channel, use whatever channel-type
155 * is currently in use. 153 * is currently in use.
156 */ 154 */
@@ -159,7 +157,7 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
159 else 157 else
160 channel_type = NL80211_CHAN_NO_HT; 158 channel_type = NL80211_CHAN_NO_HT;
161 } else if (local->tmp_channel) { 159 } else if (local->tmp_channel) {
162 chan = scan_chan = local->tmp_channel; 160 chan = local->tmp_channel;
163 channel_type = local->tmp_channel_type; 161 channel_type = local->tmp_channel_type;
164 } else { 162 } else {
165 chan = local->oper_channel; 163 chan = local->oper_channel;
@@ -595,7 +593,10 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
595 593
596 wiphy->flags |= WIPHY_FLAG_NETNS_OK | 594 wiphy->flags |= WIPHY_FLAG_NETNS_OK |
597 WIPHY_FLAG_4ADDR_AP | 595 WIPHY_FLAG_4ADDR_AP |
598 WIPHY_FLAG_4ADDR_STATION; 596 WIPHY_FLAG_4ADDR_STATION |
597 WIPHY_FLAG_REPORTS_OBSS;
598
599 wiphy->features = NL80211_FEATURE_SK_TX_STATUS;
599 600
600 if (!ops->set_key) 601 if (!ops->set_key)
601 wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 602 wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
@@ -670,6 +671,11 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
670 INIT_WORK(&local->sched_scan_stopped_work, 671 INIT_WORK(&local->sched_scan_stopped_work,
671 ieee80211_sched_scan_stopped_work); 672 ieee80211_sched_scan_stopped_work);
672 673
674 spin_lock_init(&local->ack_status_lock);
675 idr_init(&local->ack_status_frames);
676 /* preallocate at least one entry */
677 idr_pre_get(&local->ack_status_frames, GFP_KERNEL);
678
673 sta_info_init(local); 679 sta_info_init(local);
674 680
675 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) { 681 for (i = 0; i < IEEE80211_MAX_QUEUES; i++) {
@@ -1045,6 +1051,13 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1045} 1051}
1046EXPORT_SYMBOL(ieee80211_unregister_hw); 1052EXPORT_SYMBOL(ieee80211_unregister_hw);
1047 1053
1054static int ieee80211_free_ack_frame(int id, void *p, void *data)
1055{
1056 WARN_ONCE(1, "Have pending ack frames!\n");
1057 kfree_skb(p);
1058 return 0;
1059}
1060
1048void ieee80211_free_hw(struct ieee80211_hw *hw) 1061void ieee80211_free_hw(struct ieee80211_hw *hw)
1049{ 1062{
1050 struct ieee80211_local *local = hw_to_local(hw); 1063 struct ieee80211_local *local = hw_to_local(hw);
@@ -1055,6 +1068,10 @@ void ieee80211_free_hw(struct ieee80211_hw *hw)
1055 if (local->wiphy_ciphers_allocated) 1068 if (local->wiphy_ciphers_allocated)
1056 kfree(local->hw.wiphy->cipher_suites); 1069 kfree(local->hw.wiphy->cipher_suites);
1057 1070
1071 idr_for_each(&local->ack_status_frames,
1072 ieee80211_free_ack_frame, NULL);
1073 idr_destroy(&local->ack_status_frames);
1074
1058 wiphy_free(local->hw.wiphy); 1075 wiphy_free(local->hw.wiphy);
1059} 1076}
1060EXPORT_SYMBOL(ieee80211_free_hw); 1077EXPORT_SYMBOL(ieee80211_free_hw);