diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/cfg.c | 7 | ||||
-rw-r--r-- | net/mac80211/debugfs.c | 73 | ||||
-rw-r--r-- | net/mac80211/debugfs.h | 2 | ||||
-rw-r--r-- | net/mac80211/debugfs_key.c | 44 | ||||
-rw-r--r-- | net/mac80211/debugfs_netdev.c | 174 | ||||
-rw-r--r-- | net/mac80211/debugfs_sta.c | 38 | ||||
-rw-r--r-- | net/mac80211/ibss.c | 4 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 123 | ||||
-rw-r--r-- | net/mac80211/iface.c | 8 | ||||
-rw-r--r-- | net/mac80211/key.h | 12 | ||||
-rw-r--r-- | net/mac80211/main.c | 11 | ||||
-rw-r--r-- | net/mac80211/rate.c | 7 | ||||
-rw-r--r-- | net/mac80211/rx.c | 173 | ||||
-rw-r--r-- | net/mac80211/scan.c | 119 | ||||
-rw-r--r-- | net/mac80211/sta_info.c | 136 | ||||
-rw-r--r-- | net/mac80211/sta_info.h | 47 | ||||
-rw-r--r-- | net/mac80211/tx.c | 99 | ||||
-rw-r--r-- | net/mac80211/util.c | 8 | ||||
-rw-r--r-- | net/wireless/core.c | 3 | ||||
-rw-r--r-- | net/wireless/core.h | 11 | ||||
-rw-r--r-- | net/wireless/debugfs.c | 15 | ||||
-rw-r--r-- | net/wireless/debugfs.h | 3 | ||||
-rw-r--r-- | net/wireless/mlme.c | 2 | ||||
-rw-r--r-- | net/wireless/nl80211.c | 34 | ||||
-rw-r--r-- | net/wireless/scan.c | 6 | ||||
-rw-r--r-- | net/wireless/wext-compat.c | 6 |
26 files changed, 466 insertions, 699 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 7b5131bd6fa1..56319b51d170 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c | |||
@@ -738,13 +738,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev, | |||
738 | 738 | ||
739 | err = sta_info_insert(sta); | 739 | err = sta_info_insert(sta); |
740 | if (err) { | 740 | if (err) { |
741 | /* STA has been freed */ | ||
742 | if (err == -EEXIST && layer2_update) { | ||
743 | /* Need to update layer 2 devices on reassociation */ | ||
744 | sta = sta_info_get(local, mac); | ||
745 | if (sta) | ||
746 | ieee80211_send_layer2_update(sta); | ||
747 | } | ||
748 | rcu_read_unlock(); | 741 | rcu_read_unlock(); |
749 | return err; | 742 | return err; |
750 | } | 743 | } |
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c index 96991b68f048..82c807723b6f 100644 --- a/net/mac80211/debugfs.c +++ b/net/mac80211/debugfs.c | |||
@@ -1,3 +1,4 @@ | |||
1 | |||
1 | /* | 2 | /* |
2 | * mac80211 debugfs for wireless PHYs | 3 | * mac80211 debugfs for wireless PHYs |
3 | * | 4 | * |
@@ -38,16 +39,10 @@ static const struct file_operations name## _ops = { \ | |||
38 | }; | 39 | }; |
39 | 40 | ||
40 | #define DEBUGFS_ADD(name) \ | 41 | #define DEBUGFS_ADD(name) \ |
41 | local->debugfs.name = debugfs_create_file(#name, 0400, phyd, \ | 42 | debugfs_create_file(#name, 0400, phyd, local, &name## _ops); |
42 | local, &name## _ops); | ||
43 | 43 | ||
44 | #define DEBUGFS_ADD_MODE(name, mode) \ | 44 | #define DEBUGFS_ADD_MODE(name, mode) \ |
45 | local->debugfs.name = debugfs_create_file(#name, mode, phyd, \ | 45 | debugfs_create_file(#name, mode, phyd, local, &name## _ops); |
46 | local, &name## _ops); | ||
47 | |||
48 | #define DEBUGFS_DEL(name) \ | ||
49 | debugfs_remove(local->debugfs.name); \ | ||
50 | local->debugfs.name = NULL; | ||
51 | 46 | ||
52 | 47 | ||
53 | DEBUGFS_READONLY_FILE(frequency, 20, "%d", | 48 | DEBUGFS_READONLY_FILE(frequency, 20, "%d", |
@@ -233,12 +228,7 @@ static const struct file_operations stats_ ##name## _ops = { \ | |||
233 | }; | 228 | }; |
234 | 229 | ||
235 | #define DEBUGFS_STATS_ADD(name) \ | 230 | #define DEBUGFS_STATS_ADD(name) \ |
236 | local->debugfs.stats.name = debugfs_create_file(#name, 0400, statsd,\ | 231 | debugfs_create_file(#name, 0400, statsd, local, &stats_ ##name## _ops); |
237 | local, &stats_ ##name## _ops); | ||
238 | |||
239 | #define DEBUGFS_STATS_DEL(name) \ | ||
240 | debugfs_remove(local->debugfs.stats.name); \ | ||
241 | local->debugfs.stats.name = NULL; | ||
242 | 232 | ||
243 | DEBUGFS_STATS_FILE(transmitted_fragment_count, 20, "%u", | 233 | DEBUGFS_STATS_FILE(transmitted_fragment_count, 20, "%u", |
244 | local->dot11TransmittedFragmentCount); | 234 | local->dot11TransmittedFragmentCount); |
@@ -326,7 +316,6 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
326 | DEBUGFS_ADD(noack); | 316 | DEBUGFS_ADD(noack); |
327 | 317 | ||
328 | statsd = debugfs_create_dir("statistics", phyd); | 318 | statsd = debugfs_create_dir("statistics", phyd); |
329 | local->debugfs.statistics = statsd; | ||
330 | 319 | ||
331 | /* if the dir failed, don't put all the other things into the root! */ | 320 | /* if the dir failed, don't put all the other things into the root! */ |
332 | if (!statsd) | 321 | if (!statsd) |
@@ -367,57 +356,3 @@ void debugfs_hw_add(struct ieee80211_local *local) | |||
367 | DEBUGFS_STATS_ADD(dot11FCSErrorCount); | 356 | DEBUGFS_STATS_ADD(dot11FCSErrorCount); |
368 | DEBUGFS_STATS_ADD(dot11RTSSuccessCount); | 357 | DEBUGFS_STATS_ADD(dot11RTSSuccessCount); |
369 | } | 358 | } |
370 | |||
371 | void debugfs_hw_del(struct ieee80211_local *local) | ||
372 | { | ||
373 | DEBUGFS_DEL(frequency); | ||
374 | DEBUGFS_DEL(total_ps_buffered); | ||
375 | DEBUGFS_DEL(wep_iv); | ||
376 | DEBUGFS_DEL(tsf); | ||
377 | DEBUGFS_DEL(queues); | ||
378 | DEBUGFS_DEL(reset); | ||
379 | DEBUGFS_DEL(noack); | ||
380 | |||
381 | DEBUGFS_STATS_DEL(transmitted_fragment_count); | ||
382 | DEBUGFS_STATS_DEL(multicast_transmitted_frame_count); | ||
383 | DEBUGFS_STATS_DEL(failed_count); | ||
384 | DEBUGFS_STATS_DEL(retry_count); | ||
385 | DEBUGFS_STATS_DEL(multiple_retry_count); | ||
386 | DEBUGFS_STATS_DEL(frame_duplicate_count); | ||
387 | DEBUGFS_STATS_DEL(received_fragment_count); | ||
388 | DEBUGFS_STATS_DEL(multicast_received_frame_count); | ||
389 | DEBUGFS_STATS_DEL(transmitted_frame_count); | ||
390 | DEBUGFS_STATS_DEL(num_scans); | ||
391 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | ||
392 | DEBUGFS_STATS_DEL(tx_handlers_drop); | ||
393 | DEBUGFS_STATS_DEL(tx_handlers_queued); | ||
394 | DEBUGFS_STATS_DEL(tx_handlers_drop_unencrypted); | ||
395 | DEBUGFS_STATS_DEL(tx_handlers_drop_fragment); | ||
396 | DEBUGFS_STATS_DEL(tx_handlers_drop_wep); | ||
397 | DEBUGFS_STATS_DEL(tx_handlers_drop_not_assoc); | ||
398 | DEBUGFS_STATS_DEL(tx_handlers_drop_unauth_port); | ||
399 | DEBUGFS_STATS_DEL(rx_handlers_drop); | ||
400 | DEBUGFS_STATS_DEL(rx_handlers_queued); | ||
401 | DEBUGFS_STATS_DEL(rx_handlers_drop_nullfunc); | ||
402 | DEBUGFS_STATS_DEL(rx_handlers_drop_defrag); | ||
403 | DEBUGFS_STATS_DEL(rx_handlers_drop_short); | ||
404 | DEBUGFS_STATS_DEL(rx_handlers_drop_passive_scan); | ||
405 | DEBUGFS_STATS_DEL(tx_expand_skb_head); | ||
406 | DEBUGFS_STATS_DEL(tx_expand_skb_head_cloned); | ||
407 | DEBUGFS_STATS_DEL(rx_expand_skb_head); | ||
408 | DEBUGFS_STATS_DEL(rx_expand_skb_head2); | ||
409 | DEBUGFS_STATS_DEL(rx_handlers_fragments); | ||
410 | DEBUGFS_STATS_DEL(tx_status_drop); | ||
411 | #endif | ||
412 | DEBUGFS_STATS_DEL(dot11ACKFailureCount); | ||
413 | DEBUGFS_STATS_DEL(dot11RTSFailureCount); | ||
414 | DEBUGFS_STATS_DEL(dot11FCSErrorCount); | ||
415 | DEBUGFS_STATS_DEL(dot11RTSSuccessCount); | ||
416 | |||
417 | debugfs_remove(local->debugfs.statistics); | ||
418 | local->debugfs.statistics = NULL; | ||
419 | debugfs_remove(local->debugfs.stations); | ||
420 | local->debugfs.stations = NULL; | ||
421 | debugfs_remove(local->debugfs.keys); | ||
422 | local->debugfs.keys = NULL; | ||
423 | } | ||
diff --git a/net/mac80211/debugfs.h b/net/mac80211/debugfs.h index dd2541935c27..68e6a2050f9a 100644 --- a/net/mac80211/debugfs.h +++ b/net/mac80211/debugfs.h | |||
@@ -3,14 +3,12 @@ | |||
3 | 3 | ||
4 | #ifdef CONFIG_MAC80211_DEBUGFS | 4 | #ifdef CONFIG_MAC80211_DEBUGFS |
5 | extern void debugfs_hw_add(struct ieee80211_local *local); | 5 | extern void debugfs_hw_add(struct ieee80211_local *local); |
6 | extern void debugfs_hw_del(struct ieee80211_local *local); | ||
7 | extern int mac80211_open_file_generic(struct inode *inode, struct file *file); | 6 | extern int mac80211_open_file_generic(struct inode *inode, struct file *file); |
8 | #else | 7 | #else |
9 | static inline void debugfs_hw_add(struct ieee80211_local *local) | 8 | static inline void debugfs_hw_add(struct ieee80211_local *local) |
10 | { | 9 | { |
11 | return; | 10 | return; |
12 | } | 11 | } |
13 | static inline void debugfs_hw_del(struct ieee80211_local *local) {} | ||
14 | #endif | 12 | #endif |
15 | 13 | ||
16 | #endif /* __MAC80211_DEBUGFS_H */ | 14 | #endif /* __MAC80211_DEBUGFS_H */ |
diff --git a/net/mac80211/debugfs_key.c b/net/mac80211/debugfs_key.c index 99c752588b30..e0f5224630da 100644 --- a/net/mac80211/debugfs_key.c +++ b/net/mac80211/debugfs_key.c | |||
@@ -225,8 +225,8 @@ static ssize_t key_key_read(struct file *file, char __user *userbuf, | |||
225 | KEY_OPS(key); | 225 | KEY_OPS(key); |
226 | 226 | ||
227 | #define DEBUGFS_ADD(name) \ | 227 | #define DEBUGFS_ADD(name) \ |
228 | key->debugfs.name = debugfs_create_file(#name, 0400,\ | 228 | debugfs_create_file(#name, 0400, key->debugfs.dir, \ |
229 | key->debugfs.dir, key, &key_##name##_ops); | 229 | key, &key_##name##_ops); |
230 | 230 | ||
231 | void ieee80211_debugfs_key_add(struct ieee80211_key *key) | 231 | void ieee80211_debugfs_key_add(struct ieee80211_key *key) |
232 | { | 232 | { |
@@ -271,30 +271,12 @@ void ieee80211_debugfs_key_add(struct ieee80211_key *key) | |||
271 | DEBUGFS_ADD(ifindex); | 271 | DEBUGFS_ADD(ifindex); |
272 | }; | 272 | }; |
273 | 273 | ||
274 | #define DEBUGFS_DEL(name) \ | ||
275 | debugfs_remove(key->debugfs.name); key->debugfs.name = NULL; | ||
276 | |||
277 | void ieee80211_debugfs_key_remove(struct ieee80211_key *key) | 274 | void ieee80211_debugfs_key_remove(struct ieee80211_key *key) |
278 | { | 275 | { |
279 | if (!key) | 276 | if (!key) |
280 | return; | 277 | return; |
281 | 278 | ||
282 | DEBUGFS_DEL(keylen); | 279 | debugfs_remove_recursive(key->debugfs.dir); |
283 | DEBUGFS_DEL(flags); | ||
284 | DEBUGFS_DEL(keyidx); | ||
285 | DEBUGFS_DEL(hw_key_idx); | ||
286 | DEBUGFS_DEL(tx_rx_count); | ||
287 | DEBUGFS_DEL(algorithm); | ||
288 | DEBUGFS_DEL(tx_spec); | ||
289 | DEBUGFS_DEL(rx_spec); | ||
290 | DEBUGFS_DEL(replays); | ||
291 | DEBUGFS_DEL(icverrors); | ||
292 | DEBUGFS_DEL(key); | ||
293 | DEBUGFS_DEL(ifindex); | ||
294 | |||
295 | debugfs_remove(key->debugfs.stalink); | ||
296 | key->debugfs.stalink = NULL; | ||
297 | debugfs_remove(key->debugfs.dir); | ||
298 | key->debugfs.dir = NULL; | 280 | key->debugfs.dir = NULL; |
299 | } | 281 | } |
300 | void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) | 282 | void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) |
@@ -302,7 +284,7 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) | |||
302 | char buf[50]; | 284 | char buf[50]; |
303 | struct ieee80211_key *key; | 285 | struct ieee80211_key *key; |
304 | 286 | ||
305 | if (!sdata->debugfsdir) | 287 | if (!sdata->debugfs.dir) |
306 | return; | 288 | return; |
307 | 289 | ||
308 | /* this is running under the key lock */ | 290 | /* this is running under the key lock */ |
@@ -310,9 +292,9 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata) | |||
310 | key = sdata->default_key; | 292 | key = sdata->default_key; |
311 | if (key) { | 293 | if (key) { |
312 | sprintf(buf, "../keys/%d", key->debugfs.cnt); | 294 | sprintf(buf, "../keys/%d", key->debugfs.cnt); |
313 | sdata->common_debugfs.default_key = | 295 | sdata->debugfs.default_key = |
314 | debugfs_create_symlink("default_key", | 296 | debugfs_create_symlink("default_key", |
315 | sdata->debugfsdir, buf); | 297 | sdata->debugfs.dir, buf); |
316 | } else | 298 | } else |
317 | ieee80211_debugfs_key_remove_default(sdata); | 299 | ieee80211_debugfs_key_remove_default(sdata); |
318 | } | 300 | } |
@@ -322,8 +304,8 @@ void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata) | |||
322 | if (!sdata) | 304 | if (!sdata) |
323 | return; | 305 | return; |
324 | 306 | ||
325 | debugfs_remove(sdata->common_debugfs.default_key); | 307 | debugfs_remove(sdata->debugfs.default_key); |
326 | sdata->common_debugfs.default_key = NULL; | 308 | sdata->debugfs.default_key = NULL; |
327 | } | 309 | } |
328 | 310 | ||
329 | void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) | 311 | void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) |
@@ -331,7 +313,7 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) | |||
331 | char buf[50]; | 313 | char buf[50]; |
332 | struct ieee80211_key *key; | 314 | struct ieee80211_key *key; |
333 | 315 | ||
334 | if (!sdata->debugfsdir) | 316 | if (!sdata->debugfs.dir) |
335 | return; | 317 | return; |
336 | 318 | ||
337 | /* this is running under the key lock */ | 319 | /* this is running under the key lock */ |
@@ -339,9 +321,9 @@ void ieee80211_debugfs_key_add_mgmt_default(struct ieee80211_sub_if_data *sdata) | |||
339 | key = sdata->default_mgmt_key; | 321 | key = sdata->default_mgmt_key; |
340 | if (key) { | 322 | if (key) { |
341 | sprintf(buf, "../keys/%d", key->debugfs.cnt); | 323 | sprintf(buf, "../keys/%d", key->debugfs.cnt); |
342 | sdata->common_debugfs.default_mgmt_key = | 324 | sdata->debugfs.default_mgmt_key = |
343 | debugfs_create_symlink("default_mgmt_key", | 325 | debugfs_create_symlink("default_mgmt_key", |
344 | sdata->debugfsdir, buf); | 326 | sdata->debugfs.dir, buf); |
345 | } else | 327 | } else |
346 | ieee80211_debugfs_key_remove_mgmt_default(sdata); | 328 | ieee80211_debugfs_key_remove_mgmt_default(sdata); |
347 | } | 329 | } |
@@ -351,8 +333,8 @@ void ieee80211_debugfs_key_remove_mgmt_default(struct ieee80211_sub_if_data *sda | |||
351 | if (!sdata) | 333 | if (!sdata) |
352 | return; | 334 | return; |
353 | 335 | ||
354 | debugfs_remove(sdata->common_debugfs.default_mgmt_key); | 336 | debugfs_remove(sdata->debugfs.default_mgmt_key); |
355 | sdata->common_debugfs.default_mgmt_key = NULL; | 337 | sdata->debugfs.default_mgmt_key = NULL; |
356 | } | 338 | } |
357 | 339 | ||
358 | void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key, | 340 | void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key, |
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index 61234e79022b..8782264f49e7 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
@@ -152,9 +152,9 @@ IEEE80211_IF_FILE(min_discovery_timeout, | |||
152 | #endif | 152 | #endif |
153 | 153 | ||
154 | 154 | ||
155 | #define DEBUGFS_ADD(name, type)\ | 155 | #define DEBUGFS_ADD(name, type) \ |
156 | sdata->debugfs.type.name = debugfs_create_file(#name, 0400,\ | 156 | debugfs_create_file(#name, 0400, sdata->debugfs.dir, \ |
157 | sdata->debugfsdir, sdata, &name##_ops); | 157 | sdata, &name##_ops); |
158 | 158 | ||
159 | static void add_sta_files(struct ieee80211_sub_if_data *sdata) | 159 | static void add_sta_files(struct ieee80211_sub_if_data *sdata) |
160 | { | 160 | { |
@@ -199,30 +199,32 @@ static void add_monitor_files(struct ieee80211_sub_if_data *sdata) | |||
199 | } | 199 | } |
200 | 200 | ||
201 | #ifdef CONFIG_MAC80211_MESH | 201 | #ifdef CONFIG_MAC80211_MESH |
202 | #define MESHSTATS_ADD(name)\ | ||
203 | sdata->mesh_stats.name = debugfs_create_file(#name, 0400,\ | ||
204 | sdata->mesh_stats_dir, sdata, &name##_ops); | ||
205 | 202 | ||
206 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) | 203 | static void add_mesh_stats(struct ieee80211_sub_if_data *sdata) |
207 | { | 204 | { |
208 | sdata->mesh_stats_dir = debugfs_create_dir("mesh_stats", | 205 | struct dentry *dir = debugfs_create_dir("mesh_stats", |
209 | sdata->debugfsdir); | 206 | sdata->debugfs.dir); |
207 | |||
208 | #define MESHSTATS_ADD(name)\ | ||
209 | debugfs_create_file(#name, 0400, dir, sdata, &name##_ops); | ||
210 | |||
210 | MESHSTATS_ADD(fwded_mcast); | 211 | MESHSTATS_ADD(fwded_mcast); |
211 | MESHSTATS_ADD(fwded_unicast); | 212 | MESHSTATS_ADD(fwded_unicast); |
212 | MESHSTATS_ADD(fwded_frames); | 213 | MESHSTATS_ADD(fwded_frames); |
213 | MESHSTATS_ADD(dropped_frames_ttl); | 214 | MESHSTATS_ADD(dropped_frames_ttl); |
214 | MESHSTATS_ADD(dropped_frames_no_route); | 215 | MESHSTATS_ADD(dropped_frames_no_route); |
215 | MESHSTATS_ADD(estab_plinks); | 216 | MESHSTATS_ADD(estab_plinks); |
217 | #undef MESHSTATS_ADD | ||
216 | } | 218 | } |
217 | 219 | ||
218 | #define MESHPARAMS_ADD(name)\ | ||
219 | sdata->mesh_config.name = debugfs_create_file(#name, 0600,\ | ||
220 | sdata->mesh_config_dir, sdata, &name##_ops); | ||
221 | |||
222 | static void add_mesh_config(struct ieee80211_sub_if_data *sdata) | 220 | static void add_mesh_config(struct ieee80211_sub_if_data *sdata) |
223 | { | 221 | { |
224 | sdata->mesh_config_dir = debugfs_create_dir("mesh_config", | 222 | struct dentry *dir = debugfs_create_dir("mesh_config", |
225 | sdata->debugfsdir); | 223 | sdata->debugfs.dir); |
224 | |||
225 | #define MESHPARAMS_ADD(name) \ | ||
226 | debugfs_create_file(#name, 0600, dir, sdata, &name##_ops); | ||
227 | |||
226 | MESHPARAMS_ADD(dot11MeshMaxRetries); | 228 | MESHPARAMS_ADD(dot11MeshMaxRetries); |
227 | MESHPARAMS_ADD(dot11MeshRetryTimeout); | 229 | MESHPARAMS_ADD(dot11MeshRetryTimeout); |
228 | MESHPARAMS_ADD(dot11MeshConfirmTimeout); | 230 | MESHPARAMS_ADD(dot11MeshConfirmTimeout); |
@@ -236,12 +238,14 @@ static void add_mesh_config(struct ieee80211_sub_if_data *sdata) | |||
236 | MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries); | 238 | MESHPARAMS_ADD(dot11MeshHWMPmaxPREQretries); |
237 | MESHPARAMS_ADD(path_refresh_time); | 239 | MESHPARAMS_ADD(path_refresh_time); |
238 | MESHPARAMS_ADD(min_discovery_timeout); | 240 | MESHPARAMS_ADD(min_discovery_timeout); |
241 | |||
242 | #undef MESHPARAMS_ADD | ||
239 | } | 243 | } |
240 | #endif | 244 | #endif |
241 | 245 | ||
242 | static void add_files(struct ieee80211_sub_if_data *sdata) | 246 | static void add_files(struct ieee80211_sub_if_data *sdata) |
243 | { | 247 | { |
244 | if (!sdata->debugfsdir) | 248 | if (!sdata->debugfs.dir) |
245 | return; | 249 | return; |
246 | 250 | ||
247 | switch (sdata->vif.type) { | 251 | switch (sdata->vif.type) { |
@@ -274,134 +278,6 @@ static void add_files(struct ieee80211_sub_if_data *sdata) | |||
274 | } | 278 | } |
275 | } | 279 | } |
276 | 280 | ||
277 | #define DEBUGFS_DEL(name, type) \ | ||
278 | do { \ | ||
279 | debugfs_remove(sdata->debugfs.type.name); \ | ||
280 | sdata->debugfs.type.name = NULL; \ | ||
281 | } while (0) | ||
282 | |||
283 | static void del_sta_files(struct ieee80211_sub_if_data *sdata) | ||
284 | { | ||
285 | DEBUGFS_DEL(drop_unencrypted, sta); | ||
286 | DEBUGFS_DEL(force_unicast_rateidx, sta); | ||
287 | DEBUGFS_DEL(max_ratectrl_rateidx, sta); | ||
288 | |||
289 | DEBUGFS_DEL(bssid, sta); | ||
290 | DEBUGFS_DEL(aid, sta); | ||
291 | DEBUGFS_DEL(capab, sta); | ||
292 | } | ||
293 | |||
294 | static void del_ap_files(struct ieee80211_sub_if_data *sdata) | ||
295 | { | ||
296 | DEBUGFS_DEL(drop_unencrypted, ap); | ||
297 | DEBUGFS_DEL(force_unicast_rateidx, ap); | ||
298 | DEBUGFS_DEL(max_ratectrl_rateidx, ap); | ||
299 | |||
300 | DEBUGFS_DEL(num_sta_ps, ap); | ||
301 | DEBUGFS_DEL(dtim_count, ap); | ||
302 | DEBUGFS_DEL(num_buffered_multicast, ap); | ||
303 | } | ||
304 | |||
305 | static void del_wds_files(struct ieee80211_sub_if_data *sdata) | ||
306 | { | ||
307 | DEBUGFS_DEL(drop_unencrypted, wds); | ||
308 | DEBUGFS_DEL(force_unicast_rateidx, wds); | ||
309 | DEBUGFS_DEL(max_ratectrl_rateidx, wds); | ||
310 | |||
311 | DEBUGFS_DEL(peer, wds); | ||
312 | } | ||
313 | |||
314 | static void del_vlan_files(struct ieee80211_sub_if_data *sdata) | ||
315 | { | ||
316 | DEBUGFS_DEL(drop_unencrypted, vlan); | ||
317 | DEBUGFS_DEL(force_unicast_rateidx, vlan); | ||
318 | DEBUGFS_DEL(max_ratectrl_rateidx, vlan); | ||
319 | } | ||
320 | |||
321 | static void del_monitor_files(struct ieee80211_sub_if_data *sdata) | ||
322 | { | ||
323 | } | ||
324 | |||
325 | #ifdef CONFIG_MAC80211_MESH | ||
326 | #define MESHSTATS_DEL(name) \ | ||
327 | do { \ | ||
328 | debugfs_remove(sdata->mesh_stats.name); \ | ||
329 | sdata->mesh_stats.name = NULL; \ | ||
330 | } while (0) | ||
331 | |||
332 | static void del_mesh_stats(struct ieee80211_sub_if_data *sdata) | ||
333 | { | ||
334 | MESHSTATS_DEL(fwded_mcast); | ||
335 | MESHSTATS_DEL(fwded_unicast); | ||
336 | MESHSTATS_DEL(fwded_frames); | ||
337 | MESHSTATS_DEL(dropped_frames_ttl); | ||
338 | MESHSTATS_DEL(dropped_frames_no_route); | ||
339 | MESHSTATS_DEL(estab_plinks); | ||
340 | debugfs_remove(sdata->mesh_stats_dir); | ||
341 | sdata->mesh_stats_dir = NULL; | ||
342 | } | ||
343 | |||
344 | #define MESHPARAMS_DEL(name) \ | ||
345 | do { \ | ||
346 | debugfs_remove(sdata->mesh_config.name); \ | ||
347 | sdata->mesh_config.name = NULL; \ | ||
348 | } while (0) | ||
349 | |||
350 | static void del_mesh_config(struct ieee80211_sub_if_data *sdata) | ||
351 | { | ||
352 | MESHPARAMS_DEL(dot11MeshMaxRetries); | ||
353 | MESHPARAMS_DEL(dot11MeshRetryTimeout); | ||
354 | MESHPARAMS_DEL(dot11MeshConfirmTimeout); | ||
355 | MESHPARAMS_DEL(dot11MeshHoldingTimeout); | ||
356 | MESHPARAMS_DEL(dot11MeshTTL); | ||
357 | MESHPARAMS_DEL(auto_open_plinks); | ||
358 | MESHPARAMS_DEL(dot11MeshMaxPeerLinks); | ||
359 | MESHPARAMS_DEL(dot11MeshHWMPactivePathTimeout); | ||
360 | MESHPARAMS_DEL(dot11MeshHWMPpreqMinInterval); | ||
361 | MESHPARAMS_DEL(dot11MeshHWMPnetDiameterTraversalTime); | ||
362 | MESHPARAMS_DEL(dot11MeshHWMPmaxPREQretries); | ||
363 | MESHPARAMS_DEL(path_refresh_time); | ||
364 | MESHPARAMS_DEL(min_discovery_timeout); | ||
365 | debugfs_remove(sdata->mesh_config_dir); | ||
366 | sdata->mesh_config_dir = NULL; | ||
367 | } | ||
368 | #endif | ||
369 | |||
370 | static void del_files(struct ieee80211_sub_if_data *sdata) | ||
371 | { | ||
372 | if (!sdata->debugfsdir) | ||
373 | return; | ||
374 | |||
375 | switch (sdata->vif.type) { | ||
376 | case NL80211_IFTYPE_MESH_POINT: | ||
377 | #ifdef CONFIG_MAC80211_MESH | ||
378 | del_mesh_stats(sdata); | ||
379 | del_mesh_config(sdata); | ||
380 | #endif | ||
381 | break; | ||
382 | case NL80211_IFTYPE_STATION: | ||
383 | del_sta_files(sdata); | ||
384 | break; | ||
385 | case NL80211_IFTYPE_ADHOC: | ||
386 | /* XXX */ | ||
387 | break; | ||
388 | case NL80211_IFTYPE_AP: | ||
389 | del_ap_files(sdata); | ||
390 | break; | ||
391 | case NL80211_IFTYPE_WDS: | ||
392 | del_wds_files(sdata); | ||
393 | break; | ||
394 | case NL80211_IFTYPE_MONITOR: | ||
395 | del_monitor_files(sdata); | ||
396 | break; | ||
397 | case NL80211_IFTYPE_AP_VLAN: | ||
398 | del_vlan_files(sdata); | ||
399 | break; | ||
400 | default: | ||
401 | break; | ||
402 | } | ||
403 | } | ||
404 | |||
405 | static int notif_registered; | 281 | static int notif_registered; |
406 | 282 | ||
407 | void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) | 283 | void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) |
@@ -412,16 +288,18 @@ void ieee80211_debugfs_add_netdev(struct ieee80211_sub_if_data *sdata) | |||
412 | return; | 288 | return; |
413 | 289 | ||
414 | sprintf(buf, "netdev:%s", sdata->dev->name); | 290 | sprintf(buf, "netdev:%s", sdata->dev->name); |
415 | sdata->debugfsdir = debugfs_create_dir(buf, | 291 | sdata->debugfs.dir = debugfs_create_dir(buf, |
416 | sdata->local->hw.wiphy->debugfsdir); | 292 | sdata->local->hw.wiphy->debugfsdir); |
417 | add_files(sdata); | 293 | add_files(sdata); |
418 | } | 294 | } |
419 | 295 | ||
420 | void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) | 296 | void ieee80211_debugfs_remove_netdev(struct ieee80211_sub_if_data *sdata) |
421 | { | 297 | { |
422 | del_files(sdata); | 298 | if (!sdata->debugfs.dir) |
423 | debugfs_remove(sdata->debugfsdir); | 299 | return; |
424 | sdata->debugfsdir = NULL; | 300 | |
301 | debugfs_remove_recursive(sdata->debugfs.dir); | ||
302 | sdata->debugfs.dir = NULL; | ||
425 | } | 303 | } |
426 | 304 | ||
427 | static int netdev_notify(struct notifier_block *nb, | 305 | static int netdev_notify(struct notifier_block *nb, |
@@ -444,7 +322,7 @@ static int netdev_notify(struct notifier_block *nb, | |||
444 | 322 | ||
445 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); | 323 | sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
446 | 324 | ||
447 | dir = sdata->debugfsdir; | 325 | dir = sdata->debugfs.dir; |
448 | 326 | ||
449 | if (!dir) | 327 | if (!dir) |
450 | return 0; | 328 | return 0; |
diff --git a/net/mac80211/debugfs_sta.c b/net/mac80211/debugfs_sta.c index 33a2e892115b..f043c29070d7 100644 --- a/net/mac80211/debugfs_sta.c +++ b/net/mac80211/debugfs_sta.c | |||
@@ -57,7 +57,6 @@ STA_FILE(tx_filtered, tx_filtered_count, LU); | |||
57 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); | 57 | STA_FILE(tx_retry_failed, tx_retry_failed, LU); |
58 | STA_FILE(tx_retry_count, tx_retry_count, LU); | 58 | STA_FILE(tx_retry_count, tx_retry_count, LU); |
59 | STA_FILE(last_signal, last_signal, D); | 59 | STA_FILE(last_signal, last_signal, D); |
60 | STA_FILE(last_qual, last_qual, D); | ||
61 | STA_FILE(last_noise, last_noise, D); | 60 | STA_FILE(last_noise, last_noise, D); |
62 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); | 61 | STA_FILE(wep_weak_iv_count, wep_weak_iv_count, LU); |
63 | 62 | ||
@@ -67,10 +66,11 @@ static ssize_t sta_flags_read(struct file *file, char __user *userbuf, | |||
67 | char buf[100]; | 66 | char buf[100]; |
68 | struct sta_info *sta = file->private_data; | 67 | struct sta_info *sta = file->private_data; |
69 | u32 staflags = get_sta_flags(sta); | 68 | u32 staflags = get_sta_flags(sta); |
70 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s", | 69 | int res = scnprintf(buf, sizeof(buf), "%s%s%s%s%s%s%s%s%s", |
71 | staflags & WLAN_STA_AUTH ? "AUTH\n" : "", | 70 | staflags & WLAN_STA_AUTH ? "AUTH\n" : "", |
72 | staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "", | 71 | staflags & WLAN_STA_ASSOC ? "ASSOC\n" : "", |
73 | staflags & WLAN_STA_PS ? "PS\n" : "", | 72 | staflags & WLAN_STA_PS_STA ? "PS (sta)\n" : "", |
73 | staflags & WLAN_STA_PS_DRIVER ? "PS (driver)\n" : "", | ||
74 | staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", | 74 | staflags & WLAN_STA_AUTHORIZED ? "AUTHORIZED\n" : "", |
75 | staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", | 75 | staflags & WLAN_STA_SHORT_PREAMBLE ? "SHORT PREAMBLE\n" : "", |
76 | staflags & WLAN_STA_WME ? "WME\n" : "", | 76 | staflags & WLAN_STA_WME ? "WME\n" : "", |
@@ -158,13 +158,9 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, | |||
158 | STA_OPS(agg_status); | 158 | STA_OPS(agg_status); |
159 | 159 | ||
160 | #define DEBUGFS_ADD(name) \ | 160 | #define DEBUGFS_ADD(name) \ |
161 | sta->debugfs.name = debugfs_create_file(#name, 0400, \ | 161 | debugfs_create_file(#name, 0400, \ |
162 | sta->debugfs.dir, sta, &sta_ ##name## _ops); | 162 | sta->debugfs.dir, sta, &sta_ ##name## _ops); |
163 | 163 | ||
164 | #define DEBUGFS_DEL(name) \ | ||
165 | debugfs_remove(sta->debugfs.name);\ | ||
166 | sta->debugfs.name = NULL; | ||
167 | |||
168 | 164 | ||
169 | void ieee80211_sta_debugfs_add(struct sta_info *sta) | 165 | void ieee80211_sta_debugfs_add(struct sta_info *sta) |
170 | { | 166 | { |
@@ -209,36 +205,12 @@ void ieee80211_sta_debugfs_add(struct sta_info *sta) | |||
209 | DEBUGFS_ADD(tx_retry_failed); | 205 | DEBUGFS_ADD(tx_retry_failed); |
210 | DEBUGFS_ADD(tx_retry_count); | 206 | DEBUGFS_ADD(tx_retry_count); |
211 | DEBUGFS_ADD(last_signal); | 207 | DEBUGFS_ADD(last_signal); |
212 | DEBUGFS_ADD(last_qual); | ||
213 | DEBUGFS_ADD(last_noise); | 208 | DEBUGFS_ADD(last_noise); |
214 | DEBUGFS_ADD(wep_weak_iv_count); | 209 | DEBUGFS_ADD(wep_weak_iv_count); |
215 | } | 210 | } |
216 | 211 | ||
217 | void ieee80211_sta_debugfs_remove(struct sta_info *sta) | 212 | void ieee80211_sta_debugfs_remove(struct sta_info *sta) |
218 | { | 213 | { |
219 | DEBUGFS_DEL(flags); | 214 | debugfs_remove_recursive(sta->debugfs.dir); |
220 | DEBUGFS_DEL(num_ps_buf_frames); | ||
221 | DEBUGFS_DEL(inactive_ms); | ||
222 | DEBUGFS_DEL(last_seq_ctrl); | ||
223 | DEBUGFS_DEL(agg_status); | ||
224 | DEBUGFS_DEL(aid); | ||
225 | DEBUGFS_DEL(dev); | ||
226 | DEBUGFS_DEL(rx_packets); | ||
227 | DEBUGFS_DEL(tx_packets); | ||
228 | DEBUGFS_DEL(rx_bytes); | ||
229 | DEBUGFS_DEL(tx_bytes); | ||
230 | DEBUGFS_DEL(rx_duplicates); | ||
231 | DEBUGFS_DEL(rx_fragments); | ||
232 | DEBUGFS_DEL(rx_dropped); | ||
233 | DEBUGFS_DEL(tx_fragments); | ||
234 | DEBUGFS_DEL(tx_filtered); | ||
235 | DEBUGFS_DEL(tx_retry_failed); | ||
236 | DEBUGFS_DEL(tx_retry_count); | ||
237 | DEBUGFS_DEL(last_signal); | ||
238 | DEBUGFS_DEL(last_qual); | ||
239 | DEBUGFS_DEL(last_noise); | ||
240 | DEBUGFS_DEL(wep_weak_iv_count); | ||
241 | |||
242 | debugfs_remove(sta->debugfs.dir); | ||
243 | sta->debugfs.dir = NULL; | 215 | sta->debugfs.dir = NULL; |
244 | } | 216 | } |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index f1362f32c17d..fbffce90edbc 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -455,6 +455,10 @@ static void ieee80211_sta_merge_ibss(struct ieee80211_sub_if_data *sdata) | |||
455 | 455 | ||
456 | ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT); | 456 | ieee80211_sta_expire(sdata, IEEE80211_IBSS_INACTIVITY_LIMIT); |
457 | 457 | ||
458 | if (time_before(jiffies, ifibss->last_scan_completed + | ||
459 | IEEE80211_IBSS_MERGE_INTERVAL)) | ||
460 | return; | ||
461 | |||
458 | if (ieee80211_sta_active_ibss(sdata)) | 462 | if (ieee80211_sta_active_ibss(sdata)) |
459 | return; | 463 | return; |
460 | 464 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 588005c84a6d..1ef767366b77 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -176,7 +176,6 @@ struct ieee80211_rx_data { | |||
176 | struct ieee80211_rate *rate; | 176 | struct ieee80211_rate *rate; |
177 | 177 | ||
178 | unsigned int flags; | 178 | unsigned int flags; |
179 | int sent_ps_buffered; | ||
180 | int queue; | 179 | int queue; |
181 | u32 tkip_iv32; | 180 | u32 tkip_iv32; |
182 | u16 tkip_iv16; | 181 | u16 tkip_iv16; |
@@ -471,74 +470,11 @@ struct ieee80211_sub_if_data { | |||
471 | } u; | 470 | } u; |
472 | 471 | ||
473 | #ifdef CONFIG_MAC80211_DEBUGFS | 472 | #ifdef CONFIG_MAC80211_DEBUGFS |
474 | struct dentry *debugfsdir; | ||
475 | union { | ||
476 | struct { | ||
477 | struct dentry *drop_unencrypted; | ||
478 | struct dentry *bssid; | ||
479 | struct dentry *aid; | ||
480 | struct dentry *capab; | ||
481 | struct dentry *force_unicast_rateidx; | ||
482 | struct dentry *max_ratectrl_rateidx; | ||
483 | } sta; | ||
484 | struct { | ||
485 | struct dentry *drop_unencrypted; | ||
486 | struct dentry *num_sta_ps; | ||
487 | struct dentry *dtim_count; | ||
488 | struct dentry *force_unicast_rateidx; | ||
489 | struct dentry *max_ratectrl_rateidx; | ||
490 | struct dentry *num_buffered_multicast; | ||
491 | } ap; | ||
492 | struct { | ||
493 | struct dentry *drop_unencrypted; | ||
494 | struct dentry *peer; | ||
495 | struct dentry *force_unicast_rateidx; | ||
496 | struct dentry *max_ratectrl_rateidx; | ||
497 | } wds; | ||
498 | struct { | ||
499 | struct dentry *drop_unencrypted; | ||
500 | struct dentry *force_unicast_rateidx; | ||
501 | struct dentry *max_ratectrl_rateidx; | ||
502 | } vlan; | ||
503 | struct { | ||
504 | struct dentry *mode; | ||
505 | } monitor; | ||
506 | } debugfs; | ||
507 | struct { | 473 | struct { |
474 | struct dentry *dir; | ||
508 | struct dentry *default_key; | 475 | struct dentry *default_key; |
509 | struct dentry *default_mgmt_key; | 476 | struct dentry *default_mgmt_key; |
510 | } common_debugfs; | 477 | } debugfs; |
511 | |||
512 | #ifdef CONFIG_MAC80211_MESH | ||
513 | struct dentry *mesh_stats_dir; | ||
514 | struct { | ||
515 | struct dentry *fwded_mcast; | ||
516 | struct dentry *fwded_unicast; | ||
517 | struct dentry *fwded_frames; | ||
518 | struct dentry *dropped_frames_ttl; | ||
519 | struct dentry *dropped_frames_no_route; | ||
520 | struct dentry *estab_plinks; | ||
521 | struct timer_list mesh_path_timer; | ||
522 | } mesh_stats; | ||
523 | |||
524 | struct dentry *mesh_config_dir; | ||
525 | struct { | ||
526 | struct dentry *dot11MeshRetryTimeout; | ||
527 | struct dentry *dot11MeshConfirmTimeout; | ||
528 | struct dentry *dot11MeshHoldingTimeout; | ||
529 | struct dentry *dot11MeshMaxRetries; | ||
530 | struct dentry *dot11MeshTTL; | ||
531 | struct dentry *auto_open_plinks; | ||
532 | struct dentry *dot11MeshMaxPeerLinks; | ||
533 | struct dentry *dot11MeshHWMPactivePathTimeout; | ||
534 | struct dentry *dot11MeshHWMPpreqMinInterval; | ||
535 | struct dentry *dot11MeshHWMPnetDiameterTraversalTime; | ||
536 | struct dentry *dot11MeshHWMPmaxPREQretries; | ||
537 | struct dentry *path_refresh_time; | ||
538 | struct dentry *min_discovery_timeout; | ||
539 | } mesh_config; | ||
540 | #endif | ||
541 | |||
542 | #endif | 478 | #endif |
543 | /* must be last, dynamically sized area in this! */ | 479 | /* must be last, dynamically sized area in this! */ |
544 | struct ieee80211_vif vif; | 480 | struct ieee80211_vif vif; |
@@ -730,10 +666,9 @@ struct ieee80211_local { | |||
730 | unsigned long scanning; | 666 | unsigned long scanning; |
731 | struct cfg80211_ssid scan_ssid; | 667 | struct cfg80211_ssid scan_ssid; |
732 | struct cfg80211_scan_request *int_scan_req; | 668 | struct cfg80211_scan_request *int_scan_req; |
733 | struct cfg80211_scan_request *scan_req; | 669 | struct cfg80211_scan_request *scan_req, *hw_scan_req; |
734 | struct ieee80211_channel *scan_channel; | 670 | struct ieee80211_channel *scan_channel; |
735 | const u8 *orig_ies; | 671 | enum ieee80211_band hw_scan_band; |
736 | int orig_ies_len; | ||
737 | int scan_channel_idx; | 672 | int scan_channel_idx; |
738 | int scan_ies_len; | 673 | int scan_ies_len; |
739 | 674 | ||
@@ -818,53 +753,6 @@ struct ieee80211_local { | |||
818 | #ifdef CONFIG_MAC80211_DEBUGFS | 753 | #ifdef CONFIG_MAC80211_DEBUGFS |
819 | struct local_debugfsdentries { | 754 | struct local_debugfsdentries { |
820 | struct dentry *rcdir; | 755 | struct dentry *rcdir; |
821 | struct dentry *rcname; | ||
822 | struct dentry *frequency; | ||
823 | struct dentry *total_ps_buffered; | ||
824 | struct dentry *wep_iv; | ||
825 | struct dentry *tsf; | ||
826 | struct dentry *queues; | ||
827 | struct dentry *reset; | ||
828 | struct dentry *noack; | ||
829 | struct dentry *statistics; | ||
830 | struct local_debugfsdentries_statsdentries { | ||
831 | struct dentry *transmitted_fragment_count; | ||
832 | struct dentry *multicast_transmitted_frame_count; | ||
833 | struct dentry *failed_count; | ||
834 | struct dentry *retry_count; | ||
835 | struct dentry *multiple_retry_count; | ||
836 | struct dentry *frame_duplicate_count; | ||
837 | struct dentry *received_fragment_count; | ||
838 | struct dentry *multicast_received_frame_count; | ||
839 | struct dentry *transmitted_frame_count; | ||
840 | struct dentry *wep_undecryptable_count; | ||
841 | struct dentry *num_scans; | ||
842 | #ifdef CONFIG_MAC80211_DEBUG_COUNTERS | ||
843 | struct dentry *tx_handlers_drop; | ||
844 | struct dentry *tx_handlers_queued; | ||
845 | struct dentry *tx_handlers_drop_unencrypted; | ||
846 | struct dentry *tx_handlers_drop_fragment; | ||
847 | struct dentry *tx_handlers_drop_wep; | ||
848 | struct dentry *tx_handlers_drop_not_assoc; | ||
849 | struct dentry *tx_handlers_drop_unauth_port; | ||
850 | struct dentry *rx_handlers_drop; | ||
851 | struct dentry *rx_handlers_queued; | ||
852 | struct dentry *rx_handlers_drop_nullfunc; | ||
853 | struct dentry *rx_handlers_drop_defrag; | ||
854 | struct dentry *rx_handlers_drop_short; | ||
855 | struct dentry *rx_handlers_drop_passive_scan; | ||
856 | struct dentry *tx_expand_skb_head; | ||
857 | struct dentry *tx_expand_skb_head_cloned; | ||
858 | struct dentry *rx_expand_skb_head; | ||
859 | struct dentry *rx_expand_skb_head2; | ||
860 | struct dentry *rx_handlers_fragments; | ||
861 | struct dentry *tx_status_drop; | ||
862 | #endif | ||
863 | struct dentry *dot11ACKFailureCount; | ||
864 | struct dentry *dot11RTSFailureCount; | ||
865 | struct dentry *dot11FCSErrorCount; | ||
866 | struct dentry *dot11RTSSuccessCount; | ||
867 | } stats; | ||
868 | struct dentry *stations; | 756 | struct dentry *stations; |
869 | struct dentry *keys; | 757 | struct dentry *keys; |
870 | } debugfs; | 758 | } debugfs; |
@@ -1160,7 +1048,8 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
1160 | u8 *extra, size_t extra_len, const u8 *bssid, | 1048 | u8 *extra, size_t extra_len, const u8 *bssid, |
1161 | const u8 *key, u8 key_len, u8 key_idx); | 1049 | const u8 *key, u8 key_len, u8 key_idx); |
1162 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 1050 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
1163 | const u8 *ie, size_t ie_len); | 1051 | const u8 *ie, size_t ie_len, |
1052 | enum ieee80211_band band); | ||
1164 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | 1053 | void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, |
1165 | const u8 *ssid, size_t ssid_len, | 1054 | const u8 *ssid, size_t ssid_len, |
1166 | const u8 *ie, size_t ie_len); | 1055 | const u8 *ie, size_t ie_len); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 14f10eb91c5c..8495161b99b8 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -214,8 +214,8 @@ static int ieee80211_open(struct net_device *dev) | |||
214 | /* must be before the call to ieee80211_configure_filter */ | 214 | /* must be before the call to ieee80211_configure_filter */ |
215 | local->monitors++; | 215 | local->monitors++; |
216 | if (local->monitors == 1) { | 216 | if (local->monitors == 1) { |
217 | local->hw.conf.flags |= IEEE80211_CONF_RADIOTAP; | 217 | local->hw.conf.flags |= IEEE80211_CONF_MONITOR; |
218 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP; | 218 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; |
219 | } | 219 | } |
220 | 220 | ||
221 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | 221 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) |
@@ -435,8 +435,8 @@ static int ieee80211_stop(struct net_device *dev) | |||
435 | 435 | ||
436 | local->monitors--; | 436 | local->monitors--; |
437 | if (local->monitors == 0) { | 437 | if (local->monitors == 0) { |
438 | local->hw.conf.flags &= ~IEEE80211_CONF_RADIOTAP; | 438 | local->hw.conf.flags &= ~IEEE80211_CONF_MONITOR; |
439 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_RADIOTAP; | 439 | hw_reconf_flags |= IEEE80211_CONF_CHANGE_MONITOR; |
440 | } | 440 | } |
441 | 441 | ||
442 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) | 442 | if (sdata->u.mntr_flags & MONITOR_FLAG_FCSFAIL) |
diff --git a/net/mac80211/key.h b/net/mac80211/key.h index 9572e00f532c..a49f93b79e92 100644 --- a/net/mac80211/key.h +++ b/net/mac80211/key.h | |||
@@ -118,18 +118,6 @@ struct ieee80211_key { | |||
118 | struct { | 118 | struct { |
119 | struct dentry *stalink; | 119 | struct dentry *stalink; |
120 | struct dentry *dir; | 120 | struct dentry *dir; |
121 | struct dentry *keylen; | ||
122 | struct dentry *flags; | ||
123 | struct dentry *keyidx; | ||
124 | struct dentry *hw_key_idx; | ||
125 | struct dentry *tx_rx_count; | ||
126 | struct dentry *algorithm; | ||
127 | struct dentry *tx_spec; | ||
128 | struct dentry *rx_spec; | ||
129 | struct dentry *replays; | ||
130 | struct dentry *icverrors; | ||
131 | struct dentry *key; | ||
132 | struct dentry *ifindex; | ||
133 | int cnt; | 121 | int cnt; |
134 | } debugfs; | 122 | } debugfs; |
135 | #endif | 123 | #endif |
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 797f53942e5f..beb8718d905e 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -385,13 +385,13 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
385 | * can be unknown, for example with different interrupt status | 385 | * can be unknown, for example with different interrupt status |
386 | * bits. | 386 | * bits. |
387 | */ | 387 | */ |
388 | if (test_sta_flags(sta, WLAN_STA_PS) && | 388 | if (test_sta_flags(sta, WLAN_STA_PS_STA) && |
389 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | 389 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { |
390 | skb_queue_tail(&sta->tx_filtered, skb); | 390 | skb_queue_tail(&sta->tx_filtered, skb); |
391 | return; | 391 | return; |
392 | } | 392 | } |
393 | 393 | ||
394 | if (!test_sta_flags(sta, WLAN_STA_PS) && | 394 | if (!test_sta_flags(sta, WLAN_STA_PS_STA) && |
395 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { | 395 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { |
396 | /* Software retry the packet once */ | 396 | /* Software retry the packet once */ |
397 | info->flags |= IEEE80211_TX_INTFL_RETRIED; | 397 | info->flags |= IEEE80211_TX_INTFL_RETRIED; |
@@ -406,7 +406,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | |||
406 | "queue_len=%d PS=%d @%lu\n", | 406 | "queue_len=%d PS=%d @%lu\n", |
407 | wiphy_name(local->hw.wiphy), | 407 | wiphy_name(local->hw.wiphy), |
408 | skb_queue_len(&sta->tx_filtered), | 408 | skb_queue_len(&sta->tx_filtered), |
409 | !!test_sta_flags(sta, WLAN_STA_PS), jiffies); | 409 | !!test_sta_flags(sta, WLAN_STA_PS_STA), jiffies); |
410 | #endif | 410 | #endif |
411 | dev_kfree_skb(skb); | 411 | dev_kfree_skb(skb); |
412 | } | 412 | } |
@@ -446,7 +446,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
446 | 446 | ||
447 | if (sta) { | 447 | if (sta) { |
448 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | 448 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && |
449 | test_sta_flags(sta, WLAN_STA_PS)) { | 449 | test_sta_flags(sta, WLAN_STA_PS_STA)) { |
450 | /* | 450 | /* |
451 | * The STA is in power save mode, so assume | 451 | * The STA is in power save mode, so assume |
452 | * that this TX packet failed because of that. | 452 | * that this TX packet failed because of that. |
@@ -901,6 +901,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
901 | i++; | 901 | i++; |
902 | } | 902 | } |
903 | } | 903 | } |
904 | local->int_scan_req->n_channels = i; | ||
904 | 905 | ||
905 | local->network_latency_notifier.notifier_call = | 906 | local->network_latency_notifier.notifier_call = |
906 | ieee80211_max_network_latency; | 907 | ieee80211_max_network_latency; |
@@ -923,7 +924,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
923 | fail_wep: | 924 | fail_wep: |
924 | sta_info_stop(local); | 925 | sta_info_stop(local); |
925 | fail_sta_info: | 926 | fail_sta_info: |
926 | debugfs_hw_del(local); | ||
927 | destroy_workqueue(local->workqueue); | 927 | destroy_workqueue(local->workqueue); |
928 | fail_workqueue: | 928 | fail_workqueue: |
929 | wiphy_unregister(local->hw.wiphy); | 929 | wiphy_unregister(local->hw.wiphy); |
@@ -959,7 +959,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
959 | ieee80211_clear_tx_pending(local); | 959 | ieee80211_clear_tx_pending(local); |
960 | sta_info_stop(local); | 960 | sta_info_stop(local); |
961 | rate_control_deinitialize(local); | 961 | rate_control_deinitialize(local); |
962 | debugfs_hw_del(local); | ||
963 | 962 | ||
964 | if (skb_queue_len(&local->skb_queue) | 963 | if (skb_queue_len(&local->skb_queue) |
965 | || skb_queue_len(&local->skb_queue_unreliable)) | 964 | || skb_queue_len(&local->skb_queue_unreliable)) |
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c index b33efc4fc267..ccda7454fb17 100644 --- a/net/mac80211/rate.c +++ b/net/mac80211/rate.c | |||
@@ -163,8 +163,7 @@ struct rate_control_ref *rate_control_alloc(const char *name, | |||
163 | #ifdef CONFIG_MAC80211_DEBUGFS | 163 | #ifdef CONFIG_MAC80211_DEBUGFS |
164 | debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir); | 164 | debugfsdir = debugfs_create_dir("rc", local->hw.wiphy->debugfsdir); |
165 | local->debugfs.rcdir = debugfsdir; | 165 | local->debugfs.rcdir = debugfsdir; |
166 | local->debugfs.rcname = debugfs_create_file("name", 0400, debugfsdir, | 166 | debugfs_create_file("name", 0400, debugfsdir, ref, &rcname_ops); |
167 | ref, &rcname_ops); | ||
168 | #endif | 167 | #endif |
169 | 168 | ||
170 | ref->priv = ref->ops->alloc(&local->hw, debugfsdir); | 169 | ref->priv = ref->ops->alloc(&local->hw, debugfsdir); |
@@ -188,9 +187,7 @@ static void rate_control_release(struct kref *kref) | |||
188 | ctrl_ref->ops->free(ctrl_ref->priv); | 187 | ctrl_ref->ops->free(ctrl_ref->priv); |
189 | 188 | ||
190 | #ifdef CONFIG_MAC80211_DEBUGFS | 189 | #ifdef CONFIG_MAC80211_DEBUGFS |
191 | debugfs_remove(ctrl_ref->local->debugfs.rcname); | 190 | debugfs_remove_recursive(ctrl_ref->local->debugfs.rcdir); |
192 | ctrl_ref->local->debugfs.rcname = NULL; | ||
193 | debugfs_remove(ctrl_ref->local->debugfs.rcdir); | ||
194 | ctrl_ref->local->debugfs.rcdir = NULL; | 191 | ctrl_ref->local->debugfs.rcdir = NULL; |
195 | #endif | 192 | #endif |
196 | 193 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 5c385e3c1d1f..28316b2a585f 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -39,11 +39,8 @@ static u8 ieee80211_sta_manage_reorder_buf(struct ieee80211_hw *hw, | |||
39 | * only useful for monitoring. | 39 | * only useful for monitoring. |
40 | */ | 40 | */ |
41 | static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, | 41 | static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, |
42 | struct sk_buff *skb, | 42 | struct sk_buff *skb) |
43 | int rtap_len) | ||
44 | { | 43 | { |
45 | skb_pull(skb, rtap_len); | ||
46 | |||
47 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { | 44 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) { |
48 | if (likely(skb->len > FCS_LEN)) | 45 | if (likely(skb->len > FCS_LEN)) |
49 | skb_trim(skb, skb->len - FCS_LEN); | 46 | skb_trim(skb, skb->len - FCS_LEN); |
@@ -59,15 +56,14 @@ static struct sk_buff *remove_monitor_info(struct ieee80211_local *local, | |||
59 | } | 56 | } |
60 | 57 | ||
61 | static inline int should_drop_frame(struct sk_buff *skb, | 58 | static inline int should_drop_frame(struct sk_buff *skb, |
62 | int present_fcs_len, | 59 | int present_fcs_len) |
63 | int radiotap_len) | ||
64 | { | 60 | { |
65 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 61 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
66 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; | 62 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; |
67 | 63 | ||
68 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) | 64 | if (status->flag & (RX_FLAG_FAILED_FCS_CRC | RX_FLAG_FAILED_PLCP_CRC)) |
69 | return 1; | 65 | return 1; |
70 | if (unlikely(skb->len < 16 + present_fcs_len + radiotap_len)) | 66 | if (unlikely(skb->len < 16 + present_fcs_len)) |
71 | return 1; | 67 | return 1; |
72 | if (ieee80211_is_ctl(hdr->frame_control) && | 68 | if (ieee80211_is_ctl(hdr->frame_control) && |
73 | !ieee80211_is_pspoll(hdr->frame_control) && | 69 | !ieee80211_is_pspoll(hdr->frame_control) && |
@@ -95,10 +91,6 @@ ieee80211_rx_radiotap_len(struct ieee80211_local *local, | |||
95 | if (len & 1) /* padding for RX_FLAGS if necessary */ | 91 | if (len & 1) /* padding for RX_FLAGS if necessary */ |
96 | len++; | 92 | len++; |
97 | 93 | ||
98 | /* make sure radiotap starts at a naturally aligned address */ | ||
99 | if (len % 8) | ||
100 | len = roundup(len, 8); | ||
101 | |||
102 | return len; | 94 | return len; |
103 | } | 95 | } |
104 | 96 | ||
@@ -116,6 +108,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
116 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); | 108 | struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); |
117 | struct ieee80211_radiotap_header *rthdr; | 109 | struct ieee80211_radiotap_header *rthdr; |
118 | unsigned char *pos; | 110 | unsigned char *pos; |
111 | u16 rx_flags = 0; | ||
119 | 112 | ||
120 | rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); | 113 | rthdr = (struct ieee80211_radiotap_header *)skb_push(skb, rtap_len); |
121 | memset(rthdr, 0, rtap_len); | 114 | memset(rthdr, 0, rtap_len); |
@@ -134,7 +127,7 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
134 | 127 | ||
135 | /* IEEE80211_RADIOTAP_TSFT */ | 128 | /* IEEE80211_RADIOTAP_TSFT */ |
136 | if (status->flag & RX_FLAG_TSFT) { | 129 | if (status->flag & RX_FLAG_TSFT) { |
137 | *(__le64 *)pos = cpu_to_le64(status->mactime); | 130 | put_unaligned_le64(status->mactime, pos); |
138 | rthdr->it_present |= | 131 | rthdr->it_present |= |
139 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); | 132 | cpu_to_le32(1 << IEEE80211_RADIOTAP_TSFT); |
140 | pos += 8; | 133 | pos += 8; |
@@ -166,17 +159,17 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
166 | pos++; | 159 | pos++; |
167 | 160 | ||
168 | /* IEEE80211_RADIOTAP_CHANNEL */ | 161 | /* IEEE80211_RADIOTAP_CHANNEL */ |
169 | *(__le16 *)pos = cpu_to_le16(status->freq); | 162 | put_unaligned_le16(status->freq, pos); |
170 | pos += 2; | 163 | pos += 2; |
171 | if (status->band == IEEE80211_BAND_5GHZ) | 164 | if (status->band == IEEE80211_BAND_5GHZ) |
172 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM | | 165 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ, |
173 | IEEE80211_CHAN_5GHZ); | 166 | pos); |
174 | else if (rate->flags & IEEE80211_RATE_ERP_G) | 167 | else if (rate->flags & IEEE80211_RATE_ERP_G) |
175 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_OFDM | | 168 | put_unaligned_le16(IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ, |
176 | IEEE80211_CHAN_2GHZ); | 169 | pos); |
177 | else | 170 | else |
178 | *(__le16 *)pos = cpu_to_le16(IEEE80211_CHAN_CCK | | 171 | put_unaligned_le16(IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ, |
179 | IEEE80211_CHAN_2GHZ); | 172 | pos); |
180 | pos += 2; | 173 | pos += 2; |
181 | 174 | ||
182 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ | 175 | /* IEEE80211_RADIOTAP_DBM_ANTSIGNAL */ |
@@ -205,10 +198,11 @@ ieee80211_add_rx_radiotap_header(struct ieee80211_local *local, | |||
205 | 198 | ||
206 | /* IEEE80211_RADIOTAP_RX_FLAGS */ | 199 | /* IEEE80211_RADIOTAP_RX_FLAGS */ |
207 | /* ensure 2 byte alignment for the 2 byte field as required */ | 200 | /* ensure 2 byte alignment for the 2 byte field as required */ |
208 | if ((pos - (unsigned char *)rthdr) & 1) | 201 | if ((pos - (u8 *)rthdr) & 1) |
209 | pos++; | 202 | pos++; |
210 | if (status->flag & RX_FLAG_FAILED_PLCP_CRC) | 203 | if (status->flag & RX_FLAG_FAILED_PLCP_CRC) |
211 | *(__le16 *)pos |= cpu_to_le16(IEEE80211_RADIOTAP_F_RX_BADPLCP); | 204 | rx_flags |= IEEE80211_RADIOTAP_F_RX_BADPLCP; |
205 | put_unaligned_le16(rx_flags, pos); | ||
212 | pos += 2; | 206 | pos += 2; |
213 | } | 207 | } |
214 | 208 | ||
@@ -227,7 +221,6 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
227 | struct sk_buff *skb, *skb2; | 221 | struct sk_buff *skb, *skb2; |
228 | struct net_device *prev_dev = NULL; | 222 | struct net_device *prev_dev = NULL; |
229 | int present_fcs_len = 0; | 223 | int present_fcs_len = 0; |
230 | int rtap_len = 0; | ||
231 | 224 | ||
232 | /* | 225 | /* |
233 | * First, we may need to make a copy of the skb because | 226 | * First, we may need to make a copy of the skb because |
@@ -237,25 +230,23 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
237 | * We don't need to, of course, if we aren't going to return | 230 | * We don't need to, of course, if we aren't going to return |
238 | * the SKB because it has a bad FCS/PLCP checksum. | 231 | * the SKB because it has a bad FCS/PLCP checksum. |
239 | */ | 232 | */ |
240 | if (status->flag & RX_FLAG_RADIOTAP) | 233 | |
241 | rtap_len = ieee80211_get_radiotap_len(origskb->data); | 234 | /* room for the radiotap header based on driver features */ |
242 | else | 235 | needed_headroom = ieee80211_rx_radiotap_len(local, status); |
243 | /* room for the radiotap header based on driver features */ | ||
244 | needed_headroom = ieee80211_rx_radiotap_len(local, status); | ||
245 | 236 | ||
246 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) | 237 | if (local->hw.flags & IEEE80211_HW_RX_INCLUDES_FCS) |
247 | present_fcs_len = FCS_LEN; | 238 | present_fcs_len = FCS_LEN; |
248 | 239 | ||
249 | if (!local->monitors) { | 240 | if (!local->monitors) { |
250 | if (should_drop_frame(origskb, present_fcs_len, rtap_len)) { | 241 | if (should_drop_frame(origskb, present_fcs_len)) { |
251 | dev_kfree_skb(origskb); | 242 | dev_kfree_skb(origskb); |
252 | return NULL; | 243 | return NULL; |
253 | } | 244 | } |
254 | 245 | ||
255 | return remove_monitor_info(local, origskb, rtap_len); | 246 | return remove_monitor_info(local, origskb); |
256 | } | 247 | } |
257 | 248 | ||
258 | if (should_drop_frame(origskb, present_fcs_len, rtap_len)) { | 249 | if (should_drop_frame(origskb, present_fcs_len)) { |
259 | /* only need to expand headroom if necessary */ | 250 | /* only need to expand headroom if necessary */ |
260 | skb = origskb; | 251 | skb = origskb; |
261 | origskb = NULL; | 252 | origskb = NULL; |
@@ -279,16 +270,14 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, | |||
279 | */ | 270 | */ |
280 | skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC); | 271 | skb = skb_copy_expand(origskb, needed_headroom, 0, GFP_ATOMIC); |
281 | 272 | ||
282 | origskb = remove_monitor_info(local, origskb, rtap_len); | 273 | origskb = remove_monitor_info(local, origskb); |
283 | 274 | ||
284 | if (!skb) | 275 | if (!skb) |
285 | return origskb; | 276 | return origskb; |
286 | } | 277 | } |
287 | 278 | ||
288 | /* if necessary, prepend radiotap information */ | 279 | /* prepend radiotap information */ |
289 | if (!(status->flag & RX_FLAG_RADIOTAP)) | 280 | ieee80211_add_rx_radiotap_header(local, skb, rate, needed_headroom); |
290 | ieee80211_add_rx_radiotap_header(local, skb, rate, | ||
291 | needed_headroom); | ||
292 | 281 | ||
293 | skb_reset_mac_header(skb); | 282 | skb_reset_mac_header(skb); |
294 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 283 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -792,7 +781,7 @@ static void ap_sta_ps_start(struct sta_info *sta) | |||
792 | struct ieee80211_local *local = sdata->local; | 781 | struct ieee80211_local *local = sdata->local; |
793 | 782 | ||
794 | atomic_inc(&sdata->bss->num_sta_ps); | 783 | atomic_inc(&sdata->bss->num_sta_ps); |
795 | set_sta_flags(sta, WLAN_STA_PS); | 784 | set_sta_flags(sta, WLAN_STA_PS_STA); |
796 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta); | 785 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_SLEEP, &sta->sta); |
797 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 786 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
798 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", | 787 | printk(KERN_DEBUG "%s: STA %pM aid %d enters power save mode\n", |
@@ -800,38 +789,28 @@ static void ap_sta_ps_start(struct sta_info *sta) | |||
800 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 789 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
801 | } | 790 | } |
802 | 791 | ||
803 | static int ap_sta_ps_end(struct sta_info *sta) | 792 | static void ap_sta_ps_end(struct sta_info *sta) |
804 | { | 793 | { |
805 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 794 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
806 | struct ieee80211_local *local = sdata->local; | ||
807 | int sent, buffered; | ||
808 | 795 | ||
809 | atomic_dec(&sdata->bss->num_sta_ps); | 796 | atomic_dec(&sdata->bss->num_sta_ps); |
810 | 797 | ||
811 | clear_sta_flags(sta, WLAN_STA_PS); | 798 | clear_sta_flags(sta, WLAN_STA_PS_STA); |
812 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta); | ||
813 | |||
814 | if (!skb_queue_empty(&sta->ps_tx_buf)) | ||
815 | sta_info_clear_tim_bit(sta); | ||
816 | 799 | ||
817 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 800 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
818 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", | 801 | printk(KERN_DEBUG "%s: STA %pM aid %d exits power save mode\n", |
819 | sdata->dev->name, sta->sta.addr, sta->sta.aid); | 802 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
820 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 803 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
821 | 804 | ||
822 | /* Send all buffered frames to the station */ | 805 | if (test_sta_flags(sta, WLAN_STA_PS_DRIVER)) { |
823 | sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); | ||
824 | buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf); | ||
825 | sent += buffered; | ||
826 | local->total_ps_buffered -= buffered; | ||
827 | |||
828 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 806 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
829 | printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " | 807 | printk(KERN_DEBUG "%s: STA %pM aid %d driver-ps-blocked\n", |
830 | "since STA not sleeping anymore\n", sdata->dev->name, | 808 | sdata->dev->name, sta->sta.addr, sta->sta.aid); |
831 | sta->sta.addr, sta->sta.aid, sent - buffered, buffered); | ||
832 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | 809 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ |
810 | return; | ||
811 | } | ||
833 | 812 | ||
834 | return sent; | 813 | ieee80211_sta_ps_deliver_wakeup(sta); |
835 | } | 814 | } |
836 | 815 | ||
837 | static ieee80211_rx_result debug_noinline | 816 | static ieee80211_rx_result debug_noinline |
@@ -870,7 +849,6 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
870 | sta->rx_fragments++; | 849 | sta->rx_fragments++; |
871 | sta->rx_bytes += rx->skb->len; | 850 | sta->rx_bytes += rx->skb->len; |
872 | sta->last_signal = rx->status->signal; | 851 | sta->last_signal = rx->status->signal; |
873 | sta->last_qual = rx->status->qual; | ||
874 | sta->last_noise = rx->status->noise; | 852 | sta->last_noise = rx->status->noise; |
875 | 853 | ||
876 | /* | 854 | /* |
@@ -880,7 +858,7 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
880 | if (!ieee80211_has_morefrags(hdr->frame_control) && | 858 | if (!ieee80211_has_morefrags(hdr->frame_control) && |
881 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || | 859 | (rx->sdata->vif.type == NL80211_IFTYPE_AP || |
882 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { | 860 | rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN)) { |
883 | if (test_sta_flags(sta, WLAN_STA_PS)) { | 861 | if (test_sta_flags(sta, WLAN_STA_PS_STA)) { |
884 | /* | 862 | /* |
885 | * Ignore doze->wake transitions that are | 863 | * Ignore doze->wake transitions that are |
886 | * indicated by non-data frames, the standard | 864 | * indicated by non-data frames, the standard |
@@ -891,19 +869,24 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx) | |||
891 | */ | 869 | */ |
892 | if (ieee80211_is_data(hdr->frame_control) && | 870 | if (ieee80211_is_data(hdr->frame_control) && |
893 | !ieee80211_has_pm(hdr->frame_control)) | 871 | !ieee80211_has_pm(hdr->frame_control)) |
894 | rx->sent_ps_buffered += ap_sta_ps_end(sta); | 872 | ap_sta_ps_end(sta); |
895 | } else { | 873 | } else { |
896 | if (ieee80211_has_pm(hdr->frame_control)) | 874 | if (ieee80211_has_pm(hdr->frame_control)) |
897 | ap_sta_ps_start(sta); | 875 | ap_sta_ps_start(sta); |
898 | } | 876 | } |
899 | } | 877 | } |
900 | 878 | ||
901 | /* Drop data::nullfunc frames silently, since they are used only to | 879 | /* |
902 | * control station power saving mode. */ | 880 | * Drop (qos-)data::nullfunc frames silently, since they |
903 | if (ieee80211_is_nullfunc(hdr->frame_control)) { | 881 | * are used only to control station power saving mode. |
882 | */ | ||
883 | if (ieee80211_is_nullfunc(hdr->frame_control) || | ||
884 | ieee80211_is_qos_nullfunc(hdr->frame_control)) { | ||
904 | I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); | 885 | I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); |
905 | /* Update counter and free packet here to avoid counting this | 886 | /* |
906 | * as a dropped packed. */ | 887 | * Update counter and free packet here to avoid |
888 | * counting this as a dropped packed. | ||
889 | */ | ||
907 | sta->rx_packets++; | 890 | sta->rx_packets++; |
908 | dev_kfree_skb(rx->skb); | 891 | dev_kfree_skb(rx->skb); |
909 | return RX_QUEUED; | 892 | return RX_QUEUED; |
@@ -1103,9 +1086,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) | |||
1103 | static ieee80211_rx_result debug_noinline | 1086 | static ieee80211_rx_result debug_noinline |
1104 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | 1087 | ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) |
1105 | { | 1088 | { |
1106 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev); | 1089 | struct ieee80211_sub_if_data *sdata = rx->sdata; |
1107 | struct sk_buff *skb; | ||
1108 | int no_pending_pkts; | ||
1109 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; | 1090 | __le16 fc = ((struct ieee80211_hdr *)rx->skb->data)->frame_control; |
1110 | 1091 | ||
1111 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || | 1092 | if (likely(!rx->sta || !ieee80211_is_pspoll(fc) || |
@@ -1116,56 +1097,10 @@ ieee80211_rx_h_ps_poll(struct ieee80211_rx_data *rx) | |||
1116 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)) | 1097 | (sdata->vif.type != NL80211_IFTYPE_AP_VLAN)) |
1117 | return RX_DROP_UNUSABLE; | 1098 | return RX_DROP_UNUSABLE; |
1118 | 1099 | ||
1119 | skb = skb_dequeue(&rx->sta->tx_filtered); | 1100 | if (!test_sta_flags(rx->sta, WLAN_STA_PS_DRIVER)) |
1120 | if (!skb) { | 1101 | ieee80211_sta_ps_deliver_poll_response(rx->sta); |
1121 | skb = skb_dequeue(&rx->sta->ps_tx_buf); | 1102 | else |
1122 | if (skb) | 1103 | set_sta_flags(rx->sta, WLAN_STA_PSPOLL); |
1123 | rx->local->total_ps_buffered--; | ||
1124 | } | ||
1125 | no_pending_pkts = skb_queue_empty(&rx->sta->tx_filtered) && | ||
1126 | skb_queue_empty(&rx->sta->ps_tx_buf); | ||
1127 | |||
1128 | if (skb) { | ||
1129 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
1130 | struct ieee80211_hdr *hdr = | ||
1131 | (struct ieee80211_hdr *) skb->data; | ||
1132 | |||
1133 | /* | ||
1134 | * Tell TX path to send this frame even though the STA may | ||
1135 | * still remain is PS mode after this frame exchange. | ||
1136 | */ | ||
1137 | info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE; | ||
1138 | |||
1139 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | ||
1140 | printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n", | ||
1141 | rx->sta->sta.addr, rx->sta->sta.aid, | ||
1142 | skb_queue_len(&rx->sta->ps_tx_buf)); | ||
1143 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1144 | |||
1145 | /* Use MoreData flag to indicate whether there are more | ||
1146 | * buffered frames for this STA */ | ||
1147 | if (no_pending_pkts) | ||
1148 | hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA); | ||
1149 | else | ||
1150 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); | ||
1151 | |||
1152 | ieee80211_add_pending_skb(rx->local, skb); | ||
1153 | |||
1154 | if (no_pending_pkts) | ||
1155 | sta_info_clear_tim_bit(rx->sta); | ||
1156 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | ||
1157 | } else if (!rx->sent_ps_buffered) { | ||
1158 | /* | ||
1159 | * FIXME: This can be the result of a race condition between | ||
1160 | * us expiring a frame and the station polling for it. | ||
1161 | * Should we send it a null-func frame indicating we | ||
1162 | * have nothing buffered for it? | ||
1163 | */ | ||
1164 | printk(KERN_DEBUG "%s: STA %pM sent PS Poll even " | ||
1165 | "though there are no buffered frames for it\n", | ||
1166 | rx->dev->name, rx->sta->sta.addr); | ||
1167 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
1168 | } | ||
1169 | 1104 | ||
1170 | /* Free PS Poll skb here instead of returning RX_DROP that would | 1105 | /* Free PS Poll skb here instead of returning RX_DROP that would |
1171 | * count as an dropped frame. */ | 1106 | * count as an dropped frame. */ |
@@ -1337,10 +1272,10 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) | |||
1337 | skb = NULL; | 1272 | skb = NULL; |
1338 | } else { | 1273 | } else { |
1339 | u8 *data = skb->data; | 1274 | u8 *data = skb->data; |
1340 | size_t len = skb->len; | 1275 | size_t len = skb_headlen(skb); |
1341 | u8 *new = __skb_push(skb, align); | 1276 | skb->data -= align; |
1342 | memmove(new, data, len); | 1277 | memmove(skb->data, data, len); |
1343 | __skb_trim(skb, len); | 1278 | skb_set_tail_pointer(skb, len); |
1344 | } | 1279 | } |
1345 | } | 1280 | } |
1346 | #endif | 1281 | #endif |
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c index 7a350d2690a0..4cf387c944bf 100644 --- a/net/mac80211/scan.c +++ b/net/mac80211/scan.c | |||
@@ -12,8 +12,6 @@ | |||
12 | * published by the Free Software Foundation. | 12 | * published by the Free Software Foundation. |
13 | */ | 13 | */ |
14 | 14 | ||
15 | /* TODO: figure out how to avoid that the "current BSS" expires */ | ||
16 | |||
17 | #include <linux/wireless.h> | 15 | #include <linux/wireless.h> |
18 | #include <linux/if_arp.h> | 16 | #include <linux/if_arp.h> |
19 | #include <linux/rtnetlink.h> | 17 | #include <linux/rtnetlink.h> |
@@ -189,6 +187,39 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
189 | return RX_QUEUED; | 187 | return RX_QUEUED; |
190 | } | 188 | } |
191 | 189 | ||
190 | /* return false if no more work */ | ||
191 | static bool ieee80211_prep_hw_scan(struct ieee80211_local *local) | ||
192 | { | ||
193 | struct cfg80211_scan_request *req = local->scan_req; | ||
194 | enum ieee80211_band band; | ||
195 | int i, ielen, n_chans; | ||
196 | |||
197 | do { | ||
198 | if (local->hw_scan_band == IEEE80211_NUM_BANDS) | ||
199 | return false; | ||
200 | |||
201 | band = local->hw_scan_band; | ||
202 | n_chans = 0; | ||
203 | for (i = 0; i < req->n_channels; i++) { | ||
204 | if (req->channels[i]->band == band) { | ||
205 | local->hw_scan_req->channels[n_chans] = | ||
206 | req->channels[i]; | ||
207 | n_chans++; | ||
208 | } | ||
209 | } | ||
210 | |||
211 | local->hw_scan_band++; | ||
212 | } while (!n_chans); | ||
213 | |||
214 | local->hw_scan_req->n_channels = n_chans; | ||
215 | |||
216 | ielen = ieee80211_build_preq_ies(local, (u8 *)local->hw_scan_req->ie, | ||
217 | req->ie, req->ie_len, band); | ||
218 | local->hw_scan_req->ie_len = ielen; | ||
219 | |||
220 | return true; | ||
221 | } | ||
222 | |||
192 | /* | 223 | /* |
193 | * inform AP that we will go to sleep so that it will buffer the frames | 224 | * inform AP that we will go to sleep so that it will buffer the frames |
194 | * while we scan | 225 | * while we scan |
@@ -249,13 +280,6 @@ static void ieee80211_scan_ps_disable(struct ieee80211_sub_if_data *sdata) | |||
249 | } | 280 | } |
250 | } | 281 | } |
251 | 282 | ||
252 | static void ieee80211_restore_scan_ies(struct ieee80211_local *local) | ||
253 | { | ||
254 | kfree(local->scan_req->ie); | ||
255 | local->scan_req->ie = local->orig_ies; | ||
256 | local->scan_req->ie_len = local->orig_ies_len; | ||
257 | } | ||
258 | |||
259 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | 283 | void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) |
260 | { | 284 | { |
261 | struct ieee80211_local *local = hw_to_local(hw); | 285 | struct ieee80211_local *local = hw_to_local(hw); |
@@ -264,25 +288,36 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted) | |||
264 | 288 | ||
265 | mutex_lock(&local->scan_mtx); | 289 | mutex_lock(&local->scan_mtx); |
266 | 290 | ||
267 | if (WARN_ON(!local->scanning)) { | 291 | /* |
292 | * It's ok to abort a not-yet-running scan (that | ||
293 | * we have one at all will be verified by checking | ||
294 | * local->scan_req next), but not to complete it | ||
295 | * successfully. | ||
296 | */ | ||
297 | if (WARN_ON(!local->scanning && !aborted)) | ||
298 | aborted = true; | ||
299 | |||
300 | if (WARN_ON(!local->scan_req)) { | ||
268 | mutex_unlock(&local->scan_mtx); | 301 | mutex_unlock(&local->scan_mtx); |
269 | return; | 302 | return; |
270 | } | 303 | } |
271 | 304 | ||
272 | if (WARN_ON(!local->scan_req)) { | 305 | was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); |
306 | if (was_hw_scan && !aborted && ieee80211_prep_hw_scan(local)) { | ||
307 | ieee80211_queue_delayed_work(&local->hw, | ||
308 | &local->scan_work, 0); | ||
273 | mutex_unlock(&local->scan_mtx); | 309 | mutex_unlock(&local->scan_mtx); |
274 | return; | 310 | return; |
275 | } | 311 | } |
276 | 312 | ||
277 | if (test_bit(SCAN_HW_SCANNING, &local->scanning)) | 313 | kfree(local->hw_scan_req); |
278 | ieee80211_restore_scan_ies(local); | 314 | local->hw_scan_req = NULL; |
279 | 315 | ||
280 | if (local->scan_req != local->int_scan_req) | 316 | if (local->scan_req != local->int_scan_req) |
281 | cfg80211_scan_done(local->scan_req, aborted); | 317 | cfg80211_scan_done(local->scan_req, aborted); |
282 | local->scan_req = NULL; | 318 | local->scan_req = NULL; |
283 | local->scan_sdata = NULL; | 319 | local->scan_sdata = NULL; |
284 | 320 | ||
285 | was_hw_scan = test_bit(SCAN_HW_SCANNING, &local->scanning); | ||
286 | local->scanning = 0; | 321 | local->scanning = 0; |
287 | local->scan_channel = NULL; | 322 | local->scan_channel = NULL; |
288 | 323 | ||
@@ -394,19 +429,23 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
394 | 429 | ||
395 | if (local->ops->hw_scan) { | 430 | if (local->ops->hw_scan) { |
396 | u8 *ies; | 431 | u8 *ies; |
397 | int ielen; | ||
398 | 432 | ||
399 | ies = kmalloc(2 + IEEE80211_MAX_SSID_LEN + | 433 | local->hw_scan_req = kmalloc( |
400 | local->scan_ies_len + req->ie_len, GFP_KERNEL); | 434 | sizeof(*local->hw_scan_req) + |
401 | if (!ies) | 435 | req->n_channels * sizeof(req->channels[0]) + |
436 | 2 + IEEE80211_MAX_SSID_LEN + local->scan_ies_len + | ||
437 | req->ie_len, GFP_KERNEL); | ||
438 | if (!local->hw_scan_req) | ||
402 | return -ENOMEM; | 439 | return -ENOMEM; |
403 | 440 | ||
404 | ielen = ieee80211_build_preq_ies(local, ies, | 441 | local->hw_scan_req->ssids = req->ssids; |
405 | req->ie, req->ie_len); | 442 | local->hw_scan_req->n_ssids = req->n_ssids; |
406 | local->orig_ies = req->ie; | 443 | ies = (u8 *)local->hw_scan_req + |
407 | local->orig_ies_len = req->ie_len; | 444 | sizeof(*local->hw_scan_req) + |
408 | req->ie = ies; | 445 | req->n_channels * sizeof(req->channels[0]); |
409 | req->ie_len = ielen; | 446 | local->hw_scan_req->ie = ies; |
447 | |||
448 | local->hw_scan_band = 0; | ||
410 | } | 449 | } |
411 | 450 | ||
412 | local->scan_req = req; | 451 | local->scan_req = req; |
@@ -438,16 +477,17 @@ static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata, | |||
438 | ieee80211_recalc_idle(local); | 477 | ieee80211_recalc_idle(local); |
439 | mutex_unlock(&local->scan_mtx); | 478 | mutex_unlock(&local->scan_mtx); |
440 | 479 | ||
441 | if (local->ops->hw_scan) | 480 | if (local->ops->hw_scan) { |
442 | rc = drv_hw_scan(local, local->scan_req); | 481 | WARN_ON(!ieee80211_prep_hw_scan(local)); |
443 | else | 482 | rc = drv_hw_scan(local, local->hw_scan_req); |
483 | } else | ||
444 | rc = ieee80211_start_sw_scan(local); | 484 | rc = ieee80211_start_sw_scan(local); |
445 | 485 | ||
446 | mutex_lock(&local->scan_mtx); | 486 | mutex_lock(&local->scan_mtx); |
447 | 487 | ||
448 | if (rc) { | 488 | if (rc) { |
449 | if (local->ops->hw_scan) | 489 | kfree(local->hw_scan_req); |
450 | ieee80211_restore_scan_ies(local); | 490 | local->hw_scan_req = NULL; |
451 | local->scanning = 0; | 491 | local->scanning = 0; |
452 | 492 | ||
453 | ieee80211_recalc_idle(local); | 493 | ieee80211_recalc_idle(local); |
@@ -574,23 +614,14 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local, | |||
574 | { | 614 | { |
575 | int skip; | 615 | int skip; |
576 | struct ieee80211_channel *chan; | 616 | struct ieee80211_channel *chan; |
577 | struct ieee80211_sub_if_data *sdata = local->scan_sdata; | ||
578 | 617 | ||
579 | skip = 0; | 618 | skip = 0; |
580 | chan = local->scan_req->channels[local->scan_channel_idx]; | 619 | chan = local->scan_req->channels[local->scan_channel_idx]; |
581 | 620 | ||
582 | if (chan->flags & IEEE80211_CHAN_DISABLED || | 621 | local->scan_channel = chan; |
583 | (sdata->vif.type == NL80211_IFTYPE_ADHOC && | 622 | if (ieee80211_hw_config(local, IEEE80211_CONF_CHANGE_CHANNEL)) |
584 | chan->flags & IEEE80211_CHAN_NO_IBSS)) | ||
585 | skip = 1; | 623 | skip = 1; |
586 | 624 | ||
587 | if (!skip) { | ||
588 | local->scan_channel = chan; | ||
589 | if (ieee80211_hw_config(local, | ||
590 | IEEE80211_CONF_CHANGE_CHANNEL)) | ||
591 | skip = 1; | ||
592 | } | ||
593 | |||
594 | /* advance state machine to next channel/band */ | 625 | /* advance state machine to next channel/band */ |
595 | local->scan_channel_idx++; | 626 | local->scan_channel_idx++; |
596 | 627 | ||
@@ -656,6 +687,14 @@ void ieee80211_scan_work(struct work_struct *work) | |||
656 | return; | 687 | return; |
657 | } | 688 | } |
658 | 689 | ||
690 | if (local->hw_scan_req) { | ||
691 | int rc = drv_hw_scan(local, local->hw_scan_req); | ||
692 | mutex_unlock(&local->scan_mtx); | ||
693 | if (rc) | ||
694 | ieee80211_scan_completed(&local->hw, true); | ||
695 | return; | ||
696 | } | ||
697 | |||
659 | if (local->scan_req && !local->scanning) { | 698 | if (local->scan_req && !local->scanning) { |
660 | struct cfg80211_scan_request *req = local->scan_req; | 699 | struct cfg80211_scan_request *req = local->scan_req; |
661 | int rc; | 700 | int rc; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 594f2318c3d8..be59456e8a42 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -171,6 +171,8 @@ void sta_info_destroy(struct sta_info *sta) | |||
171 | 171 | ||
172 | local = sta->local; | 172 | local = sta->local; |
173 | 173 | ||
174 | cancel_work_sync(&sta->drv_unblock_wk); | ||
175 | |||
174 | rate_control_remove_sta_debugfs(sta); | 176 | rate_control_remove_sta_debugfs(sta); |
175 | ieee80211_sta_debugfs_remove(sta); | 177 | ieee80211_sta_debugfs_remove(sta); |
176 | 178 | ||
@@ -259,6 +261,21 @@ static void sta_info_hash_add(struct ieee80211_local *local, | |||
259 | rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta); | 261 | rcu_assign_pointer(local->sta_hash[STA_HASH(sta->sta.addr)], sta); |
260 | } | 262 | } |
261 | 263 | ||
264 | static void sta_unblock(struct work_struct *wk) | ||
265 | { | ||
266 | struct sta_info *sta; | ||
267 | |||
268 | sta = container_of(wk, struct sta_info, drv_unblock_wk); | ||
269 | |||
270 | if (sta->dead) | ||
271 | return; | ||
272 | |||
273 | if (!test_sta_flags(sta, WLAN_STA_PS_STA)) | ||
274 | ieee80211_sta_ps_deliver_wakeup(sta); | ||
275 | else if (test_and_clear_sta_flags(sta, WLAN_STA_PSPOLL)) | ||
276 | ieee80211_sta_ps_deliver_poll_response(sta); | ||
277 | } | ||
278 | |||
262 | struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | 279 | struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, |
263 | u8 *addr, gfp_t gfp) | 280 | u8 *addr, gfp_t gfp) |
264 | { | 281 | { |
@@ -272,6 +289,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
272 | 289 | ||
273 | spin_lock_init(&sta->lock); | 290 | spin_lock_init(&sta->lock); |
274 | spin_lock_init(&sta->flaglock); | 291 | spin_lock_init(&sta->flaglock); |
292 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); | ||
275 | 293 | ||
276 | memcpy(sta->sta.addr, addr, ETH_ALEN); | 294 | memcpy(sta->sta.addr, addr, ETH_ALEN); |
277 | sta->local = local; | 295 | sta->local = local; |
@@ -478,8 +496,10 @@ static void __sta_info_unlink(struct sta_info **sta) | |||
478 | } | 496 | } |
479 | 497 | ||
480 | list_del(&(*sta)->list); | 498 | list_del(&(*sta)->list); |
499 | (*sta)->dead = true; | ||
481 | 500 | ||
482 | if (test_and_clear_sta_flags(*sta, WLAN_STA_PS)) { | 501 | if (test_and_clear_sta_flags(*sta, |
502 | WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) { | ||
483 | BUG_ON(!sdata->bss); | 503 | BUG_ON(!sdata->bss); |
484 | 504 | ||
485 | atomic_dec(&sdata->bss->num_sta_ps); | 505 | atomic_dec(&sdata->bss->num_sta_ps); |
@@ -801,8 +821,8 @@ void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | |||
801 | sta_info_destroy(sta); | 821 | sta_info_destroy(sta); |
802 | } | 822 | } |
803 | 823 | ||
804 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, | 824 | struct ieee80211_sta *ieee80211_find_sta_by_hw(struct ieee80211_hw *hw, |
805 | const u8 *addr) | 825 | const u8 *addr) |
806 | { | 826 | { |
807 | struct sta_info *sta = sta_info_get(hw_to_local(hw), addr); | 827 | struct sta_info *sta = sta_info_get(hw_to_local(hw), addr); |
808 | 828 | ||
@@ -810,4 +830,114 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_hw *hw, | |||
810 | return NULL; | 830 | return NULL; |
811 | return &sta->sta; | 831 | return &sta->sta; |
812 | } | 832 | } |
833 | EXPORT_SYMBOL_GPL(ieee80211_find_sta_by_hw); | ||
834 | |||
835 | struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, | ||
836 | const u8 *addr) | ||
837 | { | ||
838 | struct ieee80211_sub_if_data *sdata; | ||
839 | |||
840 | if (!vif) | ||
841 | return NULL; | ||
842 | |||
843 | sdata = vif_to_sdata(vif); | ||
844 | |||
845 | return ieee80211_find_sta_by_hw(&sdata->local->hw, addr); | ||
846 | } | ||
813 | EXPORT_SYMBOL(ieee80211_find_sta); | 847 | EXPORT_SYMBOL(ieee80211_find_sta); |
848 | |||
849 | /* powersave support code */ | ||
850 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | ||
851 | { | ||
852 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
853 | struct ieee80211_local *local = sdata->local; | ||
854 | int sent, buffered; | ||
855 | |||
856 | drv_sta_notify(local, &sdata->vif, STA_NOTIFY_AWAKE, &sta->sta); | ||
857 | |||
858 | if (!skb_queue_empty(&sta->ps_tx_buf)) | ||
859 | sta_info_clear_tim_bit(sta); | ||
860 | |||
861 | /* Send all buffered frames to the station */ | ||
862 | sent = ieee80211_add_pending_skbs(local, &sta->tx_filtered); | ||
863 | buffered = ieee80211_add_pending_skbs(local, &sta->ps_tx_buf); | ||
864 | sent += buffered; | ||
865 | local->total_ps_buffered -= buffered; | ||
866 | |||
867 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | ||
868 | printk(KERN_DEBUG "%s: STA %pM aid %d sending %d filtered/%d PS frames " | ||
869 | "since STA not sleeping anymore\n", sdata->dev->name, | ||
870 | sta->sta.addr, sta->sta.aid, sent - buffered, buffered); | ||
871 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
872 | } | ||
873 | |||
874 | void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta) | ||
875 | { | ||
876 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
877 | struct ieee80211_local *local = sdata->local; | ||
878 | struct sk_buff *skb; | ||
879 | int no_pending_pkts; | ||
880 | |||
881 | skb = skb_dequeue(&sta->tx_filtered); | ||
882 | if (!skb) { | ||
883 | skb = skb_dequeue(&sta->ps_tx_buf); | ||
884 | if (skb) | ||
885 | local->total_ps_buffered--; | ||
886 | } | ||
887 | no_pending_pkts = skb_queue_empty(&sta->tx_filtered) && | ||
888 | skb_queue_empty(&sta->ps_tx_buf); | ||
889 | |||
890 | if (skb) { | ||
891 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
892 | struct ieee80211_hdr *hdr = | ||
893 | (struct ieee80211_hdr *) skb->data; | ||
894 | |||
895 | /* | ||
896 | * Tell TX path to send this frame even though the STA may | ||
897 | * still remain is PS mode after this frame exchange. | ||
898 | */ | ||
899 | info->flags |= IEEE80211_TX_CTL_PSPOLL_RESPONSE; | ||
900 | |||
901 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | ||
902 | printk(KERN_DEBUG "STA %pM aid %d: PS Poll (entries after %d)\n", | ||
903 | sta->sta.addr, sta->sta.aid, | ||
904 | skb_queue_len(&sta->ps_tx_buf)); | ||
905 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
906 | |||
907 | /* Use MoreData flag to indicate whether there are more | ||
908 | * buffered frames for this STA */ | ||
909 | if (no_pending_pkts) | ||
910 | hdr->frame_control &= cpu_to_le16(~IEEE80211_FCTL_MOREDATA); | ||
911 | else | ||
912 | hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); | ||
913 | |||
914 | ieee80211_add_pending_skb(local, skb); | ||
915 | |||
916 | if (no_pending_pkts) | ||
917 | sta_info_clear_tim_bit(sta); | ||
918 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | ||
919 | } else { | ||
920 | /* | ||
921 | * FIXME: This can be the result of a race condition between | ||
922 | * us expiring a frame and the station polling for it. | ||
923 | * Should we send it a null-func frame indicating we | ||
924 | * have nothing buffered for it? | ||
925 | */ | ||
926 | printk(KERN_DEBUG "%s: STA %pM sent PS Poll even " | ||
927 | "though there are no buffered frames for it\n", | ||
928 | sdata->dev->name, sta->sta.addr); | ||
929 | #endif /* CONFIG_MAC80211_VERBOSE_PS_DEBUG */ | ||
930 | } | ||
931 | } | ||
932 | |||
933 | void ieee80211_sta_block_awake(struct ieee80211_hw *hw, | ||
934 | struct ieee80211_sta *pubsta, bool block) | ||
935 | { | ||
936 | struct sta_info *sta = container_of(pubsta, struct sta_info, sta); | ||
937 | |||
938 | if (block) | ||
939 | set_sta_flags(sta, WLAN_STA_PS_DRIVER); | ||
940 | else | ||
941 | ieee80211_queue_work(hw, &sta->drv_unblock_wk); | ||
942 | } | ||
943 | EXPORT_SYMBOL(ieee80211_sta_block_awake); | ||
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index ccc3adf962c7..4673454176ed 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/list.h> | 12 | #include <linux/list.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/if_ether.h> | 14 | #include <linux/if_ether.h> |
15 | #include <linux/workqueue.h> | ||
15 | #include "key.h" | 16 | #include "key.h" |
16 | 17 | ||
17 | /** | 18 | /** |
@@ -21,7 +22,7 @@ | |||
21 | * | 22 | * |
22 | * @WLAN_STA_AUTH: Station is authenticated. | 23 | * @WLAN_STA_AUTH: Station is authenticated. |
23 | * @WLAN_STA_ASSOC: Station is associated. | 24 | * @WLAN_STA_ASSOC: Station is associated. |
24 | * @WLAN_STA_PS: Station is in power-save mode | 25 | * @WLAN_STA_PS_STA: Station is in power-save mode |
25 | * @WLAN_STA_AUTHORIZED: Station is authorized to send/receive traffic. | 26 | * @WLAN_STA_AUTHORIZED: Station is authorized to send/receive traffic. |
26 | * This bit is always checked so needs to be enabled for all stations | 27 | * This bit is always checked so needs to be enabled for all stations |
27 | * when virtual port control is not in use. | 28 | * when virtual port control is not in use. |
@@ -36,11 +37,16 @@ | |||
36 | * @WLAN_STA_MFP: Management frame protection is used with this STA. | 37 | * @WLAN_STA_MFP: Management frame protection is used with this STA. |
37 | * @WLAN_STA_SUSPEND: Set/cleared during a suspend/resume cycle. | 38 | * @WLAN_STA_SUSPEND: Set/cleared during a suspend/resume cycle. |
38 | * Used to deny ADDBA requests (both TX and RX). | 39 | * Used to deny ADDBA requests (both TX and RX). |
40 | * @WLAN_STA_PS_DRIVER: driver requires keeping this station in | ||
41 | * power-save mode logically to flush frames that might still | ||
42 | * be in the queues | ||
43 | * @WLAN_STA_PSPOLL: Station sent PS-poll while driver was keeping | ||
44 | * station in power-save mode, reply when the driver unblocks. | ||
39 | */ | 45 | */ |
40 | enum ieee80211_sta_info_flags { | 46 | enum ieee80211_sta_info_flags { |
41 | WLAN_STA_AUTH = 1<<0, | 47 | WLAN_STA_AUTH = 1<<0, |
42 | WLAN_STA_ASSOC = 1<<1, | 48 | WLAN_STA_ASSOC = 1<<1, |
43 | WLAN_STA_PS = 1<<2, | 49 | WLAN_STA_PS_STA = 1<<2, |
44 | WLAN_STA_AUTHORIZED = 1<<3, | 50 | WLAN_STA_AUTHORIZED = 1<<3, |
45 | WLAN_STA_SHORT_PREAMBLE = 1<<4, | 51 | WLAN_STA_SHORT_PREAMBLE = 1<<4, |
46 | WLAN_STA_ASSOC_AP = 1<<5, | 52 | WLAN_STA_ASSOC_AP = 1<<5, |
@@ -48,7 +54,9 @@ enum ieee80211_sta_info_flags { | |||
48 | WLAN_STA_WDS = 1<<7, | 54 | WLAN_STA_WDS = 1<<7, |
49 | WLAN_STA_CLEAR_PS_FILT = 1<<9, | 55 | WLAN_STA_CLEAR_PS_FILT = 1<<9, |
50 | WLAN_STA_MFP = 1<<10, | 56 | WLAN_STA_MFP = 1<<10, |
51 | WLAN_STA_SUSPEND = 1<<11 | 57 | WLAN_STA_SUSPEND = 1<<11, |
58 | WLAN_STA_PS_DRIVER = 1<<12, | ||
59 | WLAN_STA_PSPOLL = 1<<13, | ||
52 | }; | 60 | }; |
53 | 61 | ||
54 | #define STA_TID_NUM 16 | 62 | #define STA_TID_NUM 16 |
@@ -193,7 +201,6 @@ struct sta_ampdu_mlme { | |||
193 | * @rx_fragments: number of received MPDUs | 201 | * @rx_fragments: number of received MPDUs |
194 | * @rx_dropped: number of dropped MPDUs from this STA | 202 | * @rx_dropped: number of dropped MPDUs from this STA |
195 | * @last_signal: signal of last received frame from this STA | 203 | * @last_signal: signal of last received frame from this STA |
196 | * @last_qual: qual of last received frame from this STA | ||
197 | * @last_noise: noise of last received frame from this STA | 204 | * @last_noise: noise of last received frame from this STA |
198 | * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) | 205 | * @last_seq_ctrl: last received seq/frag number from this STA (per RX queue) |
199 | * @tx_filtered_count: number of frames the hardware filtered for this STA | 206 | * @tx_filtered_count: number of frames the hardware filtered for this STA |
@@ -217,6 +224,8 @@ struct sta_ampdu_mlme { | |||
217 | * @plink_timer_was_running: used by suspend/resume to restore timers | 224 | * @plink_timer_was_running: used by suspend/resume to restore timers |
218 | * @debugfs: debug filesystem info | 225 | * @debugfs: debug filesystem info |
219 | * @sta: station information we share with the driver | 226 | * @sta: station information we share with the driver |
227 | * @dead: set to true when sta is unlinked | ||
228 | * @drv_unblock_wk used for driver PS unblocking | ||
220 | */ | 229 | */ |
221 | struct sta_info { | 230 | struct sta_info { |
222 | /* General information, mostly static */ | 231 | /* General information, mostly static */ |
@@ -230,8 +239,12 @@ struct sta_info { | |||
230 | spinlock_t lock; | 239 | spinlock_t lock; |
231 | spinlock_t flaglock; | 240 | spinlock_t flaglock; |
232 | 241 | ||
242 | struct work_struct drv_unblock_wk; | ||
243 | |||
233 | u16 listen_interval; | 244 | u16 listen_interval; |
234 | 245 | ||
246 | bool dead; | ||
247 | |||
235 | /* | 248 | /* |
236 | * for use by the internal lifetime management, | 249 | * for use by the internal lifetime management, |
237 | * see __sta_info_unlink | 250 | * see __sta_info_unlink |
@@ -259,7 +272,6 @@ struct sta_info { | |||
259 | unsigned long rx_fragments; | 272 | unsigned long rx_fragments; |
260 | unsigned long rx_dropped; | 273 | unsigned long rx_dropped; |
261 | int last_signal; | 274 | int last_signal; |
262 | int last_qual; | ||
263 | int last_noise; | 275 | int last_noise; |
264 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; | 276 | __le16 last_seq_ctrl[NUM_RX_DATA_QUEUES]; |
265 | 277 | ||
@@ -301,28 +313,6 @@ struct sta_info { | |||
301 | #ifdef CONFIG_MAC80211_DEBUGFS | 313 | #ifdef CONFIG_MAC80211_DEBUGFS |
302 | struct sta_info_debugfsdentries { | 314 | struct sta_info_debugfsdentries { |
303 | struct dentry *dir; | 315 | struct dentry *dir; |
304 | struct dentry *flags; | ||
305 | struct dentry *num_ps_buf_frames; | ||
306 | struct dentry *inactive_ms; | ||
307 | struct dentry *last_seq_ctrl; | ||
308 | struct dentry *agg_status; | ||
309 | struct dentry *aid; | ||
310 | struct dentry *dev; | ||
311 | struct dentry *rx_packets; | ||
312 | struct dentry *tx_packets; | ||
313 | struct dentry *rx_bytes; | ||
314 | struct dentry *tx_bytes; | ||
315 | struct dentry *rx_duplicates; | ||
316 | struct dentry *rx_fragments; | ||
317 | struct dentry *rx_dropped; | ||
318 | struct dentry *tx_fragments; | ||
319 | struct dentry *tx_filtered; | ||
320 | struct dentry *tx_retry_failed; | ||
321 | struct dentry *tx_retry_count; | ||
322 | struct dentry *last_signal; | ||
323 | struct dentry *last_qual; | ||
324 | struct dentry *last_noise; | ||
325 | struct dentry *wep_weak_iv_count; | ||
326 | bool add_has_run; | 316 | bool add_has_run; |
327 | } debugfs; | 317 | } debugfs; |
328 | #endif | 318 | #endif |
@@ -454,4 +444,7 @@ int sta_info_flush(struct ieee80211_local *local, | |||
454 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, | 444 | void ieee80211_sta_expire(struct ieee80211_sub_if_data *sdata, |
455 | unsigned long exp_time); | 445 | unsigned long exp_time); |
456 | 446 | ||
447 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta); | ||
448 | void ieee80211_sta_ps_deliver_poll_response(struct sta_info *sta); | ||
449 | |||
457 | #endif /* STA_INFO_H */ | 450 | #endif /* STA_INFO_H */ |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index eaa4118de988..bfaa43e096d2 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -317,12 +317,11 @@ ieee80211_tx_h_multicast_ps_buf(struct ieee80211_tx_data *tx) | |||
317 | if (!atomic_read(&tx->sdata->bss->num_sta_ps)) | 317 | if (!atomic_read(&tx->sdata->bss->num_sta_ps)) |
318 | return TX_CONTINUE; | 318 | return TX_CONTINUE; |
319 | 319 | ||
320 | /* buffered in hardware */ | 320 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; |
321 | if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)) { | ||
322 | info->flags |= IEEE80211_TX_CTL_SEND_AFTER_DTIM; | ||
323 | 321 | ||
322 | /* device releases frame after DTIM beacon */ | ||
323 | if (!(tx->local->hw.flags & IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING)) | ||
324 | return TX_CONTINUE; | 324 | return TX_CONTINUE; |
325 | } | ||
326 | 325 | ||
327 | /* buffered in mac80211 */ | 326 | /* buffered in mac80211 */ |
328 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 327 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
@@ -375,7 +374,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
375 | 374 | ||
376 | staflags = get_sta_flags(sta); | 375 | staflags = get_sta_flags(sta); |
377 | 376 | ||
378 | if (unlikely((staflags & WLAN_STA_PS) && | 377 | if (unlikely((staflags & (WLAN_STA_PS_STA | WLAN_STA_PS_DRIVER)) && |
379 | !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) { | 378 | !(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE))) { |
380 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 379 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
381 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " | 380 | printk(KERN_DEBUG "STA %pM aid %d: PS buffer (entries " |
@@ -398,8 +397,13 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
398 | } else | 397 | } else |
399 | tx->local->total_ps_buffered++; | 398 | tx->local->total_ps_buffered++; |
400 | 399 | ||
401 | /* Queue frame to be sent after STA sends an PS Poll frame */ | 400 | /* |
402 | if (skb_queue_empty(&sta->ps_tx_buf)) | 401 | * Queue frame to be sent after STA wakes up/polls, |
402 | * but don't set the TIM bit if the driver is blocking | ||
403 | * wakeup or poll response transmissions anyway. | ||
404 | */ | ||
405 | if (skb_queue_empty(&sta->ps_tx_buf) && | ||
406 | !(staflags & WLAN_STA_PS_DRIVER)) | ||
403 | sta_info_set_tim_bit(sta); | 407 | sta_info_set_tim_bit(sta); |
404 | 408 | ||
405 | info->control.jiffies = jiffies; | 409 | info->control.jiffies = jiffies; |
@@ -409,7 +413,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
409 | return TX_QUEUED; | 413 | return TX_QUEUED; |
410 | } | 414 | } |
411 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG | 415 | #ifdef CONFIG_MAC80211_VERBOSE_PS_DEBUG |
412 | else if (unlikely(test_sta_flags(sta, WLAN_STA_PS))) { | 416 | else if (unlikely(staflags & WLAN_STA_PS_STA)) { |
413 | printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll " | 417 | printk(KERN_DEBUG "%s: STA %pM in PS mode, but pspoll " |
414 | "set -> send frame\n", tx->dev->name, | 418 | "set -> send frame\n", tx->dev->name, |
415 | sta->sta.addr); | 419 | sta->sta.addr); |
@@ -1201,23 +1205,25 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx) | |||
1201 | struct sk_buff *skb = tx->skb; | 1205 | struct sk_buff *skb = tx->skb; |
1202 | ieee80211_tx_result res = TX_DROP; | 1206 | ieee80211_tx_result res = TX_DROP; |
1203 | 1207 | ||
1204 | #define CALL_TXH(txh) \ | 1208 | #define CALL_TXH(txh) \ |
1205 | res = txh(tx); \ | 1209 | do { \ |
1206 | if (res != TX_CONTINUE) \ | 1210 | res = txh(tx); \ |
1207 | goto txh_done; | 1211 | if (res != TX_CONTINUE) \ |
1208 | 1212 | goto txh_done; \ | |
1209 | CALL_TXH(ieee80211_tx_h_check_assoc) | 1213 | } while (0) |
1210 | CALL_TXH(ieee80211_tx_h_ps_buf) | 1214 | |
1211 | CALL_TXH(ieee80211_tx_h_select_key) | 1215 | CALL_TXH(ieee80211_tx_h_check_assoc); |
1212 | CALL_TXH(ieee80211_tx_h_michael_mic_add) | 1216 | CALL_TXH(ieee80211_tx_h_ps_buf); |
1213 | CALL_TXH(ieee80211_tx_h_rate_ctrl) | 1217 | CALL_TXH(ieee80211_tx_h_select_key); |
1214 | CALL_TXH(ieee80211_tx_h_misc) | 1218 | CALL_TXH(ieee80211_tx_h_michael_mic_add); |
1215 | CALL_TXH(ieee80211_tx_h_sequence) | 1219 | CALL_TXH(ieee80211_tx_h_rate_ctrl); |
1216 | CALL_TXH(ieee80211_tx_h_fragment) | 1220 | CALL_TXH(ieee80211_tx_h_misc); |
1221 | CALL_TXH(ieee80211_tx_h_sequence); | ||
1222 | CALL_TXH(ieee80211_tx_h_fragment); | ||
1217 | /* handlers after fragment must be aware of tx info fragmentation! */ | 1223 | /* handlers after fragment must be aware of tx info fragmentation! */ |
1218 | CALL_TXH(ieee80211_tx_h_stats) | 1224 | CALL_TXH(ieee80211_tx_h_stats); |
1219 | CALL_TXH(ieee80211_tx_h_encrypt) | 1225 | CALL_TXH(ieee80211_tx_h_encrypt); |
1220 | CALL_TXH(ieee80211_tx_h_calculate_duration) | 1226 | CALL_TXH(ieee80211_tx_h_calculate_duration); |
1221 | #undef CALL_TXH | 1227 | #undef CALL_TXH |
1222 | 1228 | ||
1223 | txh_done: | 1229 | txh_done: |
@@ -1387,6 +1393,30 @@ static int ieee80211_skb_resize(struct ieee80211_local *local, | |||
1387 | return 0; | 1393 | return 0; |
1388 | } | 1394 | } |
1389 | 1395 | ||
1396 | static bool need_dynamic_ps(struct ieee80211_local *local) | ||
1397 | { | ||
1398 | /* driver doesn't support power save */ | ||
1399 | if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS)) | ||
1400 | return false; | ||
1401 | |||
1402 | /* hardware does dynamic power save */ | ||
1403 | if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS) | ||
1404 | return false; | ||
1405 | |||
1406 | /* dynamic power save disabled */ | ||
1407 | if (local->hw.conf.dynamic_ps_timeout <= 0) | ||
1408 | return false; | ||
1409 | |||
1410 | /* we are scanning, don't enable power save */ | ||
1411 | if (local->scanning) | ||
1412 | return false; | ||
1413 | |||
1414 | if (!local->ps_sdata) | ||
1415 | return false; | ||
1416 | |||
1417 | return true; | ||
1418 | } | ||
1419 | |||
1390 | static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | 1420 | static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, |
1391 | struct sk_buff *skb) | 1421 | struct sk_buff *skb) |
1392 | { | 1422 | { |
@@ -1399,9 +1429,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, | |||
1399 | 1429 | ||
1400 | dev_hold(sdata->dev); | 1430 | dev_hold(sdata->dev); |
1401 | 1431 | ||
1402 | if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && | 1432 | if (need_dynamic_ps(local)) { |
1403 | local->hw.conf.dynamic_ps_timeout > 0 && | ||
1404 | !(local->scanning) && local->ps_sdata) { | ||
1405 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { | 1433 | if (local->hw.conf.flags & IEEE80211_CONF_PS) { |
1406 | ieee80211_stop_queues_by_reason(&local->hw, | 1434 | ieee80211_stop_queues_by_reason(&local->hw, |
1407 | IEEE80211_QUEUE_STOP_REASON_PS); | 1435 | IEEE80211_QUEUE_STOP_REASON_PS); |
@@ -1990,8 +2018,9 @@ static void ieee80211_beacon_add_tim(struct ieee80211_if_ap *bss, | |||
1990 | } | 2018 | } |
1991 | } | 2019 | } |
1992 | 2020 | ||
1993 | struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | 2021 | struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw, |
1994 | struct ieee80211_vif *vif) | 2022 | struct ieee80211_vif *vif, |
2023 | u16 *tim_offset, u16 *tim_length) | ||
1995 | { | 2024 | { |
1996 | struct ieee80211_local *local = hw_to_local(hw); | 2025 | struct ieee80211_local *local = hw_to_local(hw); |
1997 | struct sk_buff *skb = NULL; | 2026 | struct sk_buff *skb = NULL; |
@@ -2008,6 +2037,11 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2008 | 2037 | ||
2009 | sdata = vif_to_sdata(vif); | 2038 | sdata = vif_to_sdata(vif); |
2010 | 2039 | ||
2040 | if (tim_offset) | ||
2041 | *tim_offset = 0; | ||
2042 | if (tim_length) | ||
2043 | *tim_length = 0; | ||
2044 | |||
2011 | if (sdata->vif.type == NL80211_IFTYPE_AP) { | 2045 | if (sdata->vif.type == NL80211_IFTYPE_AP) { |
2012 | ap = &sdata->u.ap; | 2046 | ap = &sdata->u.ap; |
2013 | beacon = rcu_dereference(ap->beacon); | 2047 | beacon = rcu_dereference(ap->beacon); |
@@ -2043,6 +2077,11 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2043 | spin_unlock_irqrestore(&local->sta_lock, flags); | 2077 | spin_unlock_irqrestore(&local->sta_lock, flags); |
2044 | } | 2078 | } |
2045 | 2079 | ||
2080 | if (tim_offset) | ||
2081 | *tim_offset = beacon->head_len; | ||
2082 | if (tim_length) | ||
2083 | *tim_length = skb->len - beacon->head_len; | ||
2084 | |||
2046 | if (beacon->tail) | 2085 | if (beacon->tail) |
2047 | memcpy(skb_put(skb, beacon->tail_len), | 2086 | memcpy(skb_put(skb, beacon->tail_len), |
2048 | beacon->tail, beacon->tail_len); | 2087 | beacon->tail, beacon->tail_len); |
@@ -2119,7 +2158,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, | |||
2119 | rcu_read_unlock(); | 2158 | rcu_read_unlock(); |
2120 | return skb; | 2159 | return skb; |
2121 | } | 2160 | } |
2122 | EXPORT_SYMBOL(ieee80211_beacon_get); | 2161 | EXPORT_SYMBOL(ieee80211_beacon_get_tim); |
2123 | 2162 | ||
2124 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | 2163 | void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
2125 | const void *frame, size_t frame_len, | 2164 | const void *frame, size_t frame_len, |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index aeb65b3d2295..aedbaaa067e6 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
@@ -872,13 +872,14 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, | |||
872 | } | 872 | } |
873 | 873 | ||
874 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, | 874 | int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, |
875 | const u8 *ie, size_t ie_len) | 875 | const u8 *ie, size_t ie_len, |
876 | enum ieee80211_band band) | ||
876 | { | 877 | { |
877 | struct ieee80211_supported_band *sband; | 878 | struct ieee80211_supported_band *sband; |
878 | u8 *pos, *supp_rates_len, *esupp_rates_len = NULL; | 879 | u8 *pos, *supp_rates_len, *esupp_rates_len = NULL; |
879 | int i; | 880 | int i; |
880 | 881 | ||
881 | sband = local->hw.wiphy->bands[local->hw.conf.channel->band]; | 882 | sband = local->hw.wiphy->bands[band]; |
882 | 883 | ||
883 | pos = buffer; | 884 | pos = buffer; |
884 | 885 | ||
@@ -966,7 +967,8 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, | |||
966 | memcpy(pos, ssid, ssid_len); | 967 | memcpy(pos, ssid, ssid_len); |
967 | pos += ssid_len; | 968 | pos += ssid_len; |
968 | 969 | ||
969 | skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len)); | 970 | skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len, |
971 | local->hw.conf.channel->band)); | ||
970 | 972 | ||
971 | ieee80211_tx_skb(sdata, skb, 0); | 973 | ieee80211_tx_skb(sdata, skb, 0); |
972 | } | 974 | } |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 07252967be9c..02835172b227 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -546,7 +546,7 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
546 | * First remove the hardware from everywhere, this makes | 546 | * First remove the hardware from everywhere, this makes |
547 | * it impossible to find from userspace. | 547 | * it impossible to find from userspace. |
548 | */ | 548 | */ |
549 | cfg80211_debugfs_rdev_del(rdev); | 549 | debugfs_remove_recursive(rdev->wiphy.debugfsdir); |
550 | list_del(&rdev->list); | 550 | list_del(&rdev->list); |
551 | 551 | ||
552 | /* | 552 | /* |
@@ -569,7 +569,6 @@ void wiphy_unregister(struct wiphy *wiphy) | |||
569 | 569 | ||
570 | cfg80211_rdev_list_generation++; | 570 | cfg80211_rdev_list_generation++; |
571 | device_del(&rdev->wiphy.dev); | 571 | device_del(&rdev->wiphy.dev); |
572 | debugfs_remove(rdev->wiphy.debugfsdir); | ||
573 | 572 | ||
574 | mutex_unlock(&cfg80211_mutex); | 573 | mutex_unlock(&cfg80211_mutex); |
575 | 574 | ||
diff --git a/net/wireless/core.h b/net/wireless/core.h index 68b321997d4c..5aeebb9085f8 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -72,17 +72,6 @@ struct cfg80211_registered_device { | |||
72 | /* current channel */ | 72 | /* current channel */ |
73 | struct ieee80211_channel *channel; | 73 | struct ieee80211_channel *channel; |
74 | 74 | ||
75 | #ifdef CONFIG_CFG80211_DEBUGFS | ||
76 | /* Debugfs entries */ | ||
77 | struct wiphy_debugfsdentries { | ||
78 | struct dentry *rts_threshold; | ||
79 | struct dentry *fragmentation_threshold; | ||
80 | struct dentry *short_retry_limit; | ||
81 | struct dentry *long_retry_limit; | ||
82 | struct dentry *ht40allow_map; | ||
83 | } debugfs; | ||
84 | #endif | ||
85 | |||
86 | /* must be last because of the way we do wiphy_priv(), | 75 | /* must be last because of the way we do wiphy_priv(), |
87 | * and it should at least be aligned to NETDEV_ALIGN */ | 76 | * and it should at least be aligned to NETDEV_ALIGN */ |
88 | struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN))); | 77 | struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN))); |
diff --git a/net/wireless/debugfs.c b/net/wireless/debugfs.c index 13d93d84f902..2e4895615037 100644 --- a/net/wireless/debugfs.c +++ b/net/wireless/debugfs.c | |||
@@ -104,11 +104,7 @@ static const struct file_operations ht40allow_map_ops = { | |||
104 | }; | 104 | }; |
105 | 105 | ||
106 | #define DEBUGFS_ADD(name) \ | 106 | #define DEBUGFS_ADD(name) \ |
107 | rdev->debugfs.name = debugfs_create_file(#name, S_IRUGO, phyd, \ | 107 | debugfs_create_file(#name, S_IRUGO, phyd, &rdev->wiphy, &name## _ops); |
108 | &rdev->wiphy, &name## _ops); | ||
109 | #define DEBUGFS_DEL(name) \ | ||
110 | debugfs_remove(rdev->debugfs.name); \ | ||
111 | rdev->debugfs.name = NULL; | ||
112 | 108 | ||
113 | void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev) | 109 | void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev) |
114 | { | 110 | { |
@@ -120,12 +116,3 @@ void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev) | |||
120 | DEBUGFS_ADD(long_retry_limit); | 116 | DEBUGFS_ADD(long_retry_limit); |
121 | DEBUGFS_ADD(ht40allow_map); | 117 | DEBUGFS_ADD(ht40allow_map); |
122 | } | 118 | } |
123 | |||
124 | void cfg80211_debugfs_rdev_del(struct cfg80211_registered_device *rdev) | ||
125 | { | ||
126 | DEBUGFS_DEL(rts_threshold); | ||
127 | DEBUGFS_DEL(fragmentation_threshold); | ||
128 | DEBUGFS_DEL(short_retry_limit); | ||
129 | DEBUGFS_DEL(long_retry_limit); | ||
130 | DEBUGFS_DEL(ht40allow_map); | ||
131 | } | ||
diff --git a/net/wireless/debugfs.h b/net/wireless/debugfs.h index 6419b6d6ce3e..74fdd3811427 100644 --- a/net/wireless/debugfs.h +++ b/net/wireless/debugfs.h | |||
@@ -3,12 +3,9 @@ | |||
3 | 3 | ||
4 | #ifdef CONFIG_CFG80211_DEBUGFS | 4 | #ifdef CONFIG_CFG80211_DEBUGFS |
5 | void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev); | 5 | void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev); |
6 | void cfg80211_debugfs_rdev_del(struct cfg80211_registered_device *rdev); | ||
7 | #else | 6 | #else |
8 | static inline | 7 | static inline |
9 | void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev) {} | 8 | void cfg80211_debugfs_rdev_add(struct cfg80211_registered_device *rdev) {} |
10 | static inline | ||
11 | void cfg80211_debugfs_rdev_del(struct cfg80211_registered_device *rdev) {} | ||
12 | #endif | 9 | #endif |
13 | 10 | ||
14 | #endif /* __CFG80211_DEBUGFS_H */ | 11 | #endif /* __CFG80211_DEBUGFS_H */ |
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c index 83c2a288dc63..2610b746effa 100644 --- a/net/wireless/mlme.c +++ b/net/wireless/mlme.c | |||
@@ -62,7 +62,6 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len) | |||
62 | u8 *ie = mgmt->u.assoc_resp.variable; | 62 | u8 *ie = mgmt->u.assoc_resp.variable; |
63 | int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); | 63 | int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); |
64 | struct cfg80211_internal_bss *bss = NULL; | 64 | struct cfg80211_internal_bss *bss = NULL; |
65 | bool need_connect_result = true; | ||
66 | 65 | ||
67 | wdev_lock(wdev); | 66 | wdev_lock(wdev); |
68 | 67 | ||
@@ -97,7 +96,6 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len) | |||
97 | WARN_ON(!bss); | 96 | WARN_ON(!bss); |
98 | } else if (wdev->conn) { | 97 | } else if (wdev->conn) { |
99 | cfg80211_sme_failed_assoc(wdev); | 98 | cfg80211_sme_failed_assoc(wdev); |
100 | need_connect_result = false; | ||
101 | /* | 99 | /* |
102 | * do not call connect_result() now because the | 100 | * do not call connect_result() now because the |
103 | * sme will schedule work that does it later. | 101 | * sme will schedule work that does it later. |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f48394126bf9..8ed62b6c172b 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2988,7 +2988,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
2988 | goto out; | 2988 | goto out; |
2989 | } | 2989 | } |
2990 | 2990 | ||
2991 | request->n_channels = n_channels; | ||
2992 | if (n_ssids) | 2991 | if (n_ssids) |
2993 | request->ssids = (void *)&request->channels[n_channels]; | 2992 | request->ssids = (void *)&request->channels[n_channels]; |
2994 | request->n_ssids = n_ssids; | 2993 | request->n_ssids = n_ssids; |
@@ -2999,32 +2998,53 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
2999 | request->ie = (void *)(request->channels + n_channels); | 2998 | request->ie = (void *)(request->channels + n_channels); |
3000 | } | 2999 | } |
3001 | 3000 | ||
3001 | i = 0; | ||
3002 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { | 3002 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { |
3003 | /* user specified, bail out if channel not found */ | 3003 | /* user specified, bail out if channel not found */ |
3004 | request->n_channels = n_channels; | ||
3005 | i = 0; | ||
3006 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) { | 3004 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) { |
3007 | request->channels[i] = ieee80211_get_channel(wiphy, nla_get_u32(attr)); | 3005 | struct ieee80211_channel *chan; |
3008 | if (!request->channels[i]) { | 3006 | |
3007 | chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); | ||
3008 | |||
3009 | if (!chan) { | ||
3009 | err = -EINVAL; | 3010 | err = -EINVAL; |
3010 | goto out_free; | 3011 | goto out_free; |
3011 | } | 3012 | } |
3013 | |||
3014 | /* ignore disabled channels */ | ||
3015 | if (chan->flags & IEEE80211_CHAN_DISABLED) | ||
3016 | continue; | ||
3017 | |||
3018 | request->channels[i] = chan; | ||
3012 | i++; | 3019 | i++; |
3013 | } | 3020 | } |
3014 | } else { | 3021 | } else { |
3015 | /* all channels */ | 3022 | /* all channels */ |
3016 | i = 0; | ||
3017 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 3023 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
3018 | int j; | 3024 | int j; |
3019 | if (!wiphy->bands[band]) | 3025 | if (!wiphy->bands[band]) |
3020 | continue; | 3026 | continue; |
3021 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { | 3027 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { |
3022 | request->channels[i] = &wiphy->bands[band]->channels[j]; | 3028 | struct ieee80211_channel *chan; |
3029 | |||
3030 | chan = &wiphy->bands[band]->channels[j]; | ||
3031 | |||
3032 | if (chan->flags & IEEE80211_CHAN_DISABLED) | ||
3033 | continue; | ||
3034 | |||
3035 | request->channels[i] = chan; | ||
3023 | i++; | 3036 | i++; |
3024 | } | 3037 | } |
3025 | } | 3038 | } |
3026 | } | 3039 | } |
3027 | 3040 | ||
3041 | if (!i) { | ||
3042 | err = -EINVAL; | ||
3043 | goto out_free; | ||
3044 | } | ||
3045 | |||
3046 | request->n_channels = i; | ||
3047 | |||
3028 | i = 0; | 3048 | i = 0; |
3029 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { | 3049 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { |
3030 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { | 3050 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 2e8c515f3c5c..e2d344ff6745 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -650,9 +650,15 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
650 | i = 0; | 650 | i = 0; |
651 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 651 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
652 | int j; | 652 | int j; |
653 | |||
653 | if (!wiphy->bands[band]) | 654 | if (!wiphy->bands[band]) |
654 | continue; | 655 | continue; |
656 | |||
655 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { | 657 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { |
658 | /* ignore disabled channels */ | ||
659 | if (wiphy->bands[band]->channels[j].flags & | ||
660 | IEEE80211_CHAN_DISABLED) | ||
661 | continue; | ||
656 | 662 | ||
657 | /* If we have a wireless request structure and the | 663 | /* If we have a wireless request structure and the |
658 | * wireless request specifies frequencies, then search | 664 | * wireless request specifies frequencies, then search |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 561a45cf2a6a..41abcbdc5fb9 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -904,8 +904,6 @@ static int cfg80211_set_auth_alg(struct wireless_dev *wdev, | |||
904 | 904 | ||
905 | static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions) | 905 | static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions) |
906 | { | 906 | { |
907 | wdev->wext.connect.crypto.wpa_versions = 0; | ||
908 | |||
909 | if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA | | 907 | if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA | |
910 | IW_AUTH_WPA_VERSION_WPA2| | 908 | IW_AUTH_WPA_VERSION_WPA2| |
911 | IW_AUTH_WPA_VERSION_DISABLED)) | 909 | IW_AUTH_WPA_VERSION_DISABLED)) |
@@ -933,8 +931,6 @@ static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions) | |||
933 | 931 | ||
934 | static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher) | 932 | static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher) |
935 | { | 933 | { |
936 | wdev->wext.connect.crypto.cipher_group = 0; | ||
937 | |||
938 | if (cipher & IW_AUTH_CIPHER_WEP40) | 934 | if (cipher & IW_AUTH_CIPHER_WEP40) |
939 | wdev->wext.connect.crypto.cipher_group = | 935 | wdev->wext.connect.crypto.cipher_group = |
940 | WLAN_CIPHER_SUITE_WEP40; | 936 | WLAN_CIPHER_SUITE_WEP40; |
@@ -950,6 +946,8 @@ static int cfg80211_set_cipher_group(struct wireless_dev *wdev, u32 cipher) | |||
950 | else if (cipher & IW_AUTH_CIPHER_AES_CMAC) | 946 | else if (cipher & IW_AUTH_CIPHER_AES_CMAC) |
951 | wdev->wext.connect.crypto.cipher_group = | 947 | wdev->wext.connect.crypto.cipher_group = |
952 | WLAN_CIPHER_SUITE_AES_CMAC; | 948 | WLAN_CIPHER_SUITE_AES_CMAC; |
949 | else if (cipher & IW_AUTH_CIPHER_NONE) | ||
950 | wdev->wext.connect.crypto.cipher_group = 0; | ||
953 | else | 951 | else |
954 | return -EINVAL; | 952 | return -EINVAL; |
955 | 953 | ||