diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/mac80211/ibss.c | 7 | ||||
-rw-r--r-- | net/mac80211/ieee80211_i.h | 7 | ||||
-rw-r--r-- | net/mac80211/iface.c | 21 | ||||
-rw-r--r-- | net/mac80211/mesh.c | 14 | ||||
-rw-r--r-- | net/mac80211/mlme.c | 5 |
5 files changed, 20 insertions, 34 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index d7a96ced2c83..a9ff904620db 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
@@ -779,7 +779,7 @@ static void ieee80211_ibss_work(struct work_struct *work) | |||
779 | return; | 779 | return; |
780 | ifibss = &sdata->u.ibss; | 780 | ifibss = &sdata->u.ibss; |
781 | 781 | ||
782 | while ((skb = skb_dequeue(&ifibss->skb_queue))) | 782 | while ((skb = skb_dequeue(&sdata->skb_queue))) |
783 | ieee80211_ibss_rx_queued_mgmt(sdata, skb); | 783 | ieee80211_ibss_rx_queued_mgmt(sdata, skb); |
784 | 784 | ||
785 | if (!test_and_clear_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request)) | 785 | if (!test_and_clear_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request)) |
@@ -850,7 +850,6 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
850 | INIT_WORK(&ifibss->work, ieee80211_ibss_work); | 850 | INIT_WORK(&ifibss->work, ieee80211_ibss_work); |
851 | setup_timer(&ifibss->timer, ieee80211_ibss_timer, | 851 | setup_timer(&ifibss->timer, ieee80211_ibss_timer, |
852 | (unsigned long) sdata); | 852 | (unsigned long) sdata); |
853 | skb_queue_head_init(&ifibss->skb_queue); | ||
854 | } | 853 | } |
855 | 854 | ||
856 | /* scan finished notification */ | 855 | /* scan finished notification */ |
@@ -890,7 +889,7 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
890 | case IEEE80211_STYPE_BEACON: | 889 | case IEEE80211_STYPE_BEACON: |
891 | case IEEE80211_STYPE_PROBE_REQ: | 890 | case IEEE80211_STYPE_PROBE_REQ: |
892 | case IEEE80211_STYPE_AUTH: | 891 | case IEEE80211_STYPE_AUTH: |
893 | skb_queue_tail(&sdata->u.ibss.skb_queue, skb); | 892 | skb_queue_tail(&sdata->skb_queue, skb); |
894 | ieee80211_queue_work(&local->hw, &sdata->u.ibss.work); | 893 | ieee80211_queue_work(&local->hw, &sdata->u.ibss.work); |
895 | return RX_QUEUED; | 894 | return RX_QUEUED; |
896 | } | 895 | } |
@@ -983,7 +982,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata) | |||
983 | synchronize_rcu(); | 982 | synchronize_rcu(); |
984 | kfree_skb(skb); | 983 | kfree_skb(skb); |
985 | 984 | ||
986 | skb_queue_purge(&sdata->u.ibss.skb_queue); | 985 | skb_queue_purge(&sdata->skb_queue); |
987 | memset(sdata->u.ibss.bssid, 0, ETH_ALEN); | 986 | memset(sdata->u.ibss.bssid, 0, ETH_ALEN); |
988 | sdata->u.ibss.ssid_len = 0; | 987 | sdata->u.ibss.ssid_len = 0; |
989 | 988 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 5782a537f74a..3cc3867c5418 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
@@ -340,8 +340,6 @@ struct ieee80211_if_managed { | |||
340 | 340 | ||
341 | u16 aid; | 341 | u16 aid; |
342 | 342 | ||
343 | struct sk_buff_head skb_queue; | ||
344 | |||
345 | unsigned long timers_running; /* used for quiesce/restart */ | 343 | unsigned long timers_running; /* used for quiesce/restart */ |
346 | bool powersave; /* powersave requested for this iface */ | 344 | bool powersave; /* powersave requested for this iface */ |
347 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ | 345 | enum ieee80211_smps_mode req_smps, /* requested smps mode */ |
@@ -388,8 +386,6 @@ struct ieee80211_if_ibss { | |||
388 | struct timer_list timer; | 386 | struct timer_list timer; |
389 | struct work_struct work; | 387 | struct work_struct work; |
390 | 388 | ||
391 | struct sk_buff_head skb_queue; | ||
392 | |||
393 | unsigned long request; | 389 | unsigned long request; |
394 | unsigned long last_scan_completed; | 390 | unsigned long last_scan_completed; |
395 | 391 | ||
@@ -420,7 +416,6 @@ struct ieee80211_if_mesh { | |||
420 | struct timer_list housekeeping_timer; | 416 | struct timer_list housekeeping_timer; |
421 | struct timer_list mesh_path_timer; | 417 | struct timer_list mesh_path_timer; |
422 | struct timer_list mesh_path_root_timer; | 418 | struct timer_list mesh_path_root_timer; |
423 | struct sk_buff_head skb_queue; | ||
424 | 419 | ||
425 | unsigned long timers_running; | 420 | unsigned long timers_running; |
426 | 421 | ||
@@ -517,6 +512,8 @@ struct ieee80211_sub_if_data { | |||
517 | 512 | ||
518 | u16 sequence_number; | 513 | u16 sequence_number; |
519 | 514 | ||
515 | struct sk_buff_head skb_queue; | ||
516 | |||
520 | /* | 517 | /* |
521 | * AP this belongs to: self in AP mode and | 518 | * AP this belongs to: self in AP mode and |
522 | * corresponding AP in VLAN mode, NULL for | 519 | * corresponding AP in VLAN mode, NULL for |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 906fc2be0cfb..56167a3d872d 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -465,21 +465,11 @@ static int ieee80211_stop(struct net_device *dev) | |||
465 | cancel_work_sync(&sdata->u.mgd.monitor_work); | 465 | cancel_work_sync(&sdata->u.mgd.monitor_work); |
466 | cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work); | 466 | cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work); |
467 | 467 | ||
468 | /* | ||
469 | * When we get here, the interface is marked down. | ||
470 | * Call synchronize_rcu() to wait for the RX path | ||
471 | * should it be using the interface and enqueuing | ||
472 | * frames at this very time on another CPU. | ||
473 | */ | ||
474 | synchronize_rcu(); | ||
475 | skb_queue_purge(&sdata->u.mgd.skb_queue); | ||
476 | /* fall through */ | 468 | /* fall through */ |
477 | case NL80211_IFTYPE_ADHOC: | 469 | case NL80211_IFTYPE_ADHOC: |
478 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { | 470 | if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { |
479 | del_timer_sync(&sdata->u.ibss.timer); | 471 | del_timer_sync(&sdata->u.ibss.timer); |
480 | cancel_work_sync(&sdata->u.ibss.work); | 472 | cancel_work_sync(&sdata->u.ibss.work); |
481 | synchronize_rcu(); | ||
482 | skb_queue_purge(&sdata->u.ibss.skb_queue); | ||
483 | } | 473 | } |
484 | /* fall through */ | 474 | /* fall through */ |
485 | case NL80211_IFTYPE_MESH_POINT: | 475 | case NL80211_IFTYPE_MESH_POINT: |
@@ -495,6 +485,15 @@ static int ieee80211_stop(struct net_device *dev) | |||
495 | } | 485 | } |
496 | /* fall through */ | 486 | /* fall through */ |
497 | default: | 487 | default: |
488 | /* | ||
489 | * When we get here, the interface is marked down. | ||
490 | * Call synchronize_rcu() to wait for the RX path | ||
491 | * should it be using the interface and enqueuing | ||
492 | * frames at this very time on another CPU. | ||
493 | */ | ||
494 | synchronize_rcu(); | ||
495 | skb_queue_purge(&sdata->skb_queue); | ||
496 | |||
498 | if (local->scan_sdata == sdata) | 497 | if (local->scan_sdata == sdata) |
499 | ieee80211_scan_cancel(local); | 498 | ieee80211_scan_cancel(local); |
500 | 499 | ||
@@ -721,6 +720,8 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata, | |||
721 | /* only monitor differs */ | 720 | /* only monitor differs */ |
722 | sdata->dev->type = ARPHRD_ETHER; | 721 | sdata->dev->type = ARPHRD_ETHER; |
723 | 722 | ||
723 | skb_queue_head_init(&sdata->skb_queue); | ||
724 | |||
724 | switch (type) { | 725 | switch (type) { |
725 | case NL80211_IFTYPE_AP: | 726 | case NL80211_IFTYPE_AP: |
726 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); | 727 | skb_queue_head_init(&sdata->u.ap.ps_bc_buf); |
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c index bde81031727a..065533a37abe 100644 --- a/net/mac80211/mesh.c +++ b/net/mac80211/mesh.c | |||
@@ -537,15 +537,6 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata) | |||
537 | * it no longer is. | 537 | * it no longer is. |
538 | */ | 538 | */ |
539 | cancel_work_sync(&sdata->u.mesh.work); | 539 | cancel_work_sync(&sdata->u.mesh.work); |
540 | |||
541 | /* | ||
542 | * When we get here, the interface is marked down. | ||
543 | * Call synchronize_rcu() to wait for the RX path | ||
544 | * should it be using the interface and enqueuing | ||
545 | * frames at this very time on another CPU. | ||
546 | */ | ||
547 | rcu_barrier(); /* Wait for RX path and call_rcu()'s */ | ||
548 | skb_queue_purge(&sdata->u.mesh.skb_queue); | ||
549 | } | 540 | } |
550 | 541 | ||
551 | static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, | 542 | static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, |
@@ -650,7 +641,7 @@ static void ieee80211_mesh_work(struct work_struct *work) | |||
650 | if (local->scanning) | 641 | if (local->scanning) |
651 | return; | 642 | return; |
652 | 643 | ||
653 | while ((skb = skb_dequeue(&ifmsh->skb_queue))) | 644 | while ((skb = skb_dequeue(&sdata->skb_queue))) |
654 | ieee80211_mesh_rx_queued_mgmt(sdata, skb); | 645 | ieee80211_mesh_rx_queued_mgmt(sdata, skb); |
655 | 646 | ||
656 | if (ifmsh->preq_queue_len && | 647 | if (ifmsh->preq_queue_len && |
@@ -690,7 +681,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata) | |||
690 | setup_timer(&ifmsh->housekeeping_timer, | 681 | setup_timer(&ifmsh->housekeeping_timer, |
691 | ieee80211_mesh_housekeeping_timer, | 682 | ieee80211_mesh_housekeeping_timer, |
692 | (unsigned long) sdata); | 683 | (unsigned long) sdata); |
693 | skb_queue_head_init(&sdata->u.mesh.skb_queue); | ||
694 | 684 | ||
695 | ifmsh->mshcfg.dot11MeshRetryTimeout = MESH_RET_T; | 685 | ifmsh->mshcfg.dot11MeshRetryTimeout = MESH_RET_T; |
696 | ifmsh->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T; | 686 | ifmsh->mshcfg.dot11MeshConfirmTimeout = MESH_CONF_T; |
@@ -750,7 +740,7 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) | |||
750 | case IEEE80211_STYPE_ACTION: | 740 | case IEEE80211_STYPE_ACTION: |
751 | case IEEE80211_STYPE_PROBE_RESP: | 741 | case IEEE80211_STYPE_PROBE_RESP: |
752 | case IEEE80211_STYPE_BEACON: | 742 | case IEEE80211_STYPE_BEACON: |
753 | skb_queue_tail(&ifmsh->skb_queue, skb); | 743 | skb_queue_tail(&sdata->skb_queue, skb); |
754 | ieee80211_queue_work(&local->hw, &ifmsh->work); | 744 | ieee80211_queue_work(&local->hw, &ifmsh->work); |
755 | return RX_QUEUED; | 745 | return RX_QUEUED; |
756 | } | 746 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 0154d74905c9..854ef4ed2cfa 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -1652,7 +1652,7 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata, | |||
1652 | case IEEE80211_STYPE_DEAUTH: | 1652 | case IEEE80211_STYPE_DEAUTH: |
1653 | case IEEE80211_STYPE_DISASSOC: | 1653 | case IEEE80211_STYPE_DISASSOC: |
1654 | case IEEE80211_STYPE_ACTION: | 1654 | case IEEE80211_STYPE_ACTION: |
1655 | skb_queue_tail(&sdata->u.mgd.skb_queue, skb); | 1655 | skb_queue_tail(&sdata->skb_queue, skb); |
1656 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); | 1656 | ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); |
1657 | return RX_QUEUED; | 1657 | return RX_QUEUED; |
1658 | } | 1658 | } |
@@ -1810,7 +1810,7 @@ static void ieee80211_sta_work(struct work_struct *work) | |||
1810 | ifmgd = &sdata->u.mgd; | 1810 | ifmgd = &sdata->u.mgd; |
1811 | 1811 | ||
1812 | /* first process frames to avoid timing out while a frame is pending */ | 1812 | /* first process frames to avoid timing out while a frame is pending */ |
1813 | while ((skb = skb_dequeue(&ifmgd->skb_queue))) | 1813 | while ((skb = skb_dequeue(&sdata->skb_queue))) |
1814 | ieee80211_sta_rx_queued_mgmt(sdata, skb); | 1814 | ieee80211_sta_rx_queued_mgmt(sdata, skb); |
1815 | 1815 | ||
1816 | /* then process the rest of the work */ | 1816 | /* then process the rest of the work */ |
@@ -1967,7 +1967,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata) | |||
1967 | (unsigned long) sdata); | 1967 | (unsigned long) sdata); |
1968 | setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, | 1968 | setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, |
1969 | (unsigned long) sdata); | 1969 | (unsigned long) sdata); |
1970 | skb_queue_head_init(&ifmgd->skb_queue); | ||
1971 | 1970 | ||
1972 | ifmgd->flags = 0; | 1971 | ifmgd->flags = 0; |
1973 | 1972 | ||