aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/ibss.c7
-rw-r--r--net/mac80211/ieee80211_i.h7
-rw-r--r--net/mac80211/iface.c21
-rw-r--r--net/mac80211/mesh.c14
-rw-r--r--net/mac80211/mlme.c5
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
551static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, 542static 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