diff options
author | Johannes Berg <johannes.berg@intel.com> | 2012-07-30 03:13:03 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2012-07-30 03:13:03 -0400 |
commit | fcb06702f023a0e7b1e6ebf9746f34b610ca0508 (patch) | |
tree | db022324c4978dd9af059be38822d23455a45f55 /net/mac80211 | |
parent | 5e31fc0815a4e2c72b1b495fe7a0d8f9bfb9e4b4 (diff) | |
parent | 9dbf5f55f8d35ff9aedc75267f4e4042aaf89755 (diff) |
Merge remote-tracking branch 'wireless/master' into mac80211
Diffstat (limited to 'net/mac80211')
40 files changed, 2150 insertions, 2002 deletions
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig index 8d249d705980..63af25458fda 100644 --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig | |||
@@ -107,6 +107,19 @@ config MAC80211_DEBUGFS | |||
107 | 107 | ||
108 | Say N unless you know you need this. | 108 | Say N unless you know you need this. |
109 | 109 | ||
110 | config MAC80211_MESSAGE_TRACING | ||
111 | bool "Trace all mac80211 debug messages" | ||
112 | depends on MAC80211 | ||
113 | ---help--- | ||
114 | Select this option to have mac80211 register the | ||
115 | mac80211_msg trace subsystem with tracepoints to | ||
116 | collect all debugging messages, independent of | ||
117 | printing them into the kernel log. | ||
118 | |||
119 | The overhead in this option is that all the messages | ||
120 | need to be present in the binary and formatted at | ||
121 | runtime for tracing. | ||
122 | |||
110 | menuconfig MAC80211_DEBUG_MENU | 123 | menuconfig MAC80211_DEBUG_MENU |
111 | bool "Select mac80211 debugging features" | 124 | bool "Select mac80211 debugging features" |
112 | depends on MAC80211 | 125 | depends on MAC80211 |
@@ -140,26 +153,35 @@ config MAC80211_VERBOSE_DEBUG | |||
140 | 153 | ||
141 | Do not select this option. | 154 | Do not select this option. |
142 | 155 | ||
143 | config MAC80211_HT_DEBUG | 156 | config MAC80211_MLME_DEBUG |
144 | bool "Verbose HT debugging" | 157 | bool "Verbose managed MLME output" |
145 | depends on MAC80211_DEBUG_MENU | 158 | depends on MAC80211_DEBUG_MENU |
146 | ---help--- | 159 | ---help--- |
147 | This option enables 802.11n High Throughput features | 160 | Selecting this option causes mac80211 to print out |
148 | debug tracing output. | 161 | debugging messages for the managed-mode MLME. It |
149 | 162 | should not be selected on production systems as some | |
150 | It should not be selected on production systems as some | ||
151 | of the messages are remotely triggerable. | 163 | of the messages are remotely triggerable. |
152 | 164 | ||
153 | Do not select this option. | 165 | Do not select this option. |
154 | 166 | ||
155 | config MAC80211_TKIP_DEBUG | 167 | config MAC80211_STA_DEBUG |
156 | bool "Verbose TKIP debugging" | 168 | bool "Verbose station debugging" |
157 | depends on MAC80211_DEBUG_MENU | 169 | depends on MAC80211_DEBUG_MENU |
158 | ---help--- | 170 | ---help--- |
159 | Selecting this option causes mac80211 to print out | 171 | Selecting this option causes mac80211 to print out |
160 | very verbose TKIP debugging messages. It should not | 172 | debugging messages for station addition/removal. |
161 | be selected on production systems as those messages | 173 | |
162 | are remotely triggerable. | 174 | Do not select this option. |
175 | |||
176 | config MAC80211_HT_DEBUG | ||
177 | bool "Verbose HT debugging" | ||
178 | depends on MAC80211_DEBUG_MENU | ||
179 | ---help--- | ||
180 | This option enables 802.11n High Throughput features | ||
181 | debug tracing output. | ||
182 | |||
183 | It should not be selected on production systems as some | ||
184 | of the messages are remotely triggerable. | ||
163 | 185 | ||
164 | Do not select this option. | 186 | Do not select this option. |
165 | 187 | ||
@@ -174,7 +196,7 @@ config MAC80211_IBSS_DEBUG | |||
174 | 196 | ||
175 | Do not select this option. | 197 | Do not select this option. |
176 | 198 | ||
177 | config MAC80211_VERBOSE_PS_DEBUG | 199 | config MAC80211_PS_DEBUG |
178 | bool "Verbose powersave mode debugging" | 200 | bool "Verbose powersave mode debugging" |
179 | depends on MAC80211_DEBUG_MENU | 201 | depends on MAC80211_DEBUG_MENU |
180 | ---help--- | 202 | ---help--- |
@@ -186,7 +208,7 @@ config MAC80211_VERBOSE_PS_DEBUG | |||
186 | 208 | ||
187 | Do not select this option. | 209 | Do not select this option. |
188 | 210 | ||
189 | config MAC80211_VERBOSE_MPL_DEBUG | 211 | config MAC80211_MPL_DEBUG |
190 | bool "Verbose mesh peer link debugging" | 212 | bool "Verbose mesh peer link debugging" |
191 | depends on MAC80211_DEBUG_MENU | 213 | depends on MAC80211_DEBUG_MENU |
192 | depends on MAC80211_MESH | 214 | depends on MAC80211_MESH |
@@ -199,7 +221,7 @@ config MAC80211_VERBOSE_MPL_DEBUG | |||
199 | 221 | ||
200 | Do not select this option. | 222 | Do not select this option. |
201 | 223 | ||
202 | config MAC80211_VERBOSE_MPATH_DEBUG | 224 | config MAC80211_MPATH_DEBUG |
203 | bool "Verbose mesh path debugging" | 225 | bool "Verbose mesh path debugging" |
204 | depends on MAC80211_DEBUG_MENU | 226 | depends on MAC80211_DEBUG_MENU |
205 | depends on MAC80211_MESH | 227 | depends on MAC80211_MESH |
@@ -212,7 +234,7 @@ config MAC80211_VERBOSE_MPATH_DEBUG | |||
212 | 234 | ||
213 | Do not select this option. | 235 | Do not select this option. |
214 | 236 | ||
215 | config MAC80211_VERBOSE_MHWMP_DEBUG | 237 | config MAC80211_MHWMP_DEBUG |
216 | bool "Verbose mesh HWMP routing debugging" | 238 | bool "Verbose mesh HWMP routing debugging" |
217 | depends on MAC80211_DEBUG_MENU | 239 | depends on MAC80211_DEBUG_MENU |
218 | depends on MAC80211_MESH | 240 | depends on MAC80211_MESH |
@@ -225,7 +247,7 @@ config MAC80211_VERBOSE_MHWMP_DEBUG | |||
225 | 247 | ||
226 | Do not select this option. | 248 | Do not select this option. |
227 | 249 | ||
228 | config MAC80211_VERBOSE_MESH_SYNC_DEBUG | 250 | config MAC80211_MESH_SYNC_DEBUG |
229 | bool "Verbose mesh mesh synchronization debugging" | 251 | bool "Verbose mesh mesh synchronization debugging" |
230 | depends on MAC80211_DEBUG_MENU | 252 | depends on MAC80211_DEBUG_MENU |
231 | depends on MAC80211_MESH | 253 | depends on MAC80211_MESH |
@@ -236,7 +258,7 @@ config MAC80211_VERBOSE_MESH_SYNC_DEBUG | |||
236 | 258 | ||
237 | Do not select this option. | 259 | Do not select this option. |
238 | 260 | ||
239 | config MAC80211_VERBOSE_TDLS_DEBUG | 261 | config MAC80211_TDLS_DEBUG |
240 | bool "Verbose TDLS debugging" | 262 | bool "Verbose TDLS debugging" |
241 | depends on MAC80211_DEBUG_MENU | 263 | depends on MAC80211_DEBUG_MENU |
242 | ---help--- | 264 | ---help--- |
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile index 3e9d931bba35..a7dd110faafa 100644 --- a/net/mac80211/Makefile +++ b/net/mac80211/Makefile | |||
@@ -9,7 +9,6 @@ mac80211-y := \ | |||
9 | scan.o offchannel.o \ | 9 | scan.o offchannel.o \ |
10 | ht.o agg-tx.o agg-rx.o \ | 10 | ht.o agg-tx.o agg-rx.o \ |
11 | ibss.o \ | 11 | ibss.o \ |
12 | work.o \ | ||
13 | iface.o \ | 12 | iface.o \ |
14 | rate.o \ | 13 | rate.o \ |
15 | michael.o \ | 14 | michael.o \ |
@@ -25,7 +24,7 @@ mac80211-y := \ | |||
25 | wme.o \ | 24 | wme.o \ |
26 | event.o \ | 25 | event.o \ |
27 | chan.o \ | 26 | chan.o \ |
28 | driver-trace.o mlme.o | 27 | trace.o mlme.o |
29 | 28 | ||
30 | mac80211-$(CONFIG_MAC80211_LEDS) += led.o | 29 | mac80211-$(CONFIG_MAC80211_LEDS) += led.o |
31 | mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ | 30 | mac80211-$(CONFIG_MAC80211_DEBUGFS) += \ |
@@ -43,7 +42,7 @@ mac80211-$(CONFIG_MAC80211_MESH) += \ | |||
43 | 42 | ||
44 | mac80211-$(CONFIG_PM) += pm.o | 43 | mac80211-$(CONFIG_PM) += pm.o |
45 | 44 | ||
46 | CFLAGS_driver-trace.o := -I$(src) | 45 | CFLAGS_trace.o := -I$(src) |
47 | 46 | ||
48 | # objects for PID algorithm | 47 | # objects for PID algorithm |
49 | rc80211_pid-y := rc80211_pid_algo.o | 48 | rc80211_pid-y := rc80211_pid_algo.o |
@@ -59,4 +58,4 @@ mac80211-$(CONFIG_MAC80211_RC_PID) += $(rc80211_pid-y) | |||
59 | mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) | 58 | mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) |
60 | mac80211-$(CONFIG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y) | 59 | mac80211-$(CONFIG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y) |
61 | 60 | ||
62 | ccflags-y += -D__CHECK_ENDIAN__ | 61 | ccflags-y += -D__CHECK_ENDIAN__ -DDEBUG |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index c649188314cc..186d9919b043 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -74,18 +74,17 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
74 | 74 | ||
75 | RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL); | 75 | RCU_INIT_POINTER(sta->ampdu_mlme.tid_rx[tid], NULL); |
76 | 76 | ||
77 | #ifdef CONFIG_MAC80211_HT_DEBUG | 77 | ht_dbg(sta->sdata, |
78 | printk(KERN_DEBUG | ||
79 | "Rx BA session stop requested for %pM tid %u %s reason: %d\n", | 78 | "Rx BA session stop requested for %pM tid %u %s reason: %d\n", |
80 | sta->sta.addr, tid, | 79 | sta->sta.addr, tid, |
81 | initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", | 80 | initiator == WLAN_BACK_RECIPIENT ? "recipient" : "inititator", |
82 | (int)reason); | 81 | (int)reason); |
83 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
84 | 82 | ||
85 | if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, | 83 | if (drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_STOP, |
86 | &sta->sta, tid, NULL, 0)) | 84 | &sta->sta, tid, NULL, 0)) |
87 | printk(KERN_DEBUG "HW problem - can not stop rx " | 85 | sdata_info(sta->sdata, |
88 | "aggregation for tid %d\n", tid); | 86 | "HW problem - can not stop rx aggregation for tid %d\n", |
87 | tid); | ||
89 | 88 | ||
90 | /* check if this is a self generated aggregation halt */ | 89 | /* check if this is a self generated aggregation halt */ |
91 | if (initiator == WLAN_BACK_RECIPIENT && tx) | 90 | if (initiator == WLAN_BACK_RECIPIENT && tx) |
@@ -160,9 +159,8 @@ static void sta_rx_agg_session_timer_expired(unsigned long data) | |||
160 | } | 159 | } |
161 | rcu_read_unlock(); | 160 | rcu_read_unlock(); |
162 | 161 | ||
163 | #ifdef CONFIG_MAC80211_HT_DEBUG | 162 | ht_dbg(sta->sdata, "rx session timer expired on tid %d\n", (u16)*ptid); |
164 | printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid); | 163 | |
165 | #endif | ||
166 | set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); | 164 | set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired); |
167 | ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); | 165 | ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work); |
168 | } | 166 | } |
@@ -249,10 +247,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
249 | status = WLAN_STATUS_REQUEST_DECLINED; | 247 | status = WLAN_STATUS_REQUEST_DECLINED; |
250 | 248 | ||
251 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { | 249 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { |
252 | #ifdef CONFIG_MAC80211_HT_DEBUG | 250 | ht_dbg(sta->sdata, "Suspend in progress - Denying ADDBA request\n"); |
253 | printk(KERN_DEBUG "Suspend in progress. " | ||
254 | "Denying ADDBA request\n"); | ||
255 | #endif | ||
256 | goto end_no_lock; | 251 | goto end_no_lock; |
257 | } | 252 | } |
258 | 253 | ||
@@ -264,10 +259,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
264 | (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) || | 259 | (!(sta->sta.ht_cap.cap & IEEE80211_HT_CAP_DELAY_BA))) || |
265 | (buf_size > IEEE80211_MAX_AMPDU_BUF)) { | 260 | (buf_size > IEEE80211_MAX_AMPDU_BUF)) { |
266 | status = WLAN_STATUS_INVALID_QOS_PARAM; | 261 | status = WLAN_STATUS_INVALID_QOS_PARAM; |
267 | #ifdef CONFIG_MAC80211_HT_DEBUG | 262 | ht_dbg_ratelimited(sta->sdata, |
268 | net_dbg_ratelimited("AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", | 263 | "AddBA Req with bad params from %pM on tid %u. policy %d, buffer size %d\n", |
269 | mgmt->sa, tid, ba_policy, buf_size); | 264 | mgmt->sa, tid, ba_policy, buf_size); |
270 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
271 | goto end_no_lock; | 265 | goto end_no_lock; |
272 | } | 266 | } |
273 | /* determine default buffer size */ | 267 | /* determine default buffer size */ |
@@ -282,10 +276,9 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
282 | mutex_lock(&sta->ampdu_mlme.mtx); | 276 | mutex_lock(&sta->ampdu_mlme.mtx); |
283 | 277 | ||
284 | if (sta->ampdu_mlme.tid_rx[tid]) { | 278 | if (sta->ampdu_mlme.tid_rx[tid]) { |
285 | #ifdef CONFIG_MAC80211_HT_DEBUG | 279 | ht_dbg_ratelimited(sta->sdata, |
286 | net_dbg_ratelimited("unexpected AddBA Req from %pM on tid %u\n", | 280 | "unexpected AddBA Req from %pM on tid %u\n", |
287 | mgmt->sa, tid); | 281 | mgmt->sa, tid); |
288 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
289 | 282 | ||
290 | /* delete existing Rx BA session on the same tid */ | 283 | /* delete existing Rx BA session on the same tid */ |
291 | ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, | 284 | ___ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_RECIPIENT, |
@@ -324,10 +317,7 @@ void ieee80211_process_addba_request(struct ieee80211_local *local, | |||
324 | 317 | ||
325 | ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, | 318 | ret = drv_ampdu_action(local, sta->sdata, IEEE80211_AMPDU_RX_START, |
326 | &sta->sta, tid, &start_seq_num, 0); | 319 | &sta->sta, tid, &start_seq_num, 0); |
327 | #ifdef CONFIG_MAC80211_HT_DEBUG | 320 | ht_dbg(sta->sdata, "Rx A-MPDU request on tid %d result %d\n", tid, ret); |
328 | printk(KERN_DEBUG "Rx A-MPDU request on tid %d result %d\n", tid, ret); | ||
329 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
330 | |||
331 | if (ret) { | 321 | if (ret) { |
332 | kfree(tid_agg_rx->reorder_buf); | 322 | kfree(tid_agg_rx->reorder_buf); |
333 | kfree(tid_agg_rx->reorder_time); | 323 | kfree(tid_agg_rx->reorder_time); |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 7cf07158805c..d0deb3edae21 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
@@ -135,7 +135,8 @@ void ieee80211_send_bar(struct ieee80211_vif *vif, u8 *ra, u16 tid, u16 ssn) | |||
135 | bar->control = cpu_to_le16(bar_control); | 135 | bar->control = cpu_to_le16(bar_control); |
136 | bar->start_seq_num = cpu_to_le16(ssn); | 136 | bar->start_seq_num = cpu_to_le16(ssn); |
137 | 137 | ||
138 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 138 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT | |
139 | IEEE80211_TX_CTL_REQ_TX_STATUS; | ||
139 | ieee80211_tx_skb_tid(sdata, skb, tid); | 140 | ieee80211_tx_skb_tid(sdata, skb, tid); |
140 | } | 141 | } |
141 | EXPORT_SYMBOL(ieee80211_send_bar); | 142 | EXPORT_SYMBOL(ieee80211_send_bar); |
@@ -184,10 +185,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
184 | 185 | ||
185 | spin_unlock_bh(&sta->lock); | 186 | spin_unlock_bh(&sta->lock); |
186 | 187 | ||
187 | #ifdef CONFIG_MAC80211_HT_DEBUG | 188 | ht_dbg(sta->sdata, "Tx BA session stop requested for %pM tid %u\n", |
188 | printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n", | ||
189 | sta->sta.addr, tid); | 189 | sta->sta.addr, tid); |
190 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
191 | 190 | ||
192 | del_timer_sync(&tid_tx->addba_resp_timer); | 191 | del_timer_sync(&tid_tx->addba_resp_timer); |
193 | del_timer_sync(&tid_tx->session_timer); | 192 | del_timer_sync(&tid_tx->session_timer); |
@@ -253,17 +252,13 @@ static void sta_addba_resp_timer_expired(unsigned long data) | |||
253 | if (!tid_tx || | 252 | if (!tid_tx || |
254 | test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { | 253 | test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) { |
255 | rcu_read_unlock(); | 254 | rcu_read_unlock(); |
256 | #ifdef CONFIG_MAC80211_HT_DEBUG | 255 | ht_dbg(sta->sdata, |
257 | printk(KERN_DEBUG "timer expired on tid %d but we are not " | 256 | "timer expired on tid %d but we are not (or no longer) expecting addBA response there\n", |
258 | "(or no longer) expecting addBA response there\n", | 257 | tid); |
259 | tid); | ||
260 | #endif | ||
261 | return; | 258 | return; |
262 | } | 259 | } |
263 | 260 | ||
264 | #ifdef CONFIG_MAC80211_HT_DEBUG | 261 | ht_dbg(sta->sdata, "addBA response timer expired on tid %d\n", tid); |
265 | printk(KERN_DEBUG "addBA response timer expired on tid %d\n", tid); | ||
266 | #endif | ||
267 | 262 | ||
268 | ieee80211_stop_tx_ba_session(&sta->sta, tid); | 263 | ieee80211_stop_tx_ba_session(&sta->sta, tid); |
269 | rcu_read_unlock(); | 264 | rcu_read_unlock(); |
@@ -323,8 +318,9 @@ ieee80211_agg_splice_packets(struct ieee80211_sub_if_data *sdata, | |||
323 | 318 | ||
324 | ieee80211_stop_queue_agg(sdata, tid); | 319 | ieee80211_stop_queue_agg(sdata, tid); |
325 | 320 | ||
326 | if (WARN(!tid_tx, "TID %d gone but expected when splicing aggregates" | 321 | if (WARN(!tid_tx, |
327 | " from the pending queue\n", tid)) | 322 | "TID %d gone but expected when splicing aggregates from the pending queue\n", |
323 | tid)) | ||
328 | return; | 324 | return; |
329 | 325 | ||
330 | if (!skb_queue_empty(&tid_tx->pending)) { | 326 | if (!skb_queue_empty(&tid_tx->pending)) { |
@@ -372,10 +368,8 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) | |||
372 | ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, | 368 | ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, |
373 | &sta->sta, tid, &start_seq_num, 0); | 369 | &sta->sta, tid, &start_seq_num, 0); |
374 | if (ret) { | 370 | if (ret) { |
375 | #ifdef CONFIG_MAC80211_HT_DEBUG | 371 | ht_dbg(sdata, |
376 | printk(KERN_DEBUG "BA request denied - HW unavailable for" | 372 | "BA request denied - HW unavailable for tid %d\n", tid); |
377 | " tid %d\n", tid); | ||
378 | #endif | ||
379 | spin_lock_bh(&sta->lock); | 373 | spin_lock_bh(&sta->lock); |
380 | ieee80211_agg_splice_packets(sdata, tid_tx, tid); | 374 | ieee80211_agg_splice_packets(sdata, tid_tx, tid); |
381 | ieee80211_assign_tid_tx(sta, tid, NULL); | 375 | ieee80211_assign_tid_tx(sta, tid, NULL); |
@@ -388,9 +382,7 @@ void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid) | |||
388 | 382 | ||
389 | /* activate the timer for the recipient's addBA response */ | 383 | /* activate the timer for the recipient's addBA response */ |
390 | mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); | 384 | mod_timer(&tid_tx->addba_resp_timer, jiffies + ADDBA_RESP_INTERVAL); |
391 | #ifdef CONFIG_MAC80211_HT_DEBUG | 385 | ht_dbg(sdata, "activated addBA response timer on tid %d\n", tid); |
392 | printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid); | ||
393 | #endif | ||
394 | 386 | ||
395 | spin_lock_bh(&sta->lock); | 387 | spin_lock_bh(&sta->lock); |
396 | sta->ampdu_mlme.last_addba_req_time[tid] = jiffies; | 388 | sta->ampdu_mlme.last_addba_req_time[tid] = jiffies; |
@@ -437,9 +429,7 @@ static void sta_tx_agg_session_timer_expired(unsigned long data) | |||
437 | 429 | ||
438 | rcu_read_unlock(); | 430 | rcu_read_unlock(); |
439 | 431 | ||
440 | #ifdef CONFIG_MAC80211_HT_DEBUG | 432 | ht_dbg(sta->sdata, "tx session timer expired on tid %d\n", (u16)*ptid); |
441 | printk(KERN_DEBUG "tx session timer expired on tid %d\n", (u16)*ptid); | ||
442 | #endif | ||
443 | 433 | ||
444 | ieee80211_stop_tx_ba_session(&sta->sta, *ptid); | 434 | ieee80211_stop_tx_ba_session(&sta->sta, *ptid); |
445 | } | 435 | } |
@@ -463,10 +453,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
463 | (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) | 453 | (local->hw.flags & IEEE80211_HW_TX_AMPDU_SETUP_IN_HW)) |
464 | return -EINVAL; | 454 | return -EINVAL; |
465 | 455 | ||
466 | #ifdef CONFIG_MAC80211_HT_DEBUG | 456 | ht_dbg(sdata, "Open BA session requested for %pM tid %u\n", |
467 | printk(KERN_DEBUG "Open BA session requested for %pM tid %u\n", | ||
468 | pubsta->addr, tid); | 457 | pubsta->addr, tid); |
469 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
470 | 458 | ||
471 | if (sdata->vif.type != NL80211_IFTYPE_STATION && | 459 | if (sdata->vif.type != NL80211_IFTYPE_STATION && |
472 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && | 460 | sdata->vif.type != NL80211_IFTYPE_MESH_POINT && |
@@ -476,10 +464,8 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
476 | return -EINVAL; | 464 | return -EINVAL; |
477 | 465 | ||
478 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { | 466 | if (test_sta_flag(sta, WLAN_STA_BLOCK_BA)) { |
479 | #ifdef CONFIG_MAC80211_HT_DEBUG | 467 | ht_dbg(sdata, |
480 | printk(KERN_DEBUG "BA sessions blocked. " | 468 | "BA sessions blocked - Denying BA session request\n"); |
481 | "Denying BA session request\n"); | ||
482 | #endif | ||
483 | return -EINVAL; | 469 | return -EINVAL; |
484 | } | 470 | } |
485 | 471 | ||
@@ -497,10 +483,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
497 | */ | 483 | */ |
498 | if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && | 484 | if (sta->sdata->vif.type == NL80211_IFTYPE_ADHOC && |
499 | !sta->sta.ht_cap.ht_supported) { | 485 | !sta->sta.ht_cap.ht_supported) { |
500 | #ifdef CONFIG_MAC80211_HT_DEBUG | 486 | ht_dbg(sdata, |
501 | printk(KERN_DEBUG "BA request denied - IBSS STA %pM" | 487 | "BA request denied - IBSS STA %pM does not advertise HT support\n", |
502 | "does not advertise HT support\n", pubsta->addr); | 488 | pubsta->addr); |
503 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
504 | return -EINVAL; | 489 | return -EINVAL; |
505 | } | 490 | } |
506 | 491 | ||
@@ -520,12 +505,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
520 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_BURST_RETRIES && | 505 | if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_BURST_RETRIES && |
521 | time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + | 506 | time_before(jiffies, sta->ampdu_mlme.last_addba_req_time[tid] + |
522 | HT_AGG_RETRIES_PERIOD)) { | 507 | HT_AGG_RETRIES_PERIOD)) { |
523 | #ifdef CONFIG_MAC80211_HT_DEBUG | 508 | ht_dbg(sdata, |
524 | printk(KERN_DEBUG "BA request denied - " | 509 | "BA request denied - waiting a grace period after %d failed requests on tid %u\n", |
525 | "waiting a grace period after %d failed requests " | ||
526 | "on tid %u\n", | ||
527 | sta->ampdu_mlme.addba_req_num[tid], tid); | 510 | sta->ampdu_mlme.addba_req_num[tid], tid); |
528 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
529 | ret = -EBUSY; | 511 | ret = -EBUSY; |
530 | goto err_unlock_sta; | 512 | goto err_unlock_sta; |
531 | } | 513 | } |
@@ -533,10 +515,9 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid, | |||
533 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 515 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
534 | /* check if the TID is not in aggregation flow already */ | 516 | /* check if the TID is not in aggregation flow already */ |
535 | if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { | 517 | if (tid_tx || sta->ampdu_mlme.tid_start_tx[tid]) { |
536 | #ifdef CONFIG_MAC80211_HT_DEBUG | 518 | ht_dbg(sdata, |
537 | printk(KERN_DEBUG "BA request denied - session is not " | 519 | "BA request denied - session is not idle on tid %u\n", |
538 | "idle on tid %u\n", tid); | 520 | tid); |
539 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
540 | ret = -EAGAIN; | 521 | ret = -EAGAIN; |
541 | goto err_unlock_sta; | 522 | goto err_unlock_sta; |
542 | } | 523 | } |
@@ -591,9 +572,7 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, | |||
591 | 572 | ||
592 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 573 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
593 | 574 | ||
594 | #ifdef CONFIG_MAC80211_HT_DEBUG | 575 | ht_dbg(sta->sdata, "Aggregation is on for tid %d\n", tid); |
595 | printk(KERN_DEBUG "Aggregation is on for tid %d\n", tid); | ||
596 | #endif | ||
597 | 576 | ||
598 | drv_ampdu_action(local, sta->sdata, | 577 | drv_ampdu_action(local, sta->sdata, |
599 | IEEE80211_AMPDU_TX_OPERATIONAL, | 578 | IEEE80211_AMPDU_TX_OPERATIONAL, |
@@ -627,10 +606,8 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) | |||
627 | trace_api_start_tx_ba_cb(sdata, ra, tid); | 606 | trace_api_start_tx_ba_cb(sdata, ra, tid); |
628 | 607 | ||
629 | if (tid >= STA_TID_NUM) { | 608 | if (tid >= STA_TID_NUM) { |
630 | #ifdef CONFIG_MAC80211_HT_DEBUG | 609 | ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", |
631 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | 610 | tid, STA_TID_NUM); |
632 | tid, STA_TID_NUM); | ||
633 | #endif | ||
634 | return; | 611 | return; |
635 | } | 612 | } |
636 | 613 | ||
@@ -638,9 +615,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) | |||
638 | sta = sta_info_get_bss(sdata, ra); | 615 | sta = sta_info_get_bss(sdata, ra); |
639 | if (!sta) { | 616 | if (!sta) { |
640 | mutex_unlock(&local->sta_mtx); | 617 | mutex_unlock(&local->sta_mtx); |
641 | #ifdef CONFIG_MAC80211_HT_DEBUG | 618 | ht_dbg(sdata, "Could not find station: %pM\n", ra); |
642 | printk(KERN_DEBUG "Could not find station: %pM\n", ra); | ||
643 | #endif | ||
644 | return; | 619 | return; |
645 | } | 620 | } |
646 | 621 | ||
@@ -648,9 +623,7 @@ void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) | |||
648 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 623 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
649 | 624 | ||
650 | if (WARN_ON(!tid_tx)) { | 625 | if (WARN_ON(!tid_tx)) { |
651 | #ifdef CONFIG_MAC80211_HT_DEBUG | 626 | ht_dbg(sdata, "addBA was not requested!\n"); |
652 | printk(KERN_DEBUG "addBA was not requested!\n"); | ||
653 | #endif | ||
654 | goto unlock; | 627 | goto unlock; |
655 | } | 628 | } |
656 | 629 | ||
@@ -750,25 +723,18 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) | |||
750 | trace_api_stop_tx_ba_cb(sdata, ra, tid); | 723 | trace_api_stop_tx_ba_cb(sdata, ra, tid); |
751 | 724 | ||
752 | if (tid >= STA_TID_NUM) { | 725 | if (tid >= STA_TID_NUM) { |
753 | #ifdef CONFIG_MAC80211_HT_DEBUG | 726 | ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", |
754 | printk(KERN_DEBUG "Bad TID value: tid = %d (>= %d)\n", | 727 | tid, STA_TID_NUM); |
755 | tid, STA_TID_NUM); | ||
756 | #endif | ||
757 | return; | 728 | return; |
758 | } | 729 | } |
759 | 730 | ||
760 | #ifdef CONFIG_MAC80211_HT_DEBUG | 731 | ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n", ra, tid); |
761 | printk(KERN_DEBUG "Stopping Tx BA session for %pM tid %d\n", | ||
762 | ra, tid); | ||
763 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
764 | 732 | ||
765 | mutex_lock(&local->sta_mtx); | 733 | mutex_lock(&local->sta_mtx); |
766 | 734 | ||
767 | sta = sta_info_get_bss(sdata, ra); | 735 | sta = sta_info_get_bss(sdata, ra); |
768 | if (!sta) { | 736 | if (!sta) { |
769 | #ifdef CONFIG_MAC80211_HT_DEBUG | 737 | ht_dbg(sdata, "Could not find station: %pM\n", ra); |
770 | printk(KERN_DEBUG "Could not find station: %pM\n", ra); | ||
771 | #endif | ||
772 | goto unlock; | 738 | goto unlock; |
773 | } | 739 | } |
774 | 740 | ||
@@ -777,9 +743,7 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) | |||
777 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 743 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
778 | 744 | ||
779 | if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { | 745 | if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { |
780 | #ifdef CONFIG_MAC80211_HT_DEBUG | 746 | ht_dbg(sdata, "unexpected callback to A-MPDU stop\n"); |
781 | printk(KERN_DEBUG "unexpected callback to A-MPDU stop\n"); | ||
782 | #endif | ||
783 | goto unlock_sta; | 747 | goto unlock_sta; |
784 | } | 748 | } |
785 | 749 | ||
@@ -855,17 +819,13 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
855 | goto out; | 819 | goto out; |
856 | 820 | ||
857 | if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { | 821 | if (mgmt->u.action.u.addba_resp.dialog_token != tid_tx->dialog_token) { |
858 | #ifdef CONFIG_MAC80211_HT_DEBUG | 822 | ht_dbg(sta->sdata, "wrong addBA response token, tid %d\n", tid); |
859 | printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid); | ||
860 | #endif | ||
861 | goto out; | 823 | goto out; |
862 | } | 824 | } |
863 | 825 | ||
864 | del_timer_sync(&tid_tx->addba_resp_timer); | 826 | del_timer_sync(&tid_tx->addba_resp_timer); |
865 | 827 | ||
866 | #ifdef CONFIG_MAC80211_HT_DEBUG | 828 | ht_dbg(sta->sdata, "switched off addBA timer for tid %d\n", tid); |
867 | printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid); | ||
868 | #endif | ||
869 | 829 | ||
870 | /* | 830 | /* |
871 | * addba_resp_timer may have fired before we got here, and | 831 | * addba_resp_timer may have fired before we got here, and |
@@ -874,11 +834,9 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local, | |||
874 | */ | 834 | */ |
875 | if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || | 835 | if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) || |
876 | test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { | 836 | test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { |
877 | #ifdef CONFIG_MAC80211_HT_DEBUG | 837 | ht_dbg(sta->sdata, |
878 | printk(KERN_DEBUG | ||
879 | "got addBA resp for tid %d but we already gave up\n", | 838 | "got addBA resp for tid %d but we already gave up\n", |
880 | tid); | 839 | tid); |
881 | #endif | ||
882 | goto out; | 840 | goto out; |
883 | } | 841 | } |
884 | 842 | ||
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7d5108a867ad..d41974aacf51 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -20,31 +20,31 @@ | |||
20 | #include "rate.h" | 20 | #include "rate.h" |
21 | #include "mesh.h" | 21 | #include "mesh.h" |
22 | 22 | ||
23 | static struct net_device *ieee80211_add_iface(struct wiphy *wiphy, char *name, | 23 | static struct wireless_dev *ieee80211_add_iface(struct wiphy *wiphy, char *name, |
24 | enum nl80211_iftype type, | 24 | enum nl80211_iftype type, |
25 | u32 *flags, | 25 | u32 *flags, |
26 | struct vif_params *params) | 26 | struct vif_params *params) |
27 | { | 27 | { |
28 | struct ieee80211_local *local = wiphy_priv(wiphy); | 28 | struct ieee80211_local *local = wiphy_priv(wiphy); |
29 | struct net_device *dev; | 29 | struct wireless_dev *wdev; |
30 | struct ieee80211_sub_if_data *sdata; | 30 | struct ieee80211_sub_if_data *sdata; |
31 | int err; | 31 | int err; |
32 | 32 | ||
33 | err = ieee80211_if_add(local, name, &dev, type, params); | 33 | err = ieee80211_if_add(local, name, &wdev, type, params); |
34 | if (err) | 34 | if (err) |
35 | return ERR_PTR(err); | 35 | return ERR_PTR(err); |
36 | 36 | ||
37 | if (type == NL80211_IFTYPE_MONITOR && flags) { | 37 | if (type == NL80211_IFTYPE_MONITOR && flags) { |
38 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 38 | sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
39 | sdata->u.mntr_flags = *flags; | 39 | sdata->u.mntr_flags = *flags; |
40 | } | 40 | } |
41 | 41 | ||
42 | return dev; | 42 | return wdev; |
43 | } | 43 | } |
44 | 44 | ||
45 | static int ieee80211_del_iface(struct wiphy *wiphy, struct net_device *dev) | 45 | static int ieee80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev) |
46 | { | 46 | { |
47 | ieee80211_if_remove(IEEE80211_DEV_TO_SUB_IF(dev)); | 47 | ieee80211_if_remove(IEEE80211_WDEV_TO_SUB_IF(wdev)); |
48 | 48 | ||
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
@@ -353,6 +353,7 @@ void sta_set_rate_info_tx(struct sta_info *sta, | |||
353 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | 353 | static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) |
354 | { | 354 | { |
355 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 355 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
356 | struct ieee80211_local *local = sdata->local; | ||
356 | struct timespec uptime; | 357 | struct timespec uptime; |
357 | 358 | ||
358 | sinfo->generation = sdata->local->sta_generation; | 359 | sinfo->generation = sdata->local->sta_generation; |
@@ -388,7 +389,9 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
388 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || | 389 | if ((sta->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) || |
389 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { | 390 | (sta->local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)) { |
390 | sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; | 391 | sinfo->filled |= STATION_INFO_SIGNAL | STATION_INFO_SIGNAL_AVG; |
391 | sinfo->signal = (s8)sta->last_signal; | 392 | if (!local->ops->get_rssi || |
393 | drv_get_rssi(local, sdata, &sta->sta, &sinfo->signal)) | ||
394 | sinfo->signal = (s8)sta->last_signal; | ||
392 | sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); | 395 | sinfo->signal_avg = (s8) -ewma_read(&sta->avg_signal); |
393 | } | 396 | } |
394 | 397 | ||
@@ -517,7 +520,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, | |||
517 | * network device. | 520 | * network device. |
518 | */ | 521 | */ |
519 | 522 | ||
520 | rcu_read_lock(); | 523 | mutex_lock(&local->sta_mtx); |
521 | 524 | ||
522 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { | 525 | if (sdata->vif.type == NL80211_IFTYPE_STATION) { |
523 | sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid); | 526 | sta = sta_info_get_bss(sdata, sdata->u.mgd.bssid); |
@@ -546,7 +549,7 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy, | |||
546 | data[i] = (u8)sinfo.signal_avg; | 549 | data[i] = (u8)sinfo.signal_avg; |
547 | i++; | 550 | i++; |
548 | } else { | 551 | } else { |
549 | list_for_each_entry_rcu(sta, &local->sta_list, list) { | 552 | list_for_each_entry(sta, &local->sta_list, list) { |
550 | /* Make sure this station belongs to the proper dev */ | 553 | /* Make sure this station belongs to the proper dev */ |
551 | if (sta->sdata->dev != dev) | 554 | if (sta->sdata->dev != dev) |
552 | continue; | 555 | continue; |
@@ -603,7 +606,7 @@ do_survey: | |||
603 | else | 606 | else |
604 | data[i++] = -1LL; | 607 | data[i++] = -1LL; |
605 | 608 | ||
606 | rcu_read_unlock(); | 609 | mutex_unlock(&local->sta_mtx); |
607 | 610 | ||
608 | if (WARN_ON(i != STA_STATS_LEN)) | 611 | if (WARN_ON(i != STA_STATS_LEN)) |
609 | return; | 612 | return; |
@@ -629,10 +632,11 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, | |||
629 | int idx, u8 *mac, struct station_info *sinfo) | 632 | int idx, u8 *mac, struct station_info *sinfo) |
630 | { | 633 | { |
631 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 634 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
635 | struct ieee80211_local *local = sdata->local; | ||
632 | struct sta_info *sta; | 636 | struct sta_info *sta; |
633 | int ret = -ENOENT; | 637 | int ret = -ENOENT; |
634 | 638 | ||
635 | rcu_read_lock(); | 639 | mutex_lock(&local->sta_mtx); |
636 | 640 | ||
637 | sta = sta_info_get_by_idx(sdata, idx); | 641 | sta = sta_info_get_by_idx(sdata, idx); |
638 | if (sta) { | 642 | if (sta) { |
@@ -641,7 +645,7 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev, | |||
641 | sta_set_sinfo(sta, sinfo); | 645 | sta_set_sinfo(sta, sinfo); |
642 | } | 646 | } |
643 | 647 | ||
644 | rcu_read_unlock(); | 648 | mutex_unlock(&local->sta_mtx); |
645 | 649 | ||
646 | return ret; | 650 | return ret; |
647 | } | 651 | } |
@@ -658,10 +662,11 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
658 | u8 *mac, struct station_info *sinfo) | 662 | u8 *mac, struct station_info *sinfo) |
659 | { | 663 | { |
660 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 664 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
665 | struct ieee80211_local *local = sdata->local; | ||
661 | struct sta_info *sta; | 666 | struct sta_info *sta; |
662 | int ret = -ENOENT; | 667 | int ret = -ENOENT; |
663 | 668 | ||
664 | rcu_read_lock(); | 669 | mutex_lock(&local->sta_mtx); |
665 | 670 | ||
666 | sta = sta_info_get_bss(sdata, mac); | 671 | sta = sta_info_get_bss(sdata, mac); |
667 | if (sta) { | 672 | if (sta) { |
@@ -669,11 +674,54 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, | |||
669 | sta_set_sinfo(sta, sinfo); | 674 | sta_set_sinfo(sta, sinfo); |
670 | } | 675 | } |
671 | 676 | ||
672 | rcu_read_unlock(); | 677 | mutex_unlock(&local->sta_mtx); |
673 | 678 | ||
674 | return ret; | 679 | return ret; |
675 | } | 680 | } |
676 | 681 | ||
682 | static int ieee80211_set_channel(struct wiphy *wiphy, | ||
683 | struct net_device *netdev, | ||
684 | struct ieee80211_channel *chan, | ||
685 | enum nl80211_channel_type channel_type) | ||
686 | { | ||
687 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
688 | struct ieee80211_sub_if_data *sdata = NULL; | ||
689 | |||
690 | if (netdev) | ||
691 | sdata = IEEE80211_DEV_TO_SUB_IF(netdev); | ||
692 | |||
693 | switch (ieee80211_get_channel_mode(local, NULL)) { | ||
694 | case CHAN_MODE_HOPPING: | ||
695 | return -EBUSY; | ||
696 | case CHAN_MODE_FIXED: | ||
697 | if (local->oper_channel != chan || | ||
698 | (!sdata && local->_oper_channel_type != channel_type)) | ||
699 | return -EBUSY; | ||
700 | if (!sdata && local->_oper_channel_type == channel_type) | ||
701 | return 0; | ||
702 | break; | ||
703 | case CHAN_MODE_UNDEFINED: | ||
704 | break; | ||
705 | } | ||
706 | |||
707 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) | ||
708 | return -EBUSY; | ||
709 | |||
710 | local->oper_channel = chan; | ||
711 | |||
712 | /* auto-detects changes */ | ||
713 | ieee80211_hw_config(local, 0); | ||
714 | |||
715 | return 0; | ||
716 | } | ||
717 | |||
718 | static int ieee80211_set_monitor_channel(struct wiphy *wiphy, | ||
719 | struct ieee80211_channel *chan, | ||
720 | enum nl80211_channel_type channel_type) | ||
721 | { | ||
722 | return ieee80211_set_channel(wiphy, NULL, chan, channel_type); | ||
723 | } | ||
724 | |||
677 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, | 725 | static int ieee80211_set_probe_resp(struct ieee80211_sub_if_data *sdata, |
678 | const u8 *resp, size_t resp_len) | 726 | const u8 *resp, size_t resp_len) |
679 | { | 727 | { |
@@ -788,6 +836,11 @@ static int ieee80211_start_ap(struct wiphy *wiphy, struct net_device *dev, | |||
788 | if (old) | 836 | if (old) |
789 | return -EALREADY; | 837 | return -EALREADY; |
790 | 838 | ||
839 | err = ieee80211_set_channel(wiphy, dev, params->channel, | ||
840 | params->channel_type); | ||
841 | if (err) | ||
842 | return err; | ||
843 | |||
791 | /* | 844 | /* |
792 | * Apply control port protocol, this allows us to | 845 | * Apply control port protocol, this allows us to |
793 | * not encrypt dynamic WEP control frames. | 846 | * not encrypt dynamic WEP control frames. |
@@ -864,6 +917,7 @@ static int ieee80211_stop_ap(struct wiphy *wiphy, struct net_device *dev) | |||
864 | 917 | ||
865 | kfree_rcu(old, rcu_head); | 918 | kfree_rcu(old, rcu_head); |
866 | 919 | ||
920 | sta_info_flush(sdata->local, sdata); | ||
867 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); | 921 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON_ENABLED); |
868 | 922 | ||
869 | return 0; | 923 | return 0; |
@@ -1482,7 +1536,7 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, | |||
1482 | if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) | 1536 | if (_chg_mesh_attr(NL80211_MESHCONF_TTL, mask)) |
1483 | conf->dot11MeshTTL = nconf->dot11MeshTTL; | 1537 | conf->dot11MeshTTL = nconf->dot11MeshTTL; |
1484 | if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask)) | 1538 | if (_chg_mesh_attr(NL80211_MESHCONF_ELEMENT_TTL, mask)) |
1485 | conf->dot11MeshTTL = nconf->element_ttl; | 1539 | conf->element_ttl = nconf->element_ttl; |
1486 | if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) | 1540 | if (_chg_mesh_attr(NL80211_MESHCONF_AUTO_OPEN_PLINKS, mask)) |
1487 | conf->auto_open_plinks = nconf->auto_open_plinks; | 1541 | conf->auto_open_plinks = nconf->auto_open_plinks; |
1488 | if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask)) | 1542 | if (_chg_mesh_attr(NL80211_MESHCONF_SYNC_OFFSET_MAX_NEIGHBOR, mask)) |
@@ -1517,17 +1571,16 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, | |||
1517 | * announcements, so require this ifmsh to also be a root node | 1571 | * announcements, so require this ifmsh to also be a root node |
1518 | * */ | 1572 | * */ |
1519 | if (nconf->dot11MeshGateAnnouncementProtocol && | 1573 | if (nconf->dot11MeshGateAnnouncementProtocol && |
1520 | !conf->dot11MeshHWMPRootMode) { | 1574 | !(conf->dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT)) { |
1521 | conf->dot11MeshHWMPRootMode = 1; | 1575 | conf->dot11MeshHWMPRootMode = IEEE80211_PROACTIVE_RANN; |
1522 | ieee80211_mesh_root_setup(ifmsh); | 1576 | ieee80211_mesh_root_setup(ifmsh); |
1523 | } | 1577 | } |
1524 | conf->dot11MeshGateAnnouncementProtocol = | 1578 | conf->dot11MeshGateAnnouncementProtocol = |
1525 | nconf->dot11MeshGateAnnouncementProtocol; | 1579 | nconf->dot11MeshGateAnnouncementProtocol; |
1526 | } | 1580 | } |
1527 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) { | 1581 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_RANN_INTERVAL, mask)) |
1528 | conf->dot11MeshHWMPRannInterval = | 1582 | conf->dot11MeshHWMPRannInterval = |
1529 | nconf->dot11MeshHWMPRannInterval; | 1583 | nconf->dot11MeshHWMPRannInterval; |
1530 | } | ||
1531 | if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) | 1584 | if (_chg_mesh_attr(NL80211_MESHCONF_FORWARDING, mask)) |
1532 | conf->dot11MeshForwarding = nconf->dot11MeshForwarding; | 1585 | conf->dot11MeshForwarding = nconf->dot11MeshForwarding; |
1533 | if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) { | 1586 | if (_chg_mesh_attr(NL80211_MESHCONF_RSSI_THRESHOLD, mask)) { |
@@ -1543,6 +1596,15 @@ static int ieee80211_update_mesh_config(struct wiphy *wiphy, | |||
1543 | sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode; | 1596 | sdata->vif.bss_conf.ht_operation_mode = nconf->ht_opmode; |
1544 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); | 1597 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); |
1545 | } | 1598 | } |
1599 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_PATH_TO_ROOT_TIMEOUT, mask)) | ||
1600 | conf->dot11MeshHWMPactivePathToRootTimeout = | ||
1601 | nconf->dot11MeshHWMPactivePathToRootTimeout; | ||
1602 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_ROOT_INTERVAL, mask)) | ||
1603 | conf->dot11MeshHWMProotInterval = | ||
1604 | nconf->dot11MeshHWMProotInterval; | ||
1605 | if (_chg_mesh_attr(NL80211_MESHCONF_HWMP_CONFIRMATION_INTERVAL, mask)) | ||
1606 | conf->dot11MeshHWMPconfirmationInterval = | ||
1607 | nconf->dot11MeshHWMPconfirmationInterval; | ||
1546 | return 0; | 1608 | return 0; |
1547 | } | 1609 | } |
1548 | 1610 | ||
@@ -1558,6 +1620,12 @@ static int ieee80211_join_mesh(struct wiphy *wiphy, struct net_device *dev, | |||
1558 | err = copy_mesh_setup(ifmsh, setup); | 1620 | err = copy_mesh_setup(ifmsh, setup); |
1559 | if (err) | 1621 | if (err) |
1560 | return err; | 1622 | return err; |
1623 | |||
1624 | err = ieee80211_set_channel(wiphy, dev, setup->channel, | ||
1625 | setup->channel_type); | ||
1626 | if (err) | ||
1627 | return err; | ||
1628 | |||
1561 | ieee80211_start_mesh(sdata); | 1629 | ieee80211_start_mesh(sdata); |
1562 | 1630 | ||
1563 | return 0; | 1631 | return 0; |
@@ -1674,54 +1742,7 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy, | |||
1674 | return -EINVAL; | 1742 | return -EINVAL; |
1675 | } | 1743 | } |
1676 | 1744 | ||
1677 | return 0; | 1745 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_QOS); |
1678 | } | ||
1679 | |||
1680 | static int ieee80211_set_channel(struct wiphy *wiphy, | ||
1681 | struct net_device *netdev, | ||
1682 | struct ieee80211_channel *chan, | ||
1683 | enum nl80211_channel_type channel_type) | ||
1684 | { | ||
1685 | struct ieee80211_local *local = wiphy_priv(wiphy); | ||
1686 | struct ieee80211_sub_if_data *sdata = NULL; | ||
1687 | struct ieee80211_channel *old_oper; | ||
1688 | enum nl80211_channel_type old_oper_type; | ||
1689 | enum nl80211_channel_type old_vif_oper_type= NL80211_CHAN_NO_HT; | ||
1690 | |||
1691 | if (netdev) | ||
1692 | sdata = IEEE80211_DEV_TO_SUB_IF(netdev); | ||
1693 | |||
1694 | switch (ieee80211_get_channel_mode(local, NULL)) { | ||
1695 | case CHAN_MODE_HOPPING: | ||
1696 | return -EBUSY; | ||
1697 | case CHAN_MODE_FIXED: | ||
1698 | if (local->oper_channel != chan) | ||
1699 | return -EBUSY; | ||
1700 | if (!sdata && local->_oper_channel_type == channel_type) | ||
1701 | return 0; | ||
1702 | break; | ||
1703 | case CHAN_MODE_UNDEFINED: | ||
1704 | break; | ||
1705 | } | ||
1706 | |||
1707 | if (sdata) | ||
1708 | old_vif_oper_type = sdata->vif.bss_conf.channel_type; | ||
1709 | old_oper_type = local->_oper_channel_type; | ||
1710 | |||
1711 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) | ||
1712 | return -EBUSY; | ||
1713 | |||
1714 | old_oper = local->oper_channel; | ||
1715 | local->oper_channel = chan; | ||
1716 | |||
1717 | /* Update driver if changes were actually made. */ | ||
1718 | if ((old_oper != local->oper_channel) || | ||
1719 | (old_oper_type != local->_oper_channel_type)) | ||
1720 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | ||
1721 | |||
1722 | if (sdata && sdata->vif.type != NL80211_IFTYPE_MONITOR && | ||
1723 | old_vif_oper_type != sdata->vif.bss_conf.channel_type) | ||
1724 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_HT); | ||
1725 | 1746 | ||
1726 | return 0; | 1747 | return 0; |
1727 | } | 1748 | } |
@@ -1743,10 +1764,11 @@ static int ieee80211_resume(struct wiphy *wiphy) | |||
1743 | #endif | 1764 | #endif |
1744 | 1765 | ||
1745 | static int ieee80211_scan(struct wiphy *wiphy, | 1766 | static int ieee80211_scan(struct wiphy *wiphy, |
1746 | struct net_device *dev, | ||
1747 | struct cfg80211_scan_request *req) | 1767 | struct cfg80211_scan_request *req) |
1748 | { | 1768 | { |
1749 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 1769 | struct ieee80211_sub_if_data *sdata; |
1770 | |||
1771 | sdata = IEEE80211_WDEV_TO_SUB_IF(req->wdev); | ||
1750 | 1772 | ||
1751 | switch (ieee80211_vif_type_p2p(&sdata->vif)) { | 1773 | switch (ieee80211_vif_type_p2p(&sdata->vif)) { |
1752 | case NL80211_IFTYPE_STATION: | 1774 | case NL80211_IFTYPE_STATION: |
@@ -2111,143 +2133,291 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy, | |||
2111 | return 0; | 2133 | return 0; |
2112 | } | 2134 | } |
2113 | 2135 | ||
2114 | static int ieee80211_remain_on_channel_hw(struct ieee80211_local *local, | 2136 | static int ieee80211_start_roc_work(struct ieee80211_local *local, |
2115 | struct net_device *dev, | 2137 | struct ieee80211_sub_if_data *sdata, |
2116 | struct ieee80211_channel *chan, | 2138 | struct ieee80211_channel *channel, |
2117 | enum nl80211_channel_type chantype, | 2139 | enum nl80211_channel_type channel_type, |
2118 | unsigned int duration, u64 *cookie) | 2140 | unsigned int duration, u64 *cookie, |
2141 | struct sk_buff *txskb) | ||
2119 | { | 2142 | { |
2143 | struct ieee80211_roc_work *roc, *tmp; | ||
2144 | bool queued = false; | ||
2120 | int ret; | 2145 | int ret; |
2121 | u32 random_cookie; | ||
2122 | 2146 | ||
2123 | lockdep_assert_held(&local->mtx); | 2147 | lockdep_assert_held(&local->mtx); |
2124 | 2148 | ||
2125 | if (local->hw_roc_cookie) | 2149 | roc = kzalloc(sizeof(*roc), GFP_KERNEL); |
2126 | return -EBUSY; | 2150 | if (!roc) |
2127 | /* must be nonzero */ | 2151 | return -ENOMEM; |
2128 | random_cookie = random32() | 1; | 2152 | |
2129 | 2153 | roc->chan = channel; | |
2130 | *cookie = random_cookie; | 2154 | roc->chan_type = channel_type; |
2131 | local->hw_roc_dev = dev; | 2155 | roc->duration = duration; |
2132 | local->hw_roc_cookie = random_cookie; | 2156 | roc->req_duration = duration; |
2133 | local->hw_roc_channel = chan; | 2157 | roc->frame = txskb; |
2134 | local->hw_roc_channel_type = chantype; | 2158 | roc->mgmt_tx_cookie = (unsigned long)txskb; |
2135 | local->hw_roc_duration = duration; | 2159 | roc->sdata = sdata; |
2136 | ret = drv_remain_on_channel(local, chan, chantype, duration); | 2160 | INIT_DELAYED_WORK(&roc->work, ieee80211_sw_roc_work); |
2161 | INIT_LIST_HEAD(&roc->dependents); | ||
2162 | |||
2163 | /* if there's one pending or we're scanning, queue this one */ | ||
2164 | if (!list_empty(&local->roc_list) || local->scanning) | ||
2165 | goto out_check_combine; | ||
2166 | |||
2167 | /* if not HW assist, just queue & schedule work */ | ||
2168 | if (!local->ops->remain_on_channel) { | ||
2169 | ieee80211_queue_delayed_work(&local->hw, &roc->work, 0); | ||
2170 | goto out_queue; | ||
2171 | } | ||
2172 | |||
2173 | /* otherwise actually kick it off here (for error handling) */ | ||
2174 | |||
2175 | /* | ||
2176 | * If the duration is zero, then the driver | ||
2177 | * wouldn't actually do anything. Set it to | ||
2178 | * 10 for now. | ||
2179 | * | ||
2180 | * TODO: cancel the off-channel operation | ||
2181 | * when we get the SKB's TX status and | ||
2182 | * the wait time was zero before. | ||
2183 | */ | ||
2184 | if (!duration) | ||
2185 | duration = 10; | ||
2186 | |||
2187 | ret = drv_remain_on_channel(local, channel, channel_type, duration); | ||
2137 | if (ret) { | 2188 | if (ret) { |
2138 | local->hw_roc_channel = NULL; | 2189 | kfree(roc); |
2139 | local->hw_roc_cookie = 0; | 2190 | return ret; |
2140 | } | 2191 | } |
2141 | 2192 | ||
2142 | return ret; | 2193 | roc->started = true; |
2194 | goto out_queue; | ||
2195 | |||
2196 | out_check_combine: | ||
2197 | list_for_each_entry(tmp, &local->roc_list, list) { | ||
2198 | if (tmp->chan != channel || tmp->chan_type != channel_type) | ||
2199 | continue; | ||
2200 | |||
2201 | /* | ||
2202 | * Extend this ROC if possible: | ||
2203 | * | ||
2204 | * If it hasn't started yet, just increase the duration | ||
2205 | * and add the new one to the list of dependents. | ||
2206 | */ | ||
2207 | if (!tmp->started) { | ||
2208 | list_add_tail(&roc->list, &tmp->dependents); | ||
2209 | tmp->duration = max(tmp->duration, roc->duration); | ||
2210 | queued = true; | ||
2211 | break; | ||
2212 | } | ||
2213 | |||
2214 | /* If it has already started, it's more difficult ... */ | ||
2215 | if (local->ops->remain_on_channel) { | ||
2216 | unsigned long j = jiffies; | ||
2217 | |||
2218 | /* | ||
2219 | * In the offloaded ROC case, if it hasn't begun, add | ||
2220 | * this new one to the dependent list to be handled | ||
2221 | * when the the master one begins. If it has begun, | ||
2222 | * check that there's still a minimum time left and | ||
2223 | * if so, start this one, transmitting the frame, but | ||
2224 | * add it to the list directly after this one with a | ||
2225 | * a reduced time so we'll ask the driver to execute | ||
2226 | * it right after finishing the previous one, in the | ||
2227 | * hope that it'll also be executed right afterwards, | ||
2228 | * effectively extending the old one. | ||
2229 | * If there's no minimum time left, just add it to the | ||
2230 | * normal list. | ||
2231 | */ | ||
2232 | if (!tmp->hw_begun) { | ||
2233 | list_add_tail(&roc->list, &tmp->dependents); | ||
2234 | queued = true; | ||
2235 | break; | ||
2236 | } | ||
2237 | |||
2238 | if (time_before(j + IEEE80211_ROC_MIN_LEFT, | ||
2239 | tmp->hw_start_time + | ||
2240 | msecs_to_jiffies(tmp->duration))) { | ||
2241 | int new_dur; | ||
2242 | |||
2243 | ieee80211_handle_roc_started(roc); | ||
2244 | |||
2245 | new_dur = roc->duration - | ||
2246 | jiffies_to_msecs(tmp->hw_start_time + | ||
2247 | msecs_to_jiffies( | ||
2248 | tmp->duration) - | ||
2249 | j); | ||
2250 | |||
2251 | if (new_dur > 0) { | ||
2252 | /* add right after tmp */ | ||
2253 | list_add(&roc->list, &tmp->list); | ||
2254 | } else { | ||
2255 | list_add_tail(&roc->list, | ||
2256 | &tmp->dependents); | ||
2257 | } | ||
2258 | queued = true; | ||
2259 | } | ||
2260 | } else if (del_timer_sync(&tmp->work.timer)) { | ||
2261 | unsigned long new_end; | ||
2262 | |||
2263 | /* | ||
2264 | * In the software ROC case, cancel the timer, if | ||
2265 | * that fails then the finish work is already | ||
2266 | * queued/pending and thus we queue the new ROC | ||
2267 | * normally, if that succeeds then we can extend | ||
2268 | * the timer duration and TX the frame (if any.) | ||
2269 | */ | ||
2270 | |||
2271 | list_add_tail(&roc->list, &tmp->dependents); | ||
2272 | queued = true; | ||
2273 | |||
2274 | new_end = jiffies + msecs_to_jiffies(roc->duration); | ||
2275 | |||
2276 | /* ok, it was started & we canceled timer */ | ||
2277 | if (time_after(new_end, tmp->work.timer.expires)) | ||
2278 | mod_timer(&tmp->work.timer, new_end); | ||
2279 | else | ||
2280 | add_timer(&tmp->work.timer); | ||
2281 | |||
2282 | ieee80211_handle_roc_started(roc); | ||
2283 | } | ||
2284 | break; | ||
2285 | } | ||
2286 | |||
2287 | out_queue: | ||
2288 | if (!queued) | ||
2289 | list_add_tail(&roc->list, &local->roc_list); | ||
2290 | |||
2291 | /* | ||
2292 | * cookie is either the roc (for normal roc) | ||
2293 | * or the SKB (for mgmt TX) | ||
2294 | */ | ||
2295 | if (txskb) | ||
2296 | *cookie = (unsigned long)txskb; | ||
2297 | else | ||
2298 | *cookie = (unsigned long)roc; | ||
2299 | |||
2300 | return 0; | ||
2143 | } | 2301 | } |
2144 | 2302 | ||
2145 | static int ieee80211_remain_on_channel(struct wiphy *wiphy, | 2303 | static int ieee80211_remain_on_channel(struct wiphy *wiphy, |
2146 | struct net_device *dev, | 2304 | struct wireless_dev *wdev, |
2147 | struct ieee80211_channel *chan, | 2305 | struct ieee80211_channel *chan, |
2148 | enum nl80211_channel_type channel_type, | 2306 | enum nl80211_channel_type channel_type, |
2149 | unsigned int duration, | 2307 | unsigned int duration, |
2150 | u64 *cookie) | 2308 | u64 *cookie) |
2151 | { | 2309 | { |
2152 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2310 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
2153 | struct ieee80211_local *local = sdata->local; | 2311 | struct ieee80211_local *local = sdata->local; |
2312 | int ret; | ||
2154 | 2313 | ||
2155 | if (local->ops->remain_on_channel) { | 2314 | mutex_lock(&local->mtx); |
2156 | int ret; | 2315 | ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, |
2157 | 2316 | duration, cookie, NULL); | |
2158 | mutex_lock(&local->mtx); | 2317 | mutex_unlock(&local->mtx); |
2159 | ret = ieee80211_remain_on_channel_hw(local, dev, | ||
2160 | chan, channel_type, | ||
2161 | duration, cookie); | ||
2162 | local->hw_roc_for_tx = false; | ||
2163 | mutex_unlock(&local->mtx); | ||
2164 | |||
2165 | return ret; | ||
2166 | } | ||
2167 | 2318 | ||
2168 | return ieee80211_wk_remain_on_channel(sdata, chan, channel_type, | 2319 | return ret; |
2169 | duration, cookie); | ||
2170 | } | 2320 | } |
2171 | 2321 | ||
2172 | static int ieee80211_cancel_remain_on_channel_hw(struct ieee80211_local *local, | 2322 | static int ieee80211_cancel_roc(struct ieee80211_local *local, |
2173 | u64 cookie) | 2323 | u64 cookie, bool mgmt_tx) |
2174 | { | 2324 | { |
2325 | struct ieee80211_roc_work *roc, *tmp, *found = NULL; | ||
2175 | int ret; | 2326 | int ret; |
2176 | 2327 | ||
2177 | lockdep_assert_held(&local->mtx); | 2328 | mutex_lock(&local->mtx); |
2329 | list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { | ||
2330 | struct ieee80211_roc_work *dep, *tmp2; | ||
2178 | 2331 | ||
2179 | if (local->hw_roc_cookie != cookie) | 2332 | list_for_each_entry_safe(dep, tmp2, &roc->dependents, list) { |
2180 | return -ENOENT; | 2333 | if (!mgmt_tx && (unsigned long)dep != cookie) |
2334 | continue; | ||
2335 | else if (mgmt_tx && dep->mgmt_tx_cookie != cookie) | ||
2336 | continue; | ||
2337 | /* found dependent item -- just remove it */ | ||
2338 | list_del(&dep->list); | ||
2339 | mutex_unlock(&local->mtx); | ||
2181 | 2340 | ||
2182 | ret = drv_cancel_remain_on_channel(local); | 2341 | ieee80211_roc_notify_destroy(dep); |
2183 | if (ret) | 2342 | return 0; |
2184 | return ret; | 2343 | } |
2185 | 2344 | ||
2186 | local->hw_roc_cookie = 0; | 2345 | if (!mgmt_tx && (unsigned long)roc != cookie) |
2187 | local->hw_roc_channel = NULL; | 2346 | continue; |
2347 | else if (mgmt_tx && roc->mgmt_tx_cookie != cookie) | ||
2348 | continue; | ||
2349 | |||
2350 | found = roc; | ||
2351 | break; | ||
2352 | } | ||
2188 | 2353 | ||
2189 | ieee80211_recalc_idle(local); | 2354 | if (!found) { |
2355 | mutex_unlock(&local->mtx); | ||
2356 | return -ENOENT; | ||
2357 | } | ||
2190 | 2358 | ||
2191 | return 0; | 2359 | /* |
2192 | } | 2360 | * We found the item to cancel, so do that. Note that it |
2361 | * may have dependents, which we also cancel (and send | ||
2362 | * the expired signal for.) Not doing so would be quite | ||
2363 | * tricky here, but we may need to fix it later. | ||
2364 | */ | ||
2193 | 2365 | ||
2194 | static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, | 2366 | if (local->ops->remain_on_channel) { |
2195 | struct net_device *dev, | 2367 | if (found->started) { |
2196 | u64 cookie) | 2368 | ret = drv_cancel_remain_on_channel(local); |
2197 | { | 2369 | if (WARN_ON_ONCE(ret)) { |
2198 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2370 | mutex_unlock(&local->mtx); |
2199 | struct ieee80211_local *local = sdata->local; | 2371 | return ret; |
2372 | } | ||
2373 | } | ||
2200 | 2374 | ||
2201 | if (local->ops->cancel_remain_on_channel) { | 2375 | list_del(&found->list); |
2202 | int ret; | ||
2203 | 2376 | ||
2204 | mutex_lock(&local->mtx); | 2377 | if (found->started) |
2205 | ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); | 2378 | ieee80211_start_next_roc(local); |
2206 | mutex_unlock(&local->mtx); | 2379 | mutex_unlock(&local->mtx); |
2207 | 2380 | ||
2208 | return ret; | 2381 | ieee80211_roc_notify_destroy(found); |
2382 | } else { | ||
2383 | /* work may be pending so use it all the time */ | ||
2384 | found->abort = true; | ||
2385 | ieee80211_queue_delayed_work(&local->hw, &found->work, 0); | ||
2386 | |||
2387 | mutex_unlock(&local->mtx); | ||
2388 | |||
2389 | /* work will clean up etc */ | ||
2390 | flush_delayed_work(&found->work); | ||
2209 | } | 2391 | } |
2210 | 2392 | ||
2211 | return ieee80211_wk_cancel_remain_on_channel(sdata, cookie); | 2393 | return 0; |
2212 | } | 2394 | } |
2213 | 2395 | ||
2214 | static enum work_done_result | 2396 | static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy, |
2215 | ieee80211_offchan_tx_done(struct ieee80211_work *wk, struct sk_buff *skb) | 2397 | struct wireless_dev *wdev, |
2398 | u64 cookie) | ||
2216 | { | 2399 | { |
2217 | /* | 2400 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
2218 | * Use the data embedded in the work struct for reporting | 2401 | struct ieee80211_local *local = sdata->local; |
2219 | * here so if the driver mangled the SKB before dropping | ||
2220 | * it (which is the only way we really should get here) | ||
2221 | * then we don't report mangled data. | ||
2222 | * | ||
2223 | * If there was no wait time, then by the time we get here | ||
2224 | * the driver will likely not have reported the status yet, | ||
2225 | * so in that case userspace will have to deal with it. | ||
2226 | */ | ||
2227 | |||
2228 | if (wk->offchan_tx.wait && !wk->offchan_tx.status) | ||
2229 | cfg80211_mgmt_tx_status(wk->sdata->dev, | ||
2230 | (unsigned long) wk->offchan_tx.frame, | ||
2231 | wk->data, wk->data_len, false, GFP_KERNEL); | ||
2232 | 2402 | ||
2233 | return WORK_DONE_DESTROY; | 2403 | return ieee80211_cancel_roc(local, cookie, false); |
2234 | } | 2404 | } |
2235 | 2405 | ||
2236 | static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | 2406 | static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, |
2237 | struct ieee80211_channel *chan, bool offchan, | 2407 | struct ieee80211_channel *chan, bool offchan, |
2238 | enum nl80211_channel_type channel_type, | 2408 | enum nl80211_channel_type channel_type, |
2239 | bool channel_type_valid, unsigned int wait, | 2409 | bool channel_type_valid, unsigned int wait, |
2240 | const u8 *buf, size_t len, bool no_cck, | 2410 | const u8 *buf, size_t len, bool no_cck, |
2241 | bool dont_wait_for_ack, u64 *cookie) | 2411 | bool dont_wait_for_ack, u64 *cookie) |
2242 | { | 2412 | { |
2243 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2413 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); |
2244 | struct ieee80211_local *local = sdata->local; | 2414 | struct ieee80211_local *local = sdata->local; |
2245 | struct sk_buff *skb; | 2415 | struct sk_buff *skb; |
2246 | struct sta_info *sta; | 2416 | struct sta_info *sta; |
2247 | struct ieee80211_work *wk; | ||
2248 | const struct ieee80211_mgmt *mgmt = (void *)buf; | 2417 | const struct ieee80211_mgmt *mgmt = (void *)buf; |
2418 | bool need_offchan = false; | ||
2249 | u32 flags; | 2419 | u32 flags; |
2250 | bool is_offchan = false; | 2420 | int ret; |
2251 | 2421 | ||
2252 | if (dont_wait_for_ack) | 2422 | if (dont_wait_for_ack) |
2253 | flags = IEEE80211_TX_CTL_NO_ACK; | 2423 | flags = IEEE80211_TX_CTL_NO_ACK; |
@@ -2255,33 +2425,28 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
2255 | flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | | 2425 | flags = IEEE80211_TX_INTFL_NL80211_FRAME_TX | |
2256 | IEEE80211_TX_CTL_REQ_TX_STATUS; | 2426 | IEEE80211_TX_CTL_REQ_TX_STATUS; |
2257 | 2427 | ||
2258 | /* Check that we are on the requested channel for transmission */ | ||
2259 | if (chan != local->tmp_channel && | ||
2260 | chan != local->oper_channel) | ||
2261 | is_offchan = true; | ||
2262 | if (channel_type_valid && | ||
2263 | (channel_type != local->tmp_channel_type && | ||
2264 | channel_type != local->_oper_channel_type)) | ||
2265 | is_offchan = true; | ||
2266 | |||
2267 | if (chan == local->hw_roc_channel) { | ||
2268 | /* TODO: check channel type? */ | ||
2269 | is_offchan = false; | ||
2270 | flags |= IEEE80211_TX_CTL_TX_OFFCHAN; | ||
2271 | } | ||
2272 | |||
2273 | if (no_cck) | 2428 | if (no_cck) |
2274 | flags |= IEEE80211_TX_CTL_NO_CCK_RATE; | 2429 | flags |= IEEE80211_TX_CTL_NO_CCK_RATE; |
2275 | 2430 | ||
2276 | if (is_offchan && !offchan) | ||
2277 | return -EBUSY; | ||
2278 | |||
2279 | switch (sdata->vif.type) { | 2431 | switch (sdata->vif.type) { |
2280 | case NL80211_IFTYPE_ADHOC: | 2432 | case NL80211_IFTYPE_ADHOC: |
2433 | if (!sdata->vif.bss_conf.ibss_joined) | ||
2434 | need_offchan = true; | ||
2435 | /* fall through */ | ||
2436 | #ifdef CONFIG_MAC80211_MESH | ||
2437 | case NL80211_IFTYPE_MESH_POINT: | ||
2438 | if (ieee80211_vif_is_mesh(&sdata->vif) && | ||
2439 | !sdata->u.mesh.mesh_id_len) | ||
2440 | need_offchan = true; | ||
2441 | /* fall through */ | ||
2442 | #endif | ||
2281 | case NL80211_IFTYPE_AP: | 2443 | case NL80211_IFTYPE_AP: |
2282 | case NL80211_IFTYPE_AP_VLAN: | 2444 | case NL80211_IFTYPE_AP_VLAN: |
2283 | case NL80211_IFTYPE_P2P_GO: | 2445 | case NL80211_IFTYPE_P2P_GO: |
2284 | case NL80211_IFTYPE_MESH_POINT: | 2446 | if (sdata->vif.type != NL80211_IFTYPE_ADHOC && |
2447 | !ieee80211_vif_is_mesh(&sdata->vif) && | ||
2448 | !rcu_access_pointer(sdata->bss->beacon)) | ||
2449 | need_offchan = true; | ||
2285 | if (!ieee80211_is_action(mgmt->frame_control) || | 2450 | if (!ieee80211_is_action(mgmt->frame_control) || |
2286 | mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) | 2451 | mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) |
2287 | break; | 2452 | break; |
@@ -2293,167 +2458,101 @@ static int ieee80211_mgmt_tx(struct wiphy *wiphy, struct net_device *dev, | |||
2293 | break; | 2458 | break; |
2294 | case NL80211_IFTYPE_STATION: | 2459 | case NL80211_IFTYPE_STATION: |
2295 | case NL80211_IFTYPE_P2P_CLIENT: | 2460 | case NL80211_IFTYPE_P2P_CLIENT: |
2461 | if (!sdata->u.mgd.associated) | ||
2462 | need_offchan = true; | ||
2296 | break; | 2463 | break; |
2297 | default: | 2464 | default: |
2298 | return -EOPNOTSUPP; | 2465 | return -EOPNOTSUPP; |
2299 | } | 2466 | } |
2300 | 2467 | ||
2468 | mutex_lock(&local->mtx); | ||
2469 | |||
2470 | /* Check if the operating channel is the requested channel */ | ||
2471 | if (!need_offchan) { | ||
2472 | need_offchan = chan != local->oper_channel; | ||
2473 | if (channel_type_valid && | ||
2474 | channel_type != local->_oper_channel_type) | ||
2475 | need_offchan = true; | ||
2476 | } | ||
2477 | |||
2478 | if (need_offchan && !offchan) { | ||
2479 | ret = -EBUSY; | ||
2480 | goto out_unlock; | ||
2481 | } | ||
2482 | |||
2301 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); | 2483 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + len); |
2302 | if (!skb) | 2484 | if (!skb) { |
2303 | return -ENOMEM; | 2485 | ret = -ENOMEM; |
2486 | goto out_unlock; | ||
2487 | } | ||
2304 | skb_reserve(skb, local->hw.extra_tx_headroom); | 2488 | skb_reserve(skb, local->hw.extra_tx_headroom); |
2305 | 2489 | ||
2306 | memcpy(skb_put(skb, len), buf, len); | 2490 | memcpy(skb_put(skb, len), buf, len); |
2307 | 2491 | ||
2308 | IEEE80211_SKB_CB(skb)->flags = flags; | 2492 | IEEE80211_SKB_CB(skb)->flags = flags; |
2309 | 2493 | ||
2310 | if (flags & IEEE80211_TX_CTL_TX_OFFCHAN) | ||
2311 | IEEE80211_SKB_CB(skb)->hw_queue = | ||
2312 | local->hw.offchannel_tx_hw_queue; | ||
2313 | |||
2314 | skb->dev = sdata->dev; | 2494 | skb->dev = sdata->dev; |
2315 | 2495 | ||
2316 | *cookie = (unsigned long) skb; | 2496 | if (!need_offchan) { |
2317 | 2497 | *cookie = (unsigned long) skb; | |
2318 | if (is_offchan && local->ops->remain_on_channel) { | 2498 | ieee80211_tx_skb(sdata, skb); |
2319 | unsigned int duration; | 2499 | ret = 0; |
2320 | int ret; | 2500 | goto out_unlock; |
2321 | 2501 | } | |
2322 | mutex_lock(&local->mtx); | ||
2323 | /* | ||
2324 | * If the duration is zero, then the driver | ||
2325 | * wouldn't actually do anything. Set it to | ||
2326 | * 100 for now. | ||
2327 | * | ||
2328 | * TODO: cancel the off-channel operation | ||
2329 | * when we get the SKB's TX status and | ||
2330 | * the wait time was zero before. | ||
2331 | */ | ||
2332 | duration = 100; | ||
2333 | if (wait) | ||
2334 | duration = wait; | ||
2335 | ret = ieee80211_remain_on_channel_hw(local, dev, chan, | ||
2336 | channel_type, | ||
2337 | duration, cookie); | ||
2338 | if (ret) { | ||
2339 | kfree_skb(skb); | ||
2340 | mutex_unlock(&local->mtx); | ||
2341 | return ret; | ||
2342 | } | ||
2343 | |||
2344 | local->hw_roc_for_tx = true; | ||
2345 | local->hw_roc_duration = wait; | ||
2346 | |||
2347 | /* | ||
2348 | * queue up frame for transmission after | ||
2349 | * ieee80211_ready_on_channel call | ||
2350 | */ | ||
2351 | 2502 | ||
2352 | /* modify cookie to prevent API mismatches */ | 2503 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; |
2353 | *cookie ^= 2; | 2504 | if (local->hw.flags & IEEE80211_HW_QUEUE_CONTROL) |
2354 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_CTL_TX_OFFCHAN; | ||
2355 | IEEE80211_SKB_CB(skb)->hw_queue = | 2505 | IEEE80211_SKB_CB(skb)->hw_queue = |
2356 | local->hw.offchannel_tx_hw_queue; | 2506 | local->hw.offchannel_tx_hw_queue; |
2357 | local->hw_roc_skb = skb; | ||
2358 | local->hw_roc_skb_for_status = skb; | ||
2359 | mutex_unlock(&local->mtx); | ||
2360 | |||
2361 | return 0; | ||
2362 | } | ||
2363 | |||
2364 | /* | ||
2365 | * Can transmit right away if the channel was the | ||
2366 | * right one and there's no wait involved... If a | ||
2367 | * wait is involved, we might otherwise not be on | ||
2368 | * the right channel for long enough! | ||
2369 | */ | ||
2370 | if (!is_offchan && !wait && !sdata->vif.bss_conf.idle) { | ||
2371 | ieee80211_tx_skb(sdata, skb); | ||
2372 | return 0; | ||
2373 | } | ||
2374 | 2507 | ||
2375 | wk = kzalloc(sizeof(*wk) + len, GFP_KERNEL); | 2508 | /* This will handle all kinds of coalescing and immediate TX */ |
2376 | if (!wk) { | 2509 | ret = ieee80211_start_roc_work(local, sdata, chan, channel_type, |
2510 | wait, cookie, skb); | ||
2511 | if (ret) | ||
2377 | kfree_skb(skb); | 2512 | kfree_skb(skb); |
2378 | return -ENOMEM; | 2513 | out_unlock: |
2379 | } | 2514 | mutex_unlock(&local->mtx); |
2380 | 2515 | return ret; | |
2381 | wk->type = IEEE80211_WORK_OFFCHANNEL_TX; | ||
2382 | wk->chan = chan; | ||
2383 | wk->chan_type = channel_type; | ||
2384 | wk->sdata = sdata; | ||
2385 | wk->done = ieee80211_offchan_tx_done; | ||
2386 | wk->offchan_tx.frame = skb; | ||
2387 | wk->offchan_tx.wait = wait; | ||
2388 | wk->data_len = len; | ||
2389 | memcpy(wk->data, buf, len); | ||
2390 | |||
2391 | ieee80211_add_work(wk); | ||
2392 | return 0; | ||
2393 | } | 2516 | } |
2394 | 2517 | ||
2395 | static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, | 2518 | static int ieee80211_mgmt_tx_cancel_wait(struct wiphy *wiphy, |
2396 | struct net_device *dev, | 2519 | struct wireless_dev *wdev, |
2397 | u64 cookie) | 2520 | u64 cookie) |
2398 | { | 2521 | { |
2399 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 2522 | struct ieee80211_local *local = wiphy_priv(wiphy); |
2400 | struct ieee80211_local *local = sdata->local; | ||
2401 | struct ieee80211_work *wk; | ||
2402 | int ret = -ENOENT; | ||
2403 | |||
2404 | mutex_lock(&local->mtx); | ||
2405 | |||
2406 | if (local->ops->cancel_remain_on_channel) { | ||
2407 | cookie ^= 2; | ||
2408 | ret = ieee80211_cancel_remain_on_channel_hw(local, cookie); | ||
2409 | |||
2410 | if (ret == 0) { | ||
2411 | kfree_skb(local->hw_roc_skb); | ||
2412 | local->hw_roc_skb = NULL; | ||
2413 | local->hw_roc_skb_for_status = NULL; | ||
2414 | } | ||
2415 | |||
2416 | mutex_unlock(&local->mtx); | ||
2417 | |||
2418 | return ret; | ||
2419 | } | ||
2420 | |||
2421 | list_for_each_entry(wk, &local->work_list, list) { | ||
2422 | if (wk->sdata != sdata) | ||
2423 | continue; | ||
2424 | |||
2425 | if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) | ||
2426 | continue; | ||
2427 | |||
2428 | if (cookie != (unsigned long) wk->offchan_tx.frame) | ||
2429 | continue; | ||
2430 | |||
2431 | wk->timeout = jiffies; | ||
2432 | |||
2433 | ieee80211_queue_work(&local->hw, &local->work_work); | ||
2434 | ret = 0; | ||
2435 | break; | ||
2436 | } | ||
2437 | mutex_unlock(&local->mtx); | ||
2438 | 2523 | ||
2439 | return ret; | 2524 | return ieee80211_cancel_roc(local, cookie, true); |
2440 | } | 2525 | } |
2441 | 2526 | ||
2442 | static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, | 2527 | static void ieee80211_mgmt_frame_register(struct wiphy *wiphy, |
2443 | struct net_device *dev, | 2528 | struct wireless_dev *wdev, |
2444 | u16 frame_type, bool reg) | 2529 | u16 frame_type, bool reg) |
2445 | { | 2530 | { |
2446 | struct ieee80211_local *local = wiphy_priv(wiphy); | 2531 | struct ieee80211_local *local = wiphy_priv(wiphy); |
2532 | struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev); | ||
2447 | 2533 | ||
2448 | if (frame_type != (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ)) | 2534 | switch (frame_type) { |
2449 | return; | 2535 | case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH: |
2536 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | ||
2537 | struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; | ||
2450 | 2538 | ||
2451 | if (reg) | 2539 | if (reg) |
2452 | local->probe_req_reg++; | 2540 | ifibss->auth_frame_registrations++; |
2453 | else | 2541 | else |
2454 | local->probe_req_reg--; | 2542 | ifibss->auth_frame_registrations--; |
2543 | } | ||
2544 | break; | ||
2545 | case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: | ||
2546 | if (reg) | ||
2547 | local->probe_req_reg++; | ||
2548 | else | ||
2549 | local->probe_req_reg--; | ||
2455 | 2550 | ||
2456 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); | 2551 | ieee80211_queue_work(&local->hw, &local->reconfig_filter); |
2552 | break; | ||
2553 | default: | ||
2554 | break; | ||
2555 | } | ||
2457 | } | 2556 | } |
2458 | 2557 | ||
2459 | static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) | 2558 | static int ieee80211_set_antenna(struct wiphy *wiphy, u32 tx_ant, u32 rx_ant) |
@@ -2573,8 +2672,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, | |||
2573 | tf->u.setup_req.capability = | 2672 | tf->u.setup_req.capability = |
2574 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | 2673 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); |
2575 | 2674 | ||
2576 | ieee80211_add_srates_ie(&sdata->vif, skb, false); | 2675 | ieee80211_add_srates_ie(sdata, skb, false); |
2577 | ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); | 2676 | ieee80211_add_ext_srates_ie(sdata, skb, false); |
2578 | ieee80211_tdls_add_ext_capab(skb); | 2677 | ieee80211_tdls_add_ext_capab(skb); |
2579 | break; | 2678 | break; |
2580 | case WLAN_TDLS_SETUP_RESPONSE: | 2679 | case WLAN_TDLS_SETUP_RESPONSE: |
@@ -2587,8 +2686,8 @@ ieee80211_prep_tdls_encap_data(struct wiphy *wiphy, struct net_device *dev, | |||
2587 | tf->u.setup_resp.capability = | 2686 | tf->u.setup_resp.capability = |
2588 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | 2687 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); |
2589 | 2688 | ||
2590 | ieee80211_add_srates_ie(&sdata->vif, skb, false); | 2689 | ieee80211_add_srates_ie(sdata, skb, false); |
2591 | ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); | 2690 | ieee80211_add_ext_srates_ie(sdata, skb, false); |
2592 | ieee80211_tdls_add_ext_capab(skb); | 2691 | ieee80211_tdls_add_ext_capab(skb); |
2593 | break; | 2692 | break; |
2594 | case WLAN_TDLS_SETUP_CONFIRM: | 2693 | case WLAN_TDLS_SETUP_CONFIRM: |
@@ -2648,8 +2747,8 @@ ieee80211_prep_tdls_direct(struct wiphy *wiphy, struct net_device *dev, | |||
2648 | mgmt->u.action.u.tdls_discover_resp.capability = | 2747 | mgmt->u.action.u.tdls_discover_resp.capability = |
2649 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); | 2748 | cpu_to_le16(ieee80211_get_tdls_sta_capab(sdata)); |
2650 | 2749 | ||
2651 | ieee80211_add_srates_ie(&sdata->vif, skb, false); | 2750 | ieee80211_add_srates_ie(sdata, skb, false); |
2652 | ieee80211_add_ext_srates_ie(&sdata->vif, skb, false); | 2751 | ieee80211_add_ext_srates_ie(sdata, skb, false); |
2653 | ieee80211_tdls_add_ext_capab(skb); | 2752 | ieee80211_tdls_add_ext_capab(skb); |
2654 | break; | 2753 | break; |
2655 | default: | 2754 | default: |
@@ -2679,9 +2778,8 @@ static int ieee80211_tdls_mgmt(struct wiphy *wiphy, struct net_device *dev, | |||
2679 | !sdata->u.mgd.associated) | 2778 | !sdata->u.mgd.associated) |
2680 | return -EINVAL; | 2779 | return -EINVAL; |
2681 | 2780 | ||
2682 | #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG | 2781 | tdls_dbg(sdata, "TDLS mgmt action %d peer %pM\n", |
2683 | printk(KERN_DEBUG "TDLS mgmt action %d peer %pM\n", action_code, peer); | 2782 | action_code, peer); |
2684 | #endif | ||
2685 | 2783 | ||
2686 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + | 2784 | skb = dev_alloc_skb(local->hw.extra_tx_headroom + |
2687 | max(sizeof(struct ieee80211_mgmt), | 2785 | max(sizeof(struct ieee80211_mgmt), |
@@ -2790,9 +2888,7 @@ static int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, | |||
2790 | if (sdata->vif.type != NL80211_IFTYPE_STATION) | 2888 | if (sdata->vif.type != NL80211_IFTYPE_STATION) |
2791 | return -EINVAL; | 2889 | return -EINVAL; |
2792 | 2890 | ||
2793 | #ifdef CONFIG_MAC80211_VERBOSE_TDLS_DEBUG | 2891 | tdls_dbg(sdata, "TDLS oper %d peer %pM\n", oper, peer); |
2794 | printk(KERN_DEBUG "TDLS oper %d peer %pM\n", oper, peer); | ||
2795 | #endif | ||
2796 | 2892 | ||
2797 | switch (oper) { | 2893 | switch (oper) { |
2798 | case NL80211_TDLS_ENABLE_LINK: | 2894 | case NL80211_TDLS_ENABLE_LINK: |
@@ -2889,8 +2985,8 @@ static int ieee80211_probe_client(struct wiphy *wiphy, struct net_device *dev, | |||
2889 | } | 2985 | } |
2890 | 2986 | ||
2891 | static struct ieee80211_channel * | 2987 | static struct ieee80211_channel * |
2892 | ieee80211_wiphy_get_channel(struct wiphy *wiphy, | 2988 | ieee80211_cfg_get_channel(struct wiphy *wiphy, struct wireless_dev *wdev, |
2893 | enum nl80211_channel_type *type) | 2989 | enum nl80211_channel_type *type) |
2894 | { | 2990 | { |
2895 | struct ieee80211_local *local = wiphy_priv(wiphy); | 2991 | struct ieee80211_local *local = wiphy_priv(wiphy); |
2896 | 2992 | ||
@@ -2936,7 +3032,7 @@ struct cfg80211_ops mac80211_config_ops = { | |||
2936 | #endif | 3032 | #endif |
2937 | .change_bss = ieee80211_change_bss, | 3033 | .change_bss = ieee80211_change_bss, |
2938 | .set_txq_params = ieee80211_set_txq_params, | 3034 | .set_txq_params = ieee80211_set_txq_params, |
2939 | .set_channel = ieee80211_set_channel, | 3035 | .set_monitor_channel = ieee80211_set_monitor_channel, |
2940 | .suspend = ieee80211_suspend, | 3036 | .suspend = ieee80211_suspend, |
2941 | .resume = ieee80211_resume, | 3037 | .resume = ieee80211_resume, |
2942 | .scan = ieee80211_scan, | 3038 | .scan = ieee80211_scan, |
@@ -2971,7 +3067,6 @@ struct cfg80211_ops mac80211_config_ops = { | |||
2971 | .tdls_oper = ieee80211_tdls_oper, | 3067 | .tdls_oper = ieee80211_tdls_oper, |
2972 | .tdls_mgmt = ieee80211_tdls_mgmt, | 3068 | .tdls_mgmt = ieee80211_tdls_mgmt, |
2973 | .probe_client = ieee80211_probe_client, | 3069 | .probe_client = ieee80211_probe_client, |
2974 | .get_channel = ieee80211_wiphy_get_channel, | ||
2975 | .set_noack_map = ieee80211_set_noack_map, | 3070 | .set_noack_map = ieee80211_set_noack_map, |
2976 | #ifdef CONFIG_PM | 3071 | #ifdef CONFIG_PM |
2977 | .set_wakeup = ieee80211_set_wakeup, | 3072 | .set_wakeup = ieee80211_set_wakeup, |
@@ -2979,4 +3074,5 @@ struct cfg80211_ops mac80211_config_ops = { | |||
2979 | .get_et_sset_count = ieee80211_get_et_sset_count, | 3074 | .get_et_sset_count = ieee80211_get_et_sset_count, |
2980 | .get_et_stats = ieee80211_get_et_stats, | 3075 | .get_et_stats = ieee80211_get_et_stats, |
2981 | .get_et_strings = ieee80211_get_et_strings, | 3076 | .get_et_strings = ieee80211_get_et_strings, |
3077 | .get_channel = ieee80211_cfg_get_channel, | ||
2982 | }; | 3078 | }; |
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index c76cf7230c7d..f0f87e5a1d35 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -41,6 +41,10 @@ __ieee80211_get_channel_mode(struct ieee80211_local *local, | |||
41 | if (!sdata->u.ap.beacon) | 41 | if (!sdata->u.ap.beacon) |
42 | continue; | 42 | continue; |
43 | break; | 43 | break; |
44 | case NL80211_IFTYPE_MESH_POINT: | ||
45 | if (!sdata->wdev.mesh_id_len) | ||
46 | continue; | ||
47 | break; | ||
44 | default: | 48 | default: |
45 | break; | 49 | break; |
46 | } | 50 | } |
diff --git a/net/mac80211/debug.h b/net/mac80211/debug.h new file mode 100644 index 000000000000..8f383a576016 --- /dev/null +++ b/net/mac80211/debug.h | |||
@@ -0,0 +1,170 @@ | |||
1 | #ifndef __MAC80211_DEBUG_H | ||
2 | #define __MAC80211_DEBUG_H | ||
3 | #include <net/cfg80211.h> | ||
4 | |||
5 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | ||
6 | #define MAC80211_IBSS_DEBUG 1 | ||
7 | #else | ||
8 | #define MAC80211_IBSS_DEBUG 0 | ||
9 | #endif | ||
10 | |||
11 | #ifdef CONFIG_MAC80211_PS_DEBUG | ||
12 | #define MAC80211_PS_DEBUG 1 | ||
13 | #else | ||
14 | #define MAC80211_PS_DEBUG 0 | ||
15 | #endif | ||
16 | |||
17 | #ifdef CONFIG_MAC80211_HT_DEBUG | ||
18 | #define MAC80211_HT_DEBUG 1 | ||
19 | #else | ||
20 | #define MAC80211_HT_DEBUG 0 | ||
21 | #endif | ||
22 | |||
23 | #ifdef CONFIG_MAC80211_MPL_DEBUG | ||
24 | #define MAC80211_MPL_DEBUG 1 | ||
25 | #else | ||
26 | #define MAC80211_MPL_DEBUG 0 | ||
27 | #endif | ||
28 | |||
29 | #ifdef CONFIG_MAC80211_MPATH_DEBUG | ||
30 | #define MAC80211_MPATH_DEBUG 1 | ||
31 | #else | ||
32 | #define MAC80211_MPATH_DEBUG 0 | ||
33 | #endif | ||
34 | |||
35 | #ifdef CONFIG_MAC80211_MHWMP_DEBUG | ||
36 | #define MAC80211_MHWMP_DEBUG 1 | ||
37 | #else | ||
38 | #define MAC80211_MHWMP_DEBUG 0 | ||
39 | #endif | ||
40 | |||
41 | #ifdef CONFIG_MAC80211_MESH_SYNC_DEBUG | ||
42 | #define MAC80211_MESH_SYNC_DEBUG 1 | ||
43 | #else | ||
44 | #define MAC80211_MESH_SYNC_DEBUG 0 | ||
45 | #endif | ||
46 | |||
47 | #ifdef CONFIG_MAC80211_TDLS_DEBUG | ||
48 | #define MAC80211_TDLS_DEBUG 1 | ||
49 | #else | ||
50 | #define MAC80211_TDLS_DEBUG 0 | ||
51 | #endif | ||
52 | |||
53 | #ifdef CONFIG_MAC80211_STA_DEBUG | ||
54 | #define MAC80211_STA_DEBUG 1 | ||
55 | #else | ||
56 | #define MAC80211_STA_DEBUG 0 | ||
57 | #endif | ||
58 | |||
59 | #ifdef CONFIG_MAC80211_MLME_DEBUG | ||
60 | #define MAC80211_MLME_DEBUG 1 | ||
61 | #else | ||
62 | #define MAC80211_MLME_DEBUG 0 | ||
63 | #endif | ||
64 | |||
65 | #ifdef CONFIG_MAC80211_MESSAGE_TRACING | ||
66 | void __sdata_info(const char *fmt, ...) __printf(1, 2); | ||
67 | void __sdata_dbg(bool print, const char *fmt, ...) __printf(2, 3); | ||
68 | void __sdata_err(const char *fmt, ...) __printf(1, 2); | ||
69 | void __wiphy_dbg(struct wiphy *wiphy, bool print, const char *fmt, ...) | ||
70 | __printf(3, 4); | ||
71 | |||
72 | #define _sdata_info(sdata, fmt, ...) \ | ||
73 | __sdata_info("%s: " fmt, (sdata)->name, ##__VA_ARGS__) | ||
74 | #define _sdata_dbg(print, sdata, fmt, ...) \ | ||
75 | __sdata_dbg(print, "%s: " fmt, (sdata)->name, ##__VA_ARGS__) | ||
76 | #define _sdata_err(sdata, fmt, ...) \ | ||
77 | __sdata_err("%s: " fmt, (sdata)->name, ##__VA_ARGS__) | ||
78 | #define _wiphy_dbg(print, wiphy, fmt, ...) \ | ||
79 | __wiphy_dbg(wiphy, print, fmt, ##__VA_ARGS__) | ||
80 | #else | ||
81 | #define _sdata_info(sdata, fmt, ...) \ | ||
82 | do { \ | ||
83 | pr_info("%s: " fmt, \ | ||
84 | (sdata)->name, ##__VA_ARGS__); \ | ||
85 | } while (0) | ||
86 | |||
87 | #define _sdata_dbg(print, sdata, fmt, ...) \ | ||
88 | do { \ | ||
89 | if (print) \ | ||
90 | pr_debug("%s: " fmt, \ | ||
91 | (sdata)->name, ##__VA_ARGS__); \ | ||
92 | } while (0) | ||
93 | |||
94 | #define _sdata_err(sdata, fmt, ...) \ | ||
95 | do { \ | ||
96 | pr_err("%s: " fmt, \ | ||
97 | (sdata)->name, ##__VA_ARGS__); \ | ||
98 | } while (0) | ||
99 | |||
100 | #define _wiphy_dbg(print, wiphy, fmt, ...) \ | ||
101 | do { \ | ||
102 | if (print) \ | ||
103 | wiphy_dbg((wiphy), fmt, ##__VA_ARGS__); \ | ||
104 | } while (0) | ||
105 | #endif | ||
106 | |||
107 | #define sdata_info(sdata, fmt, ...) \ | ||
108 | _sdata_info(sdata, fmt, ##__VA_ARGS__) | ||
109 | #define sdata_err(sdata, fmt, ...) \ | ||
110 | _sdata_err(sdata, fmt, ##__VA_ARGS__) | ||
111 | #define sdata_dbg(sdata, fmt, ...) \ | ||
112 | _sdata_dbg(1, sdata, fmt, ##__VA_ARGS__) | ||
113 | |||
114 | #define ht_dbg(sdata, fmt, ...) \ | ||
115 | _sdata_dbg(MAC80211_HT_DEBUG, \ | ||
116 | sdata, fmt, ##__VA_ARGS__) | ||
117 | |||
118 | #define ht_dbg_ratelimited(sdata, fmt, ...) \ | ||
119 | _sdata_dbg(MAC80211_HT_DEBUG && net_ratelimit(), \ | ||
120 | sdata, fmt, ##__VA_ARGS__) | ||
121 | |||
122 | #define ibss_dbg(sdata, fmt, ...) \ | ||
123 | _sdata_dbg(MAC80211_IBSS_DEBUG, \ | ||
124 | sdata, fmt, ##__VA_ARGS__) | ||
125 | |||
126 | #define ps_dbg(sdata, fmt, ...) \ | ||
127 | _sdata_dbg(MAC80211_PS_DEBUG, \ | ||
128 | sdata, fmt, ##__VA_ARGS__) | ||
129 | |||
130 | #define ps_dbg_hw(hw, fmt, ...) \ | ||
131 | _wiphy_dbg(MAC80211_PS_DEBUG, \ | ||
132 | (hw)->wiphy, fmt, ##__VA_ARGS__) | ||
133 | |||
134 | #define ps_dbg_ratelimited(sdata, fmt, ...) \ | ||
135 | _sdata_dbg(MAC80211_PS_DEBUG && net_ratelimit(), \ | ||
136 | sdata, fmt, ##__VA_ARGS__) | ||
137 | |||
138 | #define mpl_dbg(sdata, fmt, ...) \ | ||
139 | _sdata_dbg(MAC80211_MPL_DEBUG, \ | ||
140 | sdata, fmt, ##__VA_ARGS__) | ||
141 | |||
142 | #define mpath_dbg(sdata, fmt, ...) \ | ||
143 | _sdata_dbg(MAC80211_MPATH_DEBUG, \ | ||
144 | sdata, fmt, ##__VA_ARGS__) | ||
145 | |||
146 | #define mhwmp_dbg(sdata, fmt, ...) \ | ||
147 | _sdata_dbg(MAC80211_MHWMP_DEBUG, \ | ||
148 | sdata, fmt, ##__VA_ARGS__) | ||
149 | |||
150 | #define msync_dbg(sdata, fmt, ...) \ | ||
151 | _sdata_dbg(MAC80211_MESH_SYNC_DEBUG, \ | ||
152 | sdata, fmt, ##__VA_ARGS__) | ||
153 | |||
154 | #define tdls_dbg(sdata, fmt, ...) \ | ||
155 | _sdata_dbg(MAC80211_TDLS_DEBUG, \ | ||
156 | sdata, fmt, ##__VA_ARGS__) | ||
157 | |||
158 | #define sta_dbg(sdata, fmt, ...) \ | ||
159 | _sdata_dbg(MAC80211_STA_DEBUG, \ | ||
160 | sdata, fmt, ##__VA_ARGS__) | ||
161 | |||
162 | #define mlme_dbg(sdata, fmt, ...) \ | ||
163 | _sdata_dbg(MAC80211_MLME_DEBUG, \ | ||
164 | sdata, fmt, ##__VA_ARGS__) | ||
165 | |||
166 | #define mlme_dbg_ratelimited(sdata, fmt, ...) \ | ||
167 | _sdata_dbg(MAC80211_MLME_DEBUG && net_ratelimit(), \ | ||
168 | sdata, fmt, ##__VA_ARGS__) | ||
169 | |||
170 | #endif /* __MAC80211_DEBUG_H */ | ||
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 778e5916d7c3..b8dfb440c8ef 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -325,8 +325,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
325 | local->rx_handlers_drop_defrag); | 325 | local->rx_handlers_drop_defrag); |
326 | DEBUGFS_STATS_ADD(rx_handlers_drop_short, | 326 | DEBUGFS_STATS_ADD(rx_handlers_drop_short, |
327 | local->rx_handlers_drop_short); | 327 | local->rx_handlers_drop_short); |
328 | DEBUGFS_STATS_ADD(rx_handlers_drop_passive_scan, | ||
329 | local->rx_handlers_drop_passive_scan); | ||
330 | DEBUGFS_STATS_ADD(tx_expand_skb_head, | 328 | DEBUGFS_STATS_ADD(tx_expand_skb_head, |
331 | local->tx_expand_skb_head); | 329 | local->tx_expand_skb_head); |
332 | DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned, | 330 | DEBUGFS_STATS_ADD(tx_expand_skb_head_cloned, |
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 7932767bb482..090d08ff22c4 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
@@ -283,6 +283,11 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) | |||
283 | 283 | ||
284 | lockdep_assert_held(&sdata->local->key_mtx); | 284 | lockdep_assert_held(&sdata->local->key_mtx); |
285 | 285 | ||
286 | if (sdata->debugfs.default_unicast_key) { | ||
287 | debugfs_remove(sdata->debugfs.default_unicast_key); | ||
288 | sdata->debugfs.default_unicast_key = NULL; | ||
289 | } | ||
290 | |||
286 | if (sdata->default_unicast_key) { | 291 | if (sdata->default_unicast_key) { |
287 | key = key_mtx_dereference(sdata->local, | 292 | key = key_mtx_dereference(sdata->local, |
288 | sdata->default_unicast_key); | 293 | sdata->default_unicast_key); |
@@ -290,9 +295,11 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) | |||
290 | sdata->debugfs.default_unicast_key = | 295 | sdata->debugfs.default_unicast_key = |
291 | debugfs_create_symlink("default_unicast_key", | 296 | debugfs_create_symlink("default_unicast_key", |
292 | sdata->debugfs.dir, buf); | 297 | sdata->debugfs.dir, buf); |
293 | } else { | 298 | } |
294 | debugfs_remove(sdata->debugfs.default_unicast_key); | 299 | |
295 | sdata->debugfs.default_unicast_key = NULL; | 300 | if (sdata->debugfs.default_multicast_key) { |
301 | debugfs_remove(sdata->debugfs.default_multicast_key); | ||
302 | sdata->debugfs.default_multicast_key = NULL; | ||
296 | } | 303 | } |
297 | 304 | ||
298 | if (sdata->default_multicast_key) { | 305 | if (sdata->default_multicast_key) { |
@@ -302,9 +309,6 @@ void ieee80211_debugfs_key_update_default(struct ieee80211_sub_if_data *sdata) | |||
302 | sdata->debugfs.default_multicast_key = | 309 | sdata->debugfs.default_multicast_key = |
303 | debugfs_create_symlink("default_multicast_key", | 310 | debugfs_create_symlink("default_multicast_key", |
304 | sdata->debugfs.dir, buf); | 311 | sdata->debugfs.dir, buf); |
305 | } else { | ||
306 | debugfs_remove(sdata->debugfs.default_multicast_key); | ||
307 | sdata->debugfs.default_multicast_key = NULL; | ||
308 | } | 312 | } |
309 | } | 313 | } |
310 | 314 | ||
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 7ed433c66d68..6d5aec9418ee 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -468,48 +468,54 @@ IEEE80211_IF_FILE(fwded_unicast, u.mesh.mshstats.fwded_unicast, DEC); | |||
468 | IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); | 468 | IEEE80211_IF_FILE(fwded_frames, u.mesh.mshstats.fwded_frames, DEC); |
469 | IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); | 469 | IEEE80211_IF_FILE(dropped_frames_ttl, u.mesh.mshstats.dropped_frames_ttl, DEC); |
470 | IEEE80211_IF_FILE(dropped_frames_congestion, | 470 | IEEE80211_IF_FILE(dropped_frames_congestion, |
471 | u.mesh.mshstats.dropped_frames_congestion, DEC); | 471 | u.mesh.mshstats.dropped_frames_congestion, DEC); |
472 | IEEE80211_IF_FILE(dropped_frames_no_route, | 472 | IEEE80211_IF_FILE(dropped_frames_no_route, |
473 | u.mesh.mshstats.dropped_frames_no_route, DEC); | 473 | u.mesh.mshstats.dropped_frames_no_route, DEC); |
474 | IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); | 474 | IEEE80211_IF_FILE(estab_plinks, u.mesh.mshstats.estab_plinks, ATOMIC); |
475 | 475 | ||
476 | /* Mesh parameters */ | 476 | /* Mesh parameters */ |
477 | IEEE80211_IF_FILE(dot11MeshMaxRetries, | 477 | IEEE80211_IF_FILE(dot11MeshMaxRetries, |
478 | u.mesh.mshcfg.dot11MeshMaxRetries, DEC); | 478 | u.mesh.mshcfg.dot11MeshMaxRetries, DEC); |
479 | IEEE80211_IF_FILE(dot11MeshRetryTimeout, | 479 | IEEE80211_IF_FILE(dot11MeshRetryTimeout, |
480 | u.mesh.mshcfg.dot11MeshRetryTimeout, DEC); | 480 | u.mesh.mshcfg.dot11MeshRetryTimeout, DEC); |
481 | IEEE80211_IF_FILE(dot11MeshConfirmTimeout, | 481 | IEEE80211_IF_FILE(dot11MeshConfirmTimeout, |
482 | u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC); | 482 | u.mesh.mshcfg.dot11MeshConfirmTimeout, DEC); |
483 | IEEE80211_IF_FILE(dot11MeshHoldingTimeout, | 483 | IEEE80211_IF_FILE(dot11MeshHoldingTimeout, |
484 | u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); | 484 | u.mesh.mshcfg.dot11MeshHoldingTimeout, DEC); |
485 | IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC); | 485 | IEEE80211_IF_FILE(dot11MeshTTL, u.mesh.mshcfg.dot11MeshTTL, DEC); |
486 | IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC); | 486 | IEEE80211_IF_FILE(element_ttl, u.mesh.mshcfg.element_ttl, DEC); |
487 | IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC); | 487 | IEEE80211_IF_FILE(auto_open_plinks, u.mesh.mshcfg.auto_open_plinks, DEC); |
488 | IEEE80211_IF_FILE(dot11MeshMaxPeerLinks, | 488 | IEEE80211_IF_FILE(dot11MeshMaxPeerLinks, |
489 | u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); | 489 | u.mesh.mshcfg.dot11MeshMaxPeerLinks, DEC); |
490 | IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout, | 490 | IEEE80211_IF_FILE(dot11MeshHWMPactivePathTimeout, |
491 | u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); | 491 | u.mesh.mshcfg.dot11MeshHWMPactivePathTimeout, DEC); |
492 | IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval, | 492 | IEEE80211_IF_FILE(dot11MeshHWMPpreqMinInterval, |
493 | u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); | 493 | u.mesh.mshcfg.dot11MeshHWMPpreqMinInterval, DEC); |
494 | IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval, | 494 | IEEE80211_IF_FILE(dot11MeshHWMPperrMinInterval, |
495 | u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC); | 495 | u.mesh.mshcfg.dot11MeshHWMPperrMinInterval, DEC); |
496 | IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime, | 496 | IEEE80211_IF_FILE(dot11MeshHWMPnetDiameterTraversalTime, |
497 | u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); | 497 | u.mesh.mshcfg.dot11MeshHWMPnetDiameterTraversalTime, DEC); |
498 | IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries, | 498 | IEEE80211_IF_FILE(dot11MeshHWMPmaxPREQretries, |
499 | u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC); | 499 | u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries, DEC); |
500 | IEEE80211_IF_FILE(path_refresh_time, | 500 | IEEE80211_IF_FILE(path_refresh_time, |
501 | u.mesh.mshcfg.path_refresh_time, DEC); | 501 | u.mesh.mshcfg.path_refresh_time, DEC); |
502 | IEEE80211_IF_FILE(min_discovery_timeout, | 502 | IEEE80211_IF_FILE(min_discovery_timeout, |
503 | u.mesh.mshcfg.min_discovery_timeout, DEC); | 503 | u.mesh.mshcfg.min_discovery_timeout, DEC); |
504 | IEEE80211_IF_FILE(dot11MeshHWMPRootMode, | 504 | IEEE80211_IF_FILE(dot11MeshHWMPRootMode, |
505 | u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); | 505 | u.mesh.mshcfg.dot11MeshHWMPRootMode, DEC); |
506 | IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, | 506 | IEEE80211_IF_FILE(dot11MeshGateAnnouncementProtocol, |
507 | u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC); | 507 | u.mesh.mshcfg.dot11MeshGateAnnouncementProtocol, DEC); |
508 | IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, | 508 | IEEE80211_IF_FILE(dot11MeshHWMPRannInterval, |
509 | u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); | 509 | u.mesh.mshcfg.dot11MeshHWMPRannInterval, DEC); |
510 | IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); | 510 | IEEE80211_IF_FILE(dot11MeshForwarding, u.mesh.mshcfg.dot11MeshForwarding, DEC); |
511 | IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); | 511 | IEEE80211_IF_FILE(rssi_threshold, u.mesh.mshcfg.rssi_threshold, DEC); |
512 | IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC); | 512 | IEEE80211_IF_FILE(ht_opmode, u.mesh.mshcfg.ht_opmode, DEC); |
513 | IEEE80211_IF_FILE(dot11MeshHWMPactivePathToRootTimeout, | ||
514 | u.mesh.mshcfg.dot11MeshHWMPactivePathToRootTimeout, DEC); | ||
515 | IEEE80211_IF_FILE(dot11MeshHWMProotInterval, | ||
516 | u.mesh.mshcfg.dot11MeshHWMProotInterval, DEC); | ||
517 | IEEE80211_IF_FILE(dot11MeshHWMPconfirmationInterval, | ||
518 | u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval, DEC); | ||
513 | #endif | 519 | #endif |
514 | 520 | ||
515 | #define DEBUGFS_ADD_MODE(name, mode) \ | 521 | #define DEBUGFS_ADD_MODE(name, mode) \ |
@@ -607,9 +613,13 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) | |||
607 | MESHPARAMS_ADD(min_discovery_timeout); | 613 | MESHPARAMS_ADD(min_discovery_timeout); |
608 | MESHPARAMS_ADD(dot11MeshHWMPRootMode); | 614 | MESHPARAMS_ADD(dot11MeshHWMPRootMode); |
609 | MESHPARAMS_ADD(dot11MeshHWMPRannInterval); | 615 | MESHPARAMS_ADD(dot11MeshHWMPRannInterval); |
616 | MESHPARAMS_ADD(dot11MeshForwarding); | ||
610 | MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); | 617 | MESHPARAMS_ADD(dot11MeshGateAnnouncementProtocol); |
611 | MESHPARAMS_ADD(rssi_threshold); | 618 | MESHPARAMS_ADD(rssi_threshold); |
612 | MESHPARAMS_ADD(ht_opmode); | 619 | MESHPARAMS_ADD(ht_opmode); |
620 | MESHPARAMS_ADD(dot11MeshHWMPactivePathToRootTimeout); | ||
621 | MESHPARAMS_ADD(dot11MeshHWMProotInterval); | ||
622 | MESHPARAMS_ADD(dot11MeshHWMPconfirmationInterval); | ||
613 | #undef MESHPARAMS_ADD | 623 | #undef MESHPARAMS_ADD |
614 | } | 624 | } |
615 | #endif | 625 | #endif |
@@ -685,6 +695,7 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) | |||
685 | 695 | ||
686 | sprintf(buf, "netdev:%s", sdata->name); | 696 | sprintf(buf, "netdev:%s", sdata->name); |
687 | if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) | 697 | if (!debugfs_rename(dir->d_parent, dir, dir->d_parent, buf)) |
688 | printk(KERN_ERR "mac80211: debugfs: failed to rename debugfs " | 698 | sdata_err(sdata, |
689 | "dir to %s\n", buf); | 699 | "debugfs: failed to rename debugfs dir to %s\n", |
700 | buf); | ||
690 | } | 701 | } |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 6d33a0c743ab..df9203199102 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
@@ -3,7 +3,7 @@ | |||
3 | 3 | ||
4 | #include <net/mac80211.h> | 4 | #include <net/mac80211.h> |
5 | #include "ieee80211_i.h" | 5 | #include "ieee80211_i.h" |
6 | #include "driver-trace.h" | 6 | #include "trace.h" |
7 | 7 | ||
8 | static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) | 8 | static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata) |
9 | { | 9 | { |
@@ -27,14 +27,6 @@ static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) | |||
27 | local->ops->tx(&local->hw, skb); | 27 | local->ops->tx(&local->hw, skb); |
28 | } | 28 | } |
29 | 29 | ||
30 | static inline void drv_tx_frags(struct ieee80211_local *local, | ||
31 | struct ieee80211_vif *vif, | ||
32 | struct ieee80211_sta *sta, | ||
33 | struct sk_buff_head *skbs) | ||
34 | { | ||
35 | local->ops->tx_frags(&local->hw, vif, sta, skbs); | ||
36 | } | ||
37 | |||
38 | static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, | 30 | static inline void drv_get_et_strings(struct ieee80211_sub_if_data *sdata, |
39 | u32 sset, u8 *data) | 31 | u32 sset, u8 *data) |
40 | { | 32 | { |
@@ -845,4 +837,33 @@ drv_allow_buffered_frames(struct ieee80211_local *local, | |||
845 | more_data); | 837 | more_data); |
846 | trace_drv_return_void(local); | 838 | trace_drv_return_void(local); |
847 | } | 839 | } |
840 | |||
841 | static inline int drv_get_rssi(struct ieee80211_local *local, | ||
842 | struct ieee80211_sub_if_data *sdata, | ||
843 | struct ieee80211_sta *sta, | ||
844 | s8 *rssi_dbm) | ||
845 | { | ||
846 | int ret; | ||
847 | |||
848 | might_sleep(); | ||
849 | |||
850 | ret = local->ops->get_rssi(&local->hw, &sdata->vif, sta, rssi_dbm); | ||
851 | trace_drv_get_rssi(local, sta, *rssi_dbm, ret); | ||
852 | |||
853 | return ret; | ||
854 | } | ||
855 | |||
856 | static inline void drv_mgd_prepare_tx(struct ieee80211_local *local, | ||
857 | struct ieee80211_sub_if_data *sdata) | ||
858 | { | ||
859 | might_sleep(); | ||
860 | |||
861 | check_sdata_in_driver(sdata); | ||
862 | WARN_ON_ONCE(sdata->vif.type != NL80211_IFTYPE_STATION); | ||
863 | |||
864 | trace_drv_mgd_prepare_tx(local, sdata); | ||
865 | if (local->ops->mgd_prepare_tx) | ||
866 | local->ops->mgd_prepare_tx(&local->hw, &sdata->vif); | ||
867 | trace_drv_return_void(local); | ||
868 | } | ||
848 | #endif /* __MAC80211_DRIVER_OPS */ | 869 | #endif /* __MAC80211_DRIVER_OPS */ |
diff --git a/net/mac80211/driver-trace.c b/net/mac80211/driver-trace.c deleted file mode 100644 index 8ed8711b1a6d..000000000000 --- a/net/mac80211/driver-trace.c +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | /* bug in tracepoint.h, it should include this */ | ||
2 | #include <linux/module.h> | ||
3 | |||
4 | /* sparse isn't too happy with all macros... */ | ||
5 | #ifndef __CHECKER__ | ||
6 | #include "driver-ops.h" | ||
7 | #define CREATE_TRACE_POINTS | ||
8 | #include "driver-trace.h" | ||
9 | #endif | ||
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 6f8615c54b22..4b4538d63925 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -305,12 +305,10 @@ void ieee80211_process_delba(struct ieee80211_sub_if_data *sdata, | |||
305 | tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; | 305 | tid = (params & IEEE80211_DELBA_PARAM_TID_MASK) >> 12; |
306 | initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11; | 306 | initiator = (params & IEEE80211_DELBA_PARAM_INITIATOR_MASK) >> 11; |
307 | 307 | ||
308 | #ifdef CONFIG_MAC80211_HT_DEBUG | 308 | ht_dbg_ratelimited(sdata, "delba from %pM (%s) tid %d reason code %d\n", |
309 | net_dbg_ratelimited("delba from %pM (%s) tid %d reason code %d\n", | 309 | mgmt->sa, initiator ? "initiator" : "recipient", |
310 | mgmt->sa, initiator ? "initiator" : "recipient", | 310 | tid, |
311 | tid, | 311 | le16_to_cpu(mgmt->u.action.u.delba.reason_code)); |
312 | le16_to_cpu(mgmt->u.action.u.delba.reason_code)); | ||
313 | #endif /* CONFIG_MAC80211_HT_DEBUG */ | ||
314 | 312 | ||
315 | if (initiator == WLAN_BACK_INITIATOR) | 313 | if (initiator == WLAN_BACK_INITIATOR) |
316 | __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0, | 314 | __ieee80211_stop_rx_ba_session(sta, tid, WLAN_BACK_INITIATOR, 0, |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 33d9d0c3e3d0..5746d62faba1 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -82,8 +82,7 @@ static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, | |||
82 | 82 | ||
83 | local->oper_channel = chan; | 83 | local->oper_channel = chan; |
84 | channel_type = ifibss->channel_type; | 84 | channel_type = ifibss->channel_type; |
85 | if (channel_type > NL80211_CHAN_HT20 && | 85 | if (!cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) |
86 | !cfg80211_can_beacon_sec_chan(local->hw.wiphy, chan, channel_type)) | ||
87 | channel_type = NL80211_CHAN_HT20; | 86 | channel_type = NL80211_CHAN_HT20; |
88 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { | 87 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { |
89 | /* can only fail due to HT40+/- mismatch */ | 88 | /* can only fail due to HT40+/- mismatch */ |
@@ -262,11 +261,7 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, | |||
262 | 261 | ||
263 | memcpy(addr, sta->sta.addr, ETH_ALEN); | 262 | memcpy(addr, sta->sta.addr, ETH_ALEN); |
264 | 263 | ||
265 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 264 | ibss_dbg(sdata, "Adding new IBSS station %pM\n", addr); |
266 | wiphy_debug(sdata->local->hw.wiphy, | ||
267 | "Adding new IBSS station %pM (dev=%s)\n", | ||
268 | addr, sdata->name); | ||
269 | #endif | ||
270 | 265 | ||
271 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); | 266 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); |
272 | sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); | 267 | sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC); |
@@ -280,12 +275,10 @@ static struct sta_info *ieee80211_ibss_finish_sta(struct sta_info *sta, | |||
280 | /* If it fails, maybe we raced another insertion? */ | 275 | /* If it fails, maybe we raced another insertion? */ |
281 | if (sta_info_insert_rcu(sta)) | 276 | if (sta_info_insert_rcu(sta)) |
282 | return sta_info_get(sdata, addr); | 277 | return sta_info_get(sdata, addr); |
283 | if (auth) { | 278 | if (auth && !sdata->u.ibss.auth_frame_registrations) { |
284 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 279 | ibss_dbg(sdata, |
285 | printk(KERN_DEBUG "TX Auth SA=%pM DA=%pM BSSID=%pM" | 280 | "TX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=1)\n", |
286 | "(auth_transaction=1)\n", sdata->vif.addr, | 281 | sdata->vif.addr, sdata->u.ibss.bssid, addr); |
287 | sdata->u.ibss.bssid, addr); | ||
288 | #endif | ||
289 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, | 282 | ieee80211_send_auth(sdata, 1, WLAN_AUTH_OPEN, NULL, 0, |
290 | addr, sdata->u.ibss.bssid, NULL, 0, 0); | 283 | addr, sdata->u.ibss.bssid, NULL, 0, 0); |
291 | } | 284 | } |
@@ -308,7 +301,7 @@ ieee80211_ibss_add_sta(struct ieee80211_sub_if_data *sdata, | |||
308 | * allow new one to be added. | 301 | * allow new one to be added. |
309 | */ | 302 | */ |
310 | if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { | 303 | if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { |
311 | net_dbg_ratelimited("%s: No room for a new IBSS STA entry %pM\n", | 304 | net_info_ratelimited("%s: No room for a new IBSS STA entry %pM\n", |
312 | sdata->name, addr); | 305 | sdata->name, addr); |
313 | rcu_read_lock(); | 306 | rcu_read_lock(); |
314 | return NULL; | 307 | return NULL; |
@@ -355,11 +348,9 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata, | |||
355 | 348 | ||
356 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) | 349 | if (auth_alg != WLAN_AUTH_OPEN || auth_transaction != 1) |
357 | return; | 350 | return; |
358 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 351 | ibss_dbg(sdata, |
359 | printk(KERN_DEBUG "%s: RX Auth SA=%pM DA=%pM BSSID=%pM." | 352 | "RX Auth SA=%pM DA=%pM BSSID=%pM (auth_transaction=%d)\n", |
360 | "(auth_transaction=%d)\n", | 353 | mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); |
361 | sdata->name, mgmt->sa, mgmt->da, mgmt->bssid, auth_transaction); | ||
362 | #endif | ||
363 | sta_info_destroy_addr(sdata, mgmt->sa); | 354 | sta_info_destroy_addr(sdata, mgmt->sa); |
364 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); | 355 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, 0, false); |
365 | rcu_read_unlock(); | 356 | rcu_read_unlock(); |
@@ -422,15 +413,10 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
422 | ieee80211_mandatory_rates(local, band); | 413 | ieee80211_mandatory_rates(local, band); |
423 | 414 | ||
424 | if (sta->sta.supp_rates[band] != prev_rates) { | 415 | if (sta->sta.supp_rates[band] != prev_rates) { |
425 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 416 | ibss_dbg(sdata, |
426 | printk(KERN_DEBUG | 417 | "updated supp_rates set for %pM based on beacon/probe_resp (0x%x -> 0x%x)\n", |
427 | "%s: updated supp_rates set " | 418 | sta->sta.addr, prev_rates, |
428 | "for %pM based on beacon" | 419 | sta->sta.supp_rates[band]); |
429 | "/probe_resp (0x%x -> 0x%x)\n", | ||
430 | sdata->name, sta->sta.addr, | ||
431 | prev_rates, | ||
432 | sta->sta.supp_rates[band]); | ||
433 | #endif | ||
434 | rates_updated = true; | 420 | rates_updated = true; |
435 | } | 421 | } |
436 | } else { | 422 | } else { |
@@ -545,22 +531,18 @@ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata, | |||
545 | rx_timestamp = drv_get_tsf(local, sdata); | 531 | rx_timestamp = drv_get_tsf(local, sdata); |
546 | } | 532 | } |
547 | 533 | ||
548 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 534 | ibss_dbg(sdata, |
549 | printk(KERN_DEBUG "RX beacon SA=%pM BSSID=" | 535 | "RX beacon SA=%pM BSSID=%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", |
550 | "%pM TSF=0x%llx BCN=0x%llx diff=%lld @%lu\n", | 536 | mgmt->sa, mgmt->bssid, |
551 | mgmt->sa, mgmt->bssid, | 537 | (unsigned long long)rx_timestamp, |
552 | (unsigned long long)rx_timestamp, | 538 | (unsigned long long)beacon_timestamp, |
553 | (unsigned long long)beacon_timestamp, | 539 | (unsigned long long)(rx_timestamp - beacon_timestamp), |
554 | (unsigned long long)(rx_timestamp - beacon_timestamp), | 540 | jiffies); |
555 | jiffies); | ||
556 | #endif | ||
557 | 541 | ||
558 | if (beacon_timestamp > rx_timestamp) { | 542 | if (beacon_timestamp > rx_timestamp) { |
559 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 543 | ibss_dbg(sdata, |
560 | printk(KERN_DEBUG "%s: beacon TSF higher than " | 544 | "beacon TSF higher than local TSF - IBSS merge with BSSID %pM\n", |
561 | "local TSF - IBSS merge with BSSID %pM\n", | 545 | mgmt->bssid); |
562 | sdata->name, mgmt->bssid); | ||
563 | #endif | ||
564 | ieee80211_sta_join_ibss(sdata, bss); | 546 | ieee80211_sta_join_ibss(sdata, bss); |
565 | supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); | 547 | supp_rates = ieee80211_sta_get_rates(local, elems, band, NULL); |
566 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, | 548 | ieee80211_ibss_add_sta(sdata, mgmt->bssid, mgmt->sa, |
@@ -586,7 +568,7 @@ void ieee80211_ibss_rx_no_sta(struct ieee80211_sub_if_data *sdata, | |||
586 | * allow new one to be added. | 568 | * allow new one to be added. |
587 | */ | 569 | */ |
588 | if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { | 570 | if (local->num_sta >= IEEE80211_IBSS_MAX_STA_ENTRIES) { |
589 | net_dbg_ratelimited("%s: No room for a new IBSS STA entry %pM\n", | 571 | net_info_ratelimited("%s: No room for a new IBSS STA entry %pM\n", |
590 | sdata->name, addr); | 572 | sdata->name, addr); |
591 | return; | 573 | return; |
592 | } | 574 | } |
@@ -662,8 +644,8 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
662 | if (ifibss->fixed_channel) | 644 | if (ifibss->fixed_channel) |
663 | return; | 645 | return; |
664 | 646 | ||
665 | printk(KERN_DEBUG "%s: No active IBSS STAs - trying to scan for other " | 647 | sdata_info(sdata, |
666 | "IBSS networks with same SSID (merge)\n", sdata->name); | 648 | "No active IBSS STAs - trying to scan for other IBSS networks with same SSID (merge)\n"); |
667 | 649 | ||
668 | ieee80211_request_internal_scan(sdata, | 650 | ieee80211_request_internal_scan(sdata, |
669 | ifibss->ssid, ifibss->ssid_len, NULL); | 651 | ifibss->ssid, ifibss->ssid_len, NULL); |
@@ -691,8 +673,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata) | |||
691 | bssid[0] |= 0x02; | 673 | bssid[0] |= 0x02; |
692 | } | 674 | } |
693 | 675 | ||
694 | printk(KERN_DEBUG "%s: Creating new IBSS network, BSSID %pM\n", | 676 | sdata_info(sdata, "Creating new IBSS network, BSSID %pM\n", bssid); |
695 | sdata->name, bssid); | ||
696 | 677 | ||
697 | capability = WLAN_CAPABILITY_IBSS; | 678 | capability = WLAN_CAPABILITY_IBSS; |
698 | 679 | ||
@@ -723,10 +704,7 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
723 | lockdep_assert_held(&ifibss->mtx); | 704 | lockdep_assert_held(&ifibss->mtx); |
724 | 705 | ||
725 | active_ibss = ieee80211_sta_active_ibss(sdata); | 706 | active_ibss = ieee80211_sta_active_ibss(sdata); |
726 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 707 | ibss_dbg(sdata, "sta_find_ibss (active_ibss=%d)\n", active_ibss); |
727 | printk(KERN_DEBUG "%s: sta_find_ibss (active_ibss=%d)\n", | ||
728 | sdata->name, active_ibss); | ||
729 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
730 | 708 | ||
731 | if (active_ibss) | 709 | if (active_ibss) |
732 | return; | 710 | return; |
@@ -749,29 +727,24 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
749 | struct ieee80211_bss *bss; | 727 | struct ieee80211_bss *bss; |
750 | 728 | ||
751 | bss = (void *)cbss->priv; | 729 | bss = (void *)cbss->priv; |
752 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 730 | ibss_dbg(sdata, |
753 | printk(KERN_DEBUG " sta_find_ibss: selected %pM current " | 731 | "sta_find_ibss: selected %pM current %pM\n", |
754 | "%pM\n", cbss->bssid, ifibss->bssid); | 732 | cbss->bssid, ifibss->bssid); |
755 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | 733 | sdata_info(sdata, |
756 | 734 | "Selected IBSS BSSID %pM based on configured SSID\n", | |
757 | printk(KERN_DEBUG "%s: Selected IBSS BSSID %pM" | 735 | cbss->bssid); |
758 | " based on configured SSID\n", | ||
759 | sdata->name, cbss->bssid); | ||
760 | 736 | ||
761 | ieee80211_sta_join_ibss(sdata, bss); | 737 | ieee80211_sta_join_ibss(sdata, bss); |
762 | ieee80211_rx_bss_put(local, bss); | 738 | ieee80211_rx_bss_put(local, bss); |
763 | return; | 739 | return; |
764 | } | 740 | } |
765 | 741 | ||
766 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 742 | ibss_dbg(sdata, "sta_find_ibss: did not try to join ibss\n"); |
767 | printk(KERN_DEBUG " did not try to join ibss\n"); | ||
768 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
769 | 743 | ||
770 | /* Selected IBSS not found in current scan results - try to scan */ | 744 | /* Selected IBSS not found in current scan results - try to scan */ |
771 | if (time_after(jiffies, ifibss->last_scan_completed + | 745 | if (time_after(jiffies, ifibss->last_scan_completed + |
772 | IEEE80211_SCAN_INTERVAL)) { | 746 | IEEE80211_SCAN_INTERVAL)) { |
773 | printk(KERN_DEBUG "%s: Trigger new scan to find an IBSS to " | 747 | sdata_info(sdata, "Trigger new scan to find an IBSS to join\n"); |
774 | "join\n", sdata->name); | ||
775 | 748 | ||
776 | ieee80211_request_internal_scan(sdata, | 749 | ieee80211_request_internal_scan(sdata, |
777 | ifibss->ssid, ifibss->ssid_len, | 750 | ifibss->ssid, ifibss->ssid_len, |
@@ -785,9 +758,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata) | |||
785 | ieee80211_sta_create_ibss(sdata); | 758 | ieee80211_sta_create_ibss(sdata); |
786 | return; | 759 | return; |
787 | } | 760 | } |
788 | printk(KERN_DEBUG "%s: IBSS not allowed on" | 761 | sdata_info(sdata, "IBSS not allowed on %d MHz\n", |
789 | " %d MHz\n", sdata->name, | 762 | local->hw.conf.channel->center_freq); |
790 | local->hw.conf.channel->center_freq); | ||
791 | 763 | ||
792 | /* No IBSS found - decrease scan interval and continue | 764 | /* No IBSS found - decrease scan interval and continue |
793 | * scanning. */ | 765 | * scanning. */ |
@@ -822,12 +794,9 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
822 | 794 | ||
823 | tx_last_beacon = drv_tx_last_beacon(local); | 795 | tx_last_beacon = drv_tx_last_beacon(local); |
824 | 796 | ||
825 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 797 | ibss_dbg(sdata, |
826 | printk(KERN_DEBUG "%s: RX ProbeReq SA=%pM DA=%pM BSSID=%pM" | 798 | "RX ProbeReq SA=%pM DA=%pM BSSID=%pM (tx_last_beacon=%d)\n", |
827 | " (tx_last_beacon=%d)\n", | 799 | mgmt->sa, mgmt->da, mgmt->bssid, tx_last_beacon); |
828 | sdata->name, mgmt->sa, mgmt->da, | ||
829 | mgmt->bssid, tx_last_beacon); | ||
830 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
831 | 800 | ||
832 | if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) | 801 | if (!tx_last_beacon && is_multicast_ether_addr(mgmt->da)) |
833 | return; | 802 | return; |
@@ -840,11 +809,8 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
840 | pos = mgmt->u.probe_req.variable; | 809 | pos = mgmt->u.probe_req.variable; |
841 | if (pos[0] != WLAN_EID_SSID || | 810 | if (pos[0] != WLAN_EID_SSID || |
842 | pos + 2 + pos[1] > end) { | 811 | pos + 2 + pos[1] > end) { |
843 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 812 | ibss_dbg(sdata, "Invalid SSID IE in ProbeReq from %pM\n", |
844 | printk(KERN_DEBUG "%s: Invalid SSID IE in ProbeReq " | 813 | mgmt->sa); |
845 | "from %pM\n", | ||
846 | sdata->name, mgmt->sa); | ||
847 | #endif | ||
848 | return; | 814 | return; |
849 | } | 815 | } |
850 | if (pos[1] != 0 && | 816 | if (pos[1] != 0 && |
@@ -861,10 +827,7 @@ static void ieee80211_rx_mgmt_probe_req(struct ieee80211_sub_if_data *sdata, | |||
861 | 827 | ||
862 | resp = (struct ieee80211_mgmt *) skb->data; | 828 | resp = (struct ieee80211_mgmt *) skb->data; |
863 | memcpy(resp->da, mgmt->sa, ETH_ALEN); | 829 | memcpy(resp->da, mgmt->sa, ETH_ALEN); |
864 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 830 | ibss_dbg(sdata, "Sending ProbeResp to %pM\n", resp->da); |
865 | printk(KERN_DEBUG "%s: Sending ProbeResp to %pM\n", | ||
866 | sdata->name, resp->da); | ||
867 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ | ||
868 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 831 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
869 | ieee80211_tx_skb(sdata, skb); | 832 | ieee80211_tx_skb(sdata, skb); |
870 | } | 833 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3f3cd50fff16..bb61f7718c4c 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <net/mac80211.h> | 30 | #include <net/mac80211.h> |
31 | #include "key.h" | 31 | #include "key.h" |
32 | #include "sta_info.h" | 32 | #include "sta_info.h" |
33 | #include "debug.h" | ||
33 | 34 | ||
34 | struct ieee80211_local; | 35 | struct ieee80211_local; |
35 | 36 | ||
@@ -55,11 +56,14 @@ struct ieee80211_local; | |||
55 | #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) | 56 | #define TU_TO_JIFFIES(x) (usecs_to_jiffies((x) * 1024)) |
56 | #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) | 57 | #define TU_TO_EXP_TIME(x) (jiffies + TU_TO_JIFFIES(x)) |
57 | 58 | ||
59 | /* | ||
60 | * Some APs experience problems when working with U-APSD. Decrease the | ||
61 | * probability of that happening by using legacy mode for all ACs but VO. | ||
62 | * The AP that caused us trouble was a Cisco 4410N. It ignores our | ||
63 | * setting, and always treats non-VO ACs as legacy. | ||
64 | */ | ||
58 | #define IEEE80211_DEFAULT_UAPSD_QUEUES \ | 65 | #define IEEE80211_DEFAULT_UAPSD_QUEUES \ |
59 | (IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | \ | 66 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |
60 | IEEE80211_WMM_IE_STA_QOSINFO_AC_BE | \ | ||
61 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VI | \ | ||
62 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) | ||
63 | 67 | ||
64 | #define IEEE80211_DEFAULT_MAX_SP_LEN \ | 68 | #define IEEE80211_DEFAULT_MAX_SP_LEN \ |
65 | IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL | 69 | IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL |
@@ -81,6 +85,8 @@ struct ieee80211_bss { | |||
81 | size_t ssid_len; | 85 | size_t ssid_len; |
82 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 86 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
83 | 87 | ||
88 | u32 device_ts; | ||
89 | |||
84 | u8 dtim_period; | 90 | u8 dtim_period; |
85 | 91 | ||
86 | bool wmm_used; | 92 | bool wmm_used; |
@@ -203,7 +209,6 @@ typedef unsigned __bitwise__ ieee80211_rx_result; | |||
203 | * enum ieee80211_packet_rx_flags - packet RX flags | 209 | * enum ieee80211_packet_rx_flags - packet RX flags |
204 | * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed | 210 | * @IEEE80211_RX_RA_MATCH: frame is destined to interface currently processed |
205 | * (incl. multicast frames) | 211 | * (incl. multicast frames) |
206 | * @IEEE80211_RX_IN_SCAN: received while scanning | ||
207 | * @IEEE80211_RX_FRAGMENTED: fragmented frame | 212 | * @IEEE80211_RX_FRAGMENTED: fragmented frame |
208 | * @IEEE80211_RX_AMSDU: a-MSDU packet | 213 | * @IEEE80211_RX_AMSDU: a-MSDU packet |
209 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed | 214 | * @IEEE80211_RX_MALFORMED_ACTION_FRM: action frame is malformed |
@@ -213,7 +218,6 @@ typedef unsigned __bitwise__ ieee80211_rx_result; | |||
213 | * @rx_flags field of &struct ieee80211_rx_status. | 218 | * @rx_flags field of &struct ieee80211_rx_status. |
214 | */ | 219 | */ |
215 | enum ieee80211_packet_rx_flags { | 220 | enum ieee80211_packet_rx_flags { |
216 | IEEE80211_RX_IN_SCAN = BIT(0), | ||
217 | IEEE80211_RX_RA_MATCH = BIT(1), | 221 | IEEE80211_RX_RA_MATCH = BIT(1), |
218 | IEEE80211_RX_FRAGMENTED = BIT(2), | 222 | IEEE80211_RX_FRAGMENTED = BIT(2), |
219 | IEEE80211_RX_AMSDU = BIT(3), | 223 | IEEE80211_RX_AMSDU = BIT(3), |
@@ -317,55 +321,30 @@ struct mesh_preq_queue { | |||
317 | u8 flags; | 321 | u8 flags; |
318 | }; | 322 | }; |
319 | 323 | ||
320 | enum ieee80211_work_type { | 324 | #if HZ/100 == 0 |
321 | IEEE80211_WORK_ABORT, | 325 | #define IEEE80211_ROC_MIN_LEFT 1 |
322 | IEEE80211_WORK_REMAIN_ON_CHANNEL, | 326 | #else |
323 | IEEE80211_WORK_OFFCHANNEL_TX, | 327 | #define IEEE80211_ROC_MIN_LEFT (HZ/100) |
324 | }; | 328 | #endif |
325 | |||
326 | /** | ||
327 | * enum work_done_result - indicates what to do after work was done | ||
328 | * | ||
329 | * @WORK_DONE_DESTROY: This work item is no longer needed, destroy. | ||
330 | * @WORK_DONE_REQUEUE: This work item was reset to be reused, and | ||
331 | * should be requeued. | ||
332 | */ | ||
333 | enum work_done_result { | ||
334 | WORK_DONE_DESTROY, | ||
335 | WORK_DONE_REQUEUE, | ||
336 | }; | ||
337 | 329 | ||
338 | struct ieee80211_work { | 330 | struct ieee80211_roc_work { |
339 | struct list_head list; | 331 | struct list_head list; |
332 | struct list_head dependents; | ||
340 | 333 | ||
341 | struct rcu_head rcu_head; | 334 | struct delayed_work work; |
342 | 335 | ||
343 | struct ieee80211_sub_if_data *sdata; | 336 | struct ieee80211_sub_if_data *sdata; |
344 | 337 | ||
345 | enum work_done_result (*done)(struct ieee80211_work *wk, | ||
346 | struct sk_buff *skb); | ||
347 | |||
348 | struct ieee80211_channel *chan; | 338 | struct ieee80211_channel *chan; |
349 | enum nl80211_channel_type chan_type; | 339 | enum nl80211_channel_type chan_type; |
350 | 340 | ||
351 | unsigned long timeout; | 341 | bool started, abort, hw_begun, notified; |
352 | enum ieee80211_work_type type; | ||
353 | 342 | ||
354 | bool started; | 343 | unsigned long hw_start_time; |
355 | 344 | ||
356 | union { | 345 | u32 duration, req_duration; |
357 | struct { | 346 | struct sk_buff *frame; |
358 | u32 duration; | 347 | u64 mgmt_tx_cookie; |
359 | } remain; | ||
360 | struct { | ||
361 | struct sk_buff *frame; | ||
362 | u32 wait; | ||
363 | bool status; | ||
364 | } offchan_tx; | ||
365 | }; | ||
366 | |||
367 | size_t data_len; | ||
368 | u8 data[]; | ||
369 | }; | 348 | }; |
370 | 349 | ||
371 | /* flags used in struct ieee80211_if_managed.flags */ | 350 | /* flags used in struct ieee80211_if_managed.flags */ |
@@ -399,7 +378,6 @@ struct ieee80211_mgd_auth_data { | |||
399 | struct ieee80211_mgd_assoc_data { | 378 | struct ieee80211_mgd_assoc_data { |
400 | struct cfg80211_bss *bss; | 379 | struct cfg80211_bss *bss; |
401 | const u8 *supp_rates; | 380 | const u8 *supp_rates; |
402 | const u8 *ht_operation_ie; | ||
403 | 381 | ||
404 | unsigned long timeout; | 382 | unsigned long timeout; |
405 | int tries; | 383 | int tries; |
@@ -414,6 +392,8 @@ struct ieee80211_mgd_assoc_data { | |||
414 | bool sent_assoc; | 392 | bool sent_assoc; |
415 | bool synced; | 393 | bool synced; |
416 | 394 | ||
395 | u8 ap_ht_param; | ||
396 | |||
417 | size_t ie_len; | 397 | size_t ie_len; |
418 | u8 ie[]; | 398 | u8 ie[]; |
419 | }; | 399 | }; |
@@ -532,6 +512,7 @@ struct ieee80211_if_ibss { | |||
532 | bool privacy; | 512 | bool privacy; |
533 | 513 | ||
534 | bool control_port; | 514 | bool control_port; |
515 | unsigned int auth_frame_registrations; | ||
535 | 516 | ||
536 | u8 bssid[ETH_ALEN] __aligned(2); | 517 | u8 bssid[ETH_ALEN] __aligned(2); |
537 | u8 ssid[IEEE80211_MAX_SSID_LEN]; | 518 | u8 ssid[IEEE80211_MAX_SSID_LEN]; |
@@ -701,6 +682,9 @@ struct ieee80211_sub_if_data { | |||
701 | /* TID bitmap for NoAck policy */ | 682 | /* TID bitmap for NoAck policy */ |
702 | u16 noack_map; | 683 | u16 noack_map; |
703 | 684 | ||
685 | /* bit field of ACM bits (BIT(802.1D tag)) */ | ||
686 | u8 wmm_acm; | ||
687 | |||
704 | struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; | 688 | struct ieee80211_key __rcu *keys[NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS]; |
705 | struct ieee80211_key __rcu *default_unicast_key; | 689 | struct ieee80211_key __rcu *default_unicast_key; |
706 | struct ieee80211_key __rcu *default_multicast_key; | 690 | struct ieee80211_key __rcu *default_multicast_key; |
@@ -847,13 +831,6 @@ struct ieee80211_local { | |||
847 | const struct ieee80211_ops *ops; | 831 | const struct ieee80211_ops *ops; |
848 | 832 | ||
849 | /* | 833 | /* |
850 | * work stuff, potentially off-channel (in the future) | ||
851 | */ | ||
852 | struct list_head work_list; | ||
853 | struct timer_list work_timer; | ||
854 | struct work_struct work_work; | ||
855 | |||
856 | /* | ||
857 | * private workqueue to mac80211. mac80211 makes this accessible | 834 | * private workqueue to mac80211. mac80211 makes this accessible |
858 | * via ieee80211_queue_work() | 835 | * via ieee80211_queue_work() |
859 | */ | 836 | */ |
@@ -912,6 +889,9 @@ struct ieee80211_local { | |||
912 | /* device is started */ | 889 | /* device is started */ |
913 | bool started; | 890 | bool started; |
914 | 891 | ||
892 | /* device is during a HW reconfig */ | ||
893 | bool in_reconfig; | ||
894 | |||
915 | /* wowlan is enabled -- don't reconfig on resume */ | 895 | /* wowlan is enabled -- don't reconfig on resume */ |
916 | bool wowlan; | 896 | bool wowlan; |
917 | 897 | ||
@@ -985,14 +965,14 @@ struct ieee80211_local { | |||
985 | int scan_channel_idx; | 965 | int scan_channel_idx; |
986 | int scan_ies_len; | 966 | int scan_ies_len; |
987 | 967 | ||
988 | bool sched_scanning; | ||
989 | struct ieee80211_sched_scan_ies sched_scan_ies; | 968 | struct ieee80211_sched_scan_ies sched_scan_ies; |
990 | struct work_struct sched_scan_stopped_work; | 969 | struct work_struct sched_scan_stopped_work; |
970 | struct ieee80211_sub_if_data __rcu *sched_scan_sdata; | ||
991 | 971 | ||
992 | unsigned long leave_oper_channel_time; | 972 | unsigned long leave_oper_channel_time; |
993 | enum mac80211_scan_state next_scan_state; | 973 | enum mac80211_scan_state next_scan_state; |
994 | struct delayed_work scan_work; | 974 | struct delayed_work scan_work; |
995 | struct ieee80211_sub_if_data *scan_sdata; | 975 | struct ieee80211_sub_if_data __rcu *scan_sdata; |
996 | enum nl80211_channel_type _oper_channel_type; | 976 | enum nl80211_channel_type _oper_channel_type; |
997 | struct ieee80211_channel *oper_channel, *csa_channel; | 977 | struct ieee80211_channel *oper_channel, *csa_channel; |
998 | 978 | ||
@@ -1034,7 +1014,6 @@ struct ieee80211_local { | |||
1034 | unsigned int rx_handlers_drop_nullfunc; | 1014 | unsigned int rx_handlers_drop_nullfunc; |
1035 | unsigned int rx_handlers_drop_defrag; | 1015 | unsigned int rx_handlers_drop_defrag; |
1036 | unsigned int rx_handlers_drop_short; | 1016 | unsigned int rx_handlers_drop_short; |
1037 | unsigned int rx_handlers_drop_passive_scan; | ||
1038 | unsigned int tx_expand_skb_head; | 1017 | unsigned int tx_expand_skb_head; |
1039 | unsigned int tx_expand_skb_head_cloned; | 1018 | unsigned int tx_expand_skb_head_cloned; |
1040 | unsigned int rx_expand_skb_head; | 1019 | unsigned int rx_expand_skb_head; |
@@ -1050,7 +1029,6 @@ struct ieee80211_local { | |||
1050 | int total_ps_buffered; /* total number of all buffered unicast and | 1029 | int total_ps_buffered; /* total number of all buffered unicast and |
1051 | * multicast packets for power saving stations | 1030 | * multicast packets for power saving stations |
1052 | */ | 1031 | */ |
1053 | unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ | ||
1054 | 1032 | ||
1055 | bool pspolling; | 1033 | bool pspolling; |
1056 | bool offchannel_ps_enabled; | 1034 | bool offchannel_ps_enabled; |
@@ -1087,14 +1065,12 @@ struct ieee80211_local { | |||
1087 | } debugfs; | 1065 | } debugfs; |
1088 | #endif | 1066 | #endif |
1089 | 1067 | ||
1090 | struct ieee80211_channel *hw_roc_channel; | 1068 | /* |
1091 | struct net_device *hw_roc_dev; | 1069 | * Remain-on-channel support |
1092 | struct sk_buff *hw_roc_skb, *hw_roc_skb_for_status; | 1070 | */ |
1071 | struct list_head roc_list; | ||
1093 | struct work_struct hw_roc_start, hw_roc_done; | 1072 | struct work_struct hw_roc_start, hw_roc_done; |
1094 | enum nl80211_channel_type hw_roc_channel_type; | 1073 | unsigned long hw_roc_start_time; |
1095 | unsigned int hw_roc_duration; | ||
1096 | u32 hw_roc_cookie; | ||
1097 | bool hw_roc_for_tx; | ||
1098 | 1074 | ||
1099 | struct idr ack_status_frames; | 1075 | struct idr ack_status_frames; |
1100 | spinlock_t ack_status_lock; | 1076 | spinlock_t ack_status_lock; |
@@ -1114,6 +1090,12 @@ IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) | |||
1114 | return netdev_priv(dev); | 1090 | return netdev_priv(dev); |
1115 | } | 1091 | } |
1116 | 1092 | ||
1093 | static inline struct ieee80211_sub_if_data * | ||
1094 | IEEE80211_WDEV_TO_SUB_IF(struct wireless_dev *wdev) | ||
1095 | { | ||
1096 | return container_of(wdev, struct ieee80211_sub_if_data, wdev); | ||
1097 | } | ||
1098 | |||
1117 | /* this struct represents 802.11n's RA/TID combination */ | 1099 | /* this struct represents 802.11n's RA/TID combination */ |
1118 | struct ieee80211_ra_tid { | 1100 | struct ieee80211_ra_tid { |
1119 | u8 ra[ETH_ALEN]; | 1101 | u8 ra[ETH_ALEN]; |
@@ -1264,8 +1246,7 @@ int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | |||
1264 | struct cfg80211_scan_request *req); | 1246 | struct cfg80211_scan_request *req); |
1265 | void ieee80211_scan_cancel(struct ieee80211_local *local); | 1247 | void ieee80211_scan_cancel(struct ieee80211_local *local); |
1266 | void ieee80211_run_deferred_scan(struct ieee80211_local *local); | 1248 | void ieee80211_run_deferred_scan(struct ieee80211_local *local); |
1267 | ieee80211_rx_result | 1249 | void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb); |
1268 | ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb); | ||
1269 | 1250 | ||
1270 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); | 1251 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local); |
1271 | struct ieee80211_bss * | 1252 | struct ieee80211_bss * |
@@ -1290,19 +1271,23 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | |||
1290 | bool offchannel_ps_enable); | 1271 | bool offchannel_ps_enable); |
1291 | void ieee80211_offchannel_return(struct ieee80211_local *local, | 1272 | void ieee80211_offchannel_return(struct ieee80211_local *local, |
1292 | bool offchannel_ps_disable); | 1273 | bool offchannel_ps_disable); |
1293 | void ieee80211_hw_roc_setup(struct ieee80211_local *local); | 1274 | void ieee80211_roc_setup(struct ieee80211_local *local); |
1275 | void ieee80211_start_next_roc(struct ieee80211_local *local); | ||
1276 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata); | ||
1277 | void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc); | ||
1278 | void ieee80211_sw_roc_work(struct work_struct *work); | ||
1279 | void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc); | ||
1294 | 1280 | ||
1295 | /* interface handling */ | 1281 | /* interface handling */ |
1296 | int ieee80211_iface_init(void); | 1282 | int ieee80211_iface_init(void); |
1297 | void ieee80211_iface_exit(void); | 1283 | void ieee80211_iface_exit(void); |
1298 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 1284 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
1299 | struct net_device **new_dev, enum nl80211_iftype type, | 1285 | struct wireless_dev **new_wdev, enum nl80211_iftype type, |
1300 | struct vif_params *params); | 1286 | struct vif_params *params); |
1301 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, | 1287 | int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata, |
1302 | enum nl80211_iftype type); | 1288 | enum nl80211_iftype type); |
1303 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); | 1289 | void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata); |
1304 | void ieee80211_remove_interfaces(struct ieee80211_local *local); | 1290 | void ieee80211_remove_interfaces(struct ieee80211_local *local); |
1305 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local); | ||
1306 | void ieee80211_recalc_idle(struct ieee80211_local *local); | 1291 | void ieee80211_recalc_idle(struct ieee80211_local *local); |
1307 | void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, | 1292 | void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, |
1308 | const int offset); | 1293 | const int offset); |
@@ -1499,18 +1484,12 @@ u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, | |||
1499 | struct ieee80211_channel *channel, | 1484 | struct ieee80211_channel *channel, |
1500 | enum nl80211_channel_type channel_type, | 1485 | enum nl80211_channel_type channel_type, |
1501 | u16 prot_mode); | 1486 | u16 prot_mode); |
1502 | 1487 | u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, | |
1503 | /* internal work items */ | 1488 | u32 cap); |
1504 | void ieee80211_work_init(struct ieee80211_local *local); | 1489 | int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, |
1505 | void ieee80211_add_work(struct ieee80211_work *wk); | 1490 | struct sk_buff *skb, bool need_basic); |
1506 | void free_work(struct ieee80211_work *wk); | 1491 | int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, |
1507 | void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata); | 1492 | struct sk_buff *skb, bool need_basic); |
1508 | int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata, | ||
1509 | struct ieee80211_channel *chan, | ||
1510 | enum nl80211_channel_type channel_type, | ||
1511 | unsigned int duration, u64 *cookie); | ||
1512 | int ieee80211_wk_cancel_remain_on_channel( | ||
1513 | struct ieee80211_sub_if_data *sdata, u64 cookie); | ||
1514 | 1493 | ||
1515 | /* channel management */ | 1494 | /* channel management */ |
1516 | enum ieee80211_chan_mode { | 1495 | enum ieee80211_chan_mode { |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 8664111d0566..bfb57dcc1538 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -43,6 +43,128 @@ | |||
43 | */ | 43 | */ |
44 | 44 | ||
45 | 45 | ||
46 | static u32 ieee80211_idle_off(struct ieee80211_local *local, | ||
47 | const char *reason) | ||
48 | { | ||
49 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) | ||
50 | return 0; | ||
51 | |||
52 | local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; | ||
53 | return IEEE80211_CONF_CHANGE_IDLE; | ||
54 | } | ||
55 | |||
56 | static u32 ieee80211_idle_on(struct ieee80211_local *local) | ||
57 | { | ||
58 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) | ||
59 | return 0; | ||
60 | |||
61 | drv_flush(local, false); | ||
62 | |||
63 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; | ||
64 | return IEEE80211_CONF_CHANGE_IDLE; | ||
65 | } | ||
66 | |||
67 | static u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | ||
68 | { | ||
69 | struct ieee80211_sub_if_data *sdata; | ||
70 | int count = 0; | ||
71 | bool working = false, scanning = false; | ||
72 | unsigned int led_trig_start = 0, led_trig_stop = 0; | ||
73 | struct ieee80211_roc_work *roc; | ||
74 | |||
75 | #ifdef CONFIG_PROVE_LOCKING | ||
76 | WARN_ON(debug_locks && !lockdep_rtnl_is_held() && | ||
77 | !lockdep_is_held(&local->iflist_mtx)); | ||
78 | #endif | ||
79 | lockdep_assert_held(&local->mtx); | ||
80 | |||
81 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
82 | if (!ieee80211_sdata_running(sdata)) { | ||
83 | sdata->vif.bss_conf.idle = true; | ||
84 | continue; | ||
85 | } | ||
86 | |||
87 | sdata->old_idle = sdata->vif.bss_conf.idle; | ||
88 | |||
89 | /* do not count disabled managed interfaces */ | ||
90 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
91 | !sdata->u.mgd.associated && | ||
92 | !sdata->u.mgd.auth_data && | ||
93 | !sdata->u.mgd.assoc_data) { | ||
94 | sdata->vif.bss_conf.idle = true; | ||
95 | continue; | ||
96 | } | ||
97 | /* do not count unused IBSS interfaces */ | ||
98 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
99 | !sdata->u.ibss.ssid_len) { | ||
100 | sdata->vif.bss_conf.idle = true; | ||
101 | continue; | ||
102 | } | ||
103 | /* count everything else */ | ||
104 | sdata->vif.bss_conf.idle = false; | ||
105 | count++; | ||
106 | } | ||
107 | |||
108 | if (!local->ops->remain_on_channel) { | ||
109 | list_for_each_entry(roc, &local->roc_list, list) { | ||
110 | working = true; | ||
111 | roc->sdata->vif.bss_conf.idle = false; | ||
112 | } | ||
113 | } | ||
114 | |||
115 | sdata = rcu_dereference_protected(local->scan_sdata, | ||
116 | lockdep_is_held(&local->mtx)); | ||
117 | if (sdata && !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { | ||
118 | scanning = true; | ||
119 | sdata->vif.bss_conf.idle = false; | ||
120 | } | ||
121 | |||
122 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
123 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | ||
124 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
125 | continue; | ||
126 | if (sdata->old_idle == sdata->vif.bss_conf.idle) | ||
127 | continue; | ||
128 | if (!ieee80211_sdata_running(sdata)) | ||
129 | continue; | ||
130 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); | ||
131 | } | ||
132 | |||
133 | if (working || scanning) | ||
134 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; | ||
135 | else | ||
136 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; | ||
137 | |||
138 | if (count) | ||
139 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | ||
140 | else | ||
141 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | ||
142 | |||
143 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); | ||
144 | |||
145 | if (working) | ||
146 | return ieee80211_idle_off(local, "working"); | ||
147 | if (scanning) | ||
148 | return ieee80211_idle_off(local, "scanning"); | ||
149 | if (!count) | ||
150 | return ieee80211_idle_on(local); | ||
151 | else | ||
152 | return ieee80211_idle_off(local, "in use"); | ||
153 | |||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | void ieee80211_recalc_idle(struct ieee80211_local *local) | ||
158 | { | ||
159 | u32 chg; | ||
160 | |||
161 | mutex_lock(&local->iflist_mtx); | ||
162 | chg = __ieee80211_recalc_idle(local); | ||
163 | mutex_unlock(&local->iflist_mtx); | ||
164 | if (chg) | ||
165 | ieee80211_hw_config(local, chg); | ||
166 | } | ||
167 | |||
46 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | 168 | static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) |
47 | { | 169 | { |
48 | int meshhdrlen; | 170 | int meshhdrlen; |
@@ -57,9 +179,6 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | |||
57 | return -EINVAL; | 179 | return -EINVAL; |
58 | } | 180 | } |
59 | 181 | ||
60 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
61 | printk(KERN_DEBUG "%s: setting MTU %d\n", dev->name, new_mtu); | ||
62 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
63 | dev->mtu = new_mtu; | 182 | dev->mtu = new_mtu; |
64 | return 0; | 183 | return 0; |
65 | } | 184 | } |
@@ -100,15 +219,12 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, | |||
100 | { | 219 | { |
101 | struct ieee80211_local *local = sdata->local; | 220 | struct ieee80211_local *local = sdata->local; |
102 | struct ieee80211_sub_if_data *nsdata; | 221 | struct ieee80211_sub_if_data *nsdata; |
103 | struct net_device *dev = sdata->dev; | ||
104 | 222 | ||
105 | ASSERT_RTNL(); | 223 | ASSERT_RTNL(); |
106 | 224 | ||
107 | /* we hold the RTNL here so can safely walk the list */ | 225 | /* we hold the RTNL here so can safely walk the list */ |
108 | list_for_each_entry(nsdata, &local->interfaces, list) { | 226 | list_for_each_entry(nsdata, &local->interfaces, list) { |
109 | struct net_device *ndev = nsdata->dev; | 227 | if (nsdata != sdata && ieee80211_sdata_running(nsdata)) { |
110 | |||
111 | if (ndev != dev && ieee80211_sdata_running(nsdata)) { | ||
112 | /* | 228 | /* |
113 | * Allow only a single IBSS interface to be up at any | 229 | * Allow only a single IBSS interface to be up at any |
114 | * time. This is restricted because beacon distribution | 230 | * time. This is restricted because beacon distribution |
@@ -127,7 +243,8 @@ static int ieee80211_check_concurrent_iface(struct ieee80211_sub_if_data *sdata, | |||
127 | * The remaining checks are only performed for interfaces | 243 | * The remaining checks are only performed for interfaces |
128 | * with the same MAC address. | 244 | * with the same MAC address. |
129 | */ | 245 | */ |
130 | if (!ether_addr_equal(dev->dev_addr, ndev->dev_addr)) | 246 | if (!ether_addr_equal(sdata->vif.addr, |
247 | nsdata->vif.addr)) | ||
131 | continue; | 248 | continue; |
132 | 249 | ||
133 | /* | 250 | /* |
@@ -217,17 +334,21 @@ static void ieee80211_set_default_queues(struct ieee80211_sub_if_data *sdata) | |||
217 | static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | 334 | static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) |
218 | { | 335 | { |
219 | struct ieee80211_sub_if_data *sdata; | 336 | struct ieee80211_sub_if_data *sdata; |
220 | int ret; | 337 | int ret = 0; |
221 | 338 | ||
222 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) | 339 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) |
223 | return 0; | 340 | return 0; |
224 | 341 | ||
342 | mutex_lock(&local->iflist_mtx); | ||
343 | |||
225 | if (local->monitor_sdata) | 344 | if (local->monitor_sdata) |
226 | return 0; | 345 | goto out_unlock; |
227 | 346 | ||
228 | sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); | 347 | sdata = kzalloc(sizeof(*sdata) + local->hw.vif_data_size, GFP_KERNEL); |
229 | if (!sdata) | 348 | if (!sdata) { |
230 | return -ENOMEM; | 349 | ret = -ENOMEM; |
350 | goto out_unlock; | ||
351 | } | ||
231 | 352 | ||
232 | /* set up data */ | 353 | /* set up data */ |
233 | sdata->local = local; | 354 | sdata->local = local; |
@@ -241,18 +362,19 @@ static int ieee80211_add_virtual_monitor(struct ieee80211_local *local) | |||
241 | if (WARN_ON(ret)) { | 362 | if (WARN_ON(ret)) { |
242 | /* ok .. stupid driver, it asked for this! */ | 363 | /* ok .. stupid driver, it asked for this! */ |
243 | kfree(sdata); | 364 | kfree(sdata); |
244 | return ret; | 365 | goto out_unlock; |
245 | } | 366 | } |
246 | 367 | ||
247 | ret = ieee80211_check_queues(sdata); | 368 | ret = ieee80211_check_queues(sdata); |
248 | if (ret) { | 369 | if (ret) { |
249 | kfree(sdata); | 370 | kfree(sdata); |
250 | return ret; | 371 | goto out_unlock; |
251 | } | 372 | } |
252 | 373 | ||
253 | rcu_assign_pointer(local->monitor_sdata, sdata); | 374 | rcu_assign_pointer(local->monitor_sdata, sdata); |
254 | 375 | out_unlock: | |
255 | return 0; | 376 | mutex_unlock(&local->iflist_mtx); |
377 | return ret; | ||
256 | } | 378 | } |
257 | 379 | ||
258 | static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | 380 | static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) |
@@ -262,10 +384,12 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | |||
262 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) | 384 | if (!(local->hw.flags & IEEE80211_HW_WANT_MONITOR_VIF)) |
263 | return; | 385 | return; |
264 | 386 | ||
265 | sdata = rtnl_dereference(local->monitor_sdata); | 387 | mutex_lock(&local->iflist_mtx); |
266 | 388 | ||
389 | sdata = rcu_dereference_protected(local->monitor_sdata, | ||
390 | lockdep_is_held(&local->iflist_mtx)); | ||
267 | if (!sdata) | 391 | if (!sdata) |
268 | return; | 392 | goto out_unlock; |
269 | 393 | ||
270 | rcu_assign_pointer(local->monitor_sdata, NULL); | 394 | rcu_assign_pointer(local->monitor_sdata, NULL); |
271 | synchronize_net(); | 395 | synchronize_net(); |
@@ -273,6 +397,8 @@ static void ieee80211_del_virtual_monitor(struct ieee80211_local *local) | |||
273 | drv_remove_interface(local, sdata); | 397 | drv_remove_interface(local, sdata); |
274 | 398 | ||
275 | kfree(sdata); | 399 | kfree(sdata); |
400 | out_unlock: | ||
401 | mutex_unlock(&local->iflist_mtx); | ||
276 | } | 402 | } |
277 | 403 | ||
278 | /* | 404 | /* |
@@ -520,7 +646,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
520 | 646 | ||
521 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); | 647 | clear_bit(SDATA_STATE_RUNNING, &sdata->state); |
522 | 648 | ||
523 | if (local->scan_sdata == sdata) | 649 | if (rcu_access_pointer(local->scan_sdata) == sdata) |
524 | ieee80211_scan_cancel(local); | 650 | ieee80211_scan_cancel(local); |
525 | 651 | ||
526 | /* | 652 | /* |
@@ -528,10 +654,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
528 | */ | 654 | */ |
529 | netif_tx_stop_all_queues(sdata->dev); | 655 | netif_tx_stop_all_queues(sdata->dev); |
530 | 656 | ||
531 | /* | 657 | ieee80211_roc_purge(sdata); |
532 | * Purge work for this interface. | ||
533 | */ | ||
534 | ieee80211_work_purge(sdata); | ||
535 | 658 | ||
536 | /* | 659 | /* |
537 | * Remove all stations associated with this interface. | 660 | * Remove all stations associated with this interface. |
@@ -637,18 +760,6 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, | |||
637 | ieee80211_configure_filter(local); | 760 | ieee80211_configure_filter(local); |
638 | break; | 761 | break; |
639 | default: | 762 | default: |
640 | mutex_lock(&local->mtx); | ||
641 | if (local->hw_roc_dev == sdata->dev && | ||
642 | local->hw_roc_channel) { | ||
643 | /* ignore return value since this is racy */ | ||
644 | drv_cancel_remain_on_channel(local); | ||
645 | ieee80211_queue_work(&local->hw, &local->hw_roc_done); | ||
646 | } | ||
647 | mutex_unlock(&local->mtx); | ||
648 | |||
649 | flush_work(&local->hw_roc_start); | ||
650 | flush_work(&local->hw_roc_done); | ||
651 | |||
652 | flush_work(&sdata->work); | 763 | flush_work(&sdata->work); |
653 | /* | 764 | /* |
654 | * When we get here, the interface is marked down. | 765 | * When we get here, the interface is marked down. |
@@ -823,7 +934,7 @@ static u16 ieee80211_monitor_select_queue(struct net_device *dev, | |||
823 | 934 | ||
824 | hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); | 935 | hdr = (void *)((u8 *)skb->data + le16_to_cpu(rtap->it_len)); |
825 | 936 | ||
826 | return ieee80211_select_queue_80211(local, skb, hdr); | 937 | return ieee80211_select_queue_80211(sdata, skb, hdr); |
827 | } | 938 | } |
828 | 939 | ||
829 | static const struct net_device_ops ieee80211_monitorif_ops = { | 940 | static const struct net_device_ops ieee80211_monitorif_ops = { |
@@ -1238,7 +1349,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1238 | 1349 | ||
1239 | if (__ffs64(mask) + hweight64(mask) != fls64(mask)) { | 1350 | if (__ffs64(mask) + hweight64(mask) != fls64(mask)) { |
1240 | /* not a contiguous mask ... not handled now! */ | 1351 | /* not a contiguous mask ... not handled now! */ |
1241 | printk(KERN_DEBUG "not contiguous\n"); | 1352 | pr_info("not contiguous\n"); |
1242 | break; | 1353 | break; |
1243 | } | 1354 | } |
1244 | 1355 | ||
@@ -1284,7 +1395,7 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1284 | } | 1395 | } |
1285 | 1396 | ||
1286 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, | 1397 | int ieee80211_if_add(struct ieee80211_local *local, const char *name, |
1287 | struct net_device **new_dev, enum nl80211_iftype type, | 1398 | struct wireless_dev **new_wdev, enum nl80211_iftype type, |
1288 | struct vif_params *params) | 1399 | struct vif_params *params) |
1289 | { | 1400 | { |
1290 | struct net_device *ndev; | 1401 | struct net_device *ndev; |
@@ -1364,6 +1475,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1364 | sdata->u.mgd.use_4addr = params->use_4addr; | 1475 | sdata->u.mgd.use_4addr = params->use_4addr; |
1365 | } | 1476 | } |
1366 | 1477 | ||
1478 | ndev->features |= local->hw.netdev_features; | ||
1479 | |||
1367 | ret = register_netdevice(ndev); | 1480 | ret = register_netdevice(ndev); |
1368 | if (ret) | 1481 | if (ret) |
1369 | goto fail; | 1482 | goto fail; |
@@ -1372,8 +1485,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name, | |||
1372 | list_add_tail_rcu(&sdata->list, &local->interfaces); | 1485 | list_add_tail_rcu(&sdata->list, &local->interfaces); |
1373 | mutex_unlock(&local->iflist_mtx); | 1486 | mutex_unlock(&local->iflist_mtx); |
1374 | 1487 | ||
1375 | if (new_dev) | 1488 | if (new_wdev) |
1376 | *new_dev = ndev; | 1489 | *new_wdev = &sdata->wdev; |
1377 | 1490 | ||
1378 | return 0; | 1491 | return 0; |
1379 | 1492 | ||
@@ -1421,138 +1534,6 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) | |||
1421 | list_del(&unreg_list); | 1534 | list_del(&unreg_list); |
1422 | } | 1535 | } |
1423 | 1536 | ||
1424 | static u32 ieee80211_idle_off(struct ieee80211_local *local, | ||
1425 | const char *reason) | ||
1426 | { | ||
1427 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) | ||
1428 | return 0; | ||
1429 | |||
1430 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1431 | wiphy_debug(local->hw.wiphy, "device no longer idle - %s\n", reason); | ||
1432 | #endif | ||
1433 | |||
1434 | local->hw.conf.flags &= ~IEEE80211_CONF_IDLE; | ||
1435 | return IEEE80211_CONF_CHANGE_IDLE; | ||
1436 | } | ||
1437 | |||
1438 | static u32 ieee80211_idle_on(struct ieee80211_local *local) | ||
1439 | { | ||
1440 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) | ||
1441 | return 0; | ||
1442 | |||
1443 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1444 | wiphy_debug(local->hw.wiphy, "device now idle\n"); | ||
1445 | #endif | ||
1446 | |||
1447 | drv_flush(local, false); | ||
1448 | |||
1449 | local->hw.conf.flags |= IEEE80211_CONF_IDLE; | ||
1450 | return IEEE80211_CONF_CHANGE_IDLE; | ||
1451 | } | ||
1452 | |||
1453 | u32 __ieee80211_recalc_idle(struct ieee80211_local *local) | ||
1454 | { | ||
1455 | struct ieee80211_sub_if_data *sdata; | ||
1456 | int count = 0; | ||
1457 | bool working = false, scanning = false, hw_roc = false; | ||
1458 | struct ieee80211_work *wk; | ||
1459 | unsigned int led_trig_start = 0, led_trig_stop = 0; | ||
1460 | |||
1461 | #ifdef CONFIG_PROVE_LOCKING | ||
1462 | WARN_ON(debug_locks && !lockdep_rtnl_is_held() && | ||
1463 | !lockdep_is_held(&local->iflist_mtx)); | ||
1464 | #endif | ||
1465 | lockdep_assert_held(&local->mtx); | ||
1466 | |||
1467 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
1468 | if (!ieee80211_sdata_running(sdata)) { | ||
1469 | sdata->vif.bss_conf.idle = true; | ||
1470 | continue; | ||
1471 | } | ||
1472 | |||
1473 | sdata->old_idle = sdata->vif.bss_conf.idle; | ||
1474 | |||
1475 | /* do not count disabled managed interfaces */ | ||
1476 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | ||
1477 | !sdata->u.mgd.associated && | ||
1478 | !sdata->u.mgd.auth_data && | ||
1479 | !sdata->u.mgd.assoc_data) { | ||
1480 | sdata->vif.bss_conf.idle = true; | ||
1481 | continue; | ||
1482 | } | ||
1483 | /* do not count unused IBSS interfaces */ | ||
1484 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC && | ||
1485 | !sdata->u.ibss.ssid_len) { | ||
1486 | sdata->vif.bss_conf.idle = true; | ||
1487 | continue; | ||
1488 | } | ||
1489 | /* count everything else */ | ||
1490 | sdata->vif.bss_conf.idle = false; | ||
1491 | count++; | ||
1492 | } | ||
1493 | |||
1494 | list_for_each_entry(wk, &local->work_list, list) { | ||
1495 | working = true; | ||
1496 | wk->sdata->vif.bss_conf.idle = false; | ||
1497 | } | ||
1498 | |||
1499 | if (local->scan_sdata && | ||
1500 | !(local->hw.flags & IEEE80211_HW_SCAN_WHILE_IDLE)) { | ||
1501 | scanning = true; | ||
1502 | local->scan_sdata->vif.bss_conf.idle = false; | ||
1503 | } | ||
1504 | |||
1505 | if (local->hw_roc_channel) | ||
1506 | hw_roc = true; | ||
1507 | |||
1508 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
1509 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || | ||
1510 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
1511 | continue; | ||
1512 | if (sdata->old_idle == sdata->vif.bss_conf.idle) | ||
1513 | continue; | ||
1514 | if (!ieee80211_sdata_running(sdata)) | ||
1515 | continue; | ||
1516 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_IDLE); | ||
1517 | } | ||
1518 | |||
1519 | if (working || scanning || hw_roc) | ||
1520 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_WORK; | ||
1521 | else | ||
1522 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_WORK; | ||
1523 | |||
1524 | if (count) | ||
1525 | led_trig_start |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | ||
1526 | else | ||
1527 | led_trig_stop |= IEEE80211_TPT_LEDTRIG_FL_CONNECTED; | ||
1528 | |||
1529 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); | ||
1530 | |||
1531 | if (hw_roc) | ||
1532 | return ieee80211_idle_off(local, "hw remain-on-channel"); | ||
1533 | if (working) | ||
1534 | return ieee80211_idle_off(local, "working"); | ||
1535 | if (scanning) | ||
1536 | return ieee80211_idle_off(local, "scanning"); | ||
1537 | if (!count) | ||
1538 | return ieee80211_idle_on(local); | ||
1539 | else | ||
1540 | return ieee80211_idle_off(local, "in use"); | ||
1541 | |||
1542 | return 0; | ||
1543 | } | ||
1544 | |||
1545 | void ieee80211_recalc_idle(struct ieee80211_local *local) | ||
1546 | { | ||
1547 | u32 chg; | ||
1548 | |||
1549 | mutex_lock(&local->iflist_mtx); | ||
1550 | chg = __ieee80211_recalc_idle(local); | ||
1551 | mutex_unlock(&local->iflist_mtx); | ||
1552 | if (chg) | ||
1553 | ieee80211_hw_config(local, chg); | ||
1554 | } | ||
1555 | |||
1556 | static int netdev_notify(struct notifier_block *nb, | 1537 | static int netdev_notify(struct notifier_block *nb, |
1557 | unsigned long state, | 1538 | unsigned long state, |
1558 | void *ndev) | 1539 | void *ndev) |
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 5bb600d93d77..7ae678ba5d67 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
@@ -139,7 +139,7 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
139 | } | 139 | } |
140 | 140 | ||
141 | if (ret != -ENOSPC && ret != -EOPNOTSUPP) | 141 | if (ret != -ENOSPC && ret != -EOPNOTSUPP) |
142 | wiphy_err(key->local->hw.wiphy, | 142 | sdata_err(sdata, |
143 | "failed to set key (%d, %pM) to hardware (%d)\n", | 143 | "failed to set key (%d, %pM) to hardware (%d)\n", |
144 | key->conf.keyidx, | 144 | key->conf.keyidx, |
145 | sta ? sta->sta.addr : bcast_addr, ret); | 145 | sta ? sta->sta.addr : bcast_addr, ret); |
@@ -186,7 +186,7 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
186 | sta ? &sta->sta : NULL, &key->conf); | 186 | sta ? &sta->sta : NULL, &key->conf); |
187 | 187 | ||
188 | if (ret) | 188 | if (ret) |
189 | wiphy_err(key->local->hw.wiphy, | 189 | sdata_err(sdata, |
190 | "failed to remove key (%d, %pM) from hardware (%d)\n", | 190 | "failed to remove key (%d, %pM) from hardware (%d)\n", |
191 | key->conf.keyidx, | 191 | key->conf.keyidx, |
192 | sta ? sta->sta.addr : bcast_addr, ret); | 192 | sta ? sta->sta.addr : bcast_addr, ret); |
@@ -194,26 +194,6 @@ static void ieee80211_key_disable_hw_accel(struct ieee80211_key *key) | |||
194 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | 194 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; |
195 | } | 195 | } |
196 | 196 | ||
197 | void ieee80211_key_removed(struct ieee80211_key_conf *key_conf) | ||
198 | { | ||
199 | struct ieee80211_key *key; | ||
200 | |||
201 | key = container_of(key_conf, struct ieee80211_key, conf); | ||
202 | |||
203 | might_sleep(); | ||
204 | assert_key_lock(key->local); | ||
205 | |||
206 | key->flags &= ~KEY_FLAG_UPLOADED_TO_HARDWARE; | ||
207 | |||
208 | /* | ||
209 | * Flush TX path to avoid attempts to use this key | ||
210 | * after this function returns. Until then, drivers | ||
211 | * must be prepared to handle the key. | ||
212 | */ | ||
213 | synchronize_rcu(); | ||
214 | } | ||
215 | EXPORT_SYMBOL_GPL(ieee80211_key_removed); | ||
216 | |||
217 | static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, | 197 | static void __ieee80211_set_default_key(struct ieee80211_sub_if_data *sdata, |
218 | int idx, bool uni, bool multi) | 198 | int idx, bool uni, bool multi) |
219 | { | 199 | { |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index f5548e953259..c26e231c733a 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -322,7 +322,8 @@ static void ieee80211_restart_work(struct work_struct *work) | |||
322 | 322 | ||
323 | mutex_lock(&local->mtx); | 323 | mutex_lock(&local->mtx); |
324 | WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) || | 324 | WARN(test_bit(SCAN_HW_SCANNING, &local->scanning) || |
325 | local->sched_scanning, | 325 | rcu_dereference_protected(local->sched_scan_sdata, |
326 | lockdep_is_held(&local->mtx)), | ||
326 | "%s called with hardware scan in progress\n", __func__); | 327 | "%s called with hardware scan in progress\n", __func__); |
327 | mutex_unlock(&local->mtx); | 328 | mutex_unlock(&local->mtx); |
328 | 329 | ||
@@ -345,6 +346,13 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) | |||
345 | ieee80211_stop_queues_by_reason(hw, | 346 | ieee80211_stop_queues_by_reason(hw, |
346 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 347 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
347 | 348 | ||
349 | /* | ||
350 | * Stop all Rx during the reconfig. We don't want state changes | ||
351 | * or driver callbacks while this is in progress. | ||
352 | */ | ||
353 | local->in_reconfig = true; | ||
354 | barrier(); | ||
355 | |||
348 | schedule_work(&local->restart_work); | 356 | schedule_work(&local->restart_work); |
349 | } | 357 | } |
350 | EXPORT_SYMBOL(ieee80211_restart_hw); | 358 | EXPORT_SYMBOL(ieee80211_restart_hw); |
@@ -455,7 +463,9 @@ static const struct ieee80211_txrx_stypes | |||
455 | ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { | 463 | ieee80211_default_mgmt_stypes[NUM_NL80211_IFTYPES] = { |
456 | [NL80211_IFTYPE_ADHOC] = { | 464 | [NL80211_IFTYPE_ADHOC] = { |
457 | .tx = 0xffff, | 465 | .tx = 0xffff, |
458 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4), | 466 | .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | |
467 | BIT(IEEE80211_STYPE_AUTH >> 4) | | ||
468 | BIT(IEEE80211_STYPE_DEAUTH >> 4), | ||
459 | }, | 469 | }, |
460 | [NL80211_IFTYPE_STATION] = { | 470 | [NL80211_IFTYPE_STATION] = { |
461 | .tx = 0xffff, | 471 | .tx = 0xffff, |
@@ -578,7 +588,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
578 | 588 | ||
579 | local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); | 589 | local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN); |
580 | 590 | ||
581 | BUG_ON(!ops->tx && !ops->tx_frags); | 591 | BUG_ON(!ops->tx); |
582 | BUG_ON(!ops->start); | 592 | BUG_ON(!ops->start); |
583 | BUG_ON(!ops->stop); | 593 | BUG_ON(!ops->stop); |
584 | BUG_ON(!ops->config); | 594 | BUG_ON(!ops->config); |
@@ -625,8 +635,6 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
625 | 635 | ||
626 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); | 636 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
627 | 637 | ||
628 | ieee80211_work_init(local); | ||
629 | |||
630 | INIT_WORK(&local->restart_work, ieee80211_restart_work); | 638 | INIT_WORK(&local->restart_work, ieee80211_restart_work); |
631 | 639 | ||
632 | INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); | 640 | INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); |
@@ -669,7 +677,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
669 | 677 | ||
670 | ieee80211_led_names(local); | 678 | ieee80211_led_names(local); |
671 | 679 | ||
672 | ieee80211_hw_roc_setup(local); | 680 | ieee80211_roc_setup(local); |
673 | 681 | ||
674 | return &local->hw; | 682 | return &local->hw; |
675 | } | 683 | } |
@@ -681,7 +689,8 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
681 | int result, i; | 689 | int result, i; |
682 | enum ieee80211_band band; | 690 | enum ieee80211_band band; |
683 | int channels, max_bitrates; | 691 | int channels, max_bitrates; |
684 | bool supp_ht; | 692 | bool supp_ht, supp_vht; |
693 | netdev_features_t feature_whitelist; | ||
685 | static const u32 cipher_suites[] = { | 694 | static const u32 cipher_suites[] = { |
686 | /* keep WEP first, it may be removed below */ | 695 | /* keep WEP first, it may be removed below */ |
687 | WLAN_CIPHER_SUITE_WEP40, | 696 | WLAN_CIPHER_SUITE_WEP40, |
@@ -698,16 +707,21 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
698 | local->hw.offchannel_tx_hw_queue >= local->hw.queues)) | 707 | local->hw.offchannel_tx_hw_queue >= local->hw.queues)) |
699 | return -EINVAL; | 708 | return -EINVAL; |
700 | 709 | ||
701 | if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) | ||
702 | #ifdef CONFIG_PM | 710 | #ifdef CONFIG_PM |
703 | && (!local->ops->suspend || !local->ops->resume) | 711 | if ((hw->wiphy->wowlan.flags || hw->wiphy->wowlan.n_patterns) && |
704 | #endif | 712 | (!local->ops->suspend || !local->ops->resume)) |
705 | ) | ||
706 | return -EINVAL; | 713 | return -EINVAL; |
714 | #endif | ||
707 | 715 | ||
708 | if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) | 716 | if ((hw->flags & IEEE80211_HW_SCAN_WHILE_IDLE) && !local->ops->hw_scan) |
709 | return -EINVAL; | 717 | return -EINVAL; |
710 | 718 | ||
719 | /* Only HW csum features are currently compatible with mac80211 */ | ||
720 | feature_whitelist = NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | | ||
721 | NETIF_F_HW_CSUM; | ||
722 | if (WARN_ON(hw->netdev_features & ~feature_whitelist)) | ||
723 | return -EINVAL; | ||
724 | |||
711 | if (hw->max_report_rates == 0) | 725 | if (hw->max_report_rates == 0) |
712 | hw->max_report_rates = hw->max_rates; | 726 | hw->max_report_rates = hw->max_rates; |
713 | 727 | ||
@@ -719,6 +733,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
719 | channels = 0; | 733 | channels = 0; |
720 | max_bitrates = 0; | 734 | max_bitrates = 0; |
721 | supp_ht = false; | 735 | supp_ht = false; |
736 | supp_vht = false; | ||
722 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 737 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
723 | struct ieee80211_supported_band *sband; | 738 | struct ieee80211_supported_band *sband; |
724 | 739 | ||
@@ -736,6 +751,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
736 | if (max_bitrates < sband->n_bitrates) | 751 | if (max_bitrates < sband->n_bitrates) |
737 | max_bitrates = sband->n_bitrates; | 752 | max_bitrates = sband->n_bitrates; |
738 | supp_ht = supp_ht || sband->ht_cap.ht_supported; | 753 | supp_ht = supp_ht || sband->ht_cap.ht_supported; |
754 | supp_vht = supp_vht || sband->vht_cap.vht_supported; | ||
739 | } | 755 | } |
740 | 756 | ||
741 | local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + | 757 | local->int_scan_req = kzalloc(sizeof(*local->int_scan_req) + |
@@ -811,6 +827,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
811 | if (supp_ht) | 827 | if (supp_ht) |
812 | local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); | 828 | local->scan_ies_len += 2 + sizeof(struct ieee80211_ht_cap); |
813 | 829 | ||
830 | if (supp_vht) | ||
831 | local->scan_ies_len += | ||
832 | 2 + sizeof(struct ieee80211_vht_capabilities); | ||
833 | |||
814 | if (!local->ops->hw_scan) { | 834 | if (!local->ops->hw_scan) { |
815 | /* For hw_scan, driver needs to set these up. */ | 835 | /* For hw_scan, driver needs to set these up. */ |
816 | local->hw.wiphy->max_scan_ssids = 4; | 836 | local->hw.wiphy->max_scan_ssids = 4; |
@@ -1009,12 +1029,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
1009 | 1029 | ||
1010 | rtnl_unlock(); | 1030 | rtnl_unlock(); |
1011 | 1031 | ||
1012 | /* | ||
1013 | * Now all work items will be gone, but the | ||
1014 | * timer might still be armed, so delete it | ||
1015 | */ | ||
1016 | del_timer_sync(&local->work_timer); | ||
1017 | |||
1018 | cancel_work_sync(&local->restart_work); | 1032 | cancel_work_sync(&local->restart_work); |
1019 | cancel_work_sync(&local->reconfig_filter); | 1033 | cancel_work_sync(&local->reconfig_filter); |
1020 | 1034 | ||
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index 2913113c5833..6fac18c0423f 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -133,7 +133,7 @@ bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie) | |||
133 | } | 133 | } |
134 | 134 | ||
135 | /** | 135 | /** |
136 | * mesh_accept_plinks_update: update accepting_plink in local mesh beacons | 136 | * mesh_accept_plinks_update - update accepting_plink in local mesh beacons |
137 | * | 137 | * |
138 | * @sdata: mesh interface in which mesh beacons are going to be updated | 138 | * @sdata: mesh interface in which mesh beacons are going to be updated |
139 | */ | 139 | */ |
@@ -443,7 +443,7 @@ static void ieee80211_mesh_path_root_timer(unsigned long data) | |||
443 | 443 | ||
444 | void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) | 444 | void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) |
445 | { | 445 | { |
446 | if (ifmsh->mshcfg.dot11MeshHWMPRootMode) | 446 | if (ifmsh->mshcfg.dot11MeshHWMPRootMode > IEEE80211_ROOTMODE_ROOT) |
447 | set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); | 447 | set_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); |
448 | else { | 448 | else { |
449 | clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); | 449 | clear_bit(MESH_WORK_ROOT, &ifmsh->wrkq_flags); |
@@ -523,11 +523,6 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, | |||
523 | { | 523 | { |
524 | bool free_plinks; | 524 | bool free_plinks; |
525 | 525 | ||
526 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
527 | printk(KERN_DEBUG "%s: running mesh housekeeping\n", | ||
528 | sdata->name); | ||
529 | #endif | ||
530 | |||
531 | ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); | 526 | ieee80211_sta_expire(sdata, IEEE80211_MESH_PEER_INACTIVITY_LIMIT); |
532 | mesh_path_expire(sdata); | 527 | mesh_path_expire(sdata); |
533 | 528 | ||
@@ -542,11 +537,17 @@ static void ieee80211_mesh_housekeeping(struct ieee80211_sub_if_data *sdata, | |||
542 | static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) | 537 | static void ieee80211_mesh_rootpath(struct ieee80211_sub_if_data *sdata) |
543 | { | 538 | { |
544 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 539 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
540 | u32 interval; | ||
545 | 541 | ||
546 | mesh_path_tx_root_frame(sdata); | 542 | mesh_path_tx_root_frame(sdata); |
543 | |||
544 | if (ifmsh->mshcfg.dot11MeshHWMPRootMode == IEEE80211_PROACTIVE_RANN) | ||
545 | interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; | ||
546 | else | ||
547 | interval = ifmsh->mshcfg.dot11MeshHWMProotInterval; | ||
548 | |||
547 | mod_timer(&ifmsh->mesh_path_root_timer, | 549 | mod_timer(&ifmsh->mesh_path_root_timer, |
548 | round_jiffies(TU_TO_EXP_TIME( | 550 | round_jiffies(TU_TO_EXP_TIME(interval))); |
549 | ifmsh->mshcfg.dot11MeshHWMPRannInterval))); | ||
550 | } | 551 | } |
551 | 552 | ||
552 | #ifdef CONFIG_PM | 553 | #ifdef CONFIG_PM |
diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h index e3642756f8f4..faaa39bcfd10 100644 --- a/net/mac80211/mesh.h +++ b/net/mac80211/mesh.h | |||
@@ -104,6 +104,7 @@ enum mesh_deferred_task_flags { | |||
104 | * an mpath to a hash bucket on a path table. | 104 | * an mpath to a hash bucket on a path table. |
105 | * @rann_snd_addr: the RANN sender address | 105 | * @rann_snd_addr: the RANN sender address |
106 | * @rann_metric: the aggregated path metric towards the root node | 106 | * @rann_metric: the aggregated path metric towards the root node |
107 | * @last_preq_to_root: Timestamp of last PREQ sent to root | ||
107 | * @is_root: the destination station of this path is a root node | 108 | * @is_root: the destination station of this path is a root node |
108 | * @is_gate: the destination station of this path is a mesh gate | 109 | * @is_gate: the destination station of this path is a mesh gate |
109 | * | 110 | * |
@@ -131,6 +132,7 @@ struct mesh_path { | |||
131 | spinlock_t state_lock; | 132 | spinlock_t state_lock; |
132 | u8 rann_snd_addr[ETH_ALEN]; | 133 | u8 rann_snd_addr[ETH_ALEN]; |
133 | u32 rann_metric; | 134 | u32 rann_metric; |
135 | unsigned long last_preq_to_root; | ||
134 | bool is_root; | 136 | bool is_root; |
135 | bool is_gate; | 137 | bool is_gate; |
136 | }; | 138 | }; |
@@ -245,7 +247,7 @@ void mesh_rmc_free(struct ieee80211_sub_if_data *sdata); | |||
245 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); | 247 | int mesh_rmc_init(struct ieee80211_sub_if_data *sdata); |
246 | void ieee80211s_init(void); | 248 | void ieee80211s_init(void); |
247 | void ieee80211s_update_metric(struct ieee80211_local *local, | 249 | void ieee80211s_update_metric(struct ieee80211_local *local, |
248 | struct sta_info *stainfo, struct sk_buff *skb); | 250 | struct sta_info *sta, struct sk_buff *skb); |
249 | void ieee80211s_stop(void); | 251 | void ieee80211s_stop(void); |
250 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); | 252 | void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata); |
251 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); | 253 | void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata); |
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index 9b59658e8650..494bc39f61a4 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c | |||
@@ -13,13 +13,6 @@ | |||
13 | #include "wme.h" | 13 | #include "wme.h" |
14 | #include "mesh.h" | 14 | #include "mesh.h" |
15 | 15 | ||
16 | #ifdef CONFIG_MAC80211_VERBOSE_MHWMP_DEBUG | ||
17 | #define mhwmp_dbg(fmt, args...) \ | ||
18 | printk(KERN_DEBUG "Mesh HWMP (%s): " fmt "\n", sdata->name, ##args) | ||
19 | #else | ||
20 | #define mhwmp_dbg(fmt, args...) do { (void)(0); } while (0) | ||
21 | #endif | ||
22 | |||
23 | #define TEST_FRAME_LEN 8192 | 16 | #define TEST_FRAME_LEN 8192 |
24 | #define MAX_METRIC 0xffffffff | 17 | #define MAX_METRIC 0xffffffff |
25 | #define ARITH_SHIFT 8 | 18 | #define ARITH_SHIFT 8 |
@@ -98,6 +91,8 @@ static inline u32 u16_field_get(u8 *preq_elem, int offset, bool ae) | |||
98 | #define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries) | 91 | #define max_preq_retries(s) (s->u.mesh.mshcfg.dot11MeshHWMPmaxPREQretries) |
99 | #define disc_timeout_jiff(s) \ | 92 | #define disc_timeout_jiff(s) \ |
100 | msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout) | 93 | msecs_to_jiffies(sdata->u.mesh.mshcfg.min_discovery_timeout) |
94 | #define root_path_confirmation_jiffies(s) \ | ||
95 | msecs_to_jiffies(sdata->u.mesh.mshcfg.dot11MeshHWMPconfirmationInterval) | ||
101 | 96 | ||
102 | enum mpath_frame_type { | 97 | enum mpath_frame_type { |
103 | MPATH_PREQ = 0, | 98 | MPATH_PREQ = 0, |
@@ -142,19 +137,19 @@ static int mesh_path_sel_frame_tx(enum mpath_frame_type action, u8 flags, | |||
142 | 137 | ||
143 | switch (action) { | 138 | switch (action) { |
144 | case MPATH_PREQ: | 139 | case MPATH_PREQ: |
145 | mhwmp_dbg("sending PREQ to %pM", target); | 140 | mhwmp_dbg(sdata, "sending PREQ to %pM\n", target); |
146 | ie_len = 37; | 141 | ie_len = 37; |
147 | pos = skb_put(skb, 2 + ie_len); | 142 | pos = skb_put(skb, 2 + ie_len); |
148 | *pos++ = WLAN_EID_PREQ; | 143 | *pos++ = WLAN_EID_PREQ; |
149 | break; | 144 | break; |
150 | case MPATH_PREP: | 145 | case MPATH_PREP: |
151 | mhwmp_dbg("sending PREP to %pM", target); | 146 | mhwmp_dbg(sdata, "sending PREP to %pM\n", target); |
152 | ie_len = 31; | 147 | ie_len = 31; |
153 | pos = skb_put(skb, 2 + ie_len); | 148 | pos = skb_put(skb, 2 + ie_len); |
154 | *pos++ = WLAN_EID_PREP; | 149 | *pos++ = WLAN_EID_PREP; |
155 | break; | 150 | break; |
156 | case MPATH_RANN: | 151 | case MPATH_RANN: |
157 | mhwmp_dbg("sending RANN from %pM", orig_addr); | 152 | mhwmp_dbg(sdata, "sending RANN from %pM\n", orig_addr); |
158 | ie_len = sizeof(struct ieee80211_rann_ie); | 153 | ie_len = sizeof(struct ieee80211_rann_ie); |
159 | pos = skb_put(skb, 2 + ie_len); | 154 | pos = skb_put(skb, 2 + ie_len); |
160 | *pos++ = WLAN_EID_RANN; | 155 | *pos++ = WLAN_EID_RANN; |
@@ -303,7 +298,7 @@ int mesh_path_error_tx(u8 ttl, u8 *target, __le32 target_sn, | |||
303 | } | 298 | } |
304 | 299 | ||
305 | void ieee80211s_update_metric(struct ieee80211_local *local, | 300 | void ieee80211s_update_metric(struct ieee80211_local *local, |
306 | struct sta_info *stainfo, struct sk_buff *skb) | 301 | struct sta_info *sta, struct sk_buff *skb) |
307 | { | 302 | { |
308 | struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); | 303 | struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb); |
309 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 304 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
@@ -315,15 +310,14 @@ void ieee80211s_update_metric(struct ieee80211_local *local, | |||
315 | failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK); | 310 | failed = !(txinfo->flags & IEEE80211_TX_STAT_ACK); |
316 | 311 | ||
317 | /* moving average, scaled to 100 */ | 312 | /* moving average, scaled to 100 */ |
318 | stainfo->fail_avg = ((80 * stainfo->fail_avg + 5) / 100 + 20 * failed); | 313 | sta->fail_avg = ((80 * sta->fail_avg + 5) / 100 + 20 * failed); |
319 | if (stainfo->fail_avg > 95) | 314 | if (sta->fail_avg > 95) |
320 | mesh_plink_broken(stainfo); | 315 | mesh_plink_broken(sta); |
321 | } | 316 | } |
322 | 317 | ||
323 | static u32 airtime_link_metric_get(struct ieee80211_local *local, | 318 | static u32 airtime_link_metric_get(struct ieee80211_local *local, |
324 | struct sta_info *sta) | 319 | struct sta_info *sta) |
325 | { | 320 | { |
326 | struct ieee80211_supported_band *sband; | ||
327 | struct rate_info rinfo; | 321 | struct rate_info rinfo; |
328 | /* This should be adjusted for each device */ | 322 | /* This should be adjusted for each device */ |
329 | int device_constant = 1 << ARITH_SHIFT; | 323 | int device_constant = 1 << ARITH_SHIFT; |
@@ -333,8 +327,6 @@ static u32 airtime_link_metric_get(struct ieee80211_local *local, | |||
333 | u32 tx_time, estimated_retx; | 327 | u32 tx_time, estimated_retx; |
334 | u64 result; | 328 | u64 result; |
335 | 329 | ||
336 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | ||
337 | |||
338 | if (sta->fail_avg >= 100) | 330 | if (sta->fail_avg >= 100) |
339 | return MAX_METRIC; | 331 | return MAX_METRIC; |
340 | 332 | ||
@@ -519,10 +511,11 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
519 | struct mesh_path *mpath = NULL; | 511 | struct mesh_path *mpath = NULL; |
520 | u8 *target_addr, *orig_addr; | 512 | u8 *target_addr, *orig_addr; |
521 | const u8 *da; | 513 | const u8 *da; |
522 | u8 target_flags, ttl; | 514 | u8 target_flags, ttl, flags; |
523 | u32 orig_sn, target_sn, lifetime; | 515 | u32 orig_sn, target_sn, lifetime, orig_metric; |
524 | bool reply = false; | 516 | bool reply = false; |
525 | bool forward = true; | 517 | bool forward = true; |
518 | bool root_is_gate; | ||
526 | 519 | ||
527 | /* Update target SN, if present */ | 520 | /* Update target SN, if present */ |
528 | target_addr = PREQ_IE_TARGET_ADDR(preq_elem); | 521 | target_addr = PREQ_IE_TARGET_ADDR(preq_elem); |
@@ -530,11 +523,15 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
530 | target_sn = PREQ_IE_TARGET_SN(preq_elem); | 523 | target_sn = PREQ_IE_TARGET_SN(preq_elem); |
531 | orig_sn = PREQ_IE_ORIG_SN(preq_elem); | 524 | orig_sn = PREQ_IE_ORIG_SN(preq_elem); |
532 | target_flags = PREQ_IE_TARGET_F(preq_elem); | 525 | target_flags = PREQ_IE_TARGET_F(preq_elem); |
526 | orig_metric = metric; | ||
527 | /* Proactive PREQ gate announcements */ | ||
528 | flags = PREQ_IE_FLAGS(preq_elem); | ||
529 | root_is_gate = !!(flags & RANN_FLAG_IS_GATE); | ||
533 | 530 | ||
534 | mhwmp_dbg("received PREQ from %pM", orig_addr); | 531 | mhwmp_dbg(sdata, "received PREQ from %pM\n", orig_addr); |
535 | 532 | ||
536 | if (ether_addr_equal(target_addr, sdata->vif.addr)) { | 533 | if (ether_addr_equal(target_addr, sdata->vif.addr)) { |
537 | mhwmp_dbg("PREQ is for us"); | 534 | mhwmp_dbg(sdata, "PREQ is for us\n"); |
538 | forward = false; | 535 | forward = false; |
539 | reply = true; | 536 | reply = true; |
540 | metric = 0; | 537 | metric = 0; |
@@ -544,6 +541,22 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
544 | target_sn = ++ifmsh->sn; | 541 | target_sn = ++ifmsh->sn; |
545 | ifmsh->last_sn_update = jiffies; | 542 | ifmsh->last_sn_update = jiffies; |
546 | } | 543 | } |
544 | } else if (is_broadcast_ether_addr(target_addr) && | ||
545 | (target_flags & IEEE80211_PREQ_TO_FLAG)) { | ||
546 | rcu_read_lock(); | ||
547 | mpath = mesh_path_lookup(orig_addr, sdata); | ||
548 | if (mpath) { | ||
549 | if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { | ||
550 | reply = true; | ||
551 | target_addr = sdata->vif.addr; | ||
552 | target_sn = ++ifmsh->sn; | ||
553 | metric = 0; | ||
554 | ifmsh->last_sn_update = jiffies; | ||
555 | } | ||
556 | if (root_is_gate) | ||
557 | mesh_path_add_gate(mpath); | ||
558 | } | ||
559 | rcu_read_unlock(); | ||
547 | } else { | 560 | } else { |
548 | rcu_read_lock(); | 561 | rcu_read_lock(); |
549 | mpath = mesh_path_lookup(target_addr, sdata); | 562 | mpath = mesh_path_lookup(target_addr, sdata); |
@@ -570,19 +583,20 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
570 | lifetime = PREQ_IE_LIFETIME(preq_elem); | 583 | lifetime = PREQ_IE_LIFETIME(preq_elem); |
571 | ttl = ifmsh->mshcfg.element_ttl; | 584 | ttl = ifmsh->mshcfg.element_ttl; |
572 | if (ttl != 0) { | 585 | if (ttl != 0) { |
573 | mhwmp_dbg("replying to the PREQ"); | 586 | mhwmp_dbg(sdata, "replying to the PREQ\n"); |
574 | mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr, | 587 | mesh_path_sel_frame_tx(MPATH_PREP, 0, orig_addr, |
575 | cpu_to_le32(orig_sn), 0, target_addr, | 588 | cpu_to_le32(orig_sn), 0, target_addr, |
576 | cpu_to_le32(target_sn), mgmt->sa, 0, ttl, | 589 | cpu_to_le32(target_sn), mgmt->sa, 0, ttl, |
577 | cpu_to_le32(lifetime), cpu_to_le32(metric), | 590 | cpu_to_le32(lifetime), cpu_to_le32(metric), |
578 | 0, sdata); | 591 | 0, sdata); |
579 | } else | 592 | } else { |
580 | ifmsh->mshstats.dropped_frames_ttl++; | 593 | ifmsh->mshstats.dropped_frames_ttl++; |
594 | } | ||
581 | } | 595 | } |
582 | 596 | ||
583 | if (forward && ifmsh->mshcfg.dot11MeshForwarding) { | 597 | if (forward && ifmsh->mshcfg.dot11MeshForwarding) { |
584 | u32 preq_id; | 598 | u32 preq_id; |
585 | u8 hopcount, flags; | 599 | u8 hopcount; |
586 | 600 | ||
587 | ttl = PREQ_IE_TTL(preq_elem); | 601 | ttl = PREQ_IE_TTL(preq_elem); |
588 | lifetime = PREQ_IE_LIFETIME(preq_elem); | 602 | lifetime = PREQ_IE_LIFETIME(preq_elem); |
@@ -590,13 +604,19 @@ static void hwmp_preq_frame_process(struct ieee80211_sub_if_data *sdata, | |||
590 | ifmsh->mshstats.dropped_frames_ttl++; | 604 | ifmsh->mshstats.dropped_frames_ttl++; |
591 | return; | 605 | return; |
592 | } | 606 | } |
593 | mhwmp_dbg("forwarding the PREQ from %pM", orig_addr); | 607 | mhwmp_dbg(sdata, "forwarding the PREQ from %pM\n", orig_addr); |
594 | --ttl; | 608 | --ttl; |
595 | flags = PREQ_IE_FLAGS(preq_elem); | ||
596 | preq_id = PREQ_IE_PREQ_ID(preq_elem); | 609 | preq_id = PREQ_IE_PREQ_ID(preq_elem); |
597 | hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; | 610 | hopcount = PREQ_IE_HOPCOUNT(preq_elem) + 1; |
598 | da = (mpath && mpath->is_root) ? | 611 | da = (mpath && mpath->is_root) ? |
599 | mpath->rann_snd_addr : broadcast_addr; | 612 | mpath->rann_snd_addr : broadcast_addr; |
613 | |||
614 | if (flags & IEEE80211_PREQ_PROACTIVE_PREP_FLAG) { | ||
615 | target_addr = PREQ_IE_TARGET_ADDR(preq_elem); | ||
616 | target_sn = PREQ_IE_TARGET_SN(preq_elem); | ||
617 | metric = orig_metric; | ||
618 | } | ||
619 | |||
600 | mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, | 620 | mesh_path_sel_frame_tx(MPATH_PREQ, flags, orig_addr, |
601 | cpu_to_le32(orig_sn), target_flags, target_addr, | 621 | cpu_to_le32(orig_sn), target_flags, target_addr, |
602 | cpu_to_le32(target_sn), da, | 622 | cpu_to_le32(target_sn), da, |
@@ -631,7 +651,8 @@ static void hwmp_prep_frame_process(struct ieee80211_sub_if_data *sdata, | |||
631 | u8 next_hop[ETH_ALEN]; | 651 | u8 next_hop[ETH_ALEN]; |
632 | u32 target_sn, orig_sn, lifetime; | 652 | u32 target_sn, orig_sn, lifetime; |
633 | 653 | ||
634 | mhwmp_dbg("received PREP from %pM", PREP_IE_ORIG_ADDR(prep_elem)); | 654 | mhwmp_dbg(sdata, "received PREP from %pM\n", |
655 | PREP_IE_ORIG_ADDR(prep_elem)); | ||
635 | 656 | ||
636 | orig_addr = PREP_IE_ORIG_ADDR(prep_elem); | 657 | orig_addr = PREP_IE_ORIG_ADDR(prep_elem); |
637 | if (ether_addr_equal(orig_addr, sdata->vif.addr)) | 658 | if (ether_addr_equal(orig_addr, sdata->vif.addr)) |
@@ -744,11 +765,6 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
744 | bool root_is_gate; | 765 | bool root_is_gate; |
745 | 766 | ||
746 | ttl = rann->rann_ttl; | 767 | ttl = rann->rann_ttl; |
747 | if (ttl <= 1) { | ||
748 | ifmsh->mshstats.dropped_frames_ttl++; | ||
749 | return; | ||
750 | } | ||
751 | ttl--; | ||
752 | flags = rann->rann_flags; | 768 | flags = rann->rann_flags; |
753 | root_is_gate = !!(flags & RANN_FLAG_IS_GATE); | 769 | root_is_gate = !!(flags & RANN_FLAG_IS_GATE); |
754 | orig_addr = rann->rann_addr; | 770 | orig_addr = rann->rann_addr; |
@@ -762,8 +778,9 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
762 | if (ether_addr_equal(orig_addr, sdata->vif.addr)) | 778 | if (ether_addr_equal(orig_addr, sdata->vif.addr)) |
763 | return; | 779 | return; |
764 | 780 | ||
765 | mhwmp_dbg("received RANN from %pM via neighbour %pM (is_gate=%d)", | 781 | mhwmp_dbg(sdata, |
766 | orig_addr, mgmt->sa, root_is_gate); | 782 | "received RANN from %pM via neighbour %pM (is_gate=%d)\n", |
783 | orig_addr, mgmt->sa, root_is_gate); | ||
767 | 784 | ||
768 | rcu_read_lock(); | 785 | rcu_read_lock(); |
769 | sta = sta_info_get(sdata, mgmt->sa); | 786 | sta = sta_info_get(sdata, mgmt->sa); |
@@ -785,34 +802,50 @@ static void hwmp_rann_frame_process(struct ieee80211_sub_if_data *sdata, | |||
785 | } | 802 | } |
786 | } | 803 | } |
787 | 804 | ||
805 | if (!(SN_LT(mpath->sn, orig_sn)) && | ||
806 | !(mpath->sn == orig_sn && metric < mpath->rann_metric)) { | ||
807 | rcu_read_unlock(); | ||
808 | return; | ||
809 | } | ||
810 | |||
788 | if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) || | 811 | if ((!(mpath->flags & (MESH_PATH_ACTIVE | MESH_PATH_RESOLVING)) || |
789 | time_after(jiffies, mpath->exp_time - 1*HZ)) && | 812 | (time_after(jiffies, mpath->last_preq_to_root + |
790 | !(mpath->flags & MESH_PATH_FIXED)) { | 813 | root_path_confirmation_jiffies(sdata)) || |
791 | mhwmp_dbg("%s time to refresh root mpath %pM", sdata->name, | 814 | time_before(jiffies, mpath->last_preq_to_root))) && |
792 | orig_addr); | 815 | !(mpath->flags & MESH_PATH_FIXED) && (ttl != 0)) { |
816 | mhwmp_dbg(sdata, | ||
817 | "time to refresh root mpath %pM\n", | ||
818 | orig_addr); | ||
793 | mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); | 819 | mesh_queue_preq(mpath, PREQ_Q_F_START | PREQ_Q_F_REFRESH); |
820 | mpath->last_preq_to_root = jiffies; | ||
794 | } | 821 | } |
795 | 822 | ||
796 | if ((SN_LT(mpath->sn, orig_sn) || (mpath->sn == orig_sn && | 823 | mpath->sn = orig_sn; |
797 | metric < mpath->rann_metric)) && ifmsh->mshcfg.dot11MeshForwarding) { | 824 | mpath->rann_metric = metric + metric_txsta; |
825 | mpath->is_root = true; | ||
826 | /* Recording RANNs sender address to send individually | ||
827 | * addressed PREQs destined for root mesh STA */ | ||
828 | memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN); | ||
829 | |||
830 | if (root_is_gate) | ||
831 | mesh_path_add_gate(mpath); | ||
832 | |||
833 | if (ttl <= 1) { | ||
834 | ifmsh->mshstats.dropped_frames_ttl++; | ||
835 | rcu_read_unlock(); | ||
836 | return; | ||
837 | } | ||
838 | ttl--; | ||
839 | |||
840 | if (ifmsh->mshcfg.dot11MeshForwarding) { | ||
798 | mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, | 841 | mesh_path_sel_frame_tx(MPATH_RANN, flags, orig_addr, |
799 | cpu_to_le32(orig_sn), | 842 | cpu_to_le32(orig_sn), |
800 | 0, NULL, 0, broadcast_addr, | 843 | 0, NULL, 0, broadcast_addr, |
801 | hopcount, ttl, cpu_to_le32(interval), | 844 | hopcount, ttl, cpu_to_le32(interval), |
802 | cpu_to_le32(metric + metric_txsta), | 845 | cpu_to_le32(metric + metric_txsta), |
803 | 0, sdata); | 846 | 0, sdata); |
804 | mpath->sn = orig_sn; | ||
805 | mpath->rann_metric = metric + metric_txsta; | ||
806 | /* Recording RANNs sender address to send individually | ||
807 | * addressed PREQs destined for root mesh STA */ | ||
808 | memcpy(mpath->rann_snd_addr, mgmt->sa, ETH_ALEN); | ||
809 | } | 847 | } |
810 | 848 | ||
811 | mpath->is_root = true; | ||
812 | |||
813 | if (root_is_gate) | ||
814 | mesh_path_add_gate(mpath); | ||
815 | |||
816 | rcu_read_unlock(); | 849 | rcu_read_unlock(); |
817 | } | 850 | } |
818 | 851 | ||
@@ -889,7 +922,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | |||
889 | 922 | ||
890 | preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC); | 923 | preq_node = kmalloc(sizeof(struct mesh_preq_queue), GFP_ATOMIC); |
891 | if (!preq_node) { | 924 | if (!preq_node) { |
892 | mhwmp_dbg("could not allocate PREQ node"); | 925 | mhwmp_dbg(sdata, "could not allocate PREQ node\n"); |
893 | return; | 926 | return; |
894 | } | 927 | } |
895 | 928 | ||
@@ -898,7 +931,7 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags) | |||
898 | spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); | 931 | spin_unlock_bh(&ifmsh->mesh_preq_queue_lock); |
899 | kfree(preq_node); | 932 | kfree(preq_node); |
900 | if (printk_ratelimit()) | 933 | if (printk_ratelimit()) |
901 | mhwmp_dbg("PREQ node queue full"); | 934 | mhwmp_dbg(sdata, "PREQ node queue full\n"); |
902 | return; | 935 | return; |
903 | } | 936 | } |
904 | 937 | ||
@@ -1021,12 +1054,15 @@ enddiscovery: | |||
1021 | kfree(preq_node); | 1054 | kfree(preq_node); |
1022 | } | 1055 | } |
1023 | 1056 | ||
1024 | /* mesh_nexthop_resolve - lookup next hop for given skb and start path | 1057 | /** |
1025 | * discovery if no forwarding information is found. | 1058 | * mesh_nexthop_resolve - lookup next hop; conditionally start path discovery |
1026 | * | 1059 | * |
1027 | * @skb: 802.11 frame to be sent | 1060 | * @skb: 802.11 frame to be sent |
1028 | * @sdata: network subif the frame will be sent through | 1061 | * @sdata: network subif the frame will be sent through |
1029 | * | 1062 | * |
1063 | * Lookup next hop for given skb and start path discovery if no | ||
1064 | * forwarding information is found. | ||
1065 | * | ||
1030 | * Returns: 0 if the next hop was found and -ENOENT if the frame was queued. | 1066 | * Returns: 0 if the next hop was found and -ENOENT if the frame was queued. |
1031 | * skb is freeed here if no mpath could be allocated. | 1067 | * skb is freeed here if no mpath could be allocated. |
1032 | */ | 1068 | */ |
@@ -1146,7 +1182,7 @@ void mesh_path_timer(unsigned long data) | |||
1146 | if (!mpath->is_gate && mesh_gate_num(sdata) > 0) { | 1182 | if (!mpath->is_gate && mesh_gate_num(sdata) > 0) { |
1147 | ret = mesh_path_send_to_gates(mpath); | 1183 | ret = mesh_path_send_to_gates(mpath); |
1148 | if (ret) | 1184 | if (ret) |
1149 | mhwmp_dbg("no gate was reachable"); | 1185 | mhwmp_dbg(sdata, "no gate was reachable\n"); |
1150 | } else | 1186 | } else |
1151 | mesh_path_flush_pending(mpath); | 1187 | mesh_path_flush_pending(mpath); |
1152 | } | 1188 | } |
@@ -1157,13 +1193,34 @@ mesh_path_tx_root_frame(struct ieee80211_sub_if_data *sdata) | |||
1157 | { | 1193 | { |
1158 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; | 1194 | struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; |
1159 | u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; | 1195 | u32 interval = ifmsh->mshcfg.dot11MeshHWMPRannInterval; |
1160 | u8 flags; | 1196 | u8 flags, target_flags = 0; |
1161 | 1197 | ||
1162 | flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol) | 1198 | flags = (ifmsh->mshcfg.dot11MeshGateAnnouncementProtocol) |
1163 | ? RANN_FLAG_IS_GATE : 0; | 1199 | ? RANN_FLAG_IS_GATE : 0; |
1164 | mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, | 1200 | |
1201 | switch (ifmsh->mshcfg.dot11MeshHWMPRootMode) { | ||
1202 | case IEEE80211_PROACTIVE_RANN: | ||
1203 | mesh_path_sel_frame_tx(MPATH_RANN, flags, sdata->vif.addr, | ||
1165 | cpu_to_le32(++ifmsh->sn), | 1204 | cpu_to_le32(++ifmsh->sn), |
1166 | 0, NULL, 0, broadcast_addr, | 1205 | 0, NULL, 0, broadcast_addr, |
1167 | 0, sdata->u.mesh.mshcfg.element_ttl, | 1206 | 0, ifmsh->mshcfg.element_ttl, |
1168 | cpu_to_le32(interval), 0, 0, sdata); | 1207 | cpu_to_le32(interval), 0, 0, sdata); |
1208 | break; | ||
1209 | case IEEE80211_PROACTIVE_PREQ_WITH_PREP: | ||
1210 | flags |= IEEE80211_PREQ_PROACTIVE_PREP_FLAG; | ||
1211 | case IEEE80211_PROACTIVE_PREQ_NO_PREP: | ||
1212 | interval = ifmsh->mshcfg.dot11MeshHWMPactivePathToRootTimeout; | ||
1213 | target_flags |= IEEE80211_PREQ_TO_FLAG | | ||
1214 | IEEE80211_PREQ_USN_FLAG; | ||
1215 | mesh_path_sel_frame_tx(MPATH_PREQ, flags, sdata->vif.addr, | ||
1216 | cpu_to_le32(++ifmsh->sn), target_flags, | ||
1217 | (u8 *) broadcast_addr, 0, broadcast_addr, | ||
1218 | 0, ifmsh->mshcfg.element_ttl, | ||
1219 | cpu_to_le32(interval), | ||
1220 | 0, cpu_to_le32(ifmsh->preq_id++), sdata); | ||
1221 | break; | ||
1222 | default: | ||
1223 | mhwmp_dbg(sdata, "Proactive mechanism not supported\n"); | ||
1224 | return; | ||
1225 | } | ||
1169 | } | 1226 | } |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index b39224d8255c..075bc535c601 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
@@ -18,12 +18,6 @@ | |||
18 | #include "ieee80211_i.h" | 18 | #include "ieee80211_i.h" |
19 | #include "mesh.h" | 19 | #include "mesh.h" |
20 | 20 | ||
21 | #ifdef CONFIG_MAC80211_VERBOSE_MPATH_DEBUG | ||
22 | #define mpath_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) | ||
23 | #else | ||
24 | #define mpath_dbg(fmt, args...) do { (void)(0); } while (0) | ||
25 | #endif | ||
26 | |||
27 | /* There will be initially 2^INIT_PATHS_SIZE_ORDER buckets */ | 21 | /* There will be initially 2^INIT_PATHS_SIZE_ORDER buckets */ |
28 | #define INIT_PATHS_SIZE_ORDER 2 | 22 | #define INIT_PATHS_SIZE_ORDER 2 |
29 | 23 | ||
@@ -322,9 +316,8 @@ static void mesh_path_move_to_queue(struct mesh_path *gate_mpath, | |||
322 | 316 | ||
323 | spin_lock_irqsave(&gate_mpath->frame_queue.lock, flags); | 317 | spin_lock_irqsave(&gate_mpath->frame_queue.lock, flags); |
324 | skb_queue_splice(&gateq, &gate_mpath->frame_queue); | 318 | skb_queue_splice(&gateq, &gate_mpath->frame_queue); |
325 | mpath_dbg("Mpath queue for gate %pM has %d frames\n", | 319 | mpath_dbg(gate_mpath->sdata, "Mpath queue for gate %pM has %d frames\n", |
326 | gate_mpath->dst, | 320 | gate_mpath->dst, skb_queue_len(&gate_mpath->frame_queue)); |
327 | skb_queue_len(&gate_mpath->frame_queue)); | ||
328 | spin_unlock_irqrestore(&gate_mpath->frame_queue.lock, flags); | 321 | spin_unlock_irqrestore(&gate_mpath->frame_queue.lock, flags); |
329 | 322 | ||
330 | if (!copy) | 323 | if (!copy) |
@@ -446,9 +439,9 @@ int mesh_path_add_gate(struct mesh_path *mpath) | |||
446 | hlist_add_head_rcu(&new_gate->list, tbl->known_gates); | 439 | hlist_add_head_rcu(&new_gate->list, tbl->known_gates); |
447 | spin_unlock_bh(&tbl->gates_lock); | 440 | spin_unlock_bh(&tbl->gates_lock); |
448 | rcu_read_unlock(); | 441 | rcu_read_unlock(); |
449 | mpath_dbg("Mesh path (%s): Recorded new gate: %pM. %d known gates\n", | 442 | mpath_dbg(mpath->sdata, |
450 | mpath->sdata->name, mpath->dst, | 443 | "Mesh path: Recorded new gate: %pM. %d known gates\n", |
451 | mpath->sdata->u.mesh.num_gates); | 444 | mpath->dst, mpath->sdata->u.mesh.num_gates); |
452 | return 0; | 445 | return 0; |
453 | err_rcu: | 446 | err_rcu: |
454 | rcu_read_unlock(); | 447 | rcu_read_unlock(); |
@@ -477,8 +470,8 @@ static int mesh_gate_del(struct mesh_table *tbl, struct mesh_path *mpath) | |||
477 | spin_unlock_bh(&tbl->gates_lock); | 470 | spin_unlock_bh(&tbl->gates_lock); |
478 | mpath->sdata->u.mesh.num_gates--; | 471 | mpath->sdata->u.mesh.num_gates--; |
479 | mpath->is_gate = false; | 472 | mpath->is_gate = false; |
480 | mpath_dbg("Mesh path (%s): Deleted gate: %pM. " | 473 | mpath_dbg(mpath->sdata, |
481 | "%d known gates\n", mpath->sdata->name, | 474 | "Mesh path: Deleted gate: %pM. %d known gates\n", |
482 | mpath->dst, mpath->sdata->u.mesh.num_gates); | 475 | mpath->dst, mpath->sdata->u.mesh.num_gates); |
483 | break; | 476 | break; |
484 | } | 477 | } |
@@ -785,7 +778,7 @@ static void __mesh_path_del(struct mesh_table *tbl, struct mpath_node *node) | |||
785 | /** | 778 | /** |
786 | * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches | 779 | * mesh_path_flush_by_nexthop - Deletes mesh paths if their next hop matches |
787 | * | 780 | * |
788 | * @sta - mesh peer to match | 781 | * @sta: mesh peer to match |
789 | * | 782 | * |
790 | * RCU notes: this function is called when a mesh plink transitions from | 783 | * RCU notes: this function is called when a mesh plink transitions from |
791 | * PLINK_ESTAB to any other state, since PLINK_ESTAB state is the only one that | 784 | * PLINK_ESTAB to any other state, since PLINK_ESTAB state is the only one that |
@@ -840,7 +833,7 @@ static void table_flush_by_iface(struct mesh_table *tbl, | |||
840 | * | 833 | * |
841 | * This function deletes both mesh paths as well as mesh portal paths. | 834 | * This function deletes both mesh paths as well as mesh portal paths. |
842 | * | 835 | * |
843 | * @sdata - interface data to match | 836 | * @sdata: interface data to match |
844 | * | 837 | * |
845 | */ | 838 | */ |
846 | void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) | 839 | void mesh_path_flush_by_iface(struct ieee80211_sub_if_data *sdata) |
@@ -946,19 +939,20 @@ int mesh_path_send_to_gates(struct mesh_path *mpath) | |||
946 | continue; | 939 | continue; |
947 | 940 | ||
948 | if (gate->mpath->flags & MESH_PATH_ACTIVE) { | 941 | if (gate->mpath->flags & MESH_PATH_ACTIVE) { |
949 | mpath_dbg("Forwarding to %pM\n", gate->mpath->dst); | 942 | mpath_dbg(sdata, "Forwarding to %pM\n", gate->mpath->dst); |
950 | mesh_path_move_to_queue(gate->mpath, from_mpath, copy); | 943 | mesh_path_move_to_queue(gate->mpath, from_mpath, copy); |
951 | from_mpath = gate->mpath; | 944 | from_mpath = gate->mpath; |
952 | copy = true; | 945 | copy = true; |
953 | } else { | 946 | } else { |
954 | mpath_dbg("Not forwarding %p\n", gate->mpath); | 947 | mpath_dbg(sdata, |
955 | mpath_dbg("flags %x\n", gate->mpath->flags); | 948 | "Not forwarding %p (flags %#x)\n", |
949 | gate->mpath, gate->mpath->flags); | ||
956 | } | 950 | } |
957 | } | 951 | } |
958 | 952 | ||
959 | hlist_for_each_entry_rcu(gate, n, known_gates, list) | 953 | hlist_for_each_entry_rcu(gate, n, known_gates, list) |
960 | if (gate->mpath->sdata == sdata) { | 954 | if (gate->mpath->sdata == sdata) { |
961 | mpath_dbg("Sending to %pM\n", gate->mpath->dst); | 955 | mpath_dbg(sdata, "Sending to %pM\n", gate->mpath->dst); |
962 | mesh_path_tx_pending(gate->mpath); | 956 | mesh_path_tx_pending(gate->mpath); |
963 | } | 957 | } |
964 | 958 | ||
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c index 60ef235c9d9b..af671b984df3 100644 --- a/net/mac80211/mesh_plink.c +++ b/net/mac80211/mesh_plink.c | |||
@@ -13,12 +13,6 @@ | |||
13 | #include "rate.h" | 13 | #include "rate.h" |
14 | #include "mesh.h" | 14 | #include "mesh.h" |
15 | 15 | ||
16 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG | ||
17 | #define mpl_dbg(fmt, args...) printk(KERN_DEBUG fmt, ##args) | ||
18 | #else | ||
19 | #define mpl_dbg(fmt, args...) do { (void)(0); } while (0) | ||
20 | #endif | ||
21 | |||
22 | #define PLINK_GET_LLID(p) (p + 2) | 16 | #define PLINK_GET_LLID(p) (p + 2) |
23 | #define PLINK_GET_PLID(p) (p + 4) | 17 | #define PLINK_GET_PLID(p) (p + 4) |
24 | 18 | ||
@@ -105,7 +99,7 @@ static struct sta_info *mesh_plink_alloc(struct ieee80211_sub_if_data *sdata, | |||
105 | return sta; | 99 | return sta; |
106 | } | 100 | } |
107 | 101 | ||
108 | /* | 102 | /** |
109 | * mesh_set_ht_prot_mode - set correct HT protection mode | 103 | * mesh_set_ht_prot_mode - set correct HT protection mode |
110 | * | 104 | * |
111 | * Section 9.23.3.5 of IEEE 80211-2012 describes the protection rules for HT | 105 | * Section 9.23.3.5 of IEEE 80211-2012 describes the protection rules for HT |
@@ -134,12 +128,14 @@ static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata) | |||
134 | 128 | ||
135 | switch (sta->ch_type) { | 129 | switch (sta->ch_type) { |
136 | case NL80211_CHAN_NO_HT: | 130 | case NL80211_CHAN_NO_HT: |
137 | mpl_dbg("mesh_plink %pM: nonHT sta (%pM) is present", | 131 | mpl_dbg(sdata, |
132 | "mesh_plink %pM: nonHT sta (%pM) is present\n", | ||
138 | sdata->vif.addr, sta->sta.addr); | 133 | sdata->vif.addr, sta->sta.addr); |
139 | non_ht_sta = true; | 134 | non_ht_sta = true; |
140 | goto out; | 135 | goto out; |
141 | case NL80211_CHAN_HT20: | 136 | case NL80211_CHAN_HT20: |
142 | mpl_dbg("mesh_plink %pM: HT20 sta (%pM) is present", | 137 | mpl_dbg(sdata, |
138 | "mesh_plink %pM: HT20 sta (%pM) is present\n", | ||
143 | sdata->vif.addr, sta->sta.addr); | 139 | sdata->vif.addr, sta->sta.addr); |
144 | ht20_sta = true; | 140 | ht20_sta = true; |
145 | default: | 141 | default: |
@@ -160,7 +156,8 @@ out: | |||
160 | sdata->vif.bss_conf.ht_operation_mode = ht_opmode; | 156 | sdata->vif.bss_conf.ht_operation_mode = ht_opmode; |
161 | sdata->u.mesh.mshcfg.ht_opmode = ht_opmode; | 157 | sdata->u.mesh.mshcfg.ht_opmode = ht_opmode; |
162 | changed = BSS_CHANGED_HT; | 158 | changed = BSS_CHANGED_HT; |
163 | mpl_dbg("mesh_plink %pM: protection mode changed to %d", | 159 | mpl_dbg(sdata, |
160 | "mesh_plink %pM: protection mode changed to %d\n", | ||
164 | sdata->vif.addr, ht_opmode); | 161 | sdata->vif.addr, ht_opmode); |
165 | } | 162 | } |
166 | 163 | ||
@@ -261,8 +258,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
261 | pos = skb_put(skb, 2); | 258 | pos = skb_put(skb, 2); |
262 | memcpy(pos + 2, &plid, 2); | 259 | memcpy(pos + 2, &plid, 2); |
263 | } | 260 | } |
264 | if (ieee80211_add_srates_ie(&sdata->vif, skb, true) || | 261 | if (ieee80211_add_srates_ie(sdata, skb, true) || |
265 | ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) || | 262 | ieee80211_add_ext_srates_ie(sdata, skb, true) || |
266 | mesh_add_rsn_ie(skb, sdata) || | 263 | mesh_add_rsn_ie(skb, sdata) || |
267 | mesh_add_meshid_ie(skb, sdata) || | 264 | mesh_add_meshid_ie(skb, sdata) || |
268 | mesh_add_meshconf_ie(skb, sdata)) | 265 | mesh_add_meshconf_ie(skb, sdata)) |
@@ -323,7 +320,8 @@ static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata, | |||
323 | return 0; | 320 | return 0; |
324 | } | 321 | } |
325 | 322 | ||
326 | /* mesh_peer_init - initialize new mesh peer and return resulting sta_info | 323 | /** |
324 | * mesh_peer_init - initialize new mesh peer and return resulting sta_info | ||
327 | * | 325 | * |
328 | * @sdata: local meshif | 326 | * @sdata: local meshif |
329 | * @addr: peer's address | 327 | * @addr: peer's address |
@@ -437,7 +435,8 @@ static void mesh_plink_timer(unsigned long data) | |||
437 | spin_unlock_bh(&sta->lock); | 435 | spin_unlock_bh(&sta->lock); |
438 | return; | 436 | return; |
439 | } | 437 | } |
440 | mpl_dbg("Mesh plink timer for %pM fired on state %d\n", | 438 | mpl_dbg(sta->sdata, |
439 | "Mesh plink timer for %pM fired on state %d\n", | ||
441 | sta->sta.addr, sta->plink_state); | 440 | sta->sta.addr, sta->plink_state); |
442 | reason = 0; | 441 | reason = 0; |
443 | llid = sta->llid; | 442 | llid = sta->llid; |
@@ -450,7 +449,8 @@ static void mesh_plink_timer(unsigned long data) | |||
450 | /* retry timer */ | 449 | /* retry timer */ |
451 | if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { | 450 | if (sta->plink_retries < dot11MeshMaxRetries(sdata)) { |
452 | u32 rand; | 451 | u32 rand; |
453 | mpl_dbg("Mesh plink for %pM (retry, timeout): %d %d\n", | 452 | mpl_dbg(sta->sdata, |
453 | "Mesh plink for %pM (retry, timeout): %d %d\n", | ||
454 | sta->sta.addr, sta->plink_retries, | 454 | sta->sta.addr, sta->plink_retries, |
455 | sta->plink_timeout); | 455 | sta->plink_timeout); |
456 | get_random_bytes(&rand, sizeof(u32)); | 456 | get_random_bytes(&rand, sizeof(u32)); |
@@ -530,7 +530,8 @@ int mesh_plink_open(struct sta_info *sta) | |||
530 | sta->plink_state = NL80211_PLINK_OPN_SNT; | 530 | sta->plink_state = NL80211_PLINK_OPN_SNT; |
531 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); | 531 | mesh_plink_timer_set(sta, dot11MeshRetryTimeout(sdata)); |
532 | spin_unlock_bh(&sta->lock); | 532 | spin_unlock_bh(&sta->lock); |
533 | mpl_dbg("Mesh plink: starting establishment with %pM\n", | 533 | mpl_dbg(sdata, |
534 | "Mesh plink: starting establishment with %pM\n", | ||
534 | sta->sta.addr); | 535 | sta->sta.addr); |
535 | 536 | ||
536 | return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, | 537 | return mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_OPEN, |
@@ -565,7 +566,6 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
565 | u8 *baseaddr; | 566 | u8 *baseaddr; |
566 | u32 changed = 0; | 567 | u32 changed = 0; |
567 | __le16 plid, llid, reason; | 568 | __le16 plid, llid, reason; |
568 | #ifdef CONFIG_MAC80211_VERBOSE_MPL_DEBUG | ||
569 | static const char *mplstates[] = { | 569 | static const char *mplstates[] = { |
570 | [NL80211_PLINK_LISTEN] = "LISTEN", | 570 | [NL80211_PLINK_LISTEN] = "LISTEN", |
571 | [NL80211_PLINK_OPN_SNT] = "OPN-SNT", | 571 | [NL80211_PLINK_OPN_SNT] = "OPN-SNT", |
@@ -575,14 +575,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
575 | [NL80211_PLINK_HOLDING] = "HOLDING", | 575 | [NL80211_PLINK_HOLDING] = "HOLDING", |
576 | [NL80211_PLINK_BLOCKED] = "BLOCKED" | 576 | [NL80211_PLINK_BLOCKED] = "BLOCKED" |
577 | }; | 577 | }; |
578 | #endif | ||
579 | 578 | ||
580 | /* need action_code, aux */ | 579 | /* need action_code, aux */ |
581 | if (len < IEEE80211_MIN_ACTION_SIZE + 3) | 580 | if (len < IEEE80211_MIN_ACTION_SIZE + 3) |
582 | return; | 581 | return; |
583 | 582 | ||
584 | if (is_multicast_ether_addr(mgmt->da)) { | 583 | if (is_multicast_ether_addr(mgmt->da)) { |
585 | mpl_dbg("Mesh plink: ignore frame from multicast address"); | 584 | mpl_dbg(sdata, |
585 | "Mesh plink: ignore frame from multicast address\n"); | ||
586 | return; | 586 | return; |
587 | } | 587 | } |
588 | 588 | ||
@@ -595,12 +595,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
595 | } | 595 | } |
596 | ieee802_11_parse_elems(baseaddr, len - baselen, &elems); | 596 | ieee802_11_parse_elems(baseaddr, len - baselen, &elems); |
597 | if (!elems.peering) { | 597 | if (!elems.peering) { |
598 | mpl_dbg("Mesh plink: missing necessary peer link ie\n"); | 598 | mpl_dbg(sdata, |
599 | "Mesh plink: missing necessary peer link ie\n"); | ||
599 | return; | 600 | return; |
600 | } | 601 | } |
601 | if (elems.rsn_len && | 602 | if (elems.rsn_len && |
602 | sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { | 603 | sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) { |
603 | mpl_dbg("Mesh plink: can't establish link with secure peer\n"); | 604 | mpl_dbg(sdata, |
605 | "Mesh plink: can't establish link with secure peer\n"); | ||
604 | return; | 606 | return; |
605 | } | 607 | } |
606 | 608 | ||
@@ -610,14 +612,15 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
610 | (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || | 612 | (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) || |
611 | (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 | 613 | (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6 |
612 | && ie_len != 8)) { | 614 | && ie_len != 8)) { |
613 | mpl_dbg("Mesh plink: incorrect plink ie length %d %d\n", | 615 | mpl_dbg(sdata, |
614 | ftype, ie_len); | 616 | "Mesh plink: incorrect plink ie length %d %d\n", |
617 | ftype, ie_len); | ||
615 | return; | 618 | return; |
616 | } | 619 | } |
617 | 620 | ||
618 | if (ftype != WLAN_SP_MESH_PEERING_CLOSE && | 621 | if (ftype != WLAN_SP_MESH_PEERING_CLOSE && |
619 | (!elems.mesh_id || !elems.mesh_config)) { | 622 | (!elems.mesh_id || !elems.mesh_config)) { |
620 | mpl_dbg("Mesh plink: missing necessary ie\n"); | 623 | mpl_dbg(sdata, "Mesh plink: missing necessary ie\n"); |
621 | return; | 624 | return; |
622 | } | 625 | } |
623 | /* Note the lines below are correct, the llid in the frame is the plid | 626 | /* Note the lines below are correct, the llid in the frame is the plid |
@@ -632,21 +635,21 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
632 | 635 | ||
633 | sta = sta_info_get(sdata, mgmt->sa); | 636 | sta = sta_info_get(sdata, mgmt->sa); |
634 | if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) { | 637 | if (!sta && ftype != WLAN_SP_MESH_PEERING_OPEN) { |
635 | mpl_dbg("Mesh plink: cls or cnf from unknown peer\n"); | 638 | mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n"); |
636 | rcu_read_unlock(); | 639 | rcu_read_unlock(); |
637 | return; | 640 | return; |
638 | } | 641 | } |
639 | 642 | ||
640 | if (ftype == WLAN_SP_MESH_PEERING_OPEN && | 643 | if (ftype == WLAN_SP_MESH_PEERING_OPEN && |
641 | !rssi_threshold_check(sta, sdata)) { | 644 | !rssi_threshold_check(sta, sdata)) { |
642 | mpl_dbg("Mesh plink: %pM does not meet rssi threshold\n", | 645 | mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n", |
643 | mgmt->sa); | 646 | mgmt->sa); |
644 | rcu_read_unlock(); | 647 | rcu_read_unlock(); |
645 | return; | 648 | return; |
646 | } | 649 | } |
647 | 650 | ||
648 | if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { | 651 | if (sta && !test_sta_flag(sta, WLAN_STA_AUTH)) { |
649 | mpl_dbg("Mesh plink: Action frame from non-authed peer\n"); | 652 | mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n"); |
650 | rcu_read_unlock(); | 653 | rcu_read_unlock(); |
651 | return; | 654 | return; |
652 | } | 655 | } |
@@ -683,7 +686,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
683 | } else if (!sta) { | 686 | } else if (!sta) { |
684 | /* ftype == WLAN_SP_MESH_PEERING_OPEN */ | 687 | /* ftype == WLAN_SP_MESH_PEERING_OPEN */ |
685 | if (!mesh_plink_free_count(sdata)) { | 688 | if (!mesh_plink_free_count(sdata)) { |
686 | mpl_dbg("Mesh plink error: no more free plinks\n"); | 689 | mpl_dbg(sdata, "Mesh plink error: no more free plinks\n"); |
687 | rcu_read_unlock(); | 690 | rcu_read_unlock(); |
688 | return; | 691 | return; |
689 | } | 692 | } |
@@ -724,7 +727,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
724 | event = CLS_ACPT; | 727 | event = CLS_ACPT; |
725 | break; | 728 | break; |
726 | default: | 729 | default: |
727 | mpl_dbg("Mesh plink: unknown frame subtype\n"); | 730 | mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n"); |
728 | rcu_read_unlock(); | 731 | rcu_read_unlock(); |
729 | return; | 732 | return; |
730 | } | 733 | } |
@@ -734,13 +737,14 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
734 | /* allocate sta entry if necessary and update info */ | 737 | /* allocate sta entry if necessary and update info */ |
735 | sta = mesh_peer_init(sdata, mgmt->sa, &elems); | 738 | sta = mesh_peer_init(sdata, mgmt->sa, &elems); |
736 | if (!sta) { | 739 | if (!sta) { |
737 | mpl_dbg("Mesh plink: failed to init peer!\n"); | 740 | mpl_dbg(sdata, "Mesh plink: failed to init peer!\n"); |
738 | rcu_read_unlock(); | 741 | rcu_read_unlock(); |
739 | return; | 742 | return; |
740 | } | 743 | } |
741 | } | 744 | } |
742 | 745 | ||
743 | mpl_dbg("Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", | 746 | mpl_dbg(sdata, |
747 | "Mesh plink (peer, state, llid, plid, event): %pM %s %d %d %d\n", | ||
744 | mgmt->sa, mplstates[sta->plink_state], | 748 | mgmt->sa, mplstates[sta->plink_state], |
745 | le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), | 749 | le16_to_cpu(sta->llid), le16_to_cpu(sta->plid), |
746 | event); | 750 | event); |
@@ -851,7 +855,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
851 | mesh_plink_inc_estab_count(sdata); | 855 | mesh_plink_inc_estab_count(sdata); |
852 | changed |= mesh_set_ht_prot_mode(sdata); | 856 | changed |= mesh_set_ht_prot_mode(sdata); |
853 | changed |= BSS_CHANGED_BEACON; | 857 | changed |= BSS_CHANGED_BEACON; |
854 | mpl_dbg("Mesh plink with %pM ESTABLISHED\n", | 858 | mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", |
855 | sta->sta.addr); | 859 | sta->sta.addr); |
856 | break; | 860 | break; |
857 | default: | 861 | default: |
@@ -887,7 +891,7 @@ void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_m | |||
887 | mesh_plink_inc_estab_count(sdata); | 891 | mesh_plink_inc_estab_count(sdata); |
888 | changed |= mesh_set_ht_prot_mode(sdata); | 892 | changed |= mesh_set_ht_prot_mode(sdata); |
889 | changed |= BSS_CHANGED_BEACON; | 893 | changed |= BSS_CHANGED_BEACON; |
890 | mpl_dbg("Mesh plink with %pM ESTABLISHED\n", | 894 | mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", |
891 | sta->sta.addr); | 895 | sta->sta.addr); |
892 | mesh_plink_frame_tx(sdata, | 896 | mesh_plink_frame_tx(sdata, |
893 | WLAN_SP_MESH_PEERING_CONFIRM, | 897 | WLAN_SP_MESH_PEERING_CONFIRM, |
diff --git a/net/mac80211/mesh_sync.c b/net/mac80211/mesh_sync.c index 38d30e8ce6dc..accfa00ffcdf 100644 --- a/net/mac80211/mesh_sync.c +++ b/net/mac80211/mesh_sync.c | |||
@@ -12,13 +12,6 @@ | |||
12 | #include "mesh.h" | 12 | #include "mesh.h" |
13 | #include "driver-ops.h" | 13 | #include "driver-ops.h" |
14 | 14 | ||
15 | #ifdef CONFIG_MAC80211_VERBOSE_MESH_SYNC_DEBUG | ||
16 | #define msync_dbg(fmt, args...) \ | ||
17 | printk(KERN_DEBUG "Mesh sync (%s): " fmt "\n", sdata->name, ##args) | ||
18 | #else | ||
19 | #define msync_dbg(fmt, args...) do { (void)(0); } while (0) | ||
20 | #endif | ||
21 | |||
22 | /* This is not in the standard. It represents a tolerable tbtt drift below | 15 | /* This is not in the standard. It represents a tolerable tbtt drift below |
23 | * which we do no TSF adjustment. | 16 | * which we do no TSF adjustment. |
24 | */ | 17 | */ |
@@ -65,14 +58,14 @@ void mesh_sync_adjust_tbtt(struct ieee80211_sub_if_data *sdata) | |||
65 | spin_lock_bh(&ifmsh->sync_offset_lock); | 58 | spin_lock_bh(&ifmsh->sync_offset_lock); |
66 | 59 | ||
67 | if (ifmsh->sync_offset_clockdrift_max < beacon_int_fraction) { | 60 | if (ifmsh->sync_offset_clockdrift_max < beacon_int_fraction) { |
68 | msync_dbg("TBTT : max clockdrift=%lld; adjusting", | 61 | msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting\n", |
69 | (long long) ifmsh->sync_offset_clockdrift_max); | 62 | (long long) ifmsh->sync_offset_clockdrift_max); |
70 | tsfdelta = -ifmsh->sync_offset_clockdrift_max; | 63 | tsfdelta = -ifmsh->sync_offset_clockdrift_max; |
71 | ifmsh->sync_offset_clockdrift_max = 0; | 64 | ifmsh->sync_offset_clockdrift_max = 0; |
72 | } else { | 65 | } else { |
73 | msync_dbg("TBTT : max clockdrift=%lld; adjusting by %llu", | 66 | msync_dbg(sdata, "TBTT : max clockdrift=%lld; adjusting by %llu\n", |
74 | (long long) ifmsh->sync_offset_clockdrift_max, | 67 | (long long) ifmsh->sync_offset_clockdrift_max, |
75 | (unsigned long long) beacon_int_fraction); | 68 | (unsigned long long) beacon_int_fraction); |
76 | tsfdelta = -beacon_int_fraction; | 69 | tsfdelta = -beacon_int_fraction; |
77 | ifmsh->sync_offset_clockdrift_max -= beacon_int_fraction; | 70 | ifmsh->sync_offset_clockdrift_max -= beacon_int_fraction; |
78 | } | 71 | } |
@@ -120,7 +113,7 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
120 | 113 | ||
121 | if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) { | 114 | if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) { |
122 | clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); | 115 | clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); |
123 | msync_dbg("STA %pM : is adjusting TBTT", sta->sta.addr); | 116 | msync_dbg(sdata, "STA %pM : is adjusting TBTT\n", sta->sta.addr); |
124 | goto no_sync; | 117 | goto no_sync; |
125 | } | 118 | } |
126 | 119 | ||
@@ -169,7 +162,8 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
169 | if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { | 162 | if (test_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN)) { |
170 | s64 t_clockdrift = sta->t_offset_setpoint | 163 | s64 t_clockdrift = sta->t_offset_setpoint |
171 | - sta->t_offset; | 164 | - sta->t_offset; |
172 | msync_dbg("STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld", | 165 | msync_dbg(sdata, |
166 | "STA %pM : sta->t_offset=%lld, sta->t_offset_setpoint=%lld, t_clockdrift=%lld\n", | ||
173 | sta->sta.addr, | 167 | sta->sta.addr, |
174 | (long long) sta->t_offset, | 168 | (long long) sta->t_offset, |
175 | (long long) | 169 | (long long) |
@@ -178,7 +172,8 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
178 | 172 | ||
179 | if (t_clockdrift > TOFFSET_MAXIMUM_ADJUSTMENT || | 173 | if (t_clockdrift > TOFFSET_MAXIMUM_ADJUSTMENT || |
180 | t_clockdrift < -TOFFSET_MAXIMUM_ADJUSTMENT) { | 174 | t_clockdrift < -TOFFSET_MAXIMUM_ADJUSTMENT) { |
181 | msync_dbg("STA %pM : t_clockdrift=%lld too large, setpoint reset", | 175 | msync_dbg(sdata, |
176 | "STA %pM : t_clockdrift=%lld too large, setpoint reset\n", | ||
182 | sta->sta.addr, | 177 | sta->sta.addr, |
183 | (long long) t_clockdrift); | 178 | (long long) t_clockdrift); |
184 | clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); | 179 | clear_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); |
@@ -197,8 +192,8 @@ static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
197 | } else { | 192 | } else { |
198 | sta->t_offset_setpoint = sta->t_offset - TOFFSET_SET_MARGIN; | 193 | sta->t_offset_setpoint = sta->t_offset - TOFFSET_SET_MARGIN; |
199 | set_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); | 194 | set_sta_flag(sta, WLAN_STA_TOFFSET_KNOWN); |
200 | msync_dbg("STA %pM : offset was invalid, " | 195 | msync_dbg(sdata, |
201 | " sta->t_offset=%lld", | 196 | "STA %pM : offset was invalid, sta->t_offset=%lld\n", |
202 | sta->sta.addr, | 197 | sta->sta.addr, |
203 | (long long) sta->t_offset); | 198 | (long long) sta->t_offset); |
204 | rcu_read_unlock(); | 199 | rcu_read_unlock(); |
@@ -226,17 +221,15 @@ static void mesh_sync_offset_adjust_tbtt(struct ieee80211_sub_if_data *sdata) | |||
226 | * to the driver tsf setter, we punt | 221 | * to the driver tsf setter, we punt |
227 | * the tsf adjustment to the mesh tasklet | 222 | * the tsf adjustment to the mesh tasklet |
228 | */ | 223 | */ |
229 | msync_dbg("TBTT : kicking off TBTT " | 224 | msync_dbg(sdata, |
230 | "adjustment with " | 225 | "TBTT : kicking off TBTT adjustment with clockdrift_max=%lld\n", |
231 | "clockdrift_max=%lld", | 226 | ifmsh->sync_offset_clockdrift_max); |
232 | ifmsh->sync_offset_clockdrift_max); | ||
233 | set_bit(MESH_WORK_DRIFT_ADJUST, | 227 | set_bit(MESH_WORK_DRIFT_ADJUST, |
234 | &ifmsh->wrkq_flags); | 228 | &ifmsh->wrkq_flags); |
235 | } else { | 229 | } else { |
236 | msync_dbg("TBTT : max clockdrift=%lld; " | 230 | msync_dbg(sdata, |
237 | "too small to adjust", | 231 | "TBTT : max clockdrift=%lld; too small to adjust\n", |
238 | (long long) | 232 | (long long)ifmsh->sync_offset_clockdrift_max); |
239 | ifmsh->sync_offset_clockdrift_max); | ||
240 | ifmsh->sync_offset_clockdrift_max = 0; | 233 | ifmsh->sync_offset_clockdrift_max = 0; |
241 | } | 234 | } |
242 | spin_unlock_bh(&ifmsh->sync_offset_lock); | 235 | spin_unlock_bh(&ifmsh->sync_offset_lock); |
@@ -268,7 +261,7 @@ static void mesh_sync_vendor_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | |||
268 | const u8 *oui; | 261 | const u8 *oui; |
269 | 262 | ||
270 | WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); | 263 | WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); |
271 | msync_dbg("called mesh_sync_vendor_rx_bcn_presp"); | 264 | msync_dbg(sdata, "called mesh_sync_vendor_rx_bcn_presp\n"); |
272 | oui = mesh_get_vendor_oui(sdata); | 265 | oui = mesh_get_vendor_oui(sdata); |
273 | /* here you would implement the vendor offset tracking for this oui */ | 266 | /* here you would implement the vendor offset tracking for this oui */ |
274 | } | 267 | } |
@@ -278,7 +271,7 @@ static void mesh_sync_vendor_adjust_tbtt(struct ieee80211_sub_if_data *sdata) | |||
278 | const u8 *oui; | 271 | const u8 *oui; |
279 | 272 | ||
280 | WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); | 273 | WARN_ON(sdata->u.mesh.mesh_sp_id != IEEE80211_SYNC_METHOD_VENDOR); |
281 | msync_dbg("called mesh_sync_vendor_adjust_tbtt"); | 274 | msync_dbg(sdata, "called mesh_sync_vendor_adjust_tbtt\n"); |
282 | oui = mesh_get_vendor_oui(sdata); | 275 | oui = mesh_get_vendor_oui(sdata); |
283 | /* here you would implement the vendor tsf adjustment for this oui */ | 276 | /* here you would implement the vendor tsf adjustment for this oui */ |
284 | } | 277 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0db5d34a06b6..cef0c9e79aba 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -258,12 +258,11 @@ static int ieee80211_compatible_rates(const u8 *supp_rates, int supp_rates_len, | |||
258 | } | 258 | } |
259 | 259 | ||
260 | static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, | 260 | static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, |
261 | struct sk_buff *skb, const u8 *ht_oper_ie, | 261 | struct sk_buff *skb, u8 ap_ht_param, |
262 | struct ieee80211_supported_band *sband, | 262 | struct ieee80211_supported_band *sband, |
263 | struct ieee80211_channel *channel, | 263 | struct ieee80211_channel *channel, |
264 | enum ieee80211_smps_mode smps) | 264 | enum ieee80211_smps_mode smps) |
265 | { | 265 | { |
266 | struct ieee80211_ht_operation *ht_oper; | ||
267 | u8 *pos; | 266 | u8 *pos; |
268 | u32 flags = channel->flags; | 267 | u32 flags = channel->flags; |
269 | u16 cap; | 268 | u16 cap; |
@@ -271,21 +270,13 @@ static void ieee80211_add_ht_ie(struct ieee80211_sub_if_data *sdata, | |||
271 | 270 | ||
272 | BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); | 271 | BUILD_BUG_ON(sizeof(ht_cap) != sizeof(sband->ht_cap)); |
273 | 272 | ||
274 | if (!ht_oper_ie) | ||
275 | return; | ||
276 | |||
277 | if (ht_oper_ie[1] < sizeof(struct ieee80211_ht_operation)) | ||
278 | return; | ||
279 | |||
280 | memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); | 273 | memcpy(&ht_cap, &sband->ht_cap, sizeof(ht_cap)); |
281 | ieee80211_apply_htcap_overrides(sdata, &ht_cap); | 274 | ieee80211_apply_htcap_overrides(sdata, &ht_cap); |
282 | 275 | ||
283 | ht_oper = (struct ieee80211_ht_operation *)(ht_oper_ie + 2); | ||
284 | |||
285 | /* determine capability flags */ | 276 | /* determine capability flags */ |
286 | cap = ht_cap.cap; | 277 | cap = ht_cap.cap; |
287 | 278 | ||
288 | switch (ht_oper->ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { | 279 | switch (ap_ht_param & IEEE80211_HT_PARAM_CHA_SEC_OFFSET) { |
289 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: | 280 | case IEEE80211_HT_PARAM_CHA_SEC_ABOVE: |
290 | if (flags & IEEE80211_CHAN_NO_HT40PLUS) { | 281 | if (flags & IEEE80211_CHAN_NO_HT40PLUS) { |
291 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; | 282 | cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40; |
@@ -509,7 +500,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
509 | } | 500 | } |
510 | 501 | ||
511 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) | 502 | if (!(ifmgd->flags & IEEE80211_STA_DISABLE_11N)) |
512 | ieee80211_add_ht_ie(sdata, skb, assoc_data->ht_operation_ie, | 503 | ieee80211_add_ht_ie(sdata, skb, assoc_data->ap_ht_param, |
513 | sband, local->oper_channel, ifmgd->ap_smps); | 504 | sband, local->oper_channel, ifmgd->ap_smps); |
514 | 505 | ||
515 | /* if present, add any custom non-vendor IEs that go after HT */ | 506 | /* if present, add any custom non-vendor IEs that go after HT */ |
@@ -550,6 +541,8 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata) | |||
550 | memcpy(pos, assoc_data->ie + offset, noffset - offset); | 541 | memcpy(pos, assoc_data->ie + offset, noffset - offset); |
551 | } | 542 | } |
552 | 543 | ||
544 | drv_mgd_prepare_tx(local, sdata); | ||
545 | |||
553 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 546 | IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
554 | ieee80211_tx_skb(sdata, skb); | 547 | ieee80211_tx_skb(sdata, skb); |
555 | } | 548 | } |
@@ -589,6 +582,9 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata, | |||
589 | if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) | 582 | if (!(ifmgd->flags & IEEE80211_STA_MFP_ENABLED)) |
590 | IEEE80211_SKB_CB(skb)->flags |= | 583 | IEEE80211_SKB_CB(skb)->flags |= |
591 | IEEE80211_TX_INTFL_DONT_ENCRYPT; | 584 | IEEE80211_TX_INTFL_DONT_ENCRYPT; |
585 | |||
586 | drv_mgd_prepare_tx(local, sdata); | ||
587 | |||
592 | ieee80211_tx_skb(sdata, skb); | 588 | ieee80211_tx_skb(sdata, skb); |
593 | } | 589 | } |
594 | } | 590 | } |
@@ -911,9 +907,6 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata) | |||
911 | if (!mgd->associated) | 907 | if (!mgd->associated) |
912 | return false; | 908 | return false; |
913 | 909 | ||
914 | if (!mgd->associated->beacon_ies) | ||
915 | return false; | ||
916 | |||
917 | if (mgd->flags & (IEEE80211_STA_BEACON_POLL | | 910 | if (mgd->flags & (IEEE80211_STA_BEACON_POLL | |
918 | IEEE80211_STA_CONNECTION_POLL)) | 911 | IEEE80211_STA_CONNECTION_POLL)) |
919 | return false; | 912 | return false; |
@@ -939,11 +932,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
939 | return; | 932 | return; |
940 | } | 933 | } |
941 | 934 | ||
942 | if (!list_empty(&local->work_list)) { | ||
943 | local->ps_sdata = NULL; | ||
944 | goto change; | ||
945 | } | ||
946 | |||
947 | list_for_each_entry(sdata, &local->interfaces, list) { | 935 | list_for_each_entry(sdata, &local->interfaces, list) { |
948 | if (!ieee80211_sdata_running(sdata)) | 936 | if (!ieee80211_sdata_running(sdata)) |
949 | continue; | 937 | continue; |
@@ -1016,7 +1004,6 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency) | |||
1016 | local->ps_sdata = NULL; | 1004 | local->ps_sdata = NULL; |
1017 | } | 1005 | } |
1018 | 1006 | ||
1019 | change: | ||
1020 | ieee80211_change_ps(local); | 1007 | ieee80211_change_ps(local); |
1021 | } | 1008 | } |
1022 | 1009 | ||
@@ -1121,7 +1108,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data) | |||
1121 | } | 1108 | } |
1122 | 1109 | ||
1123 | /* MLME */ | 1110 | /* MLME */ |
1124 | static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | 1111 | static bool ieee80211_sta_wmm_params(struct ieee80211_local *local, |
1125 | struct ieee80211_sub_if_data *sdata, | 1112 | struct ieee80211_sub_if_data *sdata, |
1126 | u8 *wmm_param, size_t wmm_param_len) | 1113 | u8 *wmm_param, size_t wmm_param_len) |
1127 | { | 1114 | { |
@@ -1132,23 +1119,23 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1132 | u8 *pos, uapsd_queues = 0; | 1119 | u8 *pos, uapsd_queues = 0; |
1133 | 1120 | ||
1134 | if (!local->ops->conf_tx) | 1121 | if (!local->ops->conf_tx) |
1135 | return; | 1122 | return false; |
1136 | 1123 | ||
1137 | if (local->hw.queues < IEEE80211_NUM_ACS) | 1124 | if (local->hw.queues < IEEE80211_NUM_ACS) |
1138 | return; | 1125 | return false; |
1139 | 1126 | ||
1140 | if (!wmm_param) | 1127 | if (!wmm_param) |
1141 | return; | 1128 | return false; |
1142 | 1129 | ||
1143 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) | 1130 | if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) |
1144 | return; | 1131 | return false; |
1145 | 1132 | ||
1146 | if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) | 1133 | if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED) |
1147 | uapsd_queues = ifmgd->uapsd_queues; | 1134 | uapsd_queues = ifmgd->uapsd_queues; |
1148 | 1135 | ||
1149 | count = wmm_param[6] & 0x0f; | 1136 | count = wmm_param[6] & 0x0f; |
1150 | if (count == ifmgd->wmm_last_param_set) | 1137 | if (count == ifmgd->wmm_last_param_set) |
1151 | return; | 1138 | return false; |
1152 | ifmgd->wmm_last_param_set = count; | 1139 | ifmgd->wmm_last_param_set = count; |
1153 | 1140 | ||
1154 | pos = wmm_param + 8; | 1141 | pos = wmm_param + 8; |
@@ -1156,7 +1143,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1156 | 1143 | ||
1157 | memset(¶ms, 0, sizeof(params)); | 1144 | memset(¶ms, 0, sizeof(params)); |
1158 | 1145 | ||
1159 | local->wmm_acm = 0; | 1146 | sdata->wmm_acm = 0; |
1160 | for (; left >= 4; left -= 4, pos += 4) { | 1147 | for (; left >= 4; left -= 4, pos += 4) { |
1161 | int aci = (pos[0] >> 5) & 0x03; | 1148 | int aci = (pos[0] >> 5) & 0x03; |
1162 | int acm = (pos[0] >> 4) & 0x01; | 1149 | int acm = (pos[0] >> 4) & 0x01; |
@@ -1167,21 +1154,21 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1167 | case 1: /* AC_BK */ | 1154 | case 1: /* AC_BK */ |
1168 | queue = 3; | 1155 | queue = 3; |
1169 | if (acm) | 1156 | if (acm) |
1170 | local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */ | 1157 | sdata->wmm_acm |= BIT(1) | BIT(2); /* BK/- */ |
1171 | if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) | 1158 | if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK) |
1172 | uapsd = true; | 1159 | uapsd = true; |
1173 | break; | 1160 | break; |
1174 | case 2: /* AC_VI */ | 1161 | case 2: /* AC_VI */ |
1175 | queue = 1; | 1162 | queue = 1; |
1176 | if (acm) | 1163 | if (acm) |
1177 | local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ | 1164 | sdata->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ |
1178 | if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) | 1165 | if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI) |
1179 | uapsd = true; | 1166 | uapsd = true; |
1180 | break; | 1167 | break; |
1181 | case 3: /* AC_VO */ | 1168 | case 3: /* AC_VO */ |
1182 | queue = 0; | 1169 | queue = 0; |
1183 | if (acm) | 1170 | if (acm) |
1184 | local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ | 1171 | sdata->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ |
1185 | if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) | 1172 | if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO) |
1186 | uapsd = true; | 1173 | uapsd = true; |
1187 | break; | 1174 | break; |
@@ -1189,7 +1176,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1189 | default: | 1176 | default: |
1190 | queue = 2; | 1177 | queue = 2; |
1191 | if (acm) | 1178 | if (acm) |
1192 | local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ | 1179 | sdata->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ |
1193 | if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) | 1180 | if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE) |
1194 | uapsd = true; | 1181 | uapsd = true; |
1195 | break; | 1182 | break; |
@@ -1201,23 +1188,21 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local, | |||
1201 | params.txop = get_unaligned_le16(pos + 2); | 1188 | params.txop = get_unaligned_le16(pos + 2); |
1202 | params.uapsd = uapsd; | 1189 | params.uapsd = uapsd; |
1203 | 1190 | ||
1204 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1191 | mlme_dbg(sdata, |
1205 | wiphy_debug(local->hw.wiphy, | 1192 | "WMM queue=%d aci=%d acm=%d aifs=%d cWmin=%d cWmax=%d txop=%d uapsd=%d\n", |
1206 | "WMM queue=%d aci=%d acm=%d aifs=%d " | 1193 | queue, aci, acm, |
1207 | "cWmin=%d cWmax=%d txop=%d uapsd=%d\n", | 1194 | params.aifs, params.cw_min, params.cw_max, |
1208 | queue, aci, acm, | 1195 | params.txop, params.uapsd); |
1209 | params.aifs, params.cw_min, params.cw_max, | ||
1210 | params.txop, params.uapsd); | ||
1211 | #endif | ||
1212 | sdata->tx_conf[queue] = params; | 1196 | sdata->tx_conf[queue] = params; |
1213 | if (drv_conf_tx(local, sdata, queue, ¶ms)) | 1197 | if (drv_conf_tx(local, sdata, queue, ¶ms)) |
1214 | wiphy_debug(local->hw.wiphy, | 1198 | sdata_err(sdata, |
1215 | "failed to set TX queue parameters for queue %d\n", | 1199 | "failed to set TX queue parameters for queue %d\n", |
1216 | queue); | 1200 | queue); |
1217 | } | 1201 | } |
1218 | 1202 | ||
1219 | /* enable WMM or activate new settings */ | 1203 | /* enable WMM or activate new settings */ |
1220 | sdata->vif.bss_conf.qos = true; | 1204 | sdata->vif.bss_conf.qos = true; |
1205 | return true; | ||
1221 | } | 1206 | } |
1222 | 1207 | ||
1223 | static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) | 1208 | static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata) |
@@ -1284,13 +1269,8 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata, | |||
1284 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; | 1269 | struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf; |
1285 | 1270 | ||
1286 | bss_info_changed |= BSS_CHANGED_ASSOC; | 1271 | bss_info_changed |= BSS_CHANGED_ASSOC; |
1287 | /* set timing information */ | ||
1288 | bss_conf->beacon_int = cbss->beacon_interval; | ||
1289 | bss_conf->last_tsf = cbss->tsf; | ||
1290 | |||
1291 | bss_info_changed |= BSS_CHANGED_BEACON_INT; | ||
1292 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, | 1272 | bss_info_changed |= ieee80211_handle_bss_capability(sdata, |
1293 | cbss->capability, bss->has_erp_value, bss->erp_value); | 1273 | bss_conf->assoc_capability, bss->has_erp_value, bss->erp_value); |
1294 | 1274 | ||
1295 | sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( | 1275 | sdata->u.mgd.beacon_timeout = usecs_to_jiffies(ieee80211_tu_to_usec( |
1296 | IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int)); | 1276 | IEEE80211_BEACON_LOSS_COUNT * bss_conf->beacon_int)); |
@@ -1380,6 +1360,21 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1380 | } | 1360 | } |
1381 | mutex_unlock(&local->sta_mtx); | 1361 | mutex_unlock(&local->sta_mtx); |
1382 | 1362 | ||
1363 | /* | ||
1364 | * if we want to get out of ps before disassoc (why?) we have | ||
1365 | * to do it before sending disassoc, as otherwise the null-packet | ||
1366 | * won't be valid. | ||
1367 | */ | ||
1368 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
1369 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | ||
1370 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | ||
1371 | } | ||
1372 | local->ps_sdata = NULL; | ||
1373 | |||
1374 | /* flush out any pending frame (e.g. DELBA) before deauth/disassoc */ | ||
1375 | if (tx) | ||
1376 | drv_flush(local, false); | ||
1377 | |||
1383 | /* deauthenticate/disassociate now */ | 1378 | /* deauthenticate/disassociate now */ |
1384 | if (tx || frame_buf) | 1379 | if (tx || frame_buf) |
1385 | ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, | 1380 | ieee80211_send_deauth_disassoc(sdata, ifmgd->bssid, stype, |
@@ -1411,12 +1406,6 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1411 | del_timer_sync(&local->dynamic_ps_timer); | 1406 | del_timer_sync(&local->dynamic_ps_timer); |
1412 | cancel_work_sync(&local->dynamic_ps_enable_work); | 1407 | cancel_work_sync(&local->dynamic_ps_enable_work); |
1413 | 1408 | ||
1414 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | ||
1415 | local->hw.conf.flags &= ~IEEE80211_CONF_PS; | ||
1416 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | ||
1417 | } | ||
1418 | local->ps_sdata = NULL; | ||
1419 | |||
1420 | /* Disable ARP filtering */ | 1409 | /* Disable ARP filtering */ |
1421 | if (sdata->vif.bss_conf.arp_filter_enabled) { | 1410 | if (sdata->vif.bss_conf.arp_filter_enabled) { |
1422 | sdata->vif.bss_conf.arp_filter_enabled = false; | 1411 | sdata->vif.bss_conf.arp_filter_enabled = false; |
@@ -1581,11 +1570,12 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | |||
1581 | goto out; | 1570 | goto out; |
1582 | } | 1571 | } |
1583 | 1572 | ||
1584 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1585 | if (beacon) | 1573 | if (beacon) |
1586 | net_dbg_ratelimited("%s: detected beacon loss from AP - sending probe request\n", | 1574 | mlme_dbg_ratelimited(sdata, |
1587 | sdata->name); | 1575 | "detected beacon loss from AP - sending probe request\n"); |
1588 | #endif | 1576 | |
1577 | ieee80211_cqm_rssi_notify(&sdata->vif, | ||
1578 | NL80211_CQM_RSSI_BEACON_LOSS_EVENT, GFP_KERNEL); | ||
1589 | 1579 | ||
1590 | /* | 1580 | /* |
1591 | * The driver/our work has already reported this event or the | 1581 | * The driver/our work has already reported this event or the |
@@ -1627,6 +1617,7 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, | |||
1627 | { | 1617 | { |
1628 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 1618 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
1629 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 1619 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
1620 | struct cfg80211_bss *cbss; | ||
1630 | struct sk_buff *skb; | 1621 | struct sk_buff *skb; |
1631 | const u8 *ssid; | 1622 | const u8 *ssid; |
1632 | int ssid_len; | 1623 | int ssid_len; |
@@ -1636,16 +1627,22 @@ struct sk_buff *ieee80211_ap_probereq_get(struct ieee80211_hw *hw, | |||
1636 | 1627 | ||
1637 | ASSERT_MGD_MTX(ifmgd); | 1628 | ASSERT_MGD_MTX(ifmgd); |
1638 | 1629 | ||
1639 | if (!ifmgd->associated) | 1630 | if (ifmgd->associated) |
1631 | cbss = ifmgd->associated; | ||
1632 | else if (ifmgd->auth_data) | ||
1633 | cbss = ifmgd->auth_data->bss; | ||
1634 | else if (ifmgd->assoc_data) | ||
1635 | cbss = ifmgd->assoc_data->bss; | ||
1636 | else | ||
1640 | return NULL; | 1637 | return NULL; |
1641 | 1638 | ||
1642 | ssid = ieee80211_bss_get_ie(ifmgd->associated, WLAN_EID_SSID); | 1639 | ssid = ieee80211_bss_get_ie(cbss, WLAN_EID_SSID); |
1643 | if (WARN_ON_ONCE(ssid == NULL)) | 1640 | if (WARN_ON_ONCE(ssid == NULL)) |
1644 | ssid_len = 0; | 1641 | ssid_len = 0; |
1645 | else | 1642 | else |
1646 | ssid_len = ssid[1]; | 1643 | ssid_len = ssid[1]; |
1647 | 1644 | ||
1648 | skb = ieee80211_build_probe_req(sdata, ifmgd->associated->bssid, | 1645 | skb = ieee80211_build_probe_req(sdata, cbss->bssid, |
1649 | (u32) -1, ssid + 2, ssid_len, | 1646 | (u32) -1, ssid + 2, ssid_len, |
1650 | NULL, 0, true); | 1647 | NULL, 0, true); |
1651 | 1648 | ||
@@ -1668,8 +1665,7 @@ static void __ieee80211_connection_loss(struct ieee80211_sub_if_data *sdata) | |||
1668 | 1665 | ||
1669 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); | 1666 | memcpy(bssid, ifmgd->associated->bssid, ETH_ALEN); |
1670 | 1667 | ||
1671 | printk(KERN_DEBUG "%s: Connection to AP %pM lost.\n", | 1668 | sdata_info(sdata, "Connection to AP %pM lost\n", bssid); |
1672 | sdata->name, bssid); | ||
1673 | 1669 | ||
1674 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | 1670 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, |
1675 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, | 1671 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY, |
@@ -1765,6 +1761,7 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata, | |||
1765 | if (!elems.challenge) | 1761 | if (!elems.challenge) |
1766 | return; | 1762 | return; |
1767 | auth_data->expected_transaction = 4; | 1763 | auth_data->expected_transaction = 4; |
1764 | drv_mgd_prepare_tx(sdata->local, sdata); | ||
1768 | ieee80211_send_auth(sdata, 3, auth_data->algorithm, | 1765 | ieee80211_send_auth(sdata, 3, auth_data->algorithm, |
1769 | elems.challenge - 2, elems.challenge_len + 2, | 1766 | elems.challenge - 2, elems.challenge_len + 2, |
1770 | auth_data->bss->bssid, auth_data->bss->bssid, | 1767 | auth_data->bss->bssid, auth_data->bss->bssid, |
@@ -1803,9 +1800,10 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1803 | return RX_MGMT_NONE; | 1800 | return RX_MGMT_NONE; |
1804 | 1801 | ||
1805 | if (status_code != WLAN_STATUS_SUCCESS) { | 1802 | if (status_code != WLAN_STATUS_SUCCESS) { |
1806 | printk(KERN_DEBUG "%s: %pM denied authentication (status %d)\n", | 1803 | sdata_info(sdata, "%pM denied authentication (status %d)\n", |
1807 | sdata->name, mgmt->sa, status_code); | 1804 | mgmt->sa, status_code); |
1808 | goto out; | 1805 | ieee80211_destroy_auth_data(sdata, false); |
1806 | return RX_MGMT_CFG80211_RX_AUTH; | ||
1809 | } | 1807 | } |
1810 | 1808 | ||
1811 | switch (ifmgd->auth_data->algorithm) { | 1809 | switch (ifmgd->auth_data->algorithm) { |
@@ -1826,8 +1824,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1826 | return RX_MGMT_NONE; | 1824 | return RX_MGMT_NONE; |
1827 | } | 1825 | } |
1828 | 1826 | ||
1829 | printk(KERN_DEBUG "%s: authenticated\n", sdata->name); | 1827 | sdata_info(sdata, "authenticated\n"); |
1830 | out: | ||
1831 | ifmgd->auth_data->done = true; | 1828 | ifmgd->auth_data->done = true; |
1832 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; | 1829 | ifmgd->auth_data->timeout = jiffies + IEEE80211_AUTH_WAIT_ASSOC; |
1833 | run_again(ifmgd, ifmgd->auth_data->timeout); | 1830 | run_again(ifmgd, ifmgd->auth_data->timeout); |
@@ -1840,8 +1837,7 @@ ieee80211_rx_mgmt_auth(struct ieee80211_sub_if_data *sdata, | |||
1840 | goto out_err; | 1837 | goto out_err; |
1841 | } | 1838 | } |
1842 | if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) { | 1839 | if (sta_info_move_state(sta, IEEE80211_STA_AUTH)) { |
1843 | printk(KERN_DEBUG "%s: failed moving %pM to auth\n", | 1840 | sdata_info(sdata, "failed moving %pM to auth\n", bssid); |
1844 | sdata->name, bssid); | ||
1845 | goto out_err; | 1841 | goto out_err; |
1846 | } | 1842 | } |
1847 | mutex_unlock(&sdata->local->sta_mtx); | 1843 | mutex_unlock(&sdata->local->sta_mtx); |
@@ -1875,8 +1871,8 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata, | |||
1875 | 1871 | ||
1876 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); | 1872 | reason_code = le16_to_cpu(mgmt->u.deauth.reason_code); |
1877 | 1873 | ||
1878 | printk(KERN_DEBUG "%s: deauthenticated from %pM (Reason: %u)\n", | 1874 | sdata_info(sdata, "deauthenticated from %pM (Reason: %u)\n", |
1879 | sdata->name, bssid, reason_code); | 1875 | bssid, reason_code); |
1880 | 1876 | ||
1881 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 1877 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
1882 | 1878 | ||
@@ -1906,8 +1902,8 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata, | |||
1906 | 1902 | ||
1907 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); | 1903 | reason_code = le16_to_cpu(mgmt->u.disassoc.reason_code); |
1908 | 1904 | ||
1909 | printk(KERN_DEBUG "%s: disassociated from %pM (Reason: %u)\n", | 1905 | sdata_info(sdata, "disassociated from %pM (Reason: %u)\n", |
1910 | sdata->name, mgmt->sa, reason_code); | 1906 | mgmt->sa, reason_code); |
1911 | 1907 | ||
1912 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 1908 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
1913 | 1909 | ||
@@ -1999,17 +1995,15 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
1999 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); | 1995 | capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info); |
2000 | 1996 | ||
2001 | if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) | 1997 | if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14))) |
2002 | printk(KERN_DEBUG | 1998 | sdata_info(sdata, "invalid AID value 0x%x; bits 15:14 not set\n", |
2003 | "%s: invalid AID value 0x%x; bits 15:14 not set\n", | 1999 | aid); |
2004 | sdata->name, aid); | ||
2005 | aid &= ~(BIT(15) | BIT(14)); | 2000 | aid &= ~(BIT(15) | BIT(14)); |
2006 | 2001 | ||
2007 | ifmgd->broken_ap = false; | 2002 | ifmgd->broken_ap = false; |
2008 | 2003 | ||
2009 | if (aid == 0 || aid > IEEE80211_MAX_AID) { | 2004 | if (aid == 0 || aid > IEEE80211_MAX_AID) { |
2010 | printk(KERN_DEBUG | 2005 | sdata_info(sdata, "invalid AID value %d (out of range), turn off PS\n", |
2011 | "%s: invalid AID value %d (out of range), turn off PS\n", | 2006 | aid); |
2012 | sdata->name, aid); | ||
2013 | aid = 0; | 2007 | aid = 0; |
2014 | ifmgd->broken_ap = true; | 2008 | ifmgd->broken_ap = true; |
2015 | } | 2009 | } |
@@ -2018,8 +2012,7 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2018 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 2012 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); |
2019 | 2013 | ||
2020 | if (!elems.supp_rates) { | 2014 | if (!elems.supp_rates) { |
2021 | printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", | 2015 | sdata_info(sdata, "no SuppRates element in AssocResp\n"); |
2022 | sdata->name); | ||
2023 | return false; | 2016 | return false; |
2024 | } | 2017 | } |
2025 | 2018 | ||
@@ -2059,9 +2052,9 @@ static bool ieee80211_assoc_success(struct ieee80211_sub_if_data *sdata, | |||
2059 | if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) | 2052 | if (!err && !(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) |
2060 | err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); | 2053 | err = sta_info_move_state(sta, IEEE80211_STA_AUTHORIZED); |
2061 | if (err) { | 2054 | if (err) { |
2062 | printk(KERN_DEBUG | 2055 | sdata_info(sdata, |
2063 | "%s: failed to move station %pM to desired state\n", | 2056 | "failed to move station %pM to desired state\n", |
2064 | sdata->name, sta->sta.addr); | 2057 | sta->sta.addr); |
2065 | WARN_ON(__sta_info_destroy(sta)); | 2058 | WARN_ON(__sta_info_destroy(sta)); |
2066 | mutex_unlock(&sdata->local->sta_mtx); | 2059 | mutex_unlock(&sdata->local->sta_mtx); |
2067 | return false; | 2060 | return false; |
@@ -2144,10 +2137,10 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2144 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); | 2137 | status_code = le16_to_cpu(mgmt->u.assoc_resp.status_code); |
2145 | aid = le16_to_cpu(mgmt->u.assoc_resp.aid); | 2138 | aid = le16_to_cpu(mgmt->u.assoc_resp.aid); |
2146 | 2139 | ||
2147 | printk(KERN_DEBUG "%s: RX %sssocResp from %pM (capab=0x%x " | 2140 | sdata_info(sdata, |
2148 | "status=%d aid=%d)\n", | 2141 | "RX %sssocResp from %pM (capab=0x%x status=%d aid=%d)\n", |
2149 | sdata->name, reassoc ? "Rea" : "A", mgmt->sa, | 2142 | reassoc ? "Rea" : "A", mgmt->sa, |
2150 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); | 2143 | capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14)))); |
2151 | 2144 | ||
2152 | pos = mgmt->u.assoc_resp.variable; | 2145 | pos = mgmt->u.assoc_resp.variable; |
2153 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | 2146 | ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); |
@@ -2158,9 +2151,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2158 | u32 tu, ms; | 2151 | u32 tu, ms; |
2159 | tu = get_unaligned_le32(elems.timeout_int + 1); | 2152 | tu = get_unaligned_le32(elems.timeout_int + 1); |
2160 | ms = tu * 1024 / 1000; | 2153 | ms = tu * 1024 / 1000; |
2161 | printk(KERN_DEBUG "%s: %pM rejected association temporarily; " | 2154 | sdata_info(sdata, |
2162 | "comeback duration %u TU (%u ms)\n", | 2155 | "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n", |
2163 | sdata->name, mgmt->sa, tu, ms); | 2156 | mgmt->sa, tu, ms); |
2164 | assoc_data->timeout = jiffies + msecs_to_jiffies(ms); | 2157 | assoc_data->timeout = jiffies + msecs_to_jiffies(ms); |
2165 | if (ms > IEEE80211_ASSOC_TIMEOUT) | 2158 | if (ms > IEEE80211_ASSOC_TIMEOUT) |
2166 | run_again(ifmgd, assoc_data->timeout); | 2159 | run_again(ifmgd, assoc_data->timeout); |
@@ -2170,8 +2163,8 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2170 | *bss = assoc_data->bss; | 2163 | *bss = assoc_data->bss; |
2171 | 2164 | ||
2172 | if (status_code != WLAN_STATUS_SUCCESS) { | 2165 | if (status_code != WLAN_STATUS_SUCCESS) { |
2173 | printk(KERN_DEBUG "%s: %pM denied association (code=%d)\n", | 2166 | sdata_info(sdata, "%pM denied association (code=%d)\n", |
2174 | sdata->name, mgmt->sa, status_code); | 2167 | mgmt->sa, status_code); |
2175 | ieee80211_destroy_assoc_data(sdata, false); | 2168 | ieee80211_destroy_assoc_data(sdata, false); |
2176 | } else { | 2169 | } else { |
2177 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { | 2170 | if (!ieee80211_assoc_success(sdata, *bss, mgmt, len)) { |
@@ -2180,7 +2173,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata, | |||
2180 | cfg80211_put_bss(*bss); | 2173 | cfg80211_put_bss(*bss); |
2181 | return RX_MGMT_CFG80211_ASSOC_TIMEOUT; | 2174 | return RX_MGMT_CFG80211_ASSOC_TIMEOUT; |
2182 | } | 2175 | } |
2183 | printk(KERN_DEBUG "%s: associated\n", sdata->name); | 2176 | sdata_info(sdata, "associated\n"); |
2184 | 2177 | ||
2185 | /* | 2178 | /* |
2186 | * destroy assoc_data afterwards, as otherwise an idle | 2179 | * destroy assoc_data afterwards, as otherwise an idle |
@@ -2280,7 +2273,7 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata, | |||
2280 | if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && | 2273 | if (ifmgd->auth_data && !ifmgd->auth_data->bss->proberesp_ies && |
2281 | ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) { | 2274 | ether_addr_equal(mgmt->bssid, ifmgd->auth_data->bss->bssid)) { |
2282 | /* got probe response, continue with auth */ | 2275 | /* got probe response, continue with auth */ |
2283 | printk(KERN_DEBUG "%s: direct probe responded\n", sdata->name); | 2276 | sdata_info(sdata, "direct probe responded\n"); |
2284 | ifmgd->auth_data->tries = 0; | 2277 | ifmgd->auth_data->tries = 0; |
2285 | ifmgd->auth_data->timeout = jiffies; | 2278 | ifmgd->auth_data->timeout = jiffies; |
2286 | run_again(ifmgd, ifmgd->auth_data->timeout); | 2279 | run_again(ifmgd, ifmgd->auth_data->timeout); |
@@ -2416,10 +2409,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2416 | } | 2409 | } |
2417 | 2410 | ||
2418 | if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { | 2411 | if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) { |
2419 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2412 | mlme_dbg_ratelimited(sdata, |
2420 | net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n", | 2413 | "cancelling probereq poll due to a received beacon\n"); |
2421 | sdata->name); | ||
2422 | #endif | ||
2423 | mutex_lock(&local->mtx); | 2414 | mutex_lock(&local->mtx); |
2424 | ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; | 2415 | ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL; |
2425 | ieee80211_run_deferred_scan(local); | 2416 | ieee80211_run_deferred_scan(local); |
@@ -2445,14 +2436,6 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2445 | directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, | 2436 | directed_tim = ieee80211_check_tim(elems.tim, elems.tim_len, |
2446 | ifmgd->aid); | 2437 | ifmgd->aid); |
2447 | 2438 | ||
2448 | if (ncrc != ifmgd->beacon_crc || !ifmgd->beacon_crc_valid) { | ||
2449 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, | ||
2450 | true); | ||
2451 | |||
2452 | ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | ||
2453 | elems.wmm_param_len); | ||
2454 | } | ||
2455 | |||
2456 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { | 2439 | if (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) { |
2457 | if (directed_tim) { | 2440 | if (directed_tim) { |
2458 | if (local->hw.conf.dynamic_ps_timeout > 0) { | 2441 | if (local->hw.conf.dynamic_ps_timeout > 0) { |
@@ -2483,6 +2466,13 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | |||
2483 | ifmgd->beacon_crc = ncrc; | 2466 | ifmgd->beacon_crc = ncrc; |
2484 | ifmgd->beacon_crc_valid = true; | 2467 | ifmgd->beacon_crc_valid = true; |
2485 | 2468 | ||
2469 | ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, | ||
2470 | true); | ||
2471 | |||
2472 | if (ieee80211_sta_wmm_params(local, sdata, elems.wmm_param, | ||
2473 | elems.wmm_param_len)) | ||
2474 | changed |= BSS_CHANGED_QOS; | ||
2475 | |||
2486 | if (elems.erp_info && elems.erp_info_len >= 1) { | 2476 | if (elems.erp_info && elems.erp_info_len >= 1) { |
2487 | erp_valid = true; | 2477 | erp_valid = true; |
2488 | erp_value = elems.erp_info[0]; | 2478 | erp_value = elems.erp_info[0]; |
@@ -2642,8 +2632,8 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2642 | auth_data->tries++; | 2632 | auth_data->tries++; |
2643 | 2633 | ||
2644 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { | 2634 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { |
2645 | printk(KERN_DEBUG "%s: authentication with %pM timed out\n", | 2635 | sdata_info(sdata, "authentication with %pM timed out\n", |
2646 | sdata->name, auth_data->bss->bssid); | 2636 | auth_data->bss->bssid); |
2647 | 2637 | ||
2648 | /* | 2638 | /* |
2649 | * Most likely AP is not in the range so remove the | 2639 | * Most likely AP is not in the range so remove the |
@@ -2654,10 +2644,12 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2654 | return -ETIMEDOUT; | 2644 | return -ETIMEDOUT; |
2655 | } | 2645 | } |
2656 | 2646 | ||
2647 | drv_mgd_prepare_tx(local, sdata); | ||
2648 | |||
2657 | if (auth_data->bss->proberesp_ies) { | 2649 | if (auth_data->bss->proberesp_ies) { |
2658 | printk(KERN_DEBUG "%s: send auth to %pM (try %d/%d)\n", | 2650 | sdata_info(sdata, "send auth to %pM (try %d/%d)\n", |
2659 | sdata->name, auth_data->bss->bssid, auth_data->tries, | 2651 | auth_data->bss->bssid, auth_data->tries, |
2660 | IEEE80211_AUTH_MAX_TRIES); | 2652 | IEEE80211_AUTH_MAX_TRIES); |
2661 | 2653 | ||
2662 | auth_data->expected_transaction = 2; | 2654 | auth_data->expected_transaction = 2; |
2663 | ieee80211_send_auth(sdata, 1, auth_data->algorithm, | 2655 | ieee80211_send_auth(sdata, 1, auth_data->algorithm, |
@@ -2667,9 +2659,9 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
2667 | } else { | 2659 | } else { |
2668 | const u8 *ssidie; | 2660 | const u8 *ssidie; |
2669 | 2661 | ||
2670 | printk(KERN_DEBUG "%s: direct probe to %pM (try %d/%i)\n", | 2662 | sdata_info(sdata, "direct probe to %pM (try %d/%i)\n", |
2671 | sdata->name, auth_data->bss->bssid, auth_data->tries, | 2663 | auth_data->bss->bssid, auth_data->tries, |
2672 | IEEE80211_AUTH_MAX_TRIES); | 2664 | IEEE80211_AUTH_MAX_TRIES); |
2673 | 2665 | ||
2674 | ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID); | 2666 | ssidie = ieee80211_bss_get_ie(auth_data->bss, WLAN_EID_SSID); |
2675 | if (!ssidie) | 2667 | if (!ssidie) |
@@ -2697,8 +2689,8 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) | |||
2697 | 2689 | ||
2698 | assoc_data->tries++; | 2690 | assoc_data->tries++; |
2699 | if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { | 2691 | if (assoc_data->tries > IEEE80211_ASSOC_MAX_TRIES) { |
2700 | printk(KERN_DEBUG "%s: association with %pM timed out\n", | 2692 | sdata_info(sdata, "association with %pM timed out\n", |
2701 | sdata->name, assoc_data->bss->bssid); | 2693 | assoc_data->bss->bssid); |
2702 | 2694 | ||
2703 | /* | 2695 | /* |
2704 | * Most likely AP is not in the range so remove the | 2696 | * Most likely AP is not in the range so remove the |
@@ -2709,9 +2701,9 @@ static int ieee80211_do_assoc(struct ieee80211_sub_if_data *sdata) | |||
2709 | return -ETIMEDOUT; | 2701 | return -ETIMEDOUT; |
2710 | } | 2702 | } |
2711 | 2703 | ||
2712 | printk(KERN_DEBUG "%s: associate with %pM (try %d/%d)\n", | 2704 | sdata_info(sdata, "associate with %pM (try %d/%d)\n", |
2713 | sdata->name, assoc_data->bss->bssid, assoc_data->tries, | 2705 | assoc_data->bss->bssid, assoc_data->tries, |
2714 | IEEE80211_ASSOC_MAX_TRIES); | 2706 | IEEE80211_ASSOC_MAX_TRIES); |
2715 | ieee80211_send_assoc(sdata); | 2707 | ieee80211_send_assoc(sdata); |
2716 | 2708 | ||
2717 | assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; | 2709 | assoc_data->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; |
@@ -2784,45 +2776,31 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata) | |||
2784 | ieee80211_reset_ap_probe(sdata); | 2776 | ieee80211_reset_ap_probe(sdata); |
2785 | else if (ifmgd->nullfunc_failed) { | 2777 | else if (ifmgd->nullfunc_failed) { |
2786 | if (ifmgd->probe_send_count < max_tries) { | 2778 | if (ifmgd->probe_send_count < max_tries) { |
2787 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2779 | mlme_dbg(sdata, |
2788 | wiphy_debug(local->hw.wiphy, | 2780 | "No ack for nullfunc frame to AP %pM, try %d/%i\n", |
2789 | "%s: No ack for nullfunc frame to" | 2781 | bssid, ifmgd->probe_send_count, |
2790 | " AP %pM, try %d/%i\n", | 2782 | max_tries); |
2791 | sdata->name, bssid, | ||
2792 | ifmgd->probe_send_count, max_tries); | ||
2793 | #endif | ||
2794 | ieee80211_mgd_probe_ap_send(sdata); | 2783 | ieee80211_mgd_probe_ap_send(sdata); |
2795 | } else { | 2784 | } else { |
2796 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2785 | mlme_dbg(sdata, |
2797 | wiphy_debug(local->hw.wiphy, | 2786 | "No ack for nullfunc frame to AP %pM, disconnecting.\n", |
2798 | "%s: No ack for nullfunc frame to" | 2787 | bssid); |
2799 | " AP %pM, disconnecting.\n", | ||
2800 | sdata->name, bssid); | ||
2801 | #endif | ||
2802 | ieee80211_sta_connection_lost(sdata, bssid, | 2788 | ieee80211_sta_connection_lost(sdata, bssid, |
2803 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); | 2789 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); |
2804 | } | 2790 | } |
2805 | } else if (time_is_after_jiffies(ifmgd->probe_timeout)) | 2791 | } else if (time_is_after_jiffies(ifmgd->probe_timeout)) |
2806 | run_again(ifmgd, ifmgd->probe_timeout); | 2792 | run_again(ifmgd, ifmgd->probe_timeout); |
2807 | else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { | 2793 | else if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) { |
2808 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2794 | mlme_dbg(sdata, |
2809 | wiphy_debug(local->hw.wiphy, | 2795 | "Failed to send nullfunc to AP %pM after %dms, disconnecting\n", |
2810 | "%s: Failed to send nullfunc to AP %pM" | 2796 | bssid, probe_wait_ms); |
2811 | " after %dms, disconnecting.\n", | ||
2812 | sdata->name, | ||
2813 | bssid, probe_wait_ms); | ||
2814 | #endif | ||
2815 | ieee80211_sta_connection_lost(sdata, bssid, | 2797 | ieee80211_sta_connection_lost(sdata, bssid, |
2816 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); | 2798 | WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY); |
2817 | } else if (ifmgd->probe_send_count < max_tries) { | 2799 | } else if (ifmgd->probe_send_count < max_tries) { |
2818 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2800 | mlme_dbg(sdata, |
2819 | wiphy_debug(local->hw.wiphy, | 2801 | "No probe response from AP %pM after %dms, try %d/%i\n", |
2820 | "%s: No probe response from AP %pM" | 2802 | bssid, probe_wait_ms, |
2821 | " after %dms, try %d/%i\n", | 2803 | ifmgd->probe_send_count, max_tries); |
2822 | sdata->name, | ||
2823 | bssid, probe_wait_ms, | ||
2824 | ifmgd->probe_send_count, max_tries); | ||
2825 | #endif | ||
2826 | ieee80211_mgd_probe_ap_send(sdata); | 2804 | ieee80211_mgd_probe_ap_send(sdata); |
2827 | } else { | 2805 | } else { |
2828 | /* | 2806 | /* |
@@ -2937,11 +2915,8 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) | |||
2937 | sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME; | 2915 | sdata->flags &= ~IEEE80211_SDATA_DISCONNECT_RESUME; |
2938 | mutex_lock(&ifmgd->mtx); | 2916 | mutex_lock(&ifmgd->mtx); |
2939 | if (ifmgd->associated) { | 2917 | if (ifmgd->associated) { |
2940 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 2918 | mlme_dbg(sdata, |
2941 | wiphy_debug(sdata->local->hw.wiphy, | 2919 | "driver requested disconnect after resume\n"); |
2942 | "%s: driver requested disconnect after resume.\n", | ||
2943 | sdata->name); | ||
2944 | #endif | ||
2945 | ieee80211_sta_connection_lost(sdata, | 2920 | ieee80211_sta_connection_lost(sdata, |
2946 | ifmgd->associated->bssid, | 2921 | ifmgd->associated->bssid, |
2947 | WLAN_REASON_UNSPECIFIED); | 2922 | WLAN_REASON_UNSPECIFIED); |
@@ -2999,7 +2974,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
2999 | /* scan finished notification */ | 2974 | /* scan finished notification */ |
3000 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) | 2975 | void ieee80211_mlme_notify_scan_completed(struct ieee80211_local *local) |
3001 | { | 2976 | { |
3002 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 2977 | struct ieee80211_sub_if_data *sdata; |
3003 | 2978 | ||
3004 | /* Restart STA timers */ | 2979 | /* Restart STA timers */ |
3005 | rcu_read_lock(); | 2980 | rcu_read_lock(); |
@@ -3029,7 +3004,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3029 | struct ieee80211_local *local = sdata->local; | 3004 | struct ieee80211_local *local = sdata->local; |
3030 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 3005 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
3031 | struct ieee80211_bss *bss = (void *)cbss->priv; | 3006 | struct ieee80211_bss *bss = (void *)cbss->priv; |
3032 | struct sta_info *sta; | 3007 | struct sta_info *sta = NULL; |
3033 | bool have_sta = false; | 3008 | bool have_sta = false; |
3034 | int err; | 3009 | int err; |
3035 | int ht_cfreq; | 3010 | int ht_cfreq; |
@@ -3082,13 +3057,11 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3082 | * since we look at probe response/beacon data here | 3057 | * since we look at probe response/beacon data here |
3083 | * it should be OK. | 3058 | * it should be OK. |
3084 | */ | 3059 | */ |
3085 | printk(KERN_DEBUG | 3060 | sdata_info(sdata, |
3086 | "%s: Wrong control channel: center-freq: %d" | 3061 | "Wrong control channel: center-freq: %d ht-cfreq: %d ht->primary_chan: %d band: %d - Disabling HT\n", |
3087 | " ht-cfreq: %d ht->primary_chan: %d" | 3062 | cbss->channel->center_freq, |
3088 | " band: %d. Disabling HT.\n", | 3063 | ht_cfreq, ht_oper->primary_chan, |
3089 | sdata->name, cbss->channel->center_freq, | 3064 | cbss->channel->band); |
3090 | ht_cfreq, ht_oper->primary_chan, | ||
3091 | cbss->channel->band); | ||
3092 | ht_oper = NULL; | 3065 | ht_oper = NULL; |
3093 | } | 3066 | } |
3094 | } | 3067 | } |
@@ -3112,9 +3085,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3112 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { | 3085 | if (!ieee80211_set_channel_type(local, sdata, channel_type)) { |
3113 | /* can only fail due to HT40+/- mismatch */ | 3086 | /* can only fail due to HT40+/- mismatch */ |
3114 | channel_type = NL80211_CHAN_HT20; | 3087 | channel_type = NL80211_CHAN_HT20; |
3115 | printk(KERN_DEBUG | 3088 | sdata_info(sdata, |
3116 | "%s: disabling 40 MHz due to multi-vif mismatch\n", | 3089 | "disabling 40 MHz due to multi-vif mismatch\n"); |
3117 | sdata->name); | ||
3118 | ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; | 3090 | ifmgd->flags |= IEEE80211_STA_DISABLE_40MHZ; |
3119 | WARN_ON(!ieee80211_set_channel_type(local, sdata, | 3091 | WARN_ON(!ieee80211_set_channel_type(local, sdata, |
3120 | channel_type)); | 3092 | channel_type)); |
@@ -3123,7 +3095,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3123 | local->oper_channel = cbss->channel; | 3095 | local->oper_channel = cbss->channel; |
3124 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); | 3096 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL); |
3125 | 3097 | ||
3126 | if (!have_sta) { | 3098 | if (sta) { |
3127 | u32 rates = 0, basic_rates = 0; | 3099 | u32 rates = 0, basic_rates = 0; |
3128 | bool have_higher_than_11mbit; | 3100 | bool have_higher_than_11mbit; |
3129 | int min_rate = INT_MAX, min_rate_index = -1; | 3101 | int min_rate = INT_MAX, min_rate_index = -1; |
@@ -3143,9 +3115,8 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3143 | * we can connect -- with a warning. | 3115 | * we can connect -- with a warning. |
3144 | */ | 3116 | */ |
3145 | if (!basic_rates && min_rate_index >= 0) { | 3117 | if (!basic_rates && min_rate_index >= 0) { |
3146 | printk(KERN_DEBUG | 3118 | sdata_info(sdata, |
3147 | "%s: No basic rates, using min rate instead.\n", | 3119 | "No basic rates, using min rate instead\n"); |
3148 | sdata->name); | ||
3149 | basic_rates = BIT(min_rate_index); | 3120 | basic_rates = BIT(min_rate_index); |
3150 | } | 3121 | } |
3151 | 3122 | ||
@@ -3161,9 +3132,15 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3161 | 3132 | ||
3162 | memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN); | 3133 | memcpy(ifmgd->bssid, cbss->bssid, ETH_ALEN); |
3163 | 3134 | ||
3164 | /* tell driver about BSSID and basic rates */ | 3135 | /* set timing information */ |
3136 | sdata->vif.bss_conf.beacon_int = cbss->beacon_interval; | ||
3137 | sdata->vif.bss_conf.sync_tsf = cbss->tsf; | ||
3138 | sdata->vif.bss_conf.sync_device_ts = bss->device_ts; | ||
3139 | |||
3140 | /* tell driver about BSSID, basic rates and timing */ | ||
3165 | ieee80211_bss_info_change_notify(sdata, | 3141 | ieee80211_bss_info_change_notify(sdata, |
3166 | BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES); | 3142 | BSS_CHANGED_BSSID | BSS_CHANGED_BASIC_RATES | |
3143 | BSS_CHANGED_BEACON_INT); | ||
3167 | 3144 | ||
3168 | if (assoc) | 3145 | if (assoc) |
3169 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); | 3146 | sta_info_pre_move_state(sta, IEEE80211_STA_AUTH); |
@@ -3171,9 +3148,9 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
3171 | err = sta_info_insert(sta); | 3148 | err = sta_info_insert(sta); |
3172 | sta = NULL; | 3149 | sta = NULL; |
3173 | if (err) { | 3150 | if (err) { |
3174 | printk(KERN_DEBUG | 3151 | sdata_info(sdata, |
3175 | "%s: failed to insert STA entry for the AP (error %d)\n", | 3152 | "failed to insert STA entry for the AP (error %d)\n", |
3176 | sdata->name, err); | 3153 | err); |
3177 | return err; | 3154 | return err; |
3178 | } | 3155 | } |
3179 | } else | 3156 | } else |
@@ -3251,8 +3228,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3251 | if (ifmgd->associated) | 3228 | if (ifmgd->associated) |
3252 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 3229 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); |
3253 | 3230 | ||
3254 | printk(KERN_DEBUG "%s: authenticate with %pM\n", | 3231 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); |
3255 | sdata->name, req->bss->bssid); | ||
3256 | 3232 | ||
3257 | err = ieee80211_prep_connection(sdata, req->bss, false); | 3233 | err = ieee80211_prep_connection(sdata, req->bss, false); |
3258 | if (err) | 3234 | if (err) |
@@ -3287,7 +3263,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3287 | struct ieee80211_bss *bss = (void *)req->bss->priv; | 3263 | struct ieee80211_bss *bss = (void *)req->bss->priv; |
3288 | struct ieee80211_mgd_assoc_data *assoc_data; | 3264 | struct ieee80211_mgd_assoc_data *assoc_data; |
3289 | struct ieee80211_supported_band *sband; | 3265 | struct ieee80211_supported_band *sband; |
3290 | const u8 *ssidie; | 3266 | const u8 *ssidie, *ht_ie; |
3291 | int i, err; | 3267 | int i, err; |
3292 | 3268 | ||
3293 | ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); | 3269 | ssidie = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); |
@@ -3335,11 +3311,15 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3335 | * We can set this to true for non-11n hardware, that'll be checked | 3311 | * We can set this to true for non-11n hardware, that'll be checked |
3336 | * separately along with the peer capabilities. | 3312 | * separately along with the peer capabilities. |
3337 | */ | 3313 | */ |
3338 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) | 3314 | for (i = 0; i < req->crypto.n_ciphers_pairwise; i++) { |
3339 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || | 3315 | if (req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP40 || |
3340 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || | 3316 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_TKIP || |
3341 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) | 3317 | req->crypto.ciphers_pairwise[i] == WLAN_CIPHER_SUITE_WEP104) { |
3342 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | 3318 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; |
3319 | netdev_info(sdata->dev, | ||
3320 | "disabling HT due to WEP/TKIP use\n"); | ||
3321 | } | ||
3322 | } | ||
3343 | 3323 | ||
3344 | if (req->flags & ASSOC_REQ_DISABLE_HT) | 3324 | if (req->flags & ASSOC_REQ_DISABLE_HT) |
3345 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | 3325 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; |
@@ -3347,8 +3327,11 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3347 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ | 3327 | /* Also disable HT if we don't support it or the AP doesn't use WMM */ |
3348 | sband = local->hw.wiphy->bands[req->bss->channel->band]; | 3328 | sband = local->hw.wiphy->bands[req->bss->channel->band]; |
3349 | if (!sband->ht_cap.ht_supported || | 3329 | if (!sband->ht_cap.ht_supported || |
3350 | local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) | 3330 | local->hw.queues < IEEE80211_NUM_ACS || !bss->wmm_used) { |
3351 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | 3331 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; |
3332 | netdev_info(sdata->dev, | ||
3333 | "disabling HT as WMM/QoS is not supported\n"); | ||
3334 | } | ||
3352 | 3335 | ||
3353 | memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); | 3336 | memcpy(&ifmgd->ht_capa, &req->ht_capa, sizeof(ifmgd->ht_capa)); |
3354 | memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, | 3337 | memcpy(&ifmgd->ht_capa_mask, &req->ht_capa_mask, |
@@ -3374,8 +3357,13 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3374 | (local->hw.queues >= IEEE80211_NUM_ACS); | 3357 | (local->hw.queues >= IEEE80211_NUM_ACS); |
3375 | assoc_data->supp_rates = bss->supp_rates; | 3358 | assoc_data->supp_rates = bss->supp_rates; |
3376 | assoc_data->supp_rates_len = bss->supp_rates_len; | 3359 | assoc_data->supp_rates_len = bss->supp_rates_len; |
3377 | assoc_data->ht_operation_ie = | 3360 | |
3378 | ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION); | 3361 | ht_ie = ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_OPERATION); |
3362 | if (ht_ie && ht_ie[1] >= sizeof(struct ieee80211_ht_operation)) | ||
3363 | assoc_data->ap_ht_param = | ||
3364 | ((struct ieee80211_ht_operation *)(ht_ie + 2))->ht_param; | ||
3365 | else | ||
3366 | ifmgd->flags |= IEEE80211_STA_DISABLE_11N; | ||
3379 | 3367 | ||
3380 | if (bss->wmm_used && bss->uapsd_supported && | 3368 | if (bss->wmm_used && bss->uapsd_supported && |
3381 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { | 3369 | (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) { |
@@ -3422,8 +3410,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3422 | * Wait up to one beacon interval ... | 3410 | * Wait up to one beacon interval ... |
3423 | * should this be more if we miss one? | 3411 | * should this be more if we miss one? |
3424 | */ | 3412 | */ |
3425 | printk(KERN_DEBUG "%s: waiting for beacon from %pM\n", | 3413 | sdata_info(sdata, "waiting for beacon from %pM\n", |
3426 | sdata->name, ifmgd->bssid); | 3414 | ifmgd->bssid); |
3427 | assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); | 3415 | assoc_data->timeout = TU_TO_EXP_TIME(req->bss->beacon_interval); |
3428 | } else { | 3416 | } else { |
3429 | assoc_data->have_beacon = true; | 3417 | assoc_data->have_beacon = true; |
@@ -3442,8 +3430,8 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3442 | corrupt_type = "beacon"; | 3430 | corrupt_type = "beacon"; |
3443 | } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) | 3431 | } else if (bss->corrupt_data & IEEE80211_BSS_CORRUPT_PROBE_RESP) |
3444 | corrupt_type = "probe response"; | 3432 | corrupt_type = "probe response"; |
3445 | printk(KERN_DEBUG "%s: associating with AP with corrupt %s\n", | 3433 | sdata_info(sdata, "associating with AP with corrupt %s\n", |
3446 | sdata->name, corrupt_type); | 3434 | corrupt_type); |
3447 | } | 3435 | } |
3448 | 3436 | ||
3449 | err = 0; | 3437 | err = 0; |
@@ -3472,9 +3460,9 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata, | |||
3472 | return 0; | 3460 | return 0; |
3473 | } | 3461 | } |
3474 | 3462 | ||
3475 | printk(KERN_DEBUG | 3463 | sdata_info(sdata, |
3476 | "%s: deauthenticating from %pM by local choice (reason=%d)\n", | 3464 | "deauthenticating from %pM by local choice (reason=%d)\n", |
3477 | sdata->name, req->bssid, req->reason_code); | 3465 | req->bssid, req->reason_code); |
3478 | 3466 | ||
3479 | if (ifmgd->associated && | 3467 | if (ifmgd->associated && |
3480 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) | 3468 | ether_addr_equal(ifmgd->associated->bssid, req->bssid)) |
@@ -3516,8 +3504,9 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata, | |||
3516 | return -ENOLINK; | 3504 | return -ENOLINK; |
3517 | } | 3505 | } |
3518 | 3506 | ||
3519 | printk(KERN_DEBUG "%s: disassociating from %pM by local choice (reason=%d)\n", | 3507 | sdata_info(sdata, |
3520 | sdata->name, req->bss->bssid, req->reason_code); | 3508 | "disassociating from %pM by local choice (reason=%d)\n", |
3509 | req->bss->bssid, req->reason_code); | ||
3521 | 3510 | ||
3522 | memcpy(bssid, req->bss->bssid, ETH_ALEN); | 3511 | memcpy(bssid, req->bss->bssid, ETH_ALEN); |
3523 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, | 3512 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DISASSOC, |
@@ -3558,10 +3547,3 @@ void ieee80211_cqm_rssi_notify(struct ieee80211_vif *vif, | |||
3558 | cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); | 3547 | cfg80211_cqm_rssi_notify(sdata->dev, rssi_event, gfp); |
3559 | } | 3548 | } |
3560 | EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); | 3549 | EXPORT_SYMBOL(ieee80211_cqm_rssi_notify); |
3561 | |||
3562 | unsigned char ieee80211_get_operstate(struct ieee80211_vif *vif) | ||
3563 | { | ||
3564 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
3565 | return sdata->dev->operstate; | ||
3566 | } | ||
3567 | EXPORT_SYMBOL(ieee80211_get_operstate); | ||
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c index 935aa4b6deee..635c3250c668 100644 --- a/net/mac80211/offchannel.c +++ b/net/mac80211/offchannel.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/export.h> | 15 | #include <linux/export.h> |
16 | #include <net/mac80211.h> | 16 | #include <net/mac80211.h> |
17 | #include "ieee80211_i.h" | 17 | #include "ieee80211_i.h" |
18 | #include "driver-trace.h" | 18 | #include "driver-ops.h" |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Tell our hardware to disable PS. | 21 | * Tell our hardware to disable PS. |
@@ -24,8 +24,7 @@ | |||
24 | * because we *may* be doing work on-operating channel, and want our | 24 | * because we *may* be doing work on-operating channel, and want our |
25 | * hardware unconditionally awake, but still let the AP send us normal frames. | 25 | * hardware unconditionally awake, but still let the AP send us normal frames. |
26 | */ | 26 | */ |
27 | static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata, | 27 | static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata) |
28 | bool tell_ap) | ||
29 | { | 28 | { |
30 | struct ieee80211_local *local = sdata->local; | 29 | struct ieee80211_local *local = sdata->local; |
31 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; | 30 | struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; |
@@ -46,8 +45,8 @@ static void ieee80211_offchannel_ps_enable(struct ieee80211_sub_if_data *sdata, | |||
46 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); | 45 | ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_PS); |
47 | } | 46 | } |
48 | 47 | ||
49 | if (tell_ap && (!local->offchannel_ps_enabled || | 48 | if (!local->offchannel_ps_enabled || |
50 | !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK))) | 49 | !(local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK)) |
51 | /* | 50 | /* |
52 | * If power save was enabled, no need to send a nullfunc | 51 | * If power save was enabled, no need to send a nullfunc |
53 | * frame because AP knows that we are sleeping. But if the | 52 | * frame because AP knows that we are sleeping. But if the |
@@ -132,7 +131,7 @@ void ieee80211_offchannel_stop_vifs(struct ieee80211_local *local, | |||
132 | if (offchannel_ps_enable && | 131 | if (offchannel_ps_enable && |
133 | (sdata->vif.type == NL80211_IFTYPE_STATION) && | 132 | (sdata->vif.type == NL80211_IFTYPE_STATION) && |
134 | sdata->u.mgd.associated) | 133 | sdata->u.mgd.associated) |
135 | ieee80211_offchannel_ps_enable(sdata, true); | 134 | ieee80211_offchannel_ps_enable(sdata); |
136 | } | 135 | } |
137 | } | 136 | } |
138 | mutex_unlock(&local->iflist_mtx); | 137 | mutex_unlock(&local->iflist_mtx); |
@@ -181,34 +180,58 @@ void ieee80211_offchannel_return(struct ieee80211_local *local, | |||
181 | mutex_unlock(&local->iflist_mtx); | 180 | mutex_unlock(&local->iflist_mtx); |
182 | } | 181 | } |
183 | 182 | ||
183 | void ieee80211_handle_roc_started(struct ieee80211_roc_work *roc) | ||
184 | { | ||
185 | if (roc->notified) | ||
186 | return; | ||
187 | |||
188 | if (roc->mgmt_tx_cookie) { | ||
189 | if (!WARN_ON(!roc->frame)) { | ||
190 | ieee80211_tx_skb(roc->sdata, roc->frame); | ||
191 | roc->frame = NULL; | ||
192 | } | ||
193 | } else { | ||
194 | cfg80211_ready_on_channel(&roc->sdata->wdev, (unsigned long)roc, | ||
195 | roc->chan, roc->chan_type, | ||
196 | roc->req_duration, GFP_KERNEL); | ||
197 | } | ||
198 | |||
199 | roc->notified = true; | ||
200 | } | ||
201 | |||
184 | static void ieee80211_hw_roc_start(struct work_struct *work) | 202 | static void ieee80211_hw_roc_start(struct work_struct *work) |
185 | { | 203 | { |
186 | struct ieee80211_local *local = | 204 | struct ieee80211_local *local = |
187 | container_of(work, struct ieee80211_local, hw_roc_start); | 205 | container_of(work, struct ieee80211_local, hw_roc_start); |
188 | struct ieee80211_sub_if_data *sdata; | 206 | struct ieee80211_roc_work *roc, *dep, *tmp; |
189 | 207 | ||
190 | mutex_lock(&local->mtx); | 208 | mutex_lock(&local->mtx); |
191 | 209 | ||
192 | if (!local->hw_roc_channel) { | 210 | if (list_empty(&local->roc_list)) |
193 | mutex_unlock(&local->mtx); | 211 | goto out_unlock; |
194 | return; | ||
195 | } | ||
196 | 212 | ||
197 | if (local->hw_roc_skb) { | 213 | roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, |
198 | sdata = IEEE80211_DEV_TO_SUB_IF(local->hw_roc_dev); | 214 | list); |
199 | ieee80211_tx_skb(sdata, local->hw_roc_skb); | 215 | |
200 | local->hw_roc_skb = NULL; | 216 | if (!roc->started) |
201 | } else { | 217 | goto out_unlock; |
202 | cfg80211_ready_on_channel(local->hw_roc_dev, | ||
203 | local->hw_roc_cookie, | ||
204 | local->hw_roc_channel, | ||
205 | local->hw_roc_channel_type, | ||
206 | local->hw_roc_duration, | ||
207 | GFP_KERNEL); | ||
208 | } | ||
209 | 218 | ||
210 | ieee80211_recalc_idle(local); | 219 | roc->hw_begun = true; |
220 | roc->hw_start_time = local->hw_roc_start_time; | ||
211 | 221 | ||
222 | ieee80211_handle_roc_started(roc); | ||
223 | list_for_each_entry_safe(dep, tmp, &roc->dependents, list) { | ||
224 | ieee80211_handle_roc_started(dep); | ||
225 | |||
226 | if (dep->duration > roc->duration) { | ||
227 | u32 dur = dep->duration; | ||
228 | dep->duration = dur - roc->duration; | ||
229 | roc->duration = dur; | ||
230 | list_del(&dep->list); | ||
231 | list_add(&dep->list, &roc->list); | ||
232 | } | ||
233 | } | ||
234 | out_unlock: | ||
212 | mutex_unlock(&local->mtx); | 235 | mutex_unlock(&local->mtx); |
213 | } | 236 | } |
214 | 237 | ||
@@ -216,52 +239,181 @@ void ieee80211_ready_on_channel(struct ieee80211_hw *hw) | |||
216 | { | 239 | { |
217 | struct ieee80211_local *local = hw_to_local(hw); | 240 | struct ieee80211_local *local = hw_to_local(hw); |
218 | 241 | ||
242 | local->hw_roc_start_time = jiffies; | ||
243 | |||
219 | trace_api_ready_on_channel(local); | 244 | trace_api_ready_on_channel(local); |
220 | 245 | ||
221 | ieee80211_queue_work(hw, &local->hw_roc_start); | 246 | ieee80211_queue_work(hw, &local->hw_roc_start); |
222 | } | 247 | } |
223 | EXPORT_SYMBOL_GPL(ieee80211_ready_on_channel); | 248 | EXPORT_SYMBOL_GPL(ieee80211_ready_on_channel); |
224 | 249 | ||
225 | static void ieee80211_hw_roc_done(struct work_struct *work) | 250 | void ieee80211_start_next_roc(struct ieee80211_local *local) |
226 | { | 251 | { |
227 | struct ieee80211_local *local = | 252 | struct ieee80211_roc_work *roc; |
228 | container_of(work, struct ieee80211_local, hw_roc_done); | ||
229 | 253 | ||
230 | mutex_lock(&local->mtx); | 254 | lockdep_assert_held(&local->mtx); |
231 | 255 | ||
232 | if (!local->hw_roc_channel) { | 256 | if (list_empty(&local->roc_list)) { |
233 | mutex_unlock(&local->mtx); | 257 | ieee80211_run_deferred_scan(local); |
234 | return; | 258 | return; |
235 | } | 259 | } |
236 | 260 | ||
237 | /* was never transmitted */ | 261 | roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, |
238 | if (local->hw_roc_skb) { | 262 | list); |
239 | u64 cookie; | ||
240 | 263 | ||
241 | cookie = local->hw_roc_cookie ^ 2; | 264 | if (WARN_ON_ONCE(roc->started)) |
265 | return; | ||
266 | |||
267 | if (local->ops->remain_on_channel) { | ||
268 | int ret, duration = roc->duration; | ||
269 | |||
270 | /* XXX: duplicated, see ieee80211_start_roc_work() */ | ||
271 | if (!duration) | ||
272 | duration = 10; | ||
273 | |||
274 | ret = drv_remain_on_channel(local, roc->chan, | ||
275 | roc->chan_type, | ||
276 | duration); | ||
277 | |||
278 | roc->started = true; | ||
279 | |||
280 | if (ret) { | ||
281 | wiphy_warn(local->hw.wiphy, | ||
282 | "failed to start next HW ROC (%d)\n", ret); | ||
283 | /* | ||
284 | * queue the work struct again to avoid recursion | ||
285 | * when multiple failures occur | ||
286 | */ | ||
287 | ieee80211_remain_on_channel_expired(&local->hw); | ||
288 | } | ||
289 | } else { | ||
290 | /* delay it a bit */ | ||
291 | ieee80211_queue_delayed_work(&local->hw, &roc->work, | ||
292 | round_jiffies_relative(HZ/2)); | ||
293 | } | ||
294 | } | ||
242 | 295 | ||
243 | cfg80211_mgmt_tx_status(local->hw_roc_dev, cookie, | 296 | void ieee80211_roc_notify_destroy(struct ieee80211_roc_work *roc) |
244 | local->hw_roc_skb->data, | 297 | { |
245 | local->hw_roc_skb->len, false, | 298 | struct ieee80211_roc_work *dep, *tmp; |
246 | GFP_KERNEL); | ||
247 | 299 | ||
248 | kfree_skb(local->hw_roc_skb); | 300 | /* was never transmitted */ |
249 | local->hw_roc_skb = NULL; | 301 | if (roc->frame) { |
250 | local->hw_roc_skb_for_status = NULL; | 302 | cfg80211_mgmt_tx_status(&roc->sdata->wdev, |
303 | (unsigned long)roc->frame, | ||
304 | roc->frame->data, roc->frame->len, | ||
305 | false, GFP_KERNEL); | ||
306 | kfree_skb(roc->frame); | ||
251 | } | 307 | } |
252 | 308 | ||
253 | if (!local->hw_roc_for_tx) | 309 | if (!roc->mgmt_tx_cookie) |
254 | cfg80211_remain_on_channel_expired(local->hw_roc_dev, | 310 | cfg80211_remain_on_channel_expired(&roc->sdata->wdev, |
255 | local->hw_roc_cookie, | 311 | (unsigned long)roc, |
256 | local->hw_roc_channel, | 312 | roc->chan, roc->chan_type, |
257 | local->hw_roc_channel_type, | ||
258 | GFP_KERNEL); | 313 | GFP_KERNEL); |
259 | 314 | ||
260 | local->hw_roc_channel = NULL; | 315 | list_for_each_entry_safe(dep, tmp, &roc->dependents, list) |
261 | local->hw_roc_cookie = 0; | 316 | ieee80211_roc_notify_destroy(dep); |
317 | |||
318 | kfree(roc); | ||
319 | } | ||
320 | |||
321 | void ieee80211_sw_roc_work(struct work_struct *work) | ||
322 | { | ||
323 | struct ieee80211_roc_work *roc = | ||
324 | container_of(work, struct ieee80211_roc_work, work.work); | ||
325 | struct ieee80211_sub_if_data *sdata = roc->sdata; | ||
326 | struct ieee80211_local *local = sdata->local; | ||
327 | bool started; | ||
328 | |||
329 | mutex_lock(&local->mtx); | ||
330 | |||
331 | if (roc->abort) | ||
332 | goto finish; | ||
333 | |||
334 | if (WARN_ON(list_empty(&local->roc_list))) | ||
335 | goto out_unlock; | ||
336 | |||
337 | if (WARN_ON(roc != list_first_entry(&local->roc_list, | ||
338 | struct ieee80211_roc_work, | ||
339 | list))) | ||
340 | goto out_unlock; | ||
262 | 341 | ||
263 | ieee80211_recalc_idle(local); | 342 | if (!roc->started) { |
343 | struct ieee80211_roc_work *dep; | ||
264 | 344 | ||
345 | /* start this ROC */ | ||
346 | |||
347 | /* switch channel etc */ | ||
348 | ieee80211_recalc_idle(local); | ||
349 | |||
350 | local->tmp_channel = roc->chan; | ||
351 | local->tmp_channel_type = roc->chan_type; | ||
352 | ieee80211_hw_config(local, 0); | ||
353 | |||
354 | /* tell userspace or send frame */ | ||
355 | ieee80211_handle_roc_started(roc); | ||
356 | list_for_each_entry(dep, &roc->dependents, list) | ||
357 | ieee80211_handle_roc_started(dep); | ||
358 | |||
359 | /* if it was pure TX, just finish right away */ | ||
360 | if (!roc->duration) | ||
361 | goto finish; | ||
362 | |||
363 | roc->started = true; | ||
364 | ieee80211_queue_delayed_work(&local->hw, &roc->work, | ||
365 | msecs_to_jiffies(roc->duration)); | ||
366 | } else { | ||
367 | /* finish this ROC */ | ||
368 | finish: | ||
369 | list_del(&roc->list); | ||
370 | started = roc->started; | ||
371 | ieee80211_roc_notify_destroy(roc); | ||
372 | |||
373 | if (started) { | ||
374 | drv_flush(local, false); | ||
375 | |||
376 | local->tmp_channel = NULL; | ||
377 | ieee80211_hw_config(local, 0); | ||
378 | |||
379 | ieee80211_offchannel_return(local, true); | ||
380 | } | ||
381 | |||
382 | ieee80211_recalc_idle(local); | ||
383 | |||
384 | if (started) | ||
385 | ieee80211_start_next_roc(local); | ||
386 | } | ||
387 | |||
388 | out_unlock: | ||
389 | mutex_unlock(&local->mtx); | ||
390 | } | ||
391 | |||
392 | static void ieee80211_hw_roc_done(struct work_struct *work) | ||
393 | { | ||
394 | struct ieee80211_local *local = | ||
395 | container_of(work, struct ieee80211_local, hw_roc_done); | ||
396 | struct ieee80211_roc_work *roc; | ||
397 | |||
398 | mutex_lock(&local->mtx); | ||
399 | |||
400 | if (list_empty(&local->roc_list)) | ||
401 | goto out_unlock; | ||
402 | |||
403 | roc = list_first_entry(&local->roc_list, struct ieee80211_roc_work, | ||
404 | list); | ||
405 | |||
406 | if (!roc->started) | ||
407 | goto out_unlock; | ||
408 | |||
409 | list_del(&roc->list); | ||
410 | |||
411 | ieee80211_roc_notify_destroy(roc); | ||
412 | |||
413 | /* if there's another roc, start it now */ | ||
414 | ieee80211_start_next_roc(local); | ||
415 | |||
416 | out_unlock: | ||
265 | mutex_unlock(&local->mtx); | 417 | mutex_unlock(&local->mtx); |
266 | } | 418 | } |
267 | 419 | ||
@@ -275,8 +427,47 @@ void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw) | |||
275 | } | 427 | } |
276 | EXPORT_SYMBOL_GPL(ieee80211_remain_on_channel_expired); | 428 | EXPORT_SYMBOL_GPL(ieee80211_remain_on_channel_expired); |
277 | 429 | ||
278 | void ieee80211_hw_roc_setup(struct ieee80211_local *local) | 430 | void ieee80211_roc_setup(struct ieee80211_local *local) |
279 | { | 431 | { |
280 | INIT_WORK(&local->hw_roc_start, ieee80211_hw_roc_start); | 432 | INIT_WORK(&local->hw_roc_start, ieee80211_hw_roc_start); |
281 | INIT_WORK(&local->hw_roc_done, ieee80211_hw_roc_done); | 433 | INIT_WORK(&local->hw_roc_done, ieee80211_hw_roc_done); |
434 | INIT_LIST_HEAD(&local->roc_list); | ||
435 | } | ||
436 | |||
437 | void ieee80211_roc_purge(struct ieee80211_sub_if_data *sdata) | ||
438 | { | ||
439 | struct ieee80211_local *local = sdata->local; | ||
440 | struct ieee80211_roc_work *roc, *tmp; | ||
441 | LIST_HEAD(tmp_list); | ||
442 | |||
443 | mutex_lock(&local->mtx); | ||
444 | list_for_each_entry_safe(roc, tmp, &local->roc_list, list) { | ||
445 | if (roc->sdata != sdata) | ||
446 | continue; | ||
447 | |||
448 | if (roc->started && local->ops->remain_on_channel) { | ||
449 | /* can race, so ignore return value */ | ||
450 | drv_cancel_remain_on_channel(local); | ||
451 | } | ||
452 | |||
453 | list_move_tail(&roc->list, &tmp_list); | ||
454 | roc->abort = true; | ||
455 | } | ||
456 | |||
457 | ieee80211_start_next_roc(local); | ||
458 | mutex_unlock(&local->mtx); | ||
459 | |||
460 | list_for_each_entry_safe(roc, tmp, &tmp_list, list) { | ||
461 | if (local->ops->remain_on_channel) { | ||
462 | list_del(&roc->list); | ||
463 | ieee80211_roc_notify_destroy(roc); | ||
464 | } else { | ||
465 | ieee80211_queue_delayed_work(&local->hw, &roc->work, 0); | ||
466 | |||
467 | /* work will clean up etc */ | ||
468 | flush_delayed_work(&roc->work); | ||
469 | } | ||
470 | } | ||
471 | |||
472 | WARN_ON_ONCE(!list_empty(&tmp_list)); | ||
282 | } | 473 | } |
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index af1c4e26e965..5c572e7a1a71 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c | |||
@@ -77,6 +77,17 @@ int __ieee80211_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) | |||
77 | int err = drv_suspend(local, wowlan); | 77 | int err = drv_suspend(local, wowlan); |
78 | if (err < 0) { | 78 | if (err < 0) { |
79 | local->quiescing = false; | 79 | local->quiescing = false; |
80 | local->wowlan = false; | ||
81 | if (hw->flags & IEEE80211_HW_AMPDU_AGGREGATION) { | ||
82 | mutex_lock(&local->sta_mtx); | ||
83 | list_for_each_entry(sta, | ||
84 | &local->sta_list, list) { | ||
85 | clear_sta_flag(sta, WLAN_STA_BLOCK_BA); | ||
86 | } | ||
87 | mutex_unlock(&local->sta_mtx); | ||
88 | } | ||
89 | ieee80211_wake_queues_by_reason(hw, | ||
90 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | ||
80 | return err; | 91 | return err; |
81 | } else if (err > 0) { | 92 | } else if (err > 0) { |
82 | WARN_ON(err != 1); | 93 | WARN_ON(err != 1); |
diff --git a/net/mac80211/rc80211_minstrel_ht.c b/net/mac80211/rc80211_minstrel_ht.c index f9e51ef8dfa2..fb1d4aa65e8c 100644 --- a/net/mac80211/rc80211_minstrel_ht.c +++ b/net/mac80211/rc80211_minstrel_ht.c | |||
@@ -626,8 +626,12 @@ minstrel_ht_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta, | |||
626 | 626 | ||
627 | #ifdef CONFIG_MAC80211_DEBUGFS | 627 | #ifdef CONFIG_MAC80211_DEBUGFS |
628 | /* use fixed index if set */ | 628 | /* use fixed index if set */ |
629 | if (mp->fixed_rate_idx != -1) | 629 | if (mp->fixed_rate_idx != -1) { |
630 | sample_idx = mp->fixed_rate_idx; | 630 | mi->max_tp_rate = mp->fixed_rate_idx; |
631 | mi->max_tp_rate2 = mp->fixed_rate_idx; | ||
632 | mi->max_prob_rate = mp->fixed_rate_idx; | ||
633 | sample_idx = -1; | ||
634 | } | ||
631 | #endif | 635 | #endif |
632 | 636 | ||
633 | if (sample_idx >= 0) { | 637 | if (sample_idx >= 0) { |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 965e6ec0adb6..0cb4edee6af5 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -94,7 +94,7 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local, | |||
94 | return len; | 94 | return len; |
95 | } | 95 | } |
96 | 96 | ||
97 | /* | 97 | /** |
98 | * ieee80211_add_rx_radiotap_header - add radiotap header | 98 | * ieee80211_add_rx_radiotap_header - add radiotap header |
99 | * | 99 | * |
100 | * add a radiotap header containing all the fields which the hardware provided. | 100 | * add a radiotap header containing all the fields which the hardware provided. |
@@ -413,29 +413,6 @@ static void ieee80211_verify_alignment(struct ieee80211_rx_data *rx) | |||
413 | 413 | ||
414 | /* rx handlers */ | 414 | /* rx handlers */ |
415 | 415 | ||
416 | static ieee80211_rx_result debug_noinline | ||
417 | ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx) | ||
418 | { | ||
419 | struct ieee80211_local *local = rx->local; | ||
420 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb); | ||
421 | struct sk_buff *skb = rx->skb; | ||
422 | |||
423 | if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | ||
424 | !local->sched_scanning)) | ||
425 | return RX_CONTINUE; | ||
426 | |||
427 | if (test_bit(SCAN_HW_SCANNING, &local->scanning) || | ||
428 | test_bit(SCAN_SW_SCANNING, &local->scanning) || | ||
429 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || | ||
430 | local->sched_scanning) | ||
431 | return ieee80211_scan_rx(rx->sdata, skb); | ||
432 | |||
433 | /* scanning finished during invoking of handlers */ | ||
434 | I802_DEBUG_INC(local->rx_handlers_drop_passive_scan); | ||
435 | return RX_DROP_UNUSABLE; | ||
436 | } | ||
437 | |||
438 | |||
439 | static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) | 416 | static int ieee80211_is_unicast_robust_mgmt_frame(struct sk_buff *skb) |
440 | { | 417 | { |
441 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 418 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
@@ -554,11 +531,11 @@ static inline u16 seq_sub(u16 sq1, u16 sq2) | |||
554 | } | 531 | } |
555 | 532 | ||
556 | 533 | ||
557 | static void ieee80211_release_reorder_frame(struct ieee80211_hw *hw, | 534 | static void ieee80211_release_reorder_frame(struct ieee80211_sub_if_data *sdata, |
558 | struct tid_ampdu_rx *tid_agg_rx, | 535 | struct tid_ampdu_rx *tid_agg_rx, |
559 | int index) | 536 | int index) |
560 | { | 537 | { |
561 | struct ieee80211_local *local = hw_to_local(hw); | 538 | struct ieee80211_local *local = sdata->local; |
562 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; | 539 | struct sk_buff *skb = tid_agg_rx->reorder_buf[index]; |
563 | struct ieee80211_rx_status *status; | 540 | struct ieee80211_rx_status *status; |
564 | 541 | ||
@@ -578,7 +555,7 @@ no_frame: | |||
578 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); | 555 | tid_agg_rx->head_seq_num = seq_inc(tid_agg_rx->head_seq_num); |
579 | } | 556 | } |
580 | 557 | ||
581 | static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | 558 | static void ieee80211_release_reorder_frames(struct ieee80211_sub_if_data *sdata, |
582 | struct tid_ampdu_rx *tid_agg_rx, | 559 | struct tid_ampdu_rx *tid_agg_rx, |
583 | u16 head_seq_num) | 560 | u16 head_seq_num) |
584 | { | 561 | { |
@@ -589,7 +566,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | |||
589 | while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { | 566 | while (seq_less(tid_agg_rx->head_seq_num, head_seq_num)) { |
590 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | 567 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
591 | tid_agg_rx->buf_size; | 568 | tid_agg_rx->buf_size; |
592 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); | 569 | ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); |
593 | } | 570 | } |
594 | } | 571 | } |
595 | 572 | ||
@@ -604,7 +581,7 @@ static void ieee80211_release_reorder_frames(struct ieee80211_hw *hw, | |||
604 | */ | 581 | */ |
605 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) | 582 | #define HT_RX_REORDER_BUF_TIMEOUT (HZ / 10) |
606 | 583 | ||
607 | static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | 584 | static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, |
608 | struct tid_ampdu_rx *tid_agg_rx) | 585 | struct tid_ampdu_rx *tid_agg_rx) |
609 | { | 586 | { |
610 | int index, j; | 587 | int index, j; |
@@ -632,12 +609,9 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | |||
632 | HT_RX_REORDER_BUF_TIMEOUT)) | 609 | HT_RX_REORDER_BUF_TIMEOUT)) |
633 | goto set_release_timer; | 610 | goto set_release_timer; |
634 | 611 | ||
635 | #ifdef CONFIG_MAC80211_HT_DEBUG | 612 | ht_dbg_ratelimited(sdata, |
636 | if (net_ratelimit()) | 613 | "release an RX reorder frame due to timeout on earlier frames\n"); |
637 | wiphy_debug(hw->wiphy, | 614 | ieee80211_release_reorder_frame(sdata, tid_agg_rx, j); |
638 | "release an RX reorder frame due to timeout on earlier frames\n"); | ||
639 | #endif | ||
640 | ieee80211_release_reorder_frame(hw, tid_agg_rx, j); | ||
641 | 615 | ||
642 | /* | 616 | /* |
643 | * Increment the head seq# also for the skipped slots. | 617 | * Increment the head seq# also for the skipped slots. |
@@ -647,7 +621,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | |||
647 | skipped = 0; | 621 | skipped = 0; |
648 | } | 622 | } |
649 | } else while (tid_agg_rx->reorder_buf[index]) { | 623 | } else while (tid_agg_rx->reorder_buf[index]) { |
650 | ieee80211_release_reorder_frame(hw, tid_agg_rx, index); | 624 | ieee80211_release_reorder_frame(sdata, tid_agg_rx, index); |
651 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % | 625 | index = seq_sub(tid_agg_rx->head_seq_num, tid_agg_rx->ssn) % |
652 | tid_agg_rx->buf_size; | 626 | tid_agg_rx->buf_size; |
653 | } | 627 | } |
@@ -677,7 +651,7 @@ static void ieee80211_sta_reorder_release(struct ieee80211_hw *hw, | |||
677 | * rcu_read_lock protection. It returns false if the frame | 651 | * rcu_read_lock protection. It returns false if the frame |
678 | * can be processed immediately, true if it was consumed. | 652 | * can be processed immediately, true if it was consumed. |
679 | */ | 653 | */ |
680 | static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | 654 | static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_sub_if_data *sdata, |
681 | struct tid_ampdu_rx *tid_agg_rx, | 655 | struct tid_ampdu_rx *tid_agg_rx, |
682 | struct sk_buff *skb) | 656 | struct sk_buff *skb) |
683 | { | 657 | { |
@@ -706,7 +680,8 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
706 | if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { | 680 | if (!seq_less(mpdu_seq_num, head_seq_num + buf_size)) { |
707 | head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); | 681 | head_seq_num = seq_inc(seq_sub(mpdu_seq_num, buf_size)); |
708 | /* release stored frames up to new head to stack */ | 682 | /* release stored frames up to new head to stack */ |
709 | ieee80211_release_reorder_frames(hw, tid_agg_rx, head_seq_num); | 683 | ieee80211_release_reorder_frames(sdata, tid_agg_rx, |
684 | head_seq_num); | ||
710 | } | 685 | } |
711 | 686 | ||
712 | /* Now the new frame is always in the range of the reordering buffer */ | 687 | /* Now the new frame is always in the range of the reordering buffer */ |
@@ -736,7 +711,7 @@ static bool ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
736 | tid_agg_rx->reorder_buf[index] = skb; | 711 | tid_agg_rx->reorder_buf[index] = skb; |
737 | tid_agg_rx->reorder_time[index] = jiffies; | 712 | tid_agg_rx->reorder_time[index] = jiffies; |
738 | tid_agg_rx->stored_mpdu_num++; | 713 | tid_agg_rx->stored_mpdu_num++; |
739 | ieee80211_sta_reorder_release(hw, tid_agg_rx); | 714 | ieee80211_sta_reorder_release(sdata, tid_agg_rx); |
740 | 715 | ||
741 | out: | 716 | out: |
742 | spin_unlock(&tid_agg_rx->reorder_lock); | 717 | spin_unlock(&tid_agg_rx->reorder_lock); |
@@ -751,7 +726,6 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
751 | { | 726 | { |
752 | struct sk_buff *skb = rx->skb; | 727 | struct sk_buff *skb = rx->skb; |
753 | struct ieee80211_local *local = rx->local; | 728 | struct ieee80211_local *local = rx->local; |
754 | struct ieee80211_hw *hw = &local->hw; | ||
755 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | 729 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; |
756 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 730 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
757 | struct sta_info *sta = rx->sta; | 731 | struct sta_info *sta = rx->sta; |
@@ -813,7 +787,7 @@ static void ieee80211_rx_reorder_ampdu(struct ieee80211_rx_data *rx) | |||
813 | * sure that we cannot get to it any more before doing | 787 | * sure that we cannot get to it any more before doing |
814 | * anything with it. | 788 | * anything with it. |
815 | */ | 789 | */ |
816 | if (ieee80211_sta_manage_reorder_buf(hw, tid_agg_rx, skb)) | 790 | if (ieee80211_sta_manage_reorder_buf(rx->sdata, tid_agg_rx, skb)) |
817 | return; | 791 | return; |
818 | 792 | ||
819 | dont_reorder: | 793 | dont_reorder: |
@@ -1136,24 +1110,18 @@ static void ap_sta_ps_start(struct sta_info *sta) | |||
1136 | set_sta_flag(sta, WLAN_STA_PS_STA); | 1110 | set_sta_flag(sta, WLAN_STA_PS_STA); |
1137 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) | 1111 | if (!(local->hw.flags & IEEE80211_HW_AP_LINK_PS)) |
1138 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); | 1112 | drv_sta_notify(local, sdata, STA_NOTIFY_SLEEP, &sta->sta); |
1139 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1113 | ps_dbg(sdata, "STA %pM aid %d enters power save mode\n", |
1140 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", | 1114 | sta->sta.addr, sta->sta.aid); |
1141 | sdata->name, sta->sta.addr, sta->sta.aid); | ||
1142 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1143 | } | 1115 | } |
1144 | 1116 | ||
1145 | static void ap_sta_ps_end(struct sta_info *sta) | 1117 | static void ap_sta_ps_end(struct sta_info *sta) |
1146 | { | 1118 | { |
1147 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1119 | ps_dbg(sta->sdata, "STA %pM aid %d exits power save mode\n", |
1148 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", | 1120 | sta->sta.addr, sta->sta.aid); |
1149 | sta->sdata->name, sta->sta.addr, sta->sta.aid); | ||
1150 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1151 | 1121 | ||
1152 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | 1122 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
1153 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 1123 | ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", |
1154 | printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", | 1124 | sta->sta.addr, sta->sta.aid); |
1155 | sta->sdata->name, sta->sta.addr, sta->sta.aid); | ||
1156 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1157 | return; | 1125 | return; |
1158 | } | 1126 | } |
1159 | 1127 | ||
@@ -1383,19 +1351,8 @@ ieee80211_reassemble_add(struct ieee80211_sub_if_data *sdata, | |||
1383 | if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) | 1351 | if (sdata->fragment_next >= IEEE80211_FRAGMENT_MAX) |
1384 | sdata->fragment_next = 0; | 1352 | sdata->fragment_next = 0; |
1385 | 1353 | ||
1386 | if (!skb_queue_empty(&entry->skb_list)) { | 1354 | if (!skb_queue_empty(&entry->skb_list)) |
1387 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
1388 | struct ieee80211_hdr *hdr = | ||
1389 | (struct ieee80211_hdr *) entry->skb_list.next->data; | ||
1390 | printk(KERN_DEBUG "%s: RX reassembly removed oldest " | ||
1391 | "fragment entry (idx=%d age=%lu seq=%d last_frag=%d " | ||
1392 | "addr1=%pM addr2=%pM\n", | ||
1393 | sdata->name, idx, | ||
1394 | jiffies - entry->first_frag_time, entry->seq, | ||
1395 | entry->last_frag, hdr->addr1, hdr->addr2); | ||
1396 | #endif | ||
1397 | __skb_queue_purge(&entry->skb_list); | 1355 | __skb_queue_purge(&entry->skb_list); |
1398 | } | ||
1399 | 1356 | ||
1400 | __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ | 1357 | __skb_queue_tail(&entry->skb_list, *skb); /* no need for locking */ |
1401 | *skb = NULL; | 1358 | *skb = NULL; |
@@ -1753,7 +1710,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1753 | */ | 1710 | */ |
1754 | xmit_skb = skb_copy(skb, GFP_ATOMIC); | 1711 | xmit_skb = skb_copy(skb, GFP_ATOMIC); |
1755 | if (!xmit_skb) | 1712 | if (!xmit_skb) |
1756 | net_dbg_ratelimited("%s: failed to clone multicast frame\n", | 1713 | net_info_ratelimited("%s: failed to clone multicast frame\n", |
1757 | dev->name); | 1714 | dev->name); |
1758 | } else { | 1715 | } else { |
1759 | dsta = sta_info_get(sdata, skb->data); | 1716 | dsta = sta_info_get(sdata, skb->data); |
@@ -1937,7 +1894,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1937 | ether_addr_equal(sdata->vif.addr, hdr->addr3)) | 1894 | ether_addr_equal(sdata->vif.addr, hdr->addr3)) |
1938 | return RX_CONTINUE; | 1895 | return RX_CONTINUE; |
1939 | 1896 | ||
1940 | q = ieee80211_select_queue_80211(local, skb, hdr); | 1897 | q = ieee80211_select_queue_80211(sdata, skb, hdr); |
1941 | if (ieee80211_queue_stopped(&local->hw, q)) { | 1898 | if (ieee80211_queue_stopped(&local->hw, q)) { |
1942 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); | 1899 | IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, dropped_frames_congestion); |
1943 | return RX_DROP_MONITOR; | 1900 | return RX_DROP_MONITOR; |
@@ -1957,7 +1914,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
1957 | 1914 | ||
1958 | fwd_skb = skb_copy(skb, GFP_ATOMIC); | 1915 | fwd_skb = skb_copy(skb, GFP_ATOMIC); |
1959 | if (!fwd_skb) { | 1916 | if (!fwd_skb) { |
1960 | net_dbg_ratelimited("%s: failed to clone mesh frame\n", | 1917 | net_info_ratelimited("%s: failed to clone mesh frame\n", |
1961 | sdata->name); | 1918 | sdata->name); |
1962 | goto out; | 1919 | goto out; |
1963 | } | 1920 | } |
@@ -2060,8 +2017,6 @@ ieee80211_rx_h_data(struct ieee80211_rx_data *rx) | |||
2060 | static ieee80211_rx_result debug_noinline | 2017 | static ieee80211_rx_result debug_noinline |
2061 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | 2018 | ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) |
2062 | { | 2019 | { |
2063 | struct ieee80211_local *local = rx->local; | ||
2064 | struct ieee80211_hw *hw = &local->hw; | ||
2065 | struct sk_buff *skb = rx->skb; | 2020 | struct sk_buff *skb = rx->skb; |
2066 | struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; | 2021 | struct ieee80211_bar *bar = (struct ieee80211_bar *)skb->data; |
2067 | struct tid_ampdu_rx *tid_agg_rx; | 2022 | struct tid_ampdu_rx *tid_agg_rx; |
@@ -2098,7 +2053,8 @@ ieee80211_rx_h_ctrl(struct ieee80211_rx_data *rx) | |||
2098 | 2053 | ||
2099 | spin_lock(&tid_agg_rx->reorder_lock); | 2054 | spin_lock(&tid_agg_rx->reorder_lock); |
2100 | /* release stored frames up to start of BAR */ | 2055 | /* release stored frames up to start of BAR */ |
2101 | ieee80211_release_reorder_frames(hw, tid_agg_rx, start_seq_num); | 2056 | ieee80211_release_reorder_frames(rx->sdata, tid_agg_rx, |
2057 | start_seq_num); | ||
2102 | spin_unlock(&tid_agg_rx->reorder_lock); | 2058 | spin_unlock(&tid_agg_rx->reorder_lock); |
2103 | 2059 | ||
2104 | kfree_skb(skb); | 2060 | kfree_skb(skb); |
@@ -2425,7 +2381,7 @@ ieee80211_rx_h_userspace_mgmt(struct ieee80211_rx_data *rx) | |||
2425 | if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) | 2381 | if (rx->local->hw.flags & IEEE80211_HW_SIGNAL_DBM) |
2426 | sig = status->signal; | 2382 | sig = status->signal; |
2427 | 2383 | ||
2428 | if (cfg80211_rx_mgmt(rx->sdata->dev, status->freq, sig, | 2384 | if (cfg80211_rx_mgmt(&rx->sdata->wdev, status->freq, sig, |
2429 | rx->skb->data, rx->skb->len, | 2385 | rx->skb->data, rx->skb->len, |
2430 | GFP_ATOMIC)) { | 2386 | GFP_ATOMIC)) { |
2431 | if (rx->sta) | 2387 | if (rx->sta) |
@@ -2716,7 +2672,6 @@ static void ieee80211_invoke_rx_handlers(struct ieee80211_rx_data *rx) | |||
2716 | goto rxh_next; \ | 2672 | goto rxh_next; \ |
2717 | } while (0); | 2673 | } while (0); |
2718 | 2674 | ||
2719 | CALL_RXH(ieee80211_rx_h_passive_scan) | ||
2720 | CALL_RXH(ieee80211_rx_h_check) | 2675 | CALL_RXH(ieee80211_rx_h_check) |
2721 | 2676 | ||
2722 | ieee80211_rx_reorder_ampdu(rx); | 2677 | ieee80211_rx_reorder_ampdu(rx); |
@@ -2752,7 +2707,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid) | |||
2752 | return; | 2707 | return; |
2753 | 2708 | ||
2754 | spin_lock(&tid_agg_rx->reorder_lock); | 2709 | spin_lock(&tid_agg_rx->reorder_lock); |
2755 | ieee80211_sta_reorder_release(&sta->local->hw, tid_agg_rx); | 2710 | ieee80211_sta_reorder_release(sta->sdata, tid_agg_rx); |
2756 | spin_unlock(&tid_agg_rx->reorder_lock); | 2711 | spin_unlock(&tid_agg_rx->reorder_lock); |
2757 | 2712 | ||
2758 | ieee80211_rx_handlers(&rx); | 2713 | ieee80211_rx_handlers(&rx); |
@@ -2786,11 +2741,8 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2786 | return 0; | 2741 | return 0; |
2787 | if (ieee80211_is_beacon(hdr->frame_control)) { | 2742 | if (ieee80211_is_beacon(hdr->frame_control)) { |
2788 | return 1; | 2743 | return 1; |
2789 | } | 2744 | } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { |
2790 | else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) { | 2745 | return 0; |
2791 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN)) | ||
2792 | return 0; | ||
2793 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | ||
2794 | } else if (!multicast && | 2746 | } else if (!multicast && |
2795 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { | 2747 | !ether_addr_equal(sdata->vif.addr, hdr->addr1)) { |
2796 | if (!(sdata->dev->flags & IFF_PROMISC)) | 2748 | if (!(sdata->dev->flags & IFF_PROMISC)) |
@@ -2828,11 +2780,9 @@ static int prepare_for_handlers(struct ieee80211_rx_data *rx, | |||
2828 | * and location updates. Note that mac80211 | 2780 | * and location updates. Note that mac80211 |
2829 | * itself never looks at these frames. | 2781 | * itself never looks at these frames. |
2830 | */ | 2782 | */ |
2831 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | 2783 | if (ieee80211_is_public_action(hdr, skb->len)) |
2832 | ieee80211_is_public_action(hdr, skb->len)) | ||
2833 | return 1; | 2784 | return 1; |
2834 | if (!(status->rx_flags & IEEE80211_RX_IN_SCAN) && | 2785 | if (!ieee80211_is_beacon(hdr->frame_control)) |
2835 | !ieee80211_is_beacon(hdr->frame_control)) | ||
2836 | return 0; | 2786 | return 0; |
2837 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; | 2787 | status->rx_flags &= ~IEEE80211_RX_RA_MATCH; |
2838 | } | 2788 | } |
@@ -2898,7 +2848,6 @@ static bool ieee80211_prepare_and_rx_handle(struct ieee80211_rx_data *rx, | |||
2898 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | 2848 | static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, |
2899 | struct sk_buff *skb) | 2849 | struct sk_buff *skb) |
2900 | { | 2850 | { |
2901 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | ||
2902 | struct ieee80211_local *local = hw_to_local(hw); | 2851 | struct ieee80211_local *local = hw_to_local(hw); |
2903 | struct ieee80211_sub_if_data *sdata; | 2852 | struct ieee80211_sub_if_data *sdata; |
2904 | struct ieee80211_hdr *hdr; | 2853 | struct ieee80211_hdr *hdr; |
@@ -2916,11 +2865,6 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2916 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) | 2865 | if (ieee80211_is_data(fc) || ieee80211_is_mgmt(fc)) |
2917 | local->dot11ReceivedFragmentCount++; | 2866 | local->dot11ReceivedFragmentCount++; |
2918 | 2867 | ||
2919 | if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) || | ||
2920 | test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning) || | ||
2921 | test_bit(SCAN_SW_SCANNING, &local->scanning))) | ||
2922 | status->rx_flags |= IEEE80211_RX_IN_SCAN; | ||
2923 | |||
2924 | if (ieee80211_is_mgmt(fc)) | 2868 | if (ieee80211_is_mgmt(fc)) |
2925 | err = skb_linearize(skb); | 2869 | err = skb_linearize(skb); |
2926 | else | 2870 | else |
@@ -2935,6 +2879,10 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw, | |||
2935 | ieee80211_parse_qos(&rx); | 2879 | ieee80211_parse_qos(&rx); |
2936 | ieee80211_verify_alignment(&rx); | 2880 | ieee80211_verify_alignment(&rx); |
2937 | 2881 | ||
2882 | if (unlikely(ieee80211_is_probe_resp(hdr->frame_control) || | ||
2883 | ieee80211_is_beacon(hdr->frame_control))) | ||
2884 | ieee80211_scan_rx(local, skb); | ||
2885 | |||
2938 | if (ieee80211_is_data(fc)) { | 2886 | if (ieee80211_is_data(fc)) { |
2939 | prev_sta = NULL; | 2887 | prev_sta = NULL; |
2940 | 2888 | ||
@@ -3032,6 +2980,10 @@ void ieee80211_rx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3032 | if (unlikely(local->quiescing || local->suspended)) | 2980 | if (unlikely(local->quiescing || local->suspended)) |
3033 | goto drop; | 2981 | goto drop; |
3034 | 2982 | ||
2983 | /* We might be during a HW reconfig, prevent Rx for the same reason */ | ||
2984 | if (unlikely(local->in_reconfig)) | ||
2985 | goto drop; | ||
2986 | |||
3035 | /* | 2987 | /* |
3036 | * The same happens when we're not even started, | 2988 | * The same happens when we're not even started, |
3037 | * but that's worth a warning. | 2989 | * but that's worth a warning. |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 7644181cb6b4..df36280ed78f 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -83,13 +83,14 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
83 | 83 | ||
84 | cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel, | 84 | cbss = cfg80211_inform_bss_frame(local->hw.wiphy, channel, |
85 | mgmt, len, signal, GFP_ATOMIC); | 85 | mgmt, len, signal, GFP_ATOMIC); |
86 | |||
87 | if (!cbss) | 86 | if (!cbss) |
88 | return NULL; | 87 | return NULL; |
89 | 88 | ||
90 | cbss->free_priv = ieee80211_rx_bss_free; | 89 | cbss->free_priv = ieee80211_rx_bss_free; |
91 | bss = (void *)cbss->priv; | 90 | bss = (void *)cbss->priv; |
92 | 91 | ||
92 | bss->device_ts = rx_status->device_timestamp; | ||
93 | |||
93 | if (elems->parse_error) { | 94 | if (elems->parse_error) { |
94 | if (beacon) | 95 | if (beacon) |
95 | bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON; | 96 | bss->corrupt_data |= IEEE80211_BSS_CORRUPT_BEACON; |
@@ -114,8 +115,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
114 | 115 | ||
115 | if (elems->tim && (!elems->parse_error || | 116 | if (elems->tim && (!elems->parse_error || |
116 | !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) { | 117 | !(bss->valid_data & IEEE80211_BSS_VALID_DTIM))) { |
117 | struct ieee80211_tim_ie *tim_ie = | 118 | struct ieee80211_tim_ie *tim_ie = elems->tim; |
118 | (struct ieee80211_tim_ie *)elems->tim; | ||
119 | bss->dtim_period = tim_ie->dtim_period; | 119 | bss->dtim_period = tim_ie->dtim_period; |
120 | if (!elems->parse_error) | 120 | if (!elems->parse_error) |
121 | bss->valid_data |= IEEE80211_BSS_VALID_DTIM; | 121 | bss->valid_data |= IEEE80211_BSS_VALID_DTIM; |
@@ -165,52 +165,47 @@ ieee80211_bss_info_update(struct ieee80211_local *local, | |||
165 | return bss; | 165 | return bss; |
166 | } | 166 | } |
167 | 167 | ||
168 | ieee80211_rx_result | 168 | void ieee80211_scan_rx(struct ieee80211_local *local, struct sk_buff *skb) |
169 | ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | ||
170 | { | 169 | { |
171 | struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); | 170 | struct ieee80211_rx_status *rx_status = IEEE80211_SKB_RXCB(skb); |
172 | struct ieee80211_mgmt *mgmt; | 171 | struct ieee80211_sub_if_data *sdata1, *sdata2; |
172 | struct ieee80211_mgmt *mgmt = (void *)skb->data; | ||
173 | struct ieee80211_bss *bss; | 173 | struct ieee80211_bss *bss; |
174 | u8 *elements; | 174 | u8 *elements; |
175 | struct ieee80211_channel *channel; | 175 | struct ieee80211_channel *channel; |
176 | size_t baselen; | 176 | size_t baselen; |
177 | int freq; | 177 | int freq; |
178 | __le16 fc; | 178 | bool beacon; |
179 | bool presp, beacon = false; | ||
180 | struct ieee802_11_elems elems; | 179 | struct ieee802_11_elems elems; |
181 | 180 | ||
182 | if (skb->len < 2) | 181 | if (skb->len < 24 || |
183 | return RX_DROP_UNUSABLE; | 182 | (!ieee80211_is_probe_resp(mgmt->frame_control) && |
184 | 183 | !ieee80211_is_beacon(mgmt->frame_control))) | |
185 | mgmt = (struct ieee80211_mgmt *) skb->data; | 184 | return; |
186 | fc = mgmt->frame_control; | ||
187 | 185 | ||
188 | if (ieee80211_is_ctl(fc)) | 186 | sdata1 = rcu_dereference(local->scan_sdata); |
189 | return RX_CONTINUE; | 187 | sdata2 = rcu_dereference(local->sched_scan_sdata); |
190 | 188 | ||
191 | if (skb->len < 24) | 189 | if (likely(!sdata1 && !sdata2)) |
192 | return RX_CONTINUE; | 190 | return; |
193 | 191 | ||
194 | presp = ieee80211_is_probe_resp(fc); | 192 | if (ieee80211_is_probe_resp(mgmt->frame_control)) { |
195 | if (presp) { | ||
196 | /* ignore ProbeResp to foreign address */ | 193 | /* ignore ProbeResp to foreign address */ |
197 | if (!ether_addr_equal(mgmt->da, sdata->vif.addr)) | 194 | if ((!sdata1 || !ether_addr_equal(mgmt->da, sdata1->vif.addr)) && |
198 | return RX_DROP_MONITOR; | 195 | (!sdata2 || !ether_addr_equal(mgmt->da, sdata2->vif.addr))) |
196 | return; | ||
199 | 197 | ||
200 | presp = true; | ||
201 | elements = mgmt->u.probe_resp.variable; | 198 | elements = mgmt->u.probe_resp.variable; |
202 | baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); | 199 | baselen = offsetof(struct ieee80211_mgmt, u.probe_resp.variable); |
200 | beacon = false; | ||
203 | } else { | 201 | } else { |
204 | beacon = ieee80211_is_beacon(fc); | ||
205 | baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); | 202 | baselen = offsetof(struct ieee80211_mgmt, u.beacon.variable); |
206 | elements = mgmt->u.beacon.variable; | 203 | elements = mgmt->u.beacon.variable; |
204 | beacon = true; | ||
207 | } | 205 | } |
208 | 206 | ||
209 | if (!presp && !beacon) | ||
210 | return RX_CONTINUE; | ||
211 | |||
212 | if (baselen > skb->len) | 207 | if (baselen > skb->len) |
213 | return RX_DROP_MONITOR; | 208 | return; |
214 | 209 | ||
215 | ieee802_11_parse_elems(elements, skb->len - baselen, &elems); | 210 | ieee802_11_parse_elems(elements, skb->len - baselen, &elems); |
216 | 211 | ||
@@ -220,22 +215,16 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
220 | else | 215 | else |
221 | freq = rx_status->freq; | 216 | freq = rx_status->freq; |
222 | 217 | ||
223 | channel = ieee80211_get_channel(sdata->local->hw.wiphy, freq); | 218 | channel = ieee80211_get_channel(local->hw.wiphy, freq); |
224 | 219 | ||
225 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) | 220 | if (!channel || channel->flags & IEEE80211_CHAN_DISABLED) |
226 | return RX_DROP_MONITOR; | 221 | return; |
227 | 222 | ||
228 | bss = ieee80211_bss_info_update(sdata->local, rx_status, | 223 | bss = ieee80211_bss_info_update(local, rx_status, |
229 | mgmt, skb->len, &elems, | 224 | mgmt, skb->len, &elems, |
230 | channel, beacon); | 225 | channel, beacon); |
231 | if (bss) | 226 | if (bss) |
232 | ieee80211_rx_bss_put(sdata->local, bss); | 227 | ieee80211_rx_bss_put(local, bss); |
233 | |||
234 | if (channel == sdata->local->oper_channel) | ||
235 | return RX_CONTINUE; | ||
236 | |||
237 | dev_kfree_skb(skb); | ||
238 | return RX_QUEUED; | ||
239 | } | 228 | } |
240 | 229 | ||
241 | /* return false if no more work */ | 230 | /* return false if no more work */ |
@@ -293,7 +282,13 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
293 | return; | 282 | return; |
294 | 283 | ||
295 | if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { | 284 | if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { |
296 | int rc = drv_hw_scan(local, local->scan_sdata, local->hw_scan_req); | 285 | int rc; |
286 | |||
287 | rc = drv_hw_scan(local, | ||
288 | rcu_dereference_protected(local->scan_sdata, | ||
289 | lockdep_is_held(&local->mtx)), | ||
290 | local->hw_scan_req); | ||
291 | |||
297 | if (rc == 0) | 292 | if (rc == 0) |
298 | return; | 293 | return; |
299 | } | 294 | } |
@@ -323,7 +318,7 @@ static void __ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted, | |||
323 | ieee80211_mlme_notify_scan_completed(local); | 318 | ieee80211_mlme_notify_scan_completed(local); |
324 | ieee80211_ibss_notify_scan_completed(local); | 319 | ieee80211_ibss_notify_scan_completed(local); |
325 | ieee80211_mesh_notify_scan_completed(local); | 320 | ieee80211_mesh_notify_scan_completed(local); |
326 | ieee80211_queue_work(&local->hw, &local->work_work); | 321 | ieee80211_start_next_roc(local); |
327 | } | 322 | } |
328 | 323 | ||
329 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | 324 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) |
@@ -376,7 +371,7 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local) | |||
376 | static bool ieee80211_can_scan(struct ieee80211_local *local, | 371 | static bool ieee80211_can_scan(struct ieee80211_local *local, |
377 | struct ieee80211_sub_if_data *sdata) | 372 | struct ieee80211_sub_if_data *sdata) |
378 | { | 373 | { |
379 | if (!list_empty(&local->work_list)) | 374 | if (!list_empty(&local->roc_list)) |
380 | return false; | 375 | return false; |
381 | 376 | ||
382 | if (sdata->vif.type == NL80211_IFTYPE_STATION && | 377 | if (sdata->vif.type == NL80211_IFTYPE_STATION && |
@@ -394,7 +389,10 @@ void ieee80211_run_deferred_scan(struct ieee80211_local *local) | |||
394 | if (!local->scan_req || local->scanning) | 389 | if (!local->scan_req || local->scanning) |
395 | return; | 390 | return; |
396 | 391 | ||
397 | if (!ieee80211_can_scan(local, local->scan_sdata)) | 392 | if (!ieee80211_can_scan(local, |
393 | rcu_dereference_protected( | ||
394 | local->scan_sdata, | ||
395 | lockdep_is_held(&local->mtx)))) | ||
398 | return; | 396 | return; |
399 | 397 | ||
400 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, | 398 | ieee80211_queue_delayed_work(&local->hw, &local->scan_work, |
@@ -405,9 +403,12 @@ static void ieee80211_scan_state_send_probe(struct ieee80211_local *local, | |||
405 | unsigned long *next_delay) | 403 | unsigned long *next_delay) |
406 | { | 404 | { |
407 | int i; | 405 | int i; |
408 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | 406 | struct ieee80211_sub_if_data *sdata; |
409 | enum ieee80211_band band = local->hw.conf.channel->band; | 407 | enum ieee80211_band band = local->hw.conf.channel->band; |
410 | 408 | ||
409 | sdata = rcu_dereference_protected(local->scan_sdata, | ||
410 | lockdep_is_held(&local->mtx));; | ||
411 | |||
411 | for (i = 0; i < local->scan_req->n_ssids; i++) | 412 | for (i = 0; i < local->scan_req->n_ssids; i++) |
412 | ieee80211_send_probe_req( | 413 | ieee80211_send_probe_req( |
413 | sdata, NULL, | 414 | sdata, NULL, |
@@ -439,7 +440,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
439 | if (!ieee80211_can_scan(local, sdata)) { | 440 | if (!ieee80211_can_scan(local, sdata)) { |
440 | /* wait for the work to finish/time out */ | 441 | /* wait for the work to finish/time out */ |
441 | local->scan_req = req; | 442 | local->scan_req = req; |
442 | local->scan_sdata = sdata; | 443 | rcu_assign_pointer(local->scan_sdata, sdata); |
443 | return 0; | 444 | return 0; |
444 | } | 445 | } |
445 | 446 | ||
@@ -473,7 +474,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
473 | } | 474 | } |
474 | 475 | ||
475 | local->scan_req = req; | 476 | local->scan_req = req; |
476 | local->scan_sdata = sdata; | 477 | rcu_assign_pointer(local->scan_sdata, sdata); |
477 | 478 | ||
478 | if (local->ops->hw_scan) { | 479 | if (local->ops->hw_scan) { |
479 | __set_bit(SCAN_HW_SCANNING, &local->scanning); | 480 | __set_bit(SCAN_HW_SCANNING, &local->scanning); |
@@ -533,7 +534,7 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
533 | ieee80211_recalc_idle(local); | 534 | ieee80211_recalc_idle(local); |
534 | 535 | ||
535 | local->scan_req = NULL; | 536 | local->scan_req = NULL; |
536 | local->scan_sdata = NULL; | 537 | rcu_assign_pointer(local->scan_sdata, NULL); |
537 | } | 538 | } |
538 | 539 | ||
539 | return rc; | 540 | return rc; |
@@ -720,7 +721,8 @@ void ieee80211_scan_work(struct work_struct *work) | |||
720 | 721 | ||
721 | mutex_lock(&local->mtx); | 722 | mutex_lock(&local->mtx); |
722 | 723 | ||
723 | sdata = local->scan_sdata; | 724 | sdata = rcu_dereference_protected(local->scan_sdata, |
725 | lockdep_is_held(&local->mtx)); | ||
724 | 726 | ||
725 | /* When scanning on-channel, the first-callback means completed. */ | 727 | /* When scanning on-channel, the first-callback means completed. */ |
726 | if (test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) { | 728 | if (test_bit(SCAN_ONCHANNEL_SCANNING, &local->scanning)) { |
@@ -741,7 +743,7 @@ void ieee80211_scan_work(struct work_struct *work) | |||
741 | int rc; | 743 | int rc; |
742 | 744 | ||
743 | local->scan_req = NULL; | 745 | local->scan_req = NULL; |
744 | local->scan_sdata = NULL; | 746 | rcu_assign_pointer(local->scan_sdata, NULL); |
745 | 747 | ||
746 | rc = __ieee80211_start_scan(sdata, req); | 748 | rc = __ieee80211_start_scan(sdata, req); |
747 | if (rc) { | 749 | if (rc) { |
@@ -893,7 +895,9 @@ void ieee80211_scan_cancel(struct ieee80211_local *local) | |||
893 | 895 | ||
894 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { | 896 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) { |
895 | if (local->ops->cancel_hw_scan) | 897 | if (local->ops->cancel_hw_scan) |
896 | drv_cancel_hw_scan(local, local->scan_sdata); | 898 | drv_cancel_hw_scan(local, |
899 | rcu_dereference_protected(local->scan_sdata, | ||
900 | lockdep_is_held(&local->mtx))); | ||
897 | goto out; | 901 | goto out; |
898 | } | 902 | } |
899 | 903 | ||
@@ -915,9 +919,9 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
915 | struct ieee80211_local *local = sdata->local; | 919 | struct ieee80211_local *local = sdata->local; |
916 | int ret, i; | 920 | int ret, i; |
917 | 921 | ||
918 | mutex_lock(&sdata->local->mtx); | 922 | mutex_lock(&local->mtx); |
919 | 923 | ||
920 | if (local->sched_scanning) { | 924 | if (rcu_access_pointer(local->sched_scan_sdata)) { |
921 | ret = -EBUSY; | 925 | ret = -EBUSY; |
922 | goto out; | 926 | goto out; |
923 | } | 927 | } |
@@ -928,6 +932,9 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
928 | } | 932 | } |
929 | 933 | ||
930 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { | 934 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) { |
935 | if (!local->hw.wiphy->bands[i]) | ||
936 | continue; | ||
937 | |||
931 | local->sched_scan_ies.ie[i] = kzalloc(2 + | 938 | local->sched_scan_ies.ie[i] = kzalloc(2 + |
932 | IEEE80211_MAX_SSID_LEN + | 939 | IEEE80211_MAX_SSID_LEN + |
933 | local->scan_ies_len + | 940 | local->scan_ies_len + |
@@ -948,7 +955,7 @@ int ieee80211_request_sched_scan_start(struct ieee80211_sub_if_data *sdata, | |||
948 | ret = drv_sched_scan_start(local, sdata, req, | 955 | ret = drv_sched_scan_start(local, sdata, req, |
949 | &local->sched_scan_ies); | 956 | &local->sched_scan_ies); |
950 | if (ret == 0) { | 957 | if (ret == 0) { |
951 | local->sched_scanning = true; | 958 | rcu_assign_pointer(local->sched_scan_sdata, sdata); |
952 | goto out; | 959 | goto out; |
953 | } | 960 | } |
954 | 961 | ||
@@ -956,7 +963,7 @@ out_free: | |||
956 | while (i > 0) | 963 | while (i > 0) |
957 | kfree(local->sched_scan_ies.ie[--i]); | 964 | kfree(local->sched_scan_ies.ie[--i]); |
958 | out: | 965 | out: |
959 | mutex_unlock(&sdata->local->mtx); | 966 | mutex_unlock(&local->mtx); |
960 | return ret; | 967 | return ret; |
961 | } | 968 | } |
962 | 969 | ||
@@ -965,22 +972,22 @@ int ieee80211_request_sched_scan_stop(struct ieee80211_sub_if_data *sdata) | |||
965 | struct ieee80211_local *local = sdata->local; | 972 | struct ieee80211_local *local = sdata->local; |
966 | int ret = 0, i; | 973 | int ret = 0, i; |
967 | 974 | ||
968 | mutex_lock(&sdata->local->mtx); | 975 | mutex_lock(&local->mtx); |
969 | 976 | ||
970 | if (!local->ops->sched_scan_stop) { | 977 | if (!local->ops->sched_scan_stop) { |
971 | ret = -ENOTSUPP; | 978 | ret = -ENOTSUPP; |
972 | goto out; | 979 | goto out; |
973 | } | 980 | } |
974 | 981 | ||
975 | if (local->sched_scanning) { | 982 | if (rcu_access_pointer(local->sched_scan_sdata)) { |
976 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | 983 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) |
977 | kfree(local->sched_scan_ies.ie[i]); | 984 | kfree(local->sched_scan_ies.ie[i]); |
978 | 985 | ||
979 | drv_sched_scan_stop(local, sdata); | 986 | drv_sched_scan_stop(local, sdata); |
980 | local->sched_scanning = false; | 987 | rcu_assign_pointer(local->sched_scan_sdata, NULL); |
981 | } | 988 | } |
982 | out: | 989 | out: |
983 | mutex_unlock(&sdata->local->mtx); | 990 | mutex_unlock(&local->mtx); |
984 | 991 | ||
985 | return ret; | 992 | return ret; |
986 | } | 993 | } |
@@ -1004,7 +1011,7 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work) | |||
1004 | 1011 | ||
1005 | mutex_lock(&local->mtx); | 1012 | mutex_lock(&local->mtx); |
1006 | 1013 | ||
1007 | if (!local->sched_scanning) { | 1014 | if (!rcu_access_pointer(local->sched_scan_sdata)) { |
1008 | mutex_unlock(&local->mtx); | 1015 | mutex_unlock(&local->mtx); |
1009 | return; | 1016 | return; |
1010 | } | 1017 | } |
@@ -1012,7 +1019,7 @@ void ieee80211_sched_scan_stopped_work(struct work_struct *work) | |||
1012 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) | 1019 | for (i = 0; i < IEEE80211_NUM_BANDS; i++) |
1013 | kfree(local->sched_scan_ies.ie[i]); | 1020 | kfree(local->sched_scan_ies.ie[i]); |
1014 | 1021 | ||
1015 | local->sched_scanning = false; | 1022 | rcu_assign_pointer(local->sched_scan_sdata, NULL); |
1016 | 1023 | ||
1017 | mutex_unlock(&local->mtx); | 1024 | mutex_unlock(&local->mtx); |
1018 | 1025 | ||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index de455f8bbb91..06fa75ceb025 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -169,9 +169,7 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) | |||
169 | if (sta->rate_ctrl) | 169 | if (sta->rate_ctrl) |
170 | rate_control_free_sta(sta); | 170 | rate_control_free_sta(sta); |
171 | 171 | ||
172 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 172 | sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr); |
173 | wiphy_debug(local->hw.wiphy, "Destroyed STA %pM\n", sta->sta.addr); | ||
174 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
175 | 173 | ||
176 | kfree(sta); | 174 | kfree(sta); |
177 | } | 175 | } |
@@ -278,9 +276,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
278 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) | 276 | for (i = 0; i < NUM_RX_DATA_QUEUES; i++) |
279 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); | 277 | sta->last_seq_ctrl[i] = cpu_to_le16(USHRT_MAX); |
280 | 278 | ||
281 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 279 | sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr); |
282 | wiphy_debug(local->hw.wiphy, "Allocated STA %pM\n", sta->sta.addr); | ||
283 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
284 | 280 | ||
285 | #ifdef CONFIG_MAC80211_MESH | 281 | #ifdef CONFIG_MAC80211_MESH |
286 | sta->plink_state = NL80211_PLINK_LISTEN; | 282 | sta->plink_state = NL80211_PLINK_LISTEN; |
@@ -333,9 +329,9 @@ static int sta_info_insert_drv_state(struct ieee80211_local *local, | |||
333 | } | 329 | } |
334 | 330 | ||
335 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | 331 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { |
336 | printk(KERN_DEBUG | 332 | sdata_info(sdata, |
337 | "%s: failed to move IBSS STA %pM to state %d (%d) - keeping it anyway.\n", | 333 | "failed to move IBSS STA %pM to state %d (%d) - keeping it anyway\n", |
338 | sdata->name, sta->sta.addr, state + 1, err); | 334 | sta->sta.addr, state + 1, err); |
339 | err = 0; | 335 | err = 0; |
340 | } | 336 | } |
341 | 337 | ||
@@ -390,9 +386,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
390 | sinfo.generation = local->sta_generation; | 386 | sinfo.generation = local->sta_generation; |
391 | cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL); | 387 | cfg80211_new_sta(sdata->dev, sta->sta.addr, &sinfo, GFP_KERNEL); |
392 | 388 | ||
393 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 389 | sta_dbg(sdata, "Inserted STA %pM\n", sta->sta.addr); |
394 | wiphy_debug(local->hw.wiphy, "Inserted STA %pM\n", sta->sta.addr); | ||
395 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
396 | 390 | ||
397 | /* move reference to rcu-protected */ | 391 | /* move reference to rcu-protected */ |
398 | rcu_read_lock(); | 392 | rcu_read_lock(); |
@@ -618,10 +612,8 @@ static bool sta_info_cleanup_expire_buffered_ac(struct ieee80211_local *local, | |||
618 | break; | 612 | break; |
619 | 613 | ||
620 | local->total_ps_buffered--; | 614 | local->total_ps_buffered--; |
621 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 615 | ps_dbg(sta->sdata, "Buffered frame expired (STA %pM)\n", |
622 | printk(KERN_DEBUG "Buffered frame expired (STA %pM)\n", | ||
623 | sta->sta.addr); | 616 | sta->sta.addr); |
624 | #endif | ||
625 | dev_kfree_skb(skb); | 617 | dev_kfree_skb(skb); |
626 | } | 618 | } |
627 | 619 | ||
@@ -747,9 +739,8 @@ int __must_check __sta_info_destroy(struct sta_info *sta) | |||
747 | mesh_accept_plinks_update(sdata); | 739 | mesh_accept_plinks_update(sdata); |
748 | #endif | 740 | #endif |
749 | 741 | ||
750 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 742 | sta_dbg(sdata, "Removed STA %pM\n", sta->sta.addr); |
751 | wiphy_debug(local->hw.wiphy, "Removed STA %pM\n", sta->sta.addr); | 743 | |
752 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | ||
753 | cancel_work_sync(&sta->drv_unblock_wk); | 744 | cancel_work_sync(&sta->drv_unblock_wk); |
754 | 745 | ||
755 | cfg80211_del_sta(sdata->dev, sta->sta.addr, GFP_KERNEL); | 746 | cfg80211_del_sta(sdata->dev, sta->sta.addr, GFP_KERNEL); |
@@ -889,10 +880,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
889 | continue; | 880 | continue; |
890 | 881 | ||
891 | if (time_after(jiffies, sta->last_rx + exp_time)) { | 882 | if (time_after(jiffies, sta->last_rx + exp_time)) { |
892 | #ifdef CONFIG_MAC80211_IBSS_DEBUG | 883 | ibss_dbg(sdata, "expiring inactive STA %pM\n", |
893 | printk(KERN_DEBUG "%s: expiring inactive STA %pM\n", | 884 | sta->sta.addr); |
894 | sdata->name, sta->sta.addr); | ||
895 | #endif | ||
896 | WARN_ON(__sta_info_destroy(sta)); | 885 | WARN_ON(__sta_info_destroy(sta)); |
897 | } | 886 | } |
898 | } | 887 | } |
@@ -990,11 +979,9 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
990 | 979 | ||
991 | sta_info_recalc_tim(sta); | 980 | sta_info_recalc_tim(sta); |
992 | 981 | ||
993 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 982 | ps_dbg(sdata, |
994 | printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " | 983 | "STA %pM aid %d sending %d filtered/%d PS frames since STA not sleeping anymore\n", |
995 | "since STA not sleeping anymore\n", sdata->name, | ||
996 | sta->sta.addr, sta->sta.aid, filtered, buffered); | 984 | sta->sta.addr, sta->sta.aid, filtered, buffered); |
997 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
998 | } | 985 | } |
999 | 986 | ||
1000 | static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, | 987 | static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata, |
@@ -1384,10 +1371,8 @@ int sta_info_move_state(struct sta_info *sta, | |||
1384 | return -EINVAL; | 1371 | return -EINVAL; |
1385 | } | 1372 | } |
1386 | 1373 | ||
1387 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1374 | sta_dbg(sta->sdata, "moving STA %pM to state %d\n", |
1388 | printk(KERN_DEBUG "%s: moving STA %pM to state %d\n", | 1375 | sta->sta.addr, new_state); |
1389 | sta->sdata->name, sta->sta.addr, new_state); | ||
1390 | #endif | ||
1391 | 1376 | ||
1392 | /* | 1377 | /* |
1393 | * notify the driver before the actual changes so it can | 1378 | * notify the driver before the actual changes so it can |
diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 28cfa981cfb1..8cd72914cdaf 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c | |||
@@ -155,13 +155,10 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
155 | return; | 155 | return; |
156 | } | 156 | } |
157 | 157 | ||
158 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 158 | ps_dbg_ratelimited(sta->sdata, |
159 | if (net_ratelimit()) | 159 | "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", |
160 | wiphy_debug(local->hw.wiphy, | 160 | skb_queue_len(&sta->tx_filtered[ac]), |
161 | "dropped TX filtered frame, queue_len=%d PS=%d @%lu\n", | 161 | !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); |
162 | skb_queue_len(&sta->tx_filtered[ac]), | ||
163 | !!test_sta_flag(sta, WLAN_STA_PS_STA), jiffies); | ||
164 | #endif | ||
165 | dev_kfree_skb(skb); | 162 | dev_kfree_skb(skb); |
166 | } | 163 | } |
167 | 164 | ||
@@ -520,36 +517,21 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
520 | 517 | ||
521 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { | 518 | if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX) { |
522 | u64 cookie = (unsigned long)skb; | 519 | u64 cookie = (unsigned long)skb; |
520 | acked = info->flags & IEEE80211_TX_STAT_ACK; | ||
523 | 521 | ||
524 | if (ieee80211_is_nullfunc(hdr->frame_control) || | 522 | /* |
525 | ieee80211_is_qos_nullfunc(hdr->frame_control)) { | 523 | * TODO: When we have non-netdev frame TX, |
526 | acked = info->flags & IEEE80211_TX_STAT_ACK; | 524 | * we cannot use skb->dev->ieee80211_ptr |
525 | */ | ||
527 | 526 | ||
527 | if (ieee80211_is_nullfunc(hdr->frame_control) || | ||
528 | ieee80211_is_qos_nullfunc(hdr->frame_control)) | ||
528 | cfg80211_probe_status(skb->dev, hdr->addr1, | 529 | cfg80211_probe_status(skb->dev, hdr->addr1, |
529 | cookie, acked, GFP_ATOMIC); | 530 | cookie, acked, GFP_ATOMIC); |
530 | } else { | 531 | else |
531 | struct ieee80211_work *wk; | ||
532 | |||
533 | rcu_read_lock(); | ||
534 | list_for_each_entry_rcu(wk, &local->work_list, list) { | ||
535 | if (wk->type != IEEE80211_WORK_OFFCHANNEL_TX) | ||
536 | continue; | ||
537 | if (wk->offchan_tx.frame != skb) | ||
538 | continue; | ||
539 | wk->offchan_tx.status = true; | ||
540 | break; | ||
541 | } | ||
542 | rcu_read_unlock(); | ||
543 | if (local->hw_roc_skb_for_status == skb) { | ||
544 | cookie = local->hw_roc_cookie ^ 2; | ||
545 | local->hw_roc_skb_for_status = NULL; | ||
546 | } | ||
547 | |||
548 | cfg80211_mgmt_tx_status( | 532 | cfg80211_mgmt_tx_status( |
549 | skb->dev, cookie, skb->data, skb->len, | 533 | skb->dev->ieee80211_ptr, cookie, skb->data, |
550 | !!(info->flags & IEEE80211_TX_STAT_ACK), | 534 | skb->len, acked, GFP_ATOMIC); |
551 | GFP_ATOMIC); | ||
552 | } | ||
553 | } | 535 | } |
554 | 536 | ||
555 | if (unlikely(info->ack_frame_id)) { | 537 | if (unlikely(info->ack_frame_id)) { |
@@ -589,7 +571,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
589 | /* send frame to monitor interfaces now */ | 571 | /* send frame to monitor interfaces now */ |
590 | rtap_len = ieee80211_tx_radiotap_len(info); | 572 | rtap_len = ieee80211_tx_radiotap_len(info); |
591 | if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { | 573 | if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { |
592 | printk(KERN_ERR "ieee80211_tx_status: headroom too small\n"); | 574 | pr_err("ieee80211_tx_status: headroom too small\n"); |
593 | dev_kfree_skb(skb); | 575 | dev_kfree_skb(skb); |
594 | return; | 576 | return; |
595 | } | 577 | } |
diff --git a/net/mac80211/tkip.c b/net/mac80211/tkip.c index 51077a956a83..57e14d59e12f 100644 --- a/net/mac80211/tkip.c +++ b/net/mac80211/tkip.c | |||
@@ -260,17 +260,6 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, | |||
260 | keyid = pos[3]; | 260 | keyid = pos[3]; |
261 | iv32 = get_unaligned_le32(pos + 4); | 261 | iv32 = get_unaligned_le32(pos + 4); |
262 | pos += 8; | 262 | pos += 8; |
263 | #ifdef CONFIG_MAC80211_TKIP_DEBUG | ||
264 | { | ||
265 | int i; | ||
266 | printk(KERN_DEBUG "TKIP decrypt: data(len=%zd)", payload_len); | ||
267 | for (i = 0; i < payload_len; i++) | ||
268 | printk(" %02x", payload[i]); | ||
269 | printk("\n"); | ||
270 | printk(KERN_DEBUG "TKIP decrypt: iv16=%04x iv32=%08x\n", | ||
271 | iv16, iv32); | ||
272 | } | ||
273 | #endif | ||
274 | 263 | ||
275 | if (!(keyid & (1 << 5))) | 264 | if (!(keyid & (1 << 5))) |
276 | return TKIP_DECRYPT_NO_EXT_IV; | 265 | return TKIP_DECRYPT_NO_EXT_IV; |
@@ -281,16 +270,8 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, | |||
281 | if (key->u.tkip.rx[queue].state != TKIP_STATE_NOT_INIT && | 270 | if (key->u.tkip.rx[queue].state != TKIP_STATE_NOT_INIT && |
282 | (iv32 < key->u.tkip.rx[queue].iv32 || | 271 | (iv32 < key->u.tkip.rx[queue].iv32 || |
283 | (iv32 == key->u.tkip.rx[queue].iv32 && | 272 | (iv32 == key->u.tkip.rx[queue].iv32 && |
284 | iv16 <= key->u.tkip.rx[queue].iv16))) { | 273 | iv16 <= key->u.tkip.rx[queue].iv16))) |
285 | #ifdef CONFIG_MAC80211_TKIP_DEBUG | ||
286 | printk(KERN_DEBUG "TKIP replay detected for RX frame from " | ||
287 | "%pM (RX IV (%04x,%02x) <= prev. IV (%04x,%02x)\n", | ||
288 | ta, | ||
289 | iv32, iv16, key->u.tkip.rx[queue].iv32, | ||
290 | key->u.tkip.rx[queue].iv16); | ||
291 | #endif | ||
292 | return TKIP_DECRYPT_REPLAY; | 274 | return TKIP_DECRYPT_REPLAY; |
293 | } | ||
294 | 275 | ||
295 | if (only_iv) { | 276 | if (only_iv) { |
296 | res = TKIP_DECRYPT_OK; | 277 | res = TKIP_DECRYPT_OK; |
@@ -302,22 +283,6 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, | |||
302 | key->u.tkip.rx[queue].iv32 != iv32) { | 283 | key->u.tkip.rx[queue].iv32 != iv32) { |
303 | /* IV16 wrapped around - perform TKIP phase 1 */ | 284 | /* IV16 wrapped around - perform TKIP phase 1 */ |
304 | tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); | 285 | tkip_mixing_phase1(tk, &key->u.tkip.rx[queue], ta, iv32); |
305 | #ifdef CONFIG_MAC80211_TKIP_DEBUG | ||
306 | { | ||
307 | int i; | ||
308 | u8 key_offset = NL80211_TKIP_DATA_OFFSET_ENCR_KEY; | ||
309 | printk(KERN_DEBUG "TKIP decrypt: Phase1 TA=%pM" | ||
310 | " TK=", ta); | ||
311 | for (i = 0; i < 16; i++) | ||
312 | printk("%02x ", | ||
313 | key->conf.key[key_offset + i]); | ||
314 | printk("\n"); | ||
315 | printk(KERN_DEBUG "TKIP decrypt: P1K="); | ||
316 | for (i = 0; i < 5; i++) | ||
317 | printk("%04x ", key->u.tkip.rx[queue].p1k[i]); | ||
318 | printk("\n"); | ||
319 | } | ||
320 | #endif | ||
321 | } | 286 | } |
322 | if (key->local->ops->update_tkip_key && | 287 | if (key->local->ops->update_tkip_key && |
323 | key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && | 288 | key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE && |
@@ -333,15 +298,6 @@ int ieee80211_tkip_decrypt_data(struct crypto_cipher *tfm, | |||
333 | } | 298 | } |
334 | 299 | ||
335 | tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); | 300 | tkip_mixing_phase2(tk, &key->u.tkip.rx[queue], iv16, rc4key); |
336 | #ifdef CONFIG_MAC80211_TKIP_DEBUG | ||
337 | { | ||
338 | int i; | ||
339 | printk(KERN_DEBUG "TKIP decrypt: Phase2 rc4key="); | ||
340 | for (i = 0; i < 16; i++) | ||
341 | printk("%02x ", rc4key[i]); | ||
342 | printk("\n"); | ||
343 | } | ||
344 | #endif | ||
345 | 301 | ||
346 | res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12); | 302 | res = ieee80211_wep_decrypt_data(tfm, rc4key, 16, pos, payload_len - 12); |
347 | done: | 303 | done: |
diff --git a/net/mac80211/trace.c b/net/mac80211/trace.c new file mode 100644 index 000000000000..386e45d8a958 --- /dev/null +++ b/net/mac80211/trace.c | |||
@@ -0,0 +1,75 @@ | |||
1 | /* bug in tracepoint.h, it should include this */ | ||
2 | #include <linux/module.h> | ||
3 | |||
4 | /* sparse isn't too happy with all macros... */ | ||
5 | #ifndef __CHECKER__ | ||
6 | #include <net/cfg80211.h> | ||
7 | #include "driver-ops.h" | ||
8 | #include "debug.h" | ||
9 | #define CREATE_TRACE_POINTS | ||
10 | #include "trace.h" | ||
11 | |||
12 | #ifdef CONFIG_MAC80211_MESSAGE_TRACING | ||
13 | void __sdata_info(const char *fmt, ...) | ||
14 | { | ||
15 | struct va_format vaf = { | ||
16 | .fmt = fmt, | ||
17 | }; | ||
18 | va_list args; | ||
19 | |||
20 | va_start(args, fmt); | ||
21 | vaf.va = &args; | ||
22 | |||
23 | pr_info("%pV", &vaf); | ||
24 | trace_mac80211_info(&vaf); | ||
25 | va_end(args); | ||
26 | } | ||
27 | |||
28 | void __sdata_dbg(bool print, const char *fmt, ...) | ||
29 | { | ||
30 | struct va_format vaf = { | ||
31 | .fmt = fmt, | ||
32 | }; | ||
33 | va_list args; | ||
34 | |||
35 | va_start(args, fmt); | ||
36 | vaf.va = &args; | ||
37 | |||
38 | if (print) | ||
39 | pr_debug("%pV", &vaf); | ||
40 | trace_mac80211_dbg(&vaf); | ||
41 | va_end(args); | ||
42 | } | ||
43 | |||
44 | void __sdata_err(const char *fmt, ...) | ||
45 | { | ||
46 | struct va_format vaf = { | ||
47 | .fmt = fmt, | ||
48 | }; | ||
49 | va_list args; | ||
50 | |||
51 | va_start(args, fmt); | ||
52 | vaf.va = &args; | ||
53 | |||
54 | pr_err("%pV", &vaf); | ||
55 | trace_mac80211_err(&vaf); | ||
56 | va_end(args); | ||
57 | } | ||
58 | |||
59 | void __wiphy_dbg(struct wiphy *wiphy, bool print, const char *fmt, ...) | ||
60 | { | ||
61 | struct va_format vaf = { | ||
62 | .fmt = fmt, | ||
63 | }; | ||
64 | va_list args; | ||
65 | |||
66 | va_start(args, fmt); | ||
67 | vaf.va = &args; | ||
68 | |||
69 | if (print) | ||
70 | wiphy_dbg(wiphy, "%pV", &vaf); | ||
71 | trace_mac80211_dbg(&vaf); | ||
72 | va_end(args); | ||
73 | } | ||
74 | #endif | ||
75 | #endif | ||
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/trace.h index 6de00b2c268c..c6d33b55b2df 100644 --- a/net/mac80211/driver-trace.h +++ b/net/mac80211/trace.h | |||
@@ -306,7 +306,8 @@ TRACE_EVENT(drv_bss_info_changed, | |||
306 | __field(u8, dtimper) | 306 | __field(u8, dtimper) |
307 | __field(u16, bcnint) | 307 | __field(u16, bcnint) |
308 | __field(u16, assoc_cap) | 308 | __field(u16, assoc_cap) |
309 | __field(u64, timestamp) | 309 | __field(u64, sync_tsf) |
310 | __field(u32, sync_device_ts) | ||
310 | __field(u32, basic_rates) | 311 | __field(u32, basic_rates) |
311 | __field(u32, changed) | 312 | __field(u32, changed) |
312 | __field(bool, enable_beacon) | 313 | __field(bool, enable_beacon) |
@@ -325,7 +326,8 @@ TRACE_EVENT(drv_bss_info_changed, | |||
325 | __entry->dtimper = info->dtim_period; | 326 | __entry->dtimper = info->dtim_period; |
326 | __entry->bcnint = info->beacon_int; | 327 | __entry->bcnint = info->beacon_int; |
327 | __entry->assoc_cap = info->assoc_capability; | 328 | __entry->assoc_cap = info->assoc_capability; |
328 | __entry->timestamp = info->last_tsf; | 329 | __entry->sync_tsf = info->sync_tsf; |
330 | __entry->sync_device_ts = info->sync_device_ts; | ||
329 | __entry->basic_rates = info->basic_rates; | 331 | __entry->basic_rates = info->basic_rates; |
330 | __entry->enable_beacon = info->enable_beacon; | 332 | __entry->enable_beacon = info->enable_beacon; |
331 | __entry->ht_operation_mode = info->ht_operation_mode; | 333 | __entry->ht_operation_mode = info->ht_operation_mode; |
@@ -1218,6 +1220,39 @@ DEFINE_EVENT(release_evt, drv_allow_buffered_frames, | |||
1218 | TP_ARGS(local, sta, tids, num_frames, reason, more_data) | 1220 | TP_ARGS(local, sta, tids, num_frames, reason, more_data) |
1219 | ); | 1221 | ); |
1220 | 1222 | ||
1223 | TRACE_EVENT(drv_get_rssi, | ||
1224 | TP_PROTO(struct ieee80211_local *local, struct ieee80211_sta *sta, | ||
1225 | s8 rssi, int ret), | ||
1226 | |||
1227 | TP_ARGS(local, sta, rssi, ret), | ||
1228 | |||
1229 | TP_STRUCT__entry( | ||
1230 | LOCAL_ENTRY | ||
1231 | STA_ENTRY | ||
1232 | __field(s8, rssi) | ||
1233 | __field(int, ret) | ||
1234 | ), | ||
1235 | |||
1236 | TP_fast_assign( | ||
1237 | LOCAL_ASSIGN; | ||
1238 | STA_ASSIGN; | ||
1239 | __entry->rssi = rssi; | ||
1240 | __entry->ret = ret; | ||
1241 | ), | ||
1242 | |||
1243 | TP_printk( | ||
1244 | LOCAL_PR_FMT STA_PR_FMT " rssi:%d ret:%d", | ||
1245 | LOCAL_PR_ARG, STA_PR_ARG, __entry->rssi, __entry->ret | ||
1246 | ) | ||
1247 | ); | ||
1248 | |||
1249 | DEFINE_EVENT(local_sdata_evt, drv_mgd_prepare_tx, | ||
1250 | TP_PROTO(struct ieee80211_local *local, | ||
1251 | struct ieee80211_sub_if_data *sdata), | ||
1252 | |||
1253 | TP_ARGS(local, sdata) | ||
1254 | ); | ||
1255 | |||
1221 | /* | 1256 | /* |
1222 | * Tracing for API calls that drivers call. | 1257 | * Tracing for API calls that drivers call. |
1223 | */ | 1258 | */ |
@@ -1606,10 +1641,49 @@ TRACE_EVENT(stop_queue, | |||
1606 | LOCAL_PR_ARG, __entry->queue, __entry->reason | 1641 | LOCAL_PR_ARG, __entry->queue, __entry->reason |
1607 | ) | 1642 | ) |
1608 | ); | 1643 | ); |
1644 | |||
1645 | #ifdef CONFIG_MAC80211_MESSAGE_TRACING | ||
1646 | #undef TRACE_SYSTEM | ||
1647 | #define TRACE_SYSTEM mac80211_msg | ||
1648 | |||
1649 | #define MAX_MSG_LEN 100 | ||
1650 | |||
1651 | DECLARE_EVENT_CLASS(mac80211_msg_event, | ||
1652 | TP_PROTO(struct va_format *vaf), | ||
1653 | |||
1654 | TP_ARGS(vaf), | ||
1655 | |||
1656 | TP_STRUCT__entry( | ||
1657 | __dynamic_array(char, msg, MAX_MSG_LEN) | ||
1658 | ), | ||
1659 | |||
1660 | TP_fast_assign( | ||
1661 | WARN_ON_ONCE(vsnprintf(__get_dynamic_array(msg), | ||
1662 | MAX_MSG_LEN, vaf->fmt, | ||
1663 | *vaf->va) >= MAX_MSG_LEN); | ||
1664 | ), | ||
1665 | |||
1666 | TP_printk("%s", __get_str(msg)) | ||
1667 | ); | ||
1668 | |||
1669 | DEFINE_EVENT(mac80211_msg_event, mac80211_info, | ||
1670 | TP_PROTO(struct va_format *vaf), | ||
1671 | TP_ARGS(vaf) | ||
1672 | ); | ||
1673 | DEFINE_EVENT(mac80211_msg_event, mac80211_dbg, | ||
1674 | TP_PROTO(struct va_format *vaf), | ||
1675 | TP_ARGS(vaf) | ||
1676 | ); | ||
1677 | DEFINE_EVENT(mac80211_msg_event, mac80211_err, | ||
1678 | TP_PROTO(struct va_format *vaf), | ||
1679 | TP_ARGS(vaf) | ||
1680 | ); | ||
1681 | #endif | ||
1682 | |||
1609 | #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ | 1683 | #endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */ |
1610 | 1684 | ||
1611 | #undef TRACE_INCLUDE_PATH | 1685 | #undef TRACE_INCLUDE_PATH |
1612 | #define TRACE_INCLUDE_PATH . | 1686 | #define TRACE_INCLUDE_PATH . |
1613 | #undef TRACE_INCLUDE_FILE | 1687 | #undef TRACE_INCLUDE_FILE |
1614 | #define TRACE_INCLUDE_FILE driver-trace | 1688 | #define TRACE_INCLUDE_FILE trace |
1615 | #include <trace/define_trace.h> | 1689 | #include <trace/define_trace.h> |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index eab0d19eb4bd..acf712ffb5e6 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -140,6 +140,8 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, | |||
140 | if (r->flags & IEEE80211_RATE_MANDATORY_A) | 140 | if (r->flags & IEEE80211_RATE_MANDATORY_A) |
141 | mrate = r->bitrate; | 141 | mrate = r->bitrate; |
142 | break; | 142 | break; |
143 | case IEEE80211_BAND_60GHZ: | ||
144 | /* TODO, for now fall through */ | ||
143 | case IEEE80211_NUM_BANDS: | 145 | case IEEE80211_NUM_BANDS: |
144 | WARN_ON(1); | 146 | WARN_ON(1); |
145 | break; | 147 | break; |
@@ -175,12 +177,6 @@ static __le16 ieee80211_duration(struct ieee80211_tx_data *tx, | |||
175 | return cpu_to_le16(dur); | 177 | return cpu_to_le16(dur); |
176 | } | 178 | } |
177 | 179 | ||
178 | static inline int is_ieee80211_device(struct ieee80211_local *local, | ||
179 | struct net_device *dev) | ||
180 | { | ||
181 | return local == wdev_priv(dev->ieee80211_ptr); | ||
182 | } | ||
183 | |||
184 | /* tx handlers */ | 180 | /* tx handlers */ |
185 | static ieee80211_tx_result debug_noinline | 181 | static ieee80211_tx_result debug_noinline |
186 | ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) | 182 | ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx) |
@@ -297,10 +293,10 @@ ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) | |||
297 | if (unlikely(!assoc && | 293 | if (unlikely(!assoc && |
298 | ieee80211_is_data(hdr->frame_control))) { | 294 | ieee80211_is_data(hdr->frame_control))) { |
299 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 295 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
300 | printk(KERN_DEBUG "%s: dropped data frame to not " | 296 | sdata_info(tx->sdata, |
301 | "associated station %pM\n", | 297 | "dropped data frame to not associated station %pM\n", |
302 | tx->sdata->name, hdr->addr1); | 298 | hdr->addr1); |
303 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 299 | #endif |
304 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); | 300 | I802_DEBUG_INC(tx->local->tx_handlers_drop_not_assoc); |
305 | return TX_DROP; | 301 | return TX_DROP; |
306 | } | 302 | } |
@@ -367,10 +363,7 @@ static void purge_old_ps_buffers(struct ieee80211_local *local) | |||
367 | rcu_read_unlock(); | 363 | rcu_read_unlock(); |
368 | 364 | ||
369 | local->total_ps_buffered = total; | 365 | local->total_ps_buffered = total; |
370 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 366 | ps_dbg_hw(&local->hw, "PS buffers full - purged %d frames\n", purged); |
371 | wiphy_debug(local->hw.wiphy, "PS buffers full - purged %d frames\n", | ||
372 | purged); | ||
373 | #endif | ||
374 | } | 367 | } |
375 | 368 | ||
376 | static ieee80211_tx_result | 369 | static ieee80211_tx_result |
@@ -412,10 +405,8 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
412 | purge_old_ps_buffers(tx->local); | 405 | purge_old_ps_buffers(tx->local); |
413 | 406 | ||
414 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= AP_MAX_BC_BUFFER) { | 407 | if (skb_queue_len(&tx->sdata->bss->ps_bc_buf) >= AP_MAX_BC_BUFFER) { |
415 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 408 | ps_dbg(tx->sdata, |
416 | net_dbg_ratelimited("%s: BC TX buffer full - dropping the oldest frame\n", | 409 | "BC TX buffer full - dropping the oldest frame\n"); |
417 | tx->sdata->name); | ||
418 | #endif | ||
419 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); | 410 | dev_kfree_skb(skb_dequeue(&tx->sdata->bss->ps_bc_buf)); |
420 | } else | 411 | } else |
421 | tx->local->total_ps_buffered++; | 412 | tx->local->total_ps_buffered++; |
@@ -466,18 +457,15 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
466 | return TX_CONTINUE; | 457 | return TX_CONTINUE; |
467 | } | 458 | } |
468 | 459 | ||
469 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 460 | ps_dbg(sta->sdata, "STA %pM aid %d: PS buffer for AC %d\n", |
470 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer for AC %d\n", | ||
471 | sta->sta.addr, sta->sta.aid, ac); | 461 | sta->sta.addr, sta->sta.aid, ac); |
472 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
473 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 462 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
474 | purge_old_ps_buffers(tx->local); | 463 | purge_old_ps_buffers(tx->local); |
475 | if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { | 464 | if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { |
476 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); | 465 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); |
477 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 466 | ps_dbg(tx->sdata, |
478 | net_dbg_ratelimited("%s: STA %pM TX buffer for AC %d full - dropping oldest frame\n", | 467 | "STA %pM TX buffer for AC %d full - dropping oldest frame\n", |
479 | tx->sdata->name, sta->sta.addr, ac); | 468 | sta->sta.addr, ac); |
480 | #endif | ||
481 | dev_kfree_skb(old); | 469 | dev_kfree_skb(old); |
482 | } else | 470 | } else |
483 | tx->local->total_ps_buffered++; | 471 | tx->local->total_ps_buffered++; |
@@ -499,14 +487,11 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
499 | sta_info_recalc_tim(sta); | 487 | sta_info_recalc_tim(sta); |
500 | 488 | ||
501 | return TX_QUEUED; | 489 | return TX_QUEUED; |
490 | } else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { | ||
491 | ps_dbg(tx->sdata, | ||
492 | "STA %pM in PS mode, but polling/in SP -> send frame\n", | ||
493 | sta->sta.addr); | ||
502 | } | 494 | } |
503 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | ||
504 | else if (unlikely(test_sta_flag(sta, WLAN_STA_PS_STA))) { | ||
505 | printk(KERN_DEBUG | ||
506 | "%s: STA %pM in PS mode, but polling/in SP -> send frame\n", | ||
507 | tx->sdata->name, sta->sta.addr); | ||
508 | } | ||
509 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
510 | 495 | ||
511 | return TX_CONTINUE; | 496 | return TX_CONTINUE; |
512 | } | 497 | } |
@@ -538,7 +523,7 @@ ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx) | |||
538 | static ieee80211_tx_result debug_noinline | 523 | static ieee80211_tx_result debug_noinline |
539 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | 524 | ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) |
540 | { | 525 | { |
541 | struct ieee80211_key *key = NULL; | 526 | struct ieee80211_key *key; |
542 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); | 527 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); |
543 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; | 528 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; |
544 | 529 | ||
@@ -557,16 +542,23 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx) | |||
557 | else if (!is_multicast_ether_addr(hdr->addr1) && | 542 | else if (!is_multicast_ether_addr(hdr->addr1) && |
558 | (key = rcu_dereference(tx->sdata->default_unicast_key))) | 543 | (key = rcu_dereference(tx->sdata->default_unicast_key))) |
559 | tx->key = key; | 544 | tx->key = key; |
560 | else if (tx->sdata->drop_unencrypted && | 545 | else if (info->flags & IEEE80211_TX_CTL_INJECTED) |
561 | (tx->skb->protocol != tx->sdata->control_port_protocol) && | 546 | tx->key = NULL; |
562 | !(info->flags & IEEE80211_TX_CTL_INJECTED) && | 547 | else if (!tx->sdata->drop_unencrypted) |
563 | (!ieee80211_is_robust_mgmt_frame(hdr) || | 548 | tx->key = NULL; |
564 | (ieee80211_is_action(hdr->frame_control) && | 549 | else if (tx->skb->protocol == tx->sdata->control_port_protocol) |
565 | tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP)))) { | 550 | tx->key = NULL; |
551 | else if (ieee80211_is_robust_mgmt_frame(hdr) && | ||
552 | !(ieee80211_is_action(hdr->frame_control) && | ||
553 | tx->sta && test_sta_flag(tx->sta, WLAN_STA_MFP))) | ||
554 | tx->key = NULL; | ||
555 | else if (ieee80211_is_mgmt(hdr->frame_control) && | ||
556 | !ieee80211_is_robust_mgmt_frame(hdr)) | ||
557 | tx->key = NULL; | ||
558 | else { | ||
566 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); | 559 | I802_DEBUG_INC(tx->local->tx_handlers_drop_unencrypted); |
567 | return TX_DROP; | 560 | return TX_DROP; |
568 | } else | 561 | } |
569 | tx->key = NULL; | ||
570 | 562 | ||
571 | if (tx->key) { | 563 | if (tx->key) { |
572 | bool skip_hw = false; | 564 | bool skip_hw = false; |
@@ -974,8 +966,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx) | |||
974 | info->control.rates[1].idx = -1; | 966 | info->control.rates[1].idx = -1; |
975 | info->control.rates[2].idx = -1; | 967 | info->control.rates[2].idx = -1; |
976 | info->control.rates[3].idx = -1; | 968 | info->control.rates[3].idx = -1; |
977 | info->control.rates[4].idx = -1; | 969 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 4); |
978 | BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); | ||
979 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; | 970 | info->flags &= ~IEEE80211_TX_CTL_RATE_CTRL_PROBE; |
980 | } else { | 971 | } else { |
981 | hdr->frame_control &= ~morefrags; | 972 | hdr->frame_control &= ~morefrags; |
@@ -1310,11 +1301,8 @@ static bool __ieee80211_tx(struct ieee80211_local *local, | |||
1310 | break; | 1301 | break; |
1311 | } | 1302 | } |
1312 | 1303 | ||
1313 | if (local->ops->tx_frags) | 1304 | result = ieee80211_tx_frags(local, vif, pubsta, skbs, |
1314 | drv_tx_frags(local, vif, pubsta, skbs); | 1305 | txpending); |
1315 | else | ||
1316 | result = ieee80211_tx_frags(local, vif, pubsta, skbs, | ||
1317 | txpending); | ||
1318 | 1306 | ||
1319 | ieee80211_tpt_led_trig_tx(local, fc, led_len); | 1307 | ieee80211_tpt_led_trig_tx(local, fc, led_len); |
1320 | ieee80211_led_tx(local, 1); | 1308 | ieee80211_led_tx(local, 1); |
@@ -1968,7 +1956,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, | |||
1968 | (cpu_to_be16(ethertype) != sdata->control_port_protocol || | 1956 | (cpu_to_be16(ethertype) != sdata->control_port_protocol || |
1969 | !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { | 1957 | !ether_addr_equal(sdata->vif.addr, skb->data + ETH_ALEN)))) { |
1970 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | 1958 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG |
1971 | net_dbg_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", | 1959 | net_info_ratelimited("%s: dropped frame to %pM (unauthorized port)\n", |
1972 | dev->name, hdr.addr1); | 1960 | dev->name, hdr.addr1); |
1973 | #endif | 1961 | #endif |
1974 | 1962 | ||
@@ -2440,9 +2428,9 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, | |||
2440 | *pos++ = WLAN_EID_SSID; | 2428 | *pos++ = WLAN_EID_SSID; |
2441 | *pos++ = 0x0; | 2429 | *pos++ = 0x0; |
2442 | 2430 | ||
2443 | if (ieee80211_add_srates_ie(&sdata->vif, skb, true) || | 2431 | if (ieee80211_add_srates_ie(sdata, skb, true) || |
2444 | mesh_add_ds_params_ie(skb, sdata) || | 2432 | mesh_add_ds_params_ie(skb, sdata) || |
2445 | ieee80211_add_ext_srates_ie(&sdata->vif, skb, true) || | 2433 | ieee80211_add_ext_srates_ie(sdata, skb, true) || |
2446 | mesh_add_rsn_ie(skb, sdata) || | 2434 | mesh_add_rsn_ie(skb, sdata) || |
2447 | mesh_add_ht_cap_ie(skb, sdata) || | 2435 | mesh_add_ht_cap_ie(skb, sdata) || |
2448 | mesh_add_ht_oper_ie(skb, sdata) || | 2436 | mesh_add_ht_oper_ie(skb, sdata) || |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 8dd4712620ff..39b82fee4904 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -268,6 +268,10 @@ EXPORT_SYMBOL(ieee80211_ctstoself_duration); | |||
268 | void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) | 268 | void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) |
269 | { | 269 | { |
270 | struct ieee80211_sub_if_data *sdata; | 270 | struct ieee80211_sub_if_data *sdata; |
271 | int n_acs = IEEE80211_NUM_ACS; | ||
272 | |||
273 | if (local->hw.queues < IEEE80211_NUM_ACS) | ||
274 | n_acs = 1; | ||
271 | 275 | ||
272 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 276 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
273 | int ac; | 277 | int ac; |
@@ -279,7 +283,7 @@ void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) | |||
279 | local->queue_stop_reasons[sdata->vif.cab_queue] != 0) | 283 | local->queue_stop_reasons[sdata->vif.cab_queue] != 0) |
280 | continue; | 284 | continue; |
281 | 285 | ||
282 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 286 | for (ac = 0; ac < n_acs; ac++) { |
283 | int ac_queue = sdata->vif.hw_queue[ac]; | 287 | int ac_queue = sdata->vif.hw_queue[ac]; |
284 | 288 | ||
285 | if (ac_queue == queue || | 289 | if (ac_queue == queue || |
@@ -341,6 +345,7 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, | |||
341 | { | 345 | { |
342 | struct ieee80211_local *local = hw_to_local(hw); | 346 | struct ieee80211_local *local = hw_to_local(hw); |
343 | struct ieee80211_sub_if_data *sdata; | 347 | struct ieee80211_sub_if_data *sdata; |
348 | int n_acs = IEEE80211_NUM_ACS; | ||
344 | 349 | ||
345 | trace_stop_queue(local, queue, reason); | 350 | trace_stop_queue(local, queue, reason); |
346 | 351 | ||
@@ -352,11 +357,14 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue, | |||
352 | 357 | ||
353 | __set_bit(reason, &local->queue_stop_reasons[queue]); | 358 | __set_bit(reason, &local->queue_stop_reasons[queue]); |
354 | 359 | ||
360 | if (local->hw.queues < IEEE80211_NUM_ACS) | ||
361 | n_acs = 1; | ||
362 | |||
355 | rcu_read_lock(); | 363 | rcu_read_lock(); |
356 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | 364 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { |
357 | int ac; | 365 | int ac; |
358 | 366 | ||
359 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 367 | for (ac = 0; ac < n_acs; ac++) { |
360 | if (sdata->vif.hw_queue[ac] == queue || | 368 | if (sdata->vif.hw_queue[ac] == queue || |
361 | sdata->vif.cab_queue == queue) | 369 | sdata->vif.cab_queue == queue) |
362 | netif_stop_subqueue(sdata->dev, ac); | 370 | netif_stop_subqueue(sdata->dev, ac); |
@@ -521,6 +529,11 @@ void ieee80211_iterate_active_interfaces( | |||
521 | &sdata->vif); | 529 | &sdata->vif); |
522 | } | 530 | } |
523 | 531 | ||
532 | sdata = rcu_dereference_protected(local->monitor_sdata, | ||
533 | lockdep_is_held(&local->iflist_mtx)); | ||
534 | if (sdata) | ||
535 | iterator(data, sdata->vif.addr, &sdata->vif); | ||
536 | |||
524 | mutex_unlock(&local->iflist_mtx); | 537 | mutex_unlock(&local->iflist_mtx); |
525 | } | 538 | } |
526 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); | 539 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces); |
@@ -549,6 +562,10 @@ void ieee80211_iterate_active_interfaces_atomic( | |||
549 | &sdata->vif); | 562 | &sdata->vif); |
550 | } | 563 | } |
551 | 564 | ||
565 | sdata = rcu_dereference(local->monitor_sdata); | ||
566 | if (sdata) | ||
567 | iterator(data, sdata->vif.addr, &sdata->vif); | ||
568 | |||
552 | rcu_read_unlock(); | 569 | rcu_read_unlock(); |
553 | } | 570 | } |
554 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | 571 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); |
@@ -804,7 +821,7 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | |||
804 | struct ieee80211_local *local = sdata->local; | 821 | struct ieee80211_local *local = sdata->local; |
805 | struct ieee80211_tx_queue_params qparam; | 822 | struct ieee80211_tx_queue_params qparam; |
806 | int ac; | 823 | int ac; |
807 | bool use_11b; | 824 | bool use_11b, enable_qos; |
808 | int aCWmin, aCWmax; | 825 | int aCWmin, aCWmax; |
809 | 826 | ||
810 | if (!local->ops->conf_tx) | 827 | if (!local->ops->conf_tx) |
@@ -818,6 +835,13 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | |||
818 | use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) && | 835 | use_11b = (local->hw.conf.channel->band == IEEE80211_BAND_2GHZ) && |
819 | !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); | 836 | !(sdata->flags & IEEE80211_SDATA_OPERATING_GMODE); |
820 | 837 | ||
838 | /* | ||
839 | * By default disable QoS in STA mode for old access points, which do | ||
840 | * not support 802.11e. New APs will provide proper queue parameters, | ||
841 | * that we will configure later. | ||
842 | */ | ||
843 | enable_qos = (sdata->vif.type != NL80211_IFTYPE_STATION); | ||
844 | |||
821 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 845 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
822 | /* Set defaults according to 802.11-2007 Table 7-37 */ | 846 | /* Set defaults according to 802.11-2007 Table 7-37 */ |
823 | aCWmax = 1023; | 847 | aCWmax = 1023; |
@@ -826,38 +850,47 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | |||
826 | else | 850 | else |
827 | aCWmin = 15; | 851 | aCWmin = 15; |
828 | 852 | ||
829 | switch (ac) { | 853 | if (enable_qos) { |
830 | case IEEE80211_AC_BK: | 854 | switch (ac) { |
831 | qparam.cw_max = aCWmax; | 855 | case IEEE80211_AC_BK: |
832 | qparam.cw_min = aCWmin; | 856 | qparam.cw_max = aCWmax; |
833 | qparam.txop = 0; | 857 | qparam.cw_min = aCWmin; |
834 | qparam.aifs = 7; | 858 | qparam.txop = 0; |
835 | break; | 859 | qparam.aifs = 7; |
836 | default: /* never happens but let's not leave undefined */ | 860 | break; |
837 | case IEEE80211_AC_BE: | 861 | /* never happens but let's not leave undefined */ |
862 | default: | ||
863 | case IEEE80211_AC_BE: | ||
864 | qparam.cw_max = aCWmax; | ||
865 | qparam.cw_min = aCWmin; | ||
866 | qparam.txop = 0; | ||
867 | qparam.aifs = 3; | ||
868 | break; | ||
869 | case IEEE80211_AC_VI: | ||
870 | qparam.cw_max = aCWmin; | ||
871 | qparam.cw_min = (aCWmin + 1) / 2 - 1; | ||
872 | if (use_11b) | ||
873 | qparam.txop = 6016/32; | ||
874 | else | ||
875 | qparam.txop = 3008/32; | ||
876 | qparam.aifs = 2; | ||
877 | break; | ||
878 | case IEEE80211_AC_VO: | ||
879 | qparam.cw_max = (aCWmin + 1) / 2 - 1; | ||
880 | qparam.cw_min = (aCWmin + 1) / 4 - 1; | ||
881 | if (use_11b) | ||
882 | qparam.txop = 3264/32; | ||
883 | else | ||
884 | qparam.txop = 1504/32; | ||
885 | qparam.aifs = 2; | ||
886 | break; | ||
887 | } | ||
888 | } else { | ||
889 | /* Confiure old 802.11b/g medium access rules. */ | ||
838 | qparam.cw_max = aCWmax; | 890 | qparam.cw_max = aCWmax; |
839 | qparam.cw_min = aCWmin; | 891 | qparam.cw_min = aCWmin; |
840 | qparam.txop = 0; | 892 | qparam.txop = 0; |
841 | qparam.aifs = 3; | ||
842 | break; | ||
843 | case IEEE80211_AC_VI: | ||
844 | qparam.cw_max = aCWmin; | ||
845 | qparam.cw_min = (aCWmin + 1) / 2 - 1; | ||
846 | if (use_11b) | ||
847 | qparam.txop = 6016/32; | ||
848 | else | ||
849 | qparam.txop = 3008/32; | ||
850 | qparam.aifs = 2; | ||
851 | break; | ||
852 | case IEEE80211_AC_VO: | ||
853 | qparam.cw_max = (aCWmin + 1) / 2 - 1; | ||
854 | qparam.cw_min = (aCWmin + 1) / 4 - 1; | ||
855 | if (use_11b) | ||
856 | qparam.txop = 3264/32; | ||
857 | else | ||
858 | qparam.txop = 1504/32; | ||
859 | qparam.aifs = 2; | 893 | qparam.aifs = 2; |
860 | break; | ||
861 | } | 894 | } |
862 | 895 | ||
863 | qparam.uapsd = false; | 896 | qparam.uapsd = false; |
@@ -866,12 +899,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata, | |||
866 | drv_conf_tx(local, sdata, ac, &qparam); | 899 | drv_conf_tx(local, sdata, ac, &qparam); |
867 | } | 900 | } |
868 | 901 | ||
869 | /* after reinitialize QoS TX queues setting to default, | ||
870 | * disable QoS at all */ | ||
871 | |||
872 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { | 902 | if (sdata->vif.type != NL80211_IFTYPE_MONITOR) { |
873 | sdata->vif.bss_conf.qos = | 903 | sdata->vif.bss_conf.qos = enable_qos; |
874 | sdata->vif.type != NL80211_IFTYPE_STATION; | ||
875 | if (bss_notify) | 904 | if (bss_notify) |
876 | ieee80211_bss_info_change_notify(sdata, | 905 | ieee80211_bss_info_change_notify(sdata, |
877 | BSS_CHANGED_QOS); | 906 | BSS_CHANGED_QOS); |
@@ -979,6 +1008,8 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
979 | int ext_rates_len; | 1008 | int ext_rates_len; |
980 | 1009 | ||
981 | sband = local->hw.wiphy->bands[band]; | 1010 | sband = local->hw.wiphy->bands[band]; |
1011 | if (WARN_ON_ONCE(!sband)) | ||
1012 | return 0; | ||
982 | 1013 | ||
983 | pos = buffer; | 1014 | pos = buffer; |
984 | 1015 | ||
@@ -1060,6 +1091,10 @@ int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | |||
1060 | pos += noffset - offset; | 1091 | pos += noffset - offset; |
1061 | } | 1092 | } |
1062 | 1093 | ||
1094 | if (sband->vht_cap.vht_supported) | ||
1095 | pos = ieee80211_ie_build_vht_cap(pos, &sband->vht_cap, | ||
1096 | sband->vht_cap.cap); | ||
1097 | |||
1063 | return pos - buffer; | 1098 | return pos - buffer; |
1064 | } | 1099 | } |
1065 | 1100 | ||
@@ -1267,14 +1302,19 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1267 | /* add STAs back */ | 1302 | /* add STAs back */ |
1268 | mutex_lock(&local->sta_mtx); | 1303 | mutex_lock(&local->sta_mtx); |
1269 | list_for_each_entry(sta, &local->sta_list, list) { | 1304 | list_for_each_entry(sta, &local->sta_list, list) { |
1270 | if (sta->uploaded) { | 1305 | enum ieee80211_sta_state state; |
1271 | enum ieee80211_sta_state state; | ||
1272 | 1306 | ||
1273 | for (state = IEEE80211_STA_NOTEXIST; | 1307 | if (!sta->uploaded) |
1274 | state < sta->sta_state; state++) | 1308 | continue; |
1275 | WARN_ON(drv_sta_state(local, sta->sdata, sta, | 1309 | |
1276 | state, state + 1)); | 1310 | /* AP-mode stations will be added later */ |
1277 | } | 1311 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP) |
1312 | continue; | ||
1313 | |||
1314 | for (state = IEEE80211_STA_NOTEXIST; | ||
1315 | state < sta->sta_state; state++) | ||
1316 | WARN_ON(drv_sta_state(local, sta->sdata, sta, state, | ||
1317 | state + 1)); | ||
1278 | } | 1318 | } |
1279 | mutex_unlock(&local->sta_mtx); | 1319 | mutex_unlock(&local->sta_mtx); |
1280 | 1320 | ||
@@ -1371,12 +1411,33 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
1371 | } | 1411 | } |
1372 | } | 1412 | } |
1373 | 1413 | ||
1414 | /* APs are now beaconing, add back stations */ | ||
1415 | mutex_lock(&local->sta_mtx); | ||
1416 | list_for_each_entry(sta, &local->sta_list, list) { | ||
1417 | enum ieee80211_sta_state state; | ||
1418 | |||
1419 | if (!sta->uploaded) | ||
1420 | continue; | ||
1421 | |||
1422 | if (sta->sdata->vif.type != NL80211_IFTYPE_AP) | ||
1423 | continue; | ||
1424 | |||
1425 | for (state = IEEE80211_STA_NOTEXIST; | ||
1426 | state < sta->sta_state; state++) | ||
1427 | WARN_ON(drv_sta_state(local, sta->sdata, sta, state, | ||
1428 | state + 1)); | ||
1429 | } | ||
1430 | mutex_unlock(&local->sta_mtx); | ||
1431 | |||
1374 | /* add back keys */ | 1432 | /* add back keys */ |
1375 | list_for_each_entry(sdata, &local->interfaces, list) | 1433 | list_for_each_entry(sdata, &local->interfaces, list) |
1376 | if (ieee80211_sdata_running(sdata)) | 1434 | if (ieee80211_sdata_running(sdata)) |
1377 | ieee80211_enable_keys(sdata); | 1435 | ieee80211_enable_keys(sdata); |
1378 | 1436 | ||
1379 | wake_up: | 1437 | wake_up: |
1438 | local->in_reconfig = false; | ||
1439 | barrier(); | ||
1440 | |||
1380 | /* | 1441 | /* |
1381 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation | 1442 | * Clear the WLAN_STA_BLOCK_BA flag so new aggregation |
1382 | * sessions can be established after a resume. | 1443 | * sessions can be established after a resume. |
@@ -1661,6 +1722,27 @@ u8 *ieee80211_ie_build_ht_cap(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, | |||
1661 | return pos; | 1722 | return pos; |
1662 | } | 1723 | } |
1663 | 1724 | ||
1725 | u8 *ieee80211_ie_build_vht_cap(u8 *pos, struct ieee80211_sta_vht_cap *vht_cap, | ||
1726 | u32 cap) | ||
1727 | { | ||
1728 | __le32 tmp; | ||
1729 | |||
1730 | *pos++ = WLAN_EID_VHT_CAPABILITY; | ||
1731 | *pos++ = sizeof(struct ieee80211_vht_capabilities); | ||
1732 | memset(pos, 0, sizeof(struct ieee80211_vht_capabilities)); | ||
1733 | |||
1734 | /* capability flags */ | ||
1735 | tmp = cpu_to_le32(cap); | ||
1736 | memcpy(pos, &tmp, sizeof(u32)); | ||
1737 | pos += sizeof(u32); | ||
1738 | |||
1739 | /* VHT MCS set */ | ||
1740 | memcpy(pos, &vht_cap->vht_mcs, sizeof(vht_cap->vht_mcs)); | ||
1741 | pos += sizeof(vht_cap->vht_mcs); | ||
1742 | |||
1743 | return pos; | ||
1744 | } | ||
1745 | |||
1664 | u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, | 1746 | u8 *ieee80211_ie_build_ht_oper(u8 *pos, struct ieee80211_sta_ht_cap *ht_cap, |
1665 | struct ieee80211_channel *channel, | 1747 | struct ieee80211_channel *channel, |
1666 | enum nl80211_channel_type channel_type, | 1748 | enum nl80211_channel_type channel_type, |
@@ -1726,15 +1808,14 @@ ieee80211_ht_oper_to_channel_type(struct ieee80211_ht_operation *ht_oper) | |||
1726 | return channel_type; | 1808 | return channel_type; |
1727 | } | 1809 | } |
1728 | 1810 | ||
1729 | int ieee80211_add_srates_ie(struct ieee80211_vif *vif, | 1811 | int ieee80211_add_srates_ie(struct ieee80211_sub_if_data *sdata, |
1730 | struct sk_buff *skb, bool need_basic) | 1812 | struct sk_buff *skb, bool need_basic) |
1731 | { | 1813 | { |
1732 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
1733 | struct ieee80211_local *local = sdata->local; | 1814 | struct ieee80211_local *local = sdata->local; |
1734 | struct ieee80211_supported_band *sband; | 1815 | struct ieee80211_supported_band *sband; |
1735 | int rate; | 1816 | int rate; |
1736 | u8 i, rates, *pos; | 1817 | u8 i, rates, *pos; |
1737 | u32 basic_rates = vif->bss_conf.basic_rates; | 1818 | u32 basic_rates = sdata->vif.bss_conf.basic_rates; |
1738 | 1819 | ||
1739 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1820 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
1740 | rates = sband->n_bitrates; | 1821 | rates = sband->n_bitrates; |
@@ -1758,15 +1839,14 @@ int ieee80211_add_srates_ie(struct ieee80211_vif *vif, | |||
1758 | return 0; | 1839 | return 0; |
1759 | } | 1840 | } |
1760 | 1841 | ||
1761 | int ieee80211_add_ext_srates_ie(struct ieee80211_vif *vif, | 1842 | int ieee80211_add_ext_srates_ie(struct ieee80211_sub_if_data *sdata, |
1762 | struct sk_buff *skb, bool need_basic) | 1843 | struct sk_buff *skb, bool need_basic) |
1763 | { | 1844 | { |
1764 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | ||
1765 | struct ieee80211_local *local = sdata->local; | 1845 | struct ieee80211_local *local = sdata->local; |
1766 | struct ieee80211_supported_band *sband; | 1846 | struct ieee80211_supported_band *sband; |
1767 | int rate; | 1847 | int rate; |
1768 | u8 i, exrates, *pos; | 1848 | u8 i, exrates, *pos; |
1769 | u32 basic_rates = vif->bss_conf.basic_rates; | 1849 | u32 basic_rates = sdata->vif.bss_conf.basic_rates; |
1770 | 1850 | ||
1771 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 1851 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; |
1772 | exrates = sband->n_bitrates; | 1852 | exrates = sband->n_bitrates; |
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index c3d643a6536c..cea06e9f26f4 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
@@ -52,11 +52,11 @@ static int wme_downgrade_ac(struct sk_buff *skb) | |||
52 | } | 52 | } |
53 | } | 53 | } |
54 | 54 | ||
55 | static u16 ieee80211_downgrade_queue(struct ieee80211_local *local, | 55 | static u16 ieee80211_downgrade_queue(struct ieee80211_sub_if_data *sdata, |
56 | struct sk_buff *skb) | 56 | struct sk_buff *skb) |
57 | { | 57 | { |
58 | /* in case we are a client verify acm is not set for this ac */ | 58 | /* in case we are a client verify acm is not set for this ac */ |
59 | while (unlikely(local->wmm_acm & BIT(skb->priority))) { | 59 | while (unlikely(sdata->wmm_acm & BIT(skb->priority))) { |
60 | if (wme_downgrade_ac(skb)) { | 60 | if (wme_downgrade_ac(skb)) { |
61 | /* | 61 | /* |
62 | * This should not really happen. The AP has marked all | 62 | * This should not really happen. The AP has marked all |
@@ -73,10 +73,11 @@ static u16 ieee80211_downgrade_queue(struct ieee80211_local *local, | |||
73 | } | 73 | } |
74 | 74 | ||
75 | /* Indicate which queue to use for this fully formed 802.11 frame */ | 75 | /* Indicate which queue to use for this fully formed 802.11 frame */ |
76 | u16 ieee80211_select_queue_80211(struct ieee80211_local *local, | 76 | u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, |
77 | struct sk_buff *skb, | 77 | struct sk_buff *skb, |
78 | struct ieee80211_hdr *hdr) | 78 | struct ieee80211_hdr *hdr) |
79 | { | 79 | { |
80 | struct ieee80211_local *local = sdata->local; | ||
80 | u8 *p; | 81 | u8 *p; |
81 | 82 | ||
82 | if (local->hw.queues < IEEE80211_NUM_ACS) | 83 | if (local->hw.queues < IEEE80211_NUM_ACS) |
@@ -94,7 +95,7 @@ u16 ieee80211_select_queue_80211(struct ieee80211_local *local, | |||
94 | p = ieee80211_get_qos_ctl(hdr); | 95 | p = ieee80211_get_qos_ctl(hdr); |
95 | skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; | 96 | skb->priority = *p & IEEE80211_QOS_CTL_TAG1D_MASK; |
96 | 97 | ||
97 | return ieee80211_downgrade_queue(local, skb); | 98 | return ieee80211_downgrade_queue(sdata, skb); |
98 | } | 99 | } |
99 | 100 | ||
100 | /* Indicate which queue to use. */ | 101 | /* Indicate which queue to use. */ |
@@ -156,7 +157,7 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
156 | * data frame has */ | 157 | * data frame has */ |
157 | skb->priority = cfg80211_classify8021d(skb); | 158 | skb->priority = cfg80211_classify8021d(skb); |
158 | 159 | ||
159 | return ieee80211_downgrade_queue(local, skb); | 160 | return ieee80211_downgrade_queue(sdata, skb); |
160 | } | 161 | } |
161 | 162 | ||
162 | void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, | 163 | void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h index ca80818b7b66..7fea4bb8acbc 100644 --- a/net/mac80211/wme.h +++ b/net/mac80211/wme.h | |||
@@ -15,7 +15,7 @@ | |||
15 | 15 | ||
16 | extern const int ieee802_1d_to_ac[8]; | 16 | extern const int ieee802_1d_to_ac[8]; |
17 | 17 | ||
18 | u16 ieee80211_select_queue_80211(struct ieee80211_local *local, | 18 | u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, |
19 | struct sk_buff *skb, | 19 | struct sk_buff *skb, |
20 | struct ieee80211_hdr *hdr); | 20 | struct ieee80211_hdr *hdr); |
21 | u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | 21 | u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c deleted file mode 100644 index b2650a9d45ff..000000000000 --- a/net/mac80211/work.c +++ /dev/null | |||
@@ -1,370 +0,0 @@ | |||
1 | /* | ||
2 | * mac80211 work implementation | ||
3 | * | ||
4 | * Copyright 2003-2008, Jouni Malinen <j@w1.fi> | ||
5 | * Copyright 2004, Instant802 Networks, Inc. | ||
6 | * Copyright 2005, Devicescape Software, Inc. | ||
7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | ||
8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | ||
9 | * Copyright 2009, Johannes Berg <johannes@sipsolutions.net> | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/delay.h> | ||
17 | #include <linux/if_ether.h> | ||
18 | #include <linux/skbuff.h> | ||
19 | #include <linux/if_arp.h> | ||
20 | #include <linux/etherdevice.h> | ||
21 | #include <linux/crc32.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <net/mac80211.h> | ||
24 | #include <asm/unaligned.h> | ||
25 | |||
26 | #include "ieee80211_i.h" | ||
27 | #include "rate.h" | ||
28 | #include "driver-ops.h" | ||
29 | |||
30 | enum work_action { | ||
31 | WORK_ACT_NONE, | ||
32 | WORK_ACT_TIMEOUT, | ||
33 | }; | ||
34 | |||
35 | |||
36 | /* utils */ | ||
37 | static inline void ASSERT_WORK_MTX(struct ieee80211_local *local) | ||
38 | { | ||
39 | lockdep_assert_held(&local->mtx); | ||
40 | } | ||
41 | |||
42 | /* | ||
43 | * We can have multiple work items (and connection probing) | ||
44 | * scheduling this timer, but we need to take care to only | ||
45 | * reschedule it when it should fire _earlier_ than it was | ||
46 | * asked for before, or if it's not pending right now. This | ||
47 | * function ensures that. Note that it then is required to | ||
48 | * run this function for all timeouts after the first one | ||
49 | * has happened -- the work that runs from this timer will | ||
50 | * do that. | ||
51 | */ | ||
52 | static void run_again(struct ieee80211_local *local, | ||
53 | unsigned long timeout) | ||
54 | { | ||
55 | ASSERT_WORK_MTX(local); | ||
56 | |||
57 | if (!timer_pending(&local->work_timer) || | ||
58 | time_before(timeout, local->work_timer.expires)) | ||
59 | mod_timer(&local->work_timer, timeout); | ||
60 | } | ||
61 | |||
62 | void free_work(struct ieee80211_work *wk) | ||
63 | { | ||
64 | kfree_rcu(wk, rcu_head); | ||
65 | } | ||
66 | |||
67 | static enum work_action __must_check | ||
68 | ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk) | ||
69 | { | ||
70 | /* | ||
71 | * First time we run, do nothing -- the generic code will | ||
72 | * have switched to the right channel etc. | ||
73 | */ | ||
74 | if (!wk->started) { | ||
75 | wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration); | ||
76 | |||
77 | cfg80211_ready_on_channel(wk->sdata->dev, (unsigned long) wk, | ||
78 | wk->chan, wk->chan_type, | ||
79 | wk->remain.duration, GFP_KERNEL); | ||
80 | |||
81 | return WORK_ACT_NONE; | ||
82 | } | ||
83 | |||
84 | return WORK_ACT_TIMEOUT; | ||
85 | } | ||
86 | |||
87 | static enum work_action __must_check | ||
88 | ieee80211_offchannel_tx(struct ieee80211_work *wk) | ||
89 | { | ||
90 | if (!wk->started) { | ||
91 | wk->timeout = jiffies + msecs_to_jiffies(wk->offchan_tx.wait); | ||
92 | |||
93 | /* | ||
94 | * After this, offchan_tx.frame remains but now is no | ||
95 | * longer a valid pointer -- we still need it as the | ||
96 | * cookie for canceling this work/status matching. | ||
97 | */ | ||
98 | ieee80211_tx_skb(wk->sdata, wk->offchan_tx.frame); | ||
99 | |||
100 | return WORK_ACT_NONE; | ||
101 | } | ||
102 | |||
103 | return WORK_ACT_TIMEOUT; | ||
104 | } | ||
105 | |||
106 | static void ieee80211_work_timer(unsigned long data) | ||
107 | { | ||
108 | struct ieee80211_local *local = (void *) data; | ||
109 | |||
110 | if (local->quiescing) | ||
111 | return; | ||
112 | |||
113 | ieee80211_queue_work(&local->hw, &local->work_work); | ||
114 | } | ||
115 | |||
116 | static void ieee80211_work_work(struct work_struct *work) | ||
117 | { | ||
118 | struct ieee80211_local *local = | ||
119 | container_of(work, struct ieee80211_local, work_work); | ||
120 | struct ieee80211_work *wk, *tmp; | ||
121 | LIST_HEAD(free_work); | ||
122 | enum work_action rma; | ||
123 | bool remain_off_channel = false; | ||
124 | |||
125 | /* | ||
126 | * ieee80211_queue_work() should have picked up most cases, | ||
127 | * here we'll pick the rest. | ||
128 | */ | ||
129 | if (WARN(local->suspended, "work scheduled while going to suspend\n")) | ||
130 | return; | ||
131 | |||
132 | mutex_lock(&local->mtx); | ||
133 | |||
134 | if (local->scanning) { | ||
135 | mutex_unlock(&local->mtx); | ||
136 | return; | ||
137 | } | ||
138 | |||
139 | ieee80211_recalc_idle(local); | ||
140 | |||
141 | list_for_each_entry_safe(wk, tmp, &local->work_list, list) { | ||
142 | bool started = wk->started; | ||
143 | |||
144 | /* mark work as started if it's on the current off-channel */ | ||
145 | if (!started && local->tmp_channel && | ||
146 | wk->chan == local->tmp_channel && | ||
147 | wk->chan_type == local->tmp_channel_type) { | ||
148 | started = true; | ||
149 | wk->timeout = jiffies; | ||
150 | } | ||
151 | |||
152 | if (!started && !local->tmp_channel) { | ||
153 | ieee80211_offchannel_stop_vifs(local, true); | ||
154 | |||
155 | local->tmp_channel = wk->chan; | ||
156 | local->tmp_channel_type = wk->chan_type; | ||
157 | |||
158 | ieee80211_hw_config(local, 0); | ||
159 | |||
160 | started = true; | ||
161 | wk->timeout = jiffies; | ||
162 | } | ||
163 | |||
164 | /* don't try to work with items that aren't started */ | ||
165 | if (!started) | ||
166 | continue; | ||
167 | |||
168 | if (time_is_after_jiffies(wk->timeout)) { | ||
169 | /* | ||
170 | * This work item isn't supposed to be worked on | ||
171 | * right now, but take care to adjust the timer | ||
172 | * properly. | ||
173 | */ | ||
174 | run_again(local, wk->timeout); | ||
175 | continue; | ||
176 | } | ||
177 | |||
178 | switch (wk->type) { | ||
179 | default: | ||
180 | WARN_ON(1); | ||
181 | /* nothing */ | ||
182 | rma = WORK_ACT_NONE; | ||
183 | break; | ||
184 | case IEEE80211_WORK_ABORT: | ||
185 | rma = WORK_ACT_TIMEOUT; | ||
186 | break; | ||
187 | case IEEE80211_WORK_REMAIN_ON_CHANNEL: | ||
188 | rma = ieee80211_remain_on_channel_timeout(wk); | ||
189 | break; | ||
190 | case IEEE80211_WORK_OFFCHANNEL_TX: | ||
191 | rma = ieee80211_offchannel_tx(wk); | ||
192 | break; | ||
193 | } | ||
194 | |||
195 | wk->started = started; | ||
196 | |||
197 | switch (rma) { | ||
198 | case WORK_ACT_NONE: | ||
199 | /* might have changed the timeout */ | ||
200 | run_again(local, wk->timeout); | ||
201 | break; | ||
202 | case WORK_ACT_TIMEOUT: | ||
203 | list_del_rcu(&wk->list); | ||
204 | synchronize_rcu(); | ||
205 | list_add(&wk->list, &free_work); | ||
206 | break; | ||
207 | default: | ||
208 | WARN(1, "unexpected: %d", rma); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | list_for_each_entry(wk, &local->work_list, list) { | ||
213 | if (!wk->started) | ||
214 | continue; | ||
215 | if (wk->chan != local->tmp_channel || | ||
216 | wk->chan_type != local->tmp_channel_type) | ||
217 | continue; | ||
218 | remain_off_channel = true; | ||
219 | } | ||
220 | |||
221 | if (!remain_off_channel && local->tmp_channel) { | ||
222 | local->tmp_channel = NULL; | ||
223 | ieee80211_hw_config(local, 0); | ||
224 | |||
225 | ieee80211_offchannel_return(local, true); | ||
226 | |||
227 | /* give connection some time to breathe */ | ||
228 | run_again(local, jiffies + HZ/2); | ||
229 | } | ||
230 | |||
231 | ieee80211_recalc_idle(local); | ||
232 | ieee80211_run_deferred_scan(local); | ||
233 | |||
234 | mutex_unlock(&local->mtx); | ||
235 | |||
236 | list_for_each_entry_safe(wk, tmp, &free_work, list) { | ||
237 | wk->done(wk, NULL); | ||
238 | list_del(&wk->list); | ||
239 | kfree(wk); | ||
240 | } | ||
241 | } | ||
242 | |||
243 | void ieee80211_add_work(struct ieee80211_work *wk) | ||
244 | { | ||
245 | struct ieee80211_local *local; | ||
246 | |||
247 | if (WARN_ON(!wk->chan)) | ||
248 | return; | ||
249 | |||
250 | if (WARN_ON(!wk->sdata)) | ||
251 | return; | ||
252 | |||
253 | if (WARN_ON(!wk->done)) | ||
254 | return; | ||
255 | |||
256 | if (WARN_ON(!ieee80211_sdata_running(wk->sdata))) | ||
257 | return; | ||
258 | |||
259 | wk->started = false; | ||
260 | |||
261 | local = wk->sdata->local; | ||
262 | mutex_lock(&local->mtx); | ||
263 | list_add_tail(&wk->list, &local->work_list); | ||
264 | mutex_unlock(&local->mtx); | ||
265 | |||
266 | ieee80211_queue_work(&local->hw, &local->work_work); | ||
267 | } | ||
268 | |||
269 | void ieee80211_work_init(struct ieee80211_local *local) | ||
270 | { | ||
271 | INIT_LIST_HEAD(&local->work_list); | ||
272 | setup_timer(&local->work_timer, ieee80211_work_timer, | ||
273 | (unsigned long)local); | ||
274 | INIT_WORK(&local->work_work, ieee80211_work_work); | ||
275 | } | ||
276 | |||
277 | void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) | ||
278 | { | ||
279 | struct ieee80211_local *local = sdata->local; | ||
280 | struct ieee80211_work *wk; | ||
281 | bool cleanup = false; | ||
282 | |||
283 | mutex_lock(&local->mtx); | ||
284 | list_for_each_entry(wk, &local->work_list, list) { | ||
285 | if (wk->sdata != sdata) | ||
286 | continue; | ||
287 | cleanup = true; | ||
288 | wk->type = IEEE80211_WORK_ABORT; | ||
289 | wk->started = true; | ||
290 | wk->timeout = jiffies; | ||
291 | } | ||
292 | mutex_unlock(&local->mtx); | ||
293 | |||
294 | /* run cleanups etc. */ | ||
295 | if (cleanup) | ||
296 | ieee80211_work_work(&local->work_work); | ||
297 | |||
298 | mutex_lock(&local->mtx); | ||
299 | list_for_each_entry(wk, &local->work_list, list) { | ||
300 | if (wk->sdata != sdata) | ||
301 | continue; | ||
302 | WARN_ON(1); | ||
303 | break; | ||
304 | } | ||
305 | mutex_unlock(&local->mtx); | ||
306 | } | ||
307 | |||
308 | static enum work_done_result ieee80211_remain_done(struct ieee80211_work *wk, | ||
309 | struct sk_buff *skb) | ||
310 | { | ||
311 | /* | ||
312 | * We are done serving the remain-on-channel command. | ||
313 | */ | ||
314 | cfg80211_remain_on_channel_expired(wk->sdata->dev, (unsigned long) wk, | ||
315 | wk->chan, wk->chan_type, | ||
316 | GFP_KERNEL); | ||
317 | |||
318 | return WORK_DONE_DESTROY; | ||
319 | } | ||
320 | |||
321 | int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata, | ||
322 | struct ieee80211_channel *chan, | ||
323 | enum nl80211_channel_type channel_type, | ||
324 | unsigned int duration, u64 *cookie) | ||
325 | { | ||
326 | struct ieee80211_work *wk; | ||
327 | |||
328 | wk = kzalloc(sizeof(*wk), GFP_KERNEL); | ||
329 | if (!wk) | ||
330 | return -ENOMEM; | ||
331 | |||
332 | wk->type = IEEE80211_WORK_REMAIN_ON_CHANNEL; | ||
333 | wk->chan = chan; | ||
334 | wk->chan_type = channel_type; | ||
335 | wk->sdata = sdata; | ||
336 | wk->done = ieee80211_remain_done; | ||
337 | |||
338 | wk->remain.duration = duration; | ||
339 | |||
340 | *cookie = (unsigned long) wk; | ||
341 | |||
342 | ieee80211_add_work(wk); | ||
343 | |||
344 | return 0; | ||
345 | } | ||
346 | |||
347 | int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata, | ||
348 | u64 cookie) | ||
349 | { | ||
350 | struct ieee80211_local *local = sdata->local; | ||
351 | struct ieee80211_work *wk, *tmp; | ||
352 | bool found = false; | ||
353 | |||
354 | mutex_lock(&local->mtx); | ||
355 | list_for_each_entry_safe(wk, tmp, &local->work_list, list) { | ||
356 | if ((unsigned long) wk == cookie) { | ||
357 | wk->timeout = jiffies; | ||
358 | found = true; | ||
359 | break; | ||
360 | } | ||
361 | } | ||
362 | mutex_unlock(&local->mtx); | ||
363 | |||
364 | if (!found) | ||
365 | return -ENOENT; | ||
366 | |||
367 | ieee80211_queue_work(&local->hw, &local->work_work); | ||
368 | |||
369 | return 0; | ||
370 | } | ||