diff options
Diffstat (limited to 'net/mac80211/main.c')
-rw-r--r-- | net/mac80211/main.c | 426 |
1 files changed, 73 insertions, 353 deletions
diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 797f53942e5f..b887e484ae04 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c | |||
@@ -9,7 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <net/mac80211.h> | 11 | #include <net/mac80211.h> |
12 | #include <net/ieee80211_radiotap.h> | ||
13 | #include <linux/module.h> | 12 | #include <linux/module.h> |
14 | #include <linux/init.h> | 13 | #include <linux/init.h> |
15 | #include <linux/netdevice.h> | 14 | #include <linux/netdevice.h> |
@@ -18,7 +17,6 @@ | |||
18 | #include <linux/skbuff.h> | 17 | #include <linux/skbuff.h> |
19 | #include <linux/etherdevice.h> | 18 | #include <linux/etherdevice.h> |
20 | #include <linux/if_arp.h> | 19 | #include <linux/if_arp.h> |
21 | #include <linux/wireless.h> | ||
22 | #include <linux/rtnetlink.h> | 20 | #include <linux/rtnetlink.h> |
23 | #include <linux/bitmap.h> | 21 | #include <linux/bitmap.h> |
24 | #include <linux/pm_qos_params.h> | 22 | #include <linux/pm_qos_params.h> |
@@ -30,25 +28,15 @@ | |||
30 | #include "rate.h" | 28 | #include "rate.h" |
31 | #include "mesh.h" | 29 | #include "mesh.h" |
32 | #include "wep.h" | 30 | #include "wep.h" |
33 | #include "wme.h" | ||
34 | #include "aes_ccm.h" | ||
35 | #include "led.h" | 31 | #include "led.h" |
36 | #include "cfg.h" | 32 | #include "cfg.h" |
37 | #include "debugfs.h" | 33 | #include "debugfs.h" |
38 | #include "debugfs_netdev.h" | ||
39 | 34 | ||
40 | /* | ||
41 | * For seeing transmitted packets on monitor interfaces | ||
42 | * we have a radiotap header too. | ||
43 | */ | ||
44 | struct ieee80211_tx_status_rtap_hdr { | ||
45 | struct ieee80211_radiotap_header hdr; | ||
46 | u8 rate; | ||
47 | u8 padding_for_rate; | ||
48 | __le16 tx_flags; | ||
49 | u8 data_retries; | ||
50 | } __attribute__ ((packed)); | ||
51 | 35 | ||
36 | bool ieee80211_disable_40mhz_24ghz; | ||
37 | module_param(ieee80211_disable_40mhz_24ghz, bool, 0644); | ||
38 | MODULE_PARM_DESC(ieee80211_disable_40mhz_24ghz, | ||
39 | "Disable 40MHz support in the 2.4GHz band"); | ||
52 | 40 | ||
53 | void ieee80211_configure_filter(struct ieee80211_local *local) | 41 | void ieee80211_configure_filter(struct ieee80211_local *local) |
54 | { | 42 | { |
@@ -118,6 +106,9 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
118 | if (scan_chan) { | 106 | if (scan_chan) { |
119 | chan = scan_chan; | 107 | chan = scan_chan; |
120 | channel_type = NL80211_CHAN_NO_HT; | 108 | channel_type = NL80211_CHAN_NO_HT; |
109 | } else if (local->tmp_channel) { | ||
110 | chan = scan_chan = local->tmp_channel; | ||
111 | channel_type = local->tmp_channel_type; | ||
121 | } else { | 112 | } else { |
122 | chan = local->oper_channel; | 113 | chan = local->oper_channel; |
123 | channel_type = local->oper_channel_type; | 114 | channel_type = local->oper_channel_type; |
@@ -130,6 +121,18 @@ int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) | |||
130 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; | 121 | changed |= IEEE80211_CONF_CHANGE_CHANNEL; |
131 | } | 122 | } |
132 | 123 | ||
124 | if (!conf_is_ht(&local->hw.conf)) { | ||
125 | /* | ||
126 | * mac80211.h documents that this is only valid | ||
127 | * when the channel is set to an HT type, and | ||
128 | * that otherwise STATIC is used. | ||
129 | */ | ||
130 | local->hw.conf.smps_mode = IEEE80211_SMPS_STATIC; | ||
131 | } else if (local->hw.conf.smps_mode != local->smps_mode) { | ||
132 | local->hw.conf.smps_mode = local->smps_mode; | ||
133 | changed |= IEEE80211_CONF_CHANGE_SMPS; | ||
134 | } | ||
135 | |||
133 | if (scan_chan) | 136 | if (scan_chan) |
134 | power = chan->max_power; | 137 | power = chan->max_power; |
135 | else | 138 | else |
@@ -189,7 +192,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
189 | } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) | 192 | } else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) |
190 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; | 193 | sdata->vif.bss_conf.bssid = sdata->u.ibss.bssid; |
191 | else if (sdata->vif.type == NL80211_IFTYPE_AP) | 194 | else if (sdata->vif.type == NL80211_IFTYPE_AP) |
192 | sdata->vif.bss_conf.bssid = sdata->dev->dev_addr; | 195 | sdata->vif.bss_conf.bssid = sdata->vif.addr; |
193 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { | 196 | else if (ieee80211_vif_is_mesh(&sdata->vif)) { |
194 | sdata->vif.bss_conf.bssid = zero; | 197 | sdata->vif.bss_conf.bssid = zero; |
195 | } else { | 198 | } else { |
@@ -211,7 +214,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
211 | } | 214 | } |
212 | 215 | ||
213 | if (changed & BSS_CHANGED_BEACON_ENABLED) { | 216 | if (changed & BSS_CHANGED_BEACON_ENABLED) { |
214 | if (local->quiescing || !netif_running(sdata->dev) || | 217 | if (local->quiescing || !ieee80211_sdata_running(sdata) || |
215 | test_bit(SCAN_SW_SCANNING, &local->scanning)) { | 218 | test_bit(SCAN_SW_SCANNING, &local->scanning)) { |
216 | sdata->vif.bss_conf.enable_beacon = false; | 219 | sdata->vif.bss_conf.enable_beacon = false; |
217 | } else { | 220 | } else { |
@@ -222,11 +225,11 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
222 | switch (sdata->vif.type) { | 225 | switch (sdata->vif.type) { |
223 | case NL80211_IFTYPE_AP: | 226 | case NL80211_IFTYPE_AP: |
224 | sdata->vif.bss_conf.enable_beacon = | 227 | sdata->vif.bss_conf.enable_beacon = |
225 | !!rcu_dereference(sdata->u.ap.beacon); | 228 | !!sdata->u.ap.beacon; |
226 | break; | 229 | break; |
227 | case NL80211_IFTYPE_ADHOC: | 230 | case NL80211_IFTYPE_ADHOC: |
228 | sdata->vif.bss_conf.enable_beacon = | 231 | sdata->vif.bss_conf.enable_beacon = |
229 | !!rcu_dereference(sdata->u.ibss.presp); | 232 | !!sdata->u.ibss.presp; |
230 | break; | 233 | break; |
231 | case NL80211_IFTYPE_MESH_POINT: | 234 | case NL80211_IFTYPE_MESH_POINT: |
232 | sdata->vif.bss_conf.enable_beacon = true; | 235 | sdata->vif.bss_conf.enable_beacon = true; |
@@ -239,8 +242,7 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata, | |||
239 | } | 242 | } |
240 | } | 243 | } |
241 | 244 | ||
242 | drv_bss_info_changed(local, &sdata->vif, | 245 | drv_bss_info_changed(local, sdata, &sdata->vif.bss_conf, changed); |
243 | &sdata->vif.bss_conf, changed); | ||
244 | } | 246 | } |
245 | 247 | ||
246 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | 248 | u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) |
@@ -253,28 +255,6 @@ u32 ieee80211_reset_erp_info(struct ieee80211_sub_if_data *sdata) | |||
253 | BSS_CHANGED_ERP_SLOT; | 255 | BSS_CHANGED_ERP_SLOT; |
254 | } | 256 | } |
255 | 257 | ||
256 | void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw, | ||
257 | struct sk_buff *skb) | ||
258 | { | ||
259 | struct ieee80211_local *local = hw_to_local(hw); | ||
260 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
261 | int tmp; | ||
262 | |||
263 | skb->pkt_type = IEEE80211_TX_STATUS_MSG; | ||
264 | skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? | ||
265 | &local->skb_queue : &local->skb_queue_unreliable, skb); | ||
266 | tmp = skb_queue_len(&local->skb_queue) + | ||
267 | skb_queue_len(&local->skb_queue_unreliable); | ||
268 | while (tmp > IEEE80211_IRQSAFE_QUEUE_LIMIT && | ||
269 | (skb = skb_dequeue(&local->skb_queue_unreliable))) { | ||
270 | dev_kfree_skb_irq(skb); | ||
271 | tmp--; | ||
272 | I802_DEBUG_INC(local->tx_status_drop); | ||
273 | } | ||
274 | tasklet_schedule(&local->tasklet); | ||
275 | } | ||
276 | EXPORT_SYMBOL(ieee80211_tx_status_irqsafe); | ||
277 | |||
278 | static void ieee80211_tasklet_handler(unsigned long data) | 258 | static void ieee80211_tasklet_handler(unsigned long data) |
279 | { | 259 | { |
280 | struct ieee80211_local *local = (struct ieee80211_local *) data; | 260 | struct ieee80211_local *local = (struct ieee80211_local *) data; |
@@ -296,14 +276,14 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
296 | break; | 276 | break; |
297 | case IEEE80211_DELBA_MSG: | 277 | case IEEE80211_DELBA_MSG: |
298 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 278 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
299 | ieee80211_stop_tx_ba_cb(local_to_hw(local), | 279 | ieee80211_stop_tx_ba_cb(ra_tid->vif, ra_tid->ra, |
300 | ra_tid->ra, ra_tid->tid); | 280 | ra_tid->tid); |
301 | dev_kfree_skb(skb); | 281 | dev_kfree_skb(skb); |
302 | break; | 282 | break; |
303 | case IEEE80211_ADDBA_MSG: | 283 | case IEEE80211_ADDBA_MSG: |
304 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 284 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; |
305 | ieee80211_start_tx_ba_cb(local_to_hw(local), | 285 | ieee80211_start_tx_ba_cb(ra_tid->vif, ra_tid->ra, |
306 | ra_tid->ra, ra_tid->tid); | 286 | ra_tid->tid); |
307 | dev_kfree_skb(skb); | 287 | dev_kfree_skb(skb); |
308 | break ; | 288 | break ; |
309 | default: | 289 | default: |
@@ -315,299 +295,6 @@ static void ieee80211_tasklet_handler(unsigned long data) | |||
315 | } | 295 | } |
316 | } | 296 | } |
317 | 297 | ||
318 | static void ieee80211_handle_filtered_frame(struct ieee80211_local *local, | ||
319 | struct sta_info *sta, | ||
320 | struct sk_buff *skb) | ||
321 | { | ||
322 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
323 | |||
324 | /* | ||
325 | * XXX: This is temporary! | ||
326 | * | ||
327 | * The problem here is that when we get here, the driver will | ||
328 | * quite likely have pretty much overwritten info->control by | ||
329 | * using info->driver_data or info->rate_driver_data. Thus, | ||
330 | * when passing out the frame to the driver again, we would be | ||
331 | * passing completely bogus data since the driver would then | ||
332 | * expect a properly filled info->control. In mac80211 itself | ||
333 | * the same problem occurs, since we need info->control.vif | ||
334 | * internally. | ||
335 | * | ||
336 | * To fix this, we should send the frame through TX processing | ||
337 | * again. However, it's not that simple, since the frame will | ||
338 | * have been software-encrypted (if applicable) already, and | ||
339 | * encrypting it again doesn't do much good. So to properly do | ||
340 | * that, we not only have to skip the actual 'raw' encryption | ||
341 | * (key selection etc. still has to be done!) but also the | ||
342 | * sequence number assignment since that impacts the crypto | ||
343 | * encapsulation, of course. | ||
344 | * | ||
345 | * Hence, for now, fix the bug by just dropping the frame. | ||
346 | */ | ||
347 | goto drop; | ||
348 | |||
349 | sta->tx_filtered_count++; | ||
350 | |||
351 | /* | ||
352 | * Clear the TX filter mask for this STA when sending the next | ||
353 | * packet. If the STA went to power save mode, this will happen | ||
354 | * when it wakes up for the next time. | ||
355 | */ | ||
356 | set_sta_flags(sta, WLAN_STA_CLEAR_PS_FILT); | ||
357 | |||
358 | /* | ||
359 | * This code races in the following way: | ||
360 | * | ||
361 | * (1) STA sends frame indicating it will go to sleep and does so | ||
362 | * (2) hardware/firmware adds STA to filter list, passes frame up | ||
363 | * (3) hardware/firmware processes TX fifo and suppresses a frame | ||
364 | * (4) we get TX status before having processed the frame and | ||
365 | * knowing that the STA has gone to sleep. | ||
366 | * | ||
367 | * This is actually quite unlikely even when both those events are | ||
368 | * processed from interrupts coming in quickly after one another or | ||
369 | * even at the same time because we queue both TX status events and | ||
370 | * RX frames to be processed by a tasklet and process them in the | ||
371 | * same order that they were received or TX status last. Hence, there | ||
372 | * is no race as long as the frame RX is processed before the next TX | ||
373 | * status, which drivers can ensure, see below. | ||
374 | * | ||
375 | * Note that this can only happen if the hardware or firmware can | ||
376 | * actually add STAs to the filter list, if this is done by the | ||
377 | * driver in response to set_tim() (which will only reduce the race | ||
378 | * this whole filtering tries to solve, not completely solve it) | ||
379 | * this situation cannot happen. | ||
380 | * | ||
381 | * To completely solve this race drivers need to make sure that they | ||
382 | * (a) don't mix the irq-safe/not irq-safe TX status/RX processing | ||
383 | * functions and | ||
384 | * (b) always process RX events before TX status events if ordering | ||
385 | * can be unknown, for example with different interrupt status | ||
386 | * bits. | ||
387 | */ | ||
388 | if (test_sta_flags(sta, WLAN_STA_PS) && | ||
389 | skb_queue_len(&sta->tx_filtered) < STA_MAX_TX_BUFFER) { | ||
390 | skb_queue_tail(&sta->tx_filtered, skb); | ||
391 | return; | ||
392 | } | ||
393 | |||
394 | if (!test_sta_flags(sta, WLAN_STA_PS) && | ||
395 | !(info->flags & IEEE80211_TX_INTFL_RETRIED)) { | ||
396 | /* Software retry the packet once */ | ||
397 | info->flags |= IEEE80211_TX_INTFL_RETRIED; | ||
398 | ieee80211_add_pending_skb(local, skb); | ||
399 | return; | ||
400 | } | ||
401 | |||
402 | drop: | ||
403 | #ifdef CONFIG_MAC80211_VERBOSE_DEBUG | ||
404 | if (net_ratelimit()) | ||
405 | printk(KERN_DEBUG "%s: dropped TX filtered frame, " | ||
406 | "queue_len=%d PS=%d @%lu\n", | ||
407 | wiphy_name(local->hw.wiphy), | ||
408 | skb_queue_len(&sta->tx_filtered), | ||
409 | !!test_sta_flags(sta, WLAN_STA_PS), jiffies); | ||
410 | #endif | ||
411 | dev_kfree_skb(skb); | ||
412 | } | ||
413 | |||
414 | void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) | ||
415 | { | ||
416 | struct sk_buff *skb2; | ||
417 | struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; | ||
418 | struct ieee80211_local *local = hw_to_local(hw); | ||
419 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
420 | u16 frag, type; | ||
421 | __le16 fc; | ||
422 | struct ieee80211_supported_band *sband; | ||
423 | struct ieee80211_tx_status_rtap_hdr *rthdr; | ||
424 | struct ieee80211_sub_if_data *sdata; | ||
425 | struct net_device *prev_dev = NULL; | ||
426 | struct sta_info *sta; | ||
427 | int retry_count = -1, i; | ||
428 | |||
429 | for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { | ||
430 | /* the HW cannot have attempted that rate */ | ||
431 | if (i >= hw->max_rates) { | ||
432 | info->status.rates[i].idx = -1; | ||
433 | info->status.rates[i].count = 0; | ||
434 | } | ||
435 | |||
436 | retry_count += info->status.rates[i].count; | ||
437 | } | ||
438 | if (retry_count < 0) | ||
439 | retry_count = 0; | ||
440 | |||
441 | rcu_read_lock(); | ||
442 | |||
443 | sband = local->hw.wiphy->bands[info->band]; | ||
444 | |||
445 | sta = sta_info_get(local, hdr->addr1); | ||
446 | |||
447 | if (sta) { | ||
448 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | ||
449 | test_sta_flags(sta, WLAN_STA_PS)) { | ||
450 | /* | ||
451 | * The STA is in power save mode, so assume | ||
452 | * that this TX packet failed because of that. | ||
453 | */ | ||
454 | ieee80211_handle_filtered_frame(local, sta, skb); | ||
455 | rcu_read_unlock(); | ||
456 | return; | ||
457 | } | ||
458 | |||
459 | fc = hdr->frame_control; | ||
460 | |||
461 | if ((info->flags & IEEE80211_TX_STAT_AMPDU_NO_BACK) && | ||
462 | (ieee80211_is_data_qos(fc))) { | ||
463 | u16 tid, ssn; | ||
464 | u8 *qc; | ||
465 | |||
466 | qc = ieee80211_get_qos_ctl(hdr); | ||
467 | tid = qc[0] & 0xf; | ||
468 | ssn = ((le16_to_cpu(hdr->seq_ctrl) + 0x10) | ||
469 | & IEEE80211_SCTL_SEQ); | ||
470 | ieee80211_send_bar(sta->sdata, hdr->addr1, | ||
471 | tid, ssn); | ||
472 | } | ||
473 | |||
474 | if (info->flags & IEEE80211_TX_STAT_TX_FILTERED) { | ||
475 | ieee80211_handle_filtered_frame(local, sta, skb); | ||
476 | rcu_read_unlock(); | ||
477 | return; | ||
478 | } else { | ||
479 | if (!(info->flags & IEEE80211_TX_STAT_ACK)) | ||
480 | sta->tx_retry_failed++; | ||
481 | sta->tx_retry_count += retry_count; | ||
482 | } | ||
483 | |||
484 | rate_control_tx_status(local, sband, sta, skb); | ||
485 | if (ieee80211_vif_is_mesh(&sta->sdata->vif)) | ||
486 | ieee80211s_update_metric(local, sta, skb); | ||
487 | } | ||
488 | |||
489 | rcu_read_unlock(); | ||
490 | |||
491 | ieee80211_led_tx(local, 0); | ||
492 | |||
493 | /* SNMP counters | ||
494 | * Fragments are passed to low-level drivers as separate skbs, so these | ||
495 | * are actually fragments, not frames. Update frame counters only for | ||
496 | * the first fragment of the frame. */ | ||
497 | |||
498 | frag = le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG; | ||
499 | type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE; | ||
500 | |||
501 | if (info->flags & IEEE80211_TX_STAT_ACK) { | ||
502 | if (frag == 0) { | ||
503 | local->dot11TransmittedFrameCount++; | ||
504 | if (is_multicast_ether_addr(hdr->addr1)) | ||
505 | local->dot11MulticastTransmittedFrameCount++; | ||
506 | if (retry_count > 0) | ||
507 | local->dot11RetryCount++; | ||
508 | if (retry_count > 1) | ||
509 | local->dot11MultipleRetryCount++; | ||
510 | } | ||
511 | |||
512 | /* This counter shall be incremented for an acknowledged MPDU | ||
513 | * with an individual address in the address 1 field or an MPDU | ||
514 | * with a multicast address in the address 1 field of type Data | ||
515 | * or Management. */ | ||
516 | if (!is_multicast_ether_addr(hdr->addr1) || | ||
517 | type == IEEE80211_FTYPE_DATA || | ||
518 | type == IEEE80211_FTYPE_MGMT) | ||
519 | local->dot11TransmittedFragmentCount++; | ||
520 | } else { | ||
521 | if (frag == 0) | ||
522 | local->dot11FailedCount++; | ||
523 | } | ||
524 | |||
525 | /* this was a transmitted frame, but now we want to reuse it */ | ||
526 | skb_orphan(skb); | ||
527 | |||
528 | /* | ||
529 | * This is a bit racy but we can avoid a lot of work | ||
530 | * with this test... | ||
531 | */ | ||
532 | if (!local->monitors && !local->cooked_mntrs) { | ||
533 | dev_kfree_skb(skb); | ||
534 | return; | ||
535 | } | ||
536 | |||
537 | /* send frame to monitor interfaces now */ | ||
538 | |||
539 | if (skb_headroom(skb) < sizeof(*rthdr)) { | ||
540 | printk(KERN_ERR "ieee80211_tx_status: headroom too small\n"); | ||
541 | dev_kfree_skb(skb); | ||
542 | return; | ||
543 | } | ||
544 | |||
545 | rthdr = (struct ieee80211_tx_status_rtap_hdr *) | ||
546 | skb_push(skb, sizeof(*rthdr)); | ||
547 | |||
548 | memset(rthdr, 0, sizeof(*rthdr)); | ||
549 | rthdr->hdr.it_len = cpu_to_le16(sizeof(*rthdr)); | ||
550 | rthdr->hdr.it_present = | ||
551 | cpu_to_le32((1 << IEEE80211_RADIOTAP_TX_FLAGS) | | ||
552 | (1 << IEEE80211_RADIOTAP_DATA_RETRIES) | | ||
553 | (1 << IEEE80211_RADIOTAP_RATE)); | ||
554 | |||
555 | if (!(info->flags & IEEE80211_TX_STAT_ACK) && | ||
556 | !is_multicast_ether_addr(hdr->addr1)) | ||
557 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL); | ||
558 | |||
559 | /* | ||
560 | * XXX: Once radiotap gets the bitmap reset thing the vendor | ||
561 | * extensions proposal contains, we can actually report | ||
562 | * the whole set of tries we did. | ||
563 | */ | ||
564 | if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) || | ||
565 | (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT)) | ||
566 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS); | ||
567 | else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) | ||
568 | rthdr->tx_flags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS); | ||
569 | if (info->status.rates[0].idx >= 0 && | ||
570 | !(info->status.rates[0].flags & IEEE80211_TX_RC_MCS)) | ||
571 | rthdr->rate = sband->bitrates[ | ||
572 | info->status.rates[0].idx].bitrate / 5; | ||
573 | |||
574 | /* for now report the total retry_count */ | ||
575 | rthdr->data_retries = retry_count; | ||
576 | |||
577 | /* XXX: is this sufficient for BPF? */ | ||
578 | skb_set_mac_header(skb, 0); | ||
579 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
580 | skb->pkt_type = PACKET_OTHERHOST; | ||
581 | skb->protocol = htons(ETH_P_802_2); | ||
582 | memset(skb->cb, 0, sizeof(skb->cb)); | ||
583 | |||
584 | rcu_read_lock(); | ||
585 | list_for_each_entry_rcu(sdata, &local->interfaces, list) { | ||
586 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR) { | ||
587 | if (!netif_running(sdata->dev)) | ||
588 | continue; | ||
589 | |||
590 | if (prev_dev) { | ||
591 | skb2 = skb_clone(skb, GFP_ATOMIC); | ||
592 | if (skb2) { | ||
593 | skb2->dev = prev_dev; | ||
594 | netif_rx(skb2); | ||
595 | } | ||
596 | } | ||
597 | |||
598 | prev_dev = sdata->dev; | ||
599 | } | ||
600 | } | ||
601 | if (prev_dev) { | ||
602 | skb->dev = prev_dev; | ||
603 | netif_rx(skb); | ||
604 | skb = NULL; | ||
605 | } | ||
606 | rcu_read_unlock(); | ||
607 | dev_kfree_skb(skb); | ||
608 | } | ||
609 | EXPORT_SYMBOL(ieee80211_tx_status); | ||
610 | |||
611 | static void ieee80211_restart_work(struct work_struct *work) | 298 | static void ieee80211_restart_work(struct work_struct *work) |
612 | { | 299 | { |
613 | struct ieee80211_local *local = | 300 | struct ieee80211_local *local = |
@@ -630,6 +317,16 @@ void ieee80211_restart_hw(struct ieee80211_hw *hw) | |||
630 | } | 317 | } |
631 | EXPORT_SYMBOL(ieee80211_restart_hw); | 318 | EXPORT_SYMBOL(ieee80211_restart_hw); |
632 | 319 | ||
320 | static void ieee80211_recalc_smps_work(struct work_struct *work) | ||
321 | { | ||
322 | struct ieee80211_local *local = | ||
323 | container_of(work, struct ieee80211_local, recalc_smps); | ||
324 | |||
325 | mutex_lock(&local->iflist_mtx); | ||
326 | ieee80211_recalc_smps(local, NULL); | ||
327 | mutex_unlock(&local->iflist_mtx); | ||
328 | } | ||
329 | |||
633 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | 330 | struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, |
634 | const struct ieee80211_ops *ops) | 331 | const struct ieee80211_ops *ops) |
635 | { | 332 | { |
@@ -659,12 +356,12 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
659 | if (!wiphy) | 356 | if (!wiphy) |
660 | return NULL; | 357 | return NULL; |
661 | 358 | ||
662 | wiphy->netnsok = true; | 359 | wiphy->flags |= WIPHY_FLAG_NETNS_OK | |
360 | WIPHY_FLAG_4ADDR_AP | | ||
361 | WIPHY_FLAG_4ADDR_STATION; | ||
663 | wiphy->privid = mac80211_wiphy_privid; | 362 | wiphy->privid = mac80211_wiphy_privid; |
664 | 363 | ||
665 | /* Yes, putting cfg80211_bss into ieee80211_bss is a hack */ | 364 | wiphy->bss_priv_size = sizeof(struct ieee80211_bss); |
666 | wiphy->bss_priv_size = sizeof(struct ieee80211_bss) - | ||
667 | sizeof(struct cfg80211_bss); | ||
668 | 365 | ||
669 | local = wiphy_priv(wiphy); | 366 | local = wiphy_priv(wiphy); |
670 | 367 | ||
@@ -687,6 +384,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
687 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; | 384 | local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; |
688 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; | 385 | local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; |
689 | local->user_power_level = -1; | 386 | local->user_power_level = -1; |
387 | local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES; | ||
388 | local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN; | ||
690 | 389 | ||
691 | INIT_LIST_HEAD(&local->interfaces); | 390 | INIT_LIST_HEAD(&local->interfaces); |
692 | mutex_init(&local->iflist_mtx); | 391 | mutex_init(&local->iflist_mtx); |
@@ -698,9 +397,13 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len, | |||
698 | 397 | ||
699 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); | 398 | INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); |
700 | 399 | ||
400 | ieee80211_work_init(local); | ||
401 | |||
701 | INIT_WORK(&local->restart_work, ieee80211_restart_work); | 402 | INIT_WORK(&local->restart_work, ieee80211_restart_work); |
702 | 403 | ||
703 | INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); | 404 | INIT_WORK(&local->reconfig_filter, ieee80211_reconfig_filter); |
405 | INIT_WORK(&local->recalc_smps, ieee80211_recalc_smps_work); | ||
406 | local->smps_mode = IEEE80211_SMPS_OFF; | ||
704 | 407 | ||
705 | INIT_WORK(&local->dynamic_ps_enable_work, | 408 | INIT_WORK(&local->dynamic_ps_enable_work, |
706 | ieee80211_dynamic_ps_enable_work); | 409 | ieee80211_dynamic_ps_enable_work); |
@@ -790,6 +493,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
790 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) | 493 | else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) |
791 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; | 494 | local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; |
792 | 495 | ||
496 | WARN((local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) | ||
497 | && (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK), | ||
498 | "U-APSD not supported with HW_PS_NULLFUNC_STACK\n"); | ||
499 | |||
793 | /* | 500 | /* |
794 | * Calculate scan IE length -- we need this to alloc | 501 | * Calculate scan IE length -- we need this to alloc |
795 | * memory and to subtract from the driver limit. It | 502 | * memory and to subtract from the driver limit. It |
@@ -844,13 +551,19 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
844 | * and we need some headroom for passing the frame to monitor | 551 | * and we need some headroom for passing the frame to monitor |
845 | * interfaces, but never both at the same time. | 552 | * interfaces, but never both at the same time. |
846 | */ | 553 | */ |
554 | BUILD_BUG_ON(IEEE80211_TX_STATUS_HEADROOM != | ||
555 | sizeof(struct ieee80211_tx_status_rtap_hdr)); | ||
847 | local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, | 556 | local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom, |
848 | sizeof(struct ieee80211_tx_status_rtap_hdr)); | 557 | sizeof(struct ieee80211_tx_status_rtap_hdr)); |
849 | 558 | ||
850 | debugfs_hw_add(local); | 559 | debugfs_hw_add(local); |
851 | 560 | ||
561 | /* | ||
562 | * if the driver doesn't specify a max listen interval we | ||
563 | * use 5 which should be a safe default | ||
564 | */ | ||
852 | if (local->hw.max_listen_interval == 0) | 565 | if (local->hw.max_listen_interval == 0) |
853 | local->hw.max_listen_interval = 1; | 566 | local->hw.max_listen_interval = 5; |
854 | 567 | ||
855 | local->hw.conf.listen_interval = local->hw.max_listen_interval; | 568 | local->hw.conf.listen_interval = local->hw.max_listen_interval; |
856 | 569 | ||
@@ -901,6 +614,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
901 | i++; | 614 | i++; |
902 | } | 615 | } |
903 | } | 616 | } |
617 | local->int_scan_req->n_channels = i; | ||
904 | 618 | ||
905 | local->network_latency_notifier.notifier_call = | 619 | local->network_latency_notifier.notifier_call = |
906 | ieee80211_max_network_latency; | 620 | ieee80211_max_network_latency; |
@@ -923,7 +637,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) | |||
923 | fail_wep: | 637 | fail_wep: |
924 | sta_info_stop(local); | 638 | sta_info_stop(local); |
925 | fail_sta_info: | 639 | fail_sta_info: |
926 | debugfs_hw_del(local); | ||
927 | destroy_workqueue(local->workqueue); | 640 | destroy_workqueue(local->workqueue); |
928 | fail_workqueue: | 641 | fail_workqueue: |
929 | wiphy_unregister(local->hw.wiphy); | 642 | wiphy_unregister(local->hw.wiphy); |
@@ -959,10 +672,9 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw) | |||
959 | ieee80211_clear_tx_pending(local); | 672 | ieee80211_clear_tx_pending(local); |
960 | sta_info_stop(local); | 673 | sta_info_stop(local); |
961 | rate_control_deinitialize(local); | 674 | rate_control_deinitialize(local); |
962 | debugfs_hw_del(local); | ||
963 | 675 | ||
964 | if (skb_queue_len(&local->skb_queue) | 676 | if (skb_queue_len(&local->skb_queue) || |
965 | || skb_queue_len(&local->skb_queue_unreliable)) | 677 | skb_queue_len(&local->skb_queue_unreliable)) |
966 | printk(KERN_WARNING "%s: skb_queue not empty\n", | 678 | printk(KERN_WARNING "%s: skb_queue not empty\n", |
967 | wiphy_name(local->hw.wiphy)); | 679 | wiphy_name(local->hw.wiphy)); |
968 | skb_queue_purge(&local->skb_queue); | 680 | skb_queue_purge(&local->skb_queue); |
@@ -1002,11 +714,19 @@ static int __init ieee80211_init(void) | |||
1002 | 714 | ||
1003 | ret = rc80211_pid_init(); | 715 | ret = rc80211_pid_init(); |
1004 | if (ret) | 716 | if (ret) |
1005 | return ret; | 717 | goto err_pid; |
1006 | 718 | ||
1007 | ieee80211_debugfs_netdev_init(); | 719 | ret = ieee80211_iface_init(); |
720 | if (ret) | ||
721 | goto err_netdev; | ||
1008 | 722 | ||
1009 | return 0; | 723 | return 0; |
724 | err_netdev: | ||
725 | rc80211_pid_exit(); | ||
726 | err_pid: | ||
727 | rc80211_minstrel_exit(); | ||
728 | |||
729 | return ret; | ||
1010 | } | 730 | } |
1011 | 731 | ||
1012 | static void __exit ieee80211_exit(void) | 732 | static void __exit ieee80211_exit(void) |
@@ -1023,7 +743,7 @@ static void __exit ieee80211_exit(void) | |||
1023 | if (mesh_allocated) | 743 | if (mesh_allocated) |
1024 | ieee80211s_stop(); | 744 | ieee80211s_stop(); |
1025 | 745 | ||
1026 | ieee80211_debugfs_netdev_exit(); | 746 | ieee80211_iface_exit(); |
1027 | } | 747 | } |
1028 | 748 | ||
1029 | 749 | ||