aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/mac80211/ibss.c29
-rw-r--r--net/mac80211/ieee80211_i.h11
-rw-r--r--net/mac80211/iface.c62
-rw-r--r--net/mac80211/mesh.c20
-rw-r--r--net/mac80211/mlme.c35
5 files changed, 84 insertions, 73 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 18c4266cca1f..db5a4796ff3c 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -727,8 +727,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
727 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true); 727 ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems, true);
728} 728}
729 729
730static void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 730void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
731 struct sk_buff *skb) 731 struct sk_buff *skb)
732{ 732{
733 struct ieee80211_rx_status *rx_status; 733 struct ieee80211_rx_status *rx_status;
734 struct ieee80211_mgmt *mgmt; 734 struct ieee80211_mgmt *mgmt;
@@ -758,29 +758,9 @@ static void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
758 kfree_skb(skb); 758 kfree_skb(skb);
759} 759}
760 760
761static void ieee80211_ibss_work(struct work_struct *work) 761void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata)
762{ 762{
763 struct ieee80211_sub_if_data *sdata = 763 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
764 container_of(work, struct ieee80211_sub_if_data, work);
765 struct ieee80211_local *local = sdata->local;
766 struct ieee80211_if_ibss *ifibss;
767 struct sk_buff *skb;
768
769 if (WARN_ON(local->suspended))
770 return;
771
772 if (!ieee80211_sdata_running(sdata))
773 return;
774
775 if (local->scanning)
776 return;
777
778 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_ADHOC))
779 return;
780 ifibss = &sdata->u.ibss;
781
782 while ((skb = skb_dequeue(&sdata->skb_queue)))
783 ieee80211_ibss_rx_queued_mgmt(sdata, skb);
784 764
785 if (!test_and_clear_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request)) 765 if (!test_and_clear_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request))
786 return; 766 return;
@@ -846,7 +826,6 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
846{ 826{
847 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 827 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
848 828
849 INIT_WORK(&sdata->work, ieee80211_ibss_work);
850 setup_timer(&ifibss->timer, ieee80211_ibss_timer, 829 setup_timer(&ifibss->timer, ieee80211_ibss_timer,
851 (unsigned long) sdata); 830 (unsigned long) sdata);
852} 831}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 2873f6374d1a..f8c8f101592b 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -995,6 +995,9 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
995 u64 timestamp); 995 u64 timestamp);
996void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata); 996void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata);
997void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata); 997void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata);
998void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata);
999void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1000 struct sk_buff *skb);
998 1001
999/* IBSS code */ 1002/* IBSS code */
1000void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local); 1003void ieee80211_ibss_notify_scan_completed(struct ieee80211_local *local);
@@ -1009,6 +1012,14 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
1009int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata); 1012int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata);
1010void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata); 1013void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata);
1011void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata); 1014void ieee80211_ibss_restart(struct ieee80211_sub_if_data *sdata);
1015void ieee80211_ibss_work(struct ieee80211_sub_if_data *sdata);
1016void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1017 struct sk_buff *skb);
1018
1019/* mesh code */
1020void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata);
1021void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1022 struct sk_buff *skb);
1012 1023
1013/* scan/BSS handling */ 1024/* scan/BSS handling */
1014void ieee80211_scan_work(struct work_struct *work); 1025void ieee80211_scan_work(struct work_struct *work);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index de7ddc303a5f..14212ad41e5a 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -701,6 +701,67 @@ static void ieee80211_if_setup(struct net_device *dev)
701 dev->destructor = free_netdev; 701 dev->destructor = free_netdev;
702} 702}
703 703
704static void ieee80211_iface_work(struct work_struct *work)
705{
706 struct ieee80211_sub_if_data *sdata =
707 container_of(work, struct ieee80211_sub_if_data, work);
708 struct ieee80211_local *local = sdata->local;
709 struct sk_buff *skb;
710
711 if (!ieee80211_sdata_running(sdata))
712 return;
713
714 if (local->scanning)
715 return;
716
717 /*
718 * ieee80211_queue_work() should have picked up most cases,
719 * here we'll pick the rest.
720 */
721 if (WARN(local->suspended,
722 "interface work scheduled while going to suspend\n"))
723 return;
724
725 /* first process frames */
726 while ((skb = skb_dequeue(&sdata->skb_queue))) {
727 switch (sdata->vif.type) {
728 case NL80211_IFTYPE_STATION:
729 ieee80211_sta_rx_queued_mgmt(sdata, skb);
730 break;
731 case NL80211_IFTYPE_ADHOC:
732 ieee80211_ibss_rx_queued_mgmt(sdata, skb);
733 break;
734 case NL80211_IFTYPE_MESH_POINT:
735 if (!ieee80211_vif_is_mesh(&sdata->vif))
736 break;
737 ieee80211_mesh_rx_queued_mgmt(sdata, skb);
738 break;
739 default:
740 WARN(1, "frame for unexpected interface type");
741 kfree_skb(skb);
742 break;
743 }
744 }
745
746 /* then other type-dependent work */
747 switch (sdata->vif.type) {
748 case NL80211_IFTYPE_STATION:
749 ieee80211_sta_work(sdata);
750 break;
751 case NL80211_IFTYPE_ADHOC:
752 ieee80211_ibss_work(sdata);
753 break;
754 case NL80211_IFTYPE_MESH_POINT:
755 if (!ieee80211_vif_is_mesh(&sdata->vif))
756 break;
757 ieee80211_mesh_work(sdata);
758 break;
759 default:
760 break;
761 }
762}
763
764
704/* 765/*
705 * Helper function to initialise an interface to a specific type. 766 * Helper function to initialise an interface to a specific type.
706 */ 767 */
@@ -719,6 +780,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,
719 sdata->dev->type = ARPHRD_ETHER; 780 sdata->dev->type = ARPHRD_ETHER;
720 781
721 skb_queue_head_init(&sdata->skb_queue); 782 skb_queue_head_init(&sdata->skb_queue);
783 INIT_WORK(&sdata->work, ieee80211_iface_work);
722 784
723 switch (type) { 785 switch (type) {
724 case NL80211_IFTYPE_AP: 786 case NL80211_IFTYPE_AP:
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index be9aa980e941..0f1f593c8477 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -596,8 +596,8 @@ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
596 } 596 }
597} 597}
598 598
599static void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 599void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
600 struct sk_buff *skb) 600 struct sk_buff *skb)
601{ 601{
602 struct ieee80211_rx_status *rx_status; 602 struct ieee80211_rx_status *rx_status;
603 struct ieee80211_if_mesh *ifmsh; 603 struct ieee80211_if_mesh *ifmsh;
@@ -624,22 +624,9 @@ static void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
624 kfree_skb(skb); 624 kfree_skb(skb);
625} 625}
626 626
627static void ieee80211_mesh_work(struct work_struct *work) 627void ieee80211_mesh_work(struct ieee80211_sub_if_data *sdata)
628{ 628{
629 struct ieee80211_sub_if_data *sdata =
630 container_of(work, struct ieee80211_sub_if_data, work);
631 struct ieee80211_local *local = sdata->local;
632 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 629 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
633 struct sk_buff *skb;
634
635 if (!ieee80211_sdata_running(sdata))
636 return;
637
638 if (local->scanning)
639 return;
640
641 while ((skb = skb_dequeue(&sdata->skb_queue)))
642 ieee80211_mesh_rx_queued_mgmt(sdata, skb);
643 630
644 if (ifmsh->preq_queue_len && 631 if (ifmsh->preq_queue_len &&
645 time_after(jiffies, 632 time_after(jiffies,
@@ -674,7 +661,6 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
674{ 661{
675 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 662 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
676 663
677 INIT_WORK(&sdata->work, ieee80211_mesh_work);
678 setup_timer(&ifmsh->housekeeping_timer, 664 setup_timer(&ifmsh->housekeeping_timer,
679 ieee80211_mesh_housekeeping_timer, 665 ieee80211_mesh_housekeeping_timer,
680 (unsigned long) sdata); 666 (unsigned long) sdata);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 75b896d47ea1..2f828ffd5698 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1660,8 +1660,8 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1660 return RX_DROP_MONITOR; 1660 return RX_DROP_MONITOR;
1661} 1661}
1662 1662
1663static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, 1663void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
1664 struct sk_buff *skb) 1664 struct sk_buff *skb)
1665{ 1665{
1666 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1666 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1667 struct ieee80211_rx_status *rx_status; 1667 struct ieee80211_rx_status *rx_status;
@@ -1782,36 +1782,10 @@ static void ieee80211_sta_timer(unsigned long data)
1782 ieee80211_queue_work(&local->hw, &sdata->work); 1782 ieee80211_queue_work(&local->hw, &sdata->work);
1783} 1783}
1784 1784
1785static void ieee80211_sta_work(struct work_struct *work) 1785void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
1786{ 1786{
1787 struct ieee80211_sub_if_data *sdata =
1788 container_of(work, struct ieee80211_sub_if_data, work);
1789 struct ieee80211_local *local = sdata->local; 1787 struct ieee80211_local *local = sdata->local;
1790 struct ieee80211_if_managed *ifmgd; 1788 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1791 struct sk_buff *skb;
1792
1793 if (!ieee80211_sdata_running(sdata))
1794 return;
1795
1796 if (local->scanning)
1797 return;
1798
1799 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
1800 return;
1801
1802 /*
1803 * ieee80211_queue_work() should have picked up most cases,
1804 * here we'll pick the rest.
1805 */
1806 if (WARN(local->suspended, "STA MLME work scheduled while "
1807 "going to suspend\n"))
1808 return;
1809
1810 ifmgd = &sdata->u.mgd;
1811
1812 /* first process frames to avoid timing out while a frame is pending */
1813 while ((skb = skb_dequeue(&sdata->skb_queue)))
1814 ieee80211_sta_rx_queued_mgmt(sdata, skb);
1815 1789
1816 /* then process the rest of the work */ 1790 /* then process the rest of the work */
1817 mutex_lock(&ifmgd->mtx); 1791 mutex_lock(&ifmgd->mtx);
@@ -1952,7 +1926,6 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1952 struct ieee80211_if_managed *ifmgd; 1926 struct ieee80211_if_managed *ifmgd;
1953 1927
1954 ifmgd = &sdata->u.mgd; 1928 ifmgd = &sdata->u.mgd;
1955 INIT_WORK(&sdata->work, ieee80211_sta_work);
1956 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); 1929 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
1957 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); 1930 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
1958 INIT_WORK(&ifmgd->beacon_connection_loss_work, 1931 INIT_WORK(&ifmgd->beacon_connection_loss_work,