aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-06-10 04:21:31 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-14 15:38:17 -0400
commit64592c8fc0e99d445fc3fdedddeb6088e20086f1 (patch)
tree2493358821abc4050b25f8a0bd813b763b188d38
parent35f20c14a103ca2c7062999e934a513b83d84de6 (diff)
mac80211: use common work struct
IBSS, managed and mesh modes all have their own work struct, and in the future we want to also use it in other modes to process frames from the now common skb queue. This also makes the skb queue and work safe to use from other interface types. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--net/mac80211/ibss.c13
-rw-r--r--net/mac80211/ieee80211_i.h4
-rw-r--r--net/mac80211/iface.c6
-rw-r--r--net/mac80211/mesh.c22
-rw-r--r--net/mac80211/mesh_hwmp.c4
-rw-r--r--net/mac80211/mesh_pathtbl.c4
-rw-r--r--net/mac80211/mlme.c12
-rw-r--r--net/mac80211/pm.c2
8 files changed, 29 insertions, 38 deletions
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index a9ff904620db..18c4266cca1f 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -761,7 +761,7 @@ static void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
761static void ieee80211_ibss_work(struct work_struct *work) 761static void ieee80211_ibss_work(struct work_struct *work)
762{ 762{
763 struct ieee80211_sub_if_data *sdata = 763 struct ieee80211_sub_if_data *sdata =
764 container_of(work, struct ieee80211_sub_if_data, u.ibss.work); 764 container_of(work, struct ieee80211_sub_if_data, work);
765 struct ieee80211_local *local = sdata->local; 765 struct ieee80211_local *local = sdata->local;
766 struct ieee80211_if_ibss *ifibss; 766 struct ieee80211_if_ibss *ifibss;
767 struct sk_buff *skb; 767 struct sk_buff *skb;
@@ -804,7 +804,7 @@ static void ieee80211_queue_ibss_work(struct ieee80211_sub_if_data *sdata)
804 struct ieee80211_local *local = sdata->local; 804 struct ieee80211_local *local = sdata->local;
805 805
806 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request); 806 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
807 ieee80211_queue_work(&local->hw, &ifibss->work); 807 ieee80211_queue_work(&local->hw, &sdata->work);
808} 808}
809 809
810static void ieee80211_ibss_timer(unsigned long data) 810static void ieee80211_ibss_timer(unsigned long data)
@@ -827,7 +827,6 @@ void ieee80211_ibss_quiesce(struct ieee80211_sub_if_data *sdata)
827{ 827{
828 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 828 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
829 829
830 cancel_work_sync(&ifibss->work);
831 if (del_timer_sync(&ifibss->timer)) 830 if (del_timer_sync(&ifibss->timer))
832 ifibss->timer_running = true; 831 ifibss->timer_running = true;
833} 832}
@@ -847,7 +846,7 @@ void ieee80211_ibss_setup_sdata(struct ieee80211_sub_if_data *sdata)
847{ 846{
848 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss; 847 struct ieee80211_if_ibss *ifibss = &sdata->u.ibss;
849 848
850 INIT_WORK(&ifibss->work, ieee80211_ibss_work); 849 INIT_WORK(&sdata->work, ieee80211_ibss_work);
851 setup_timer(&ifibss->timer, ieee80211_ibss_timer, 850 setup_timer(&ifibss->timer, ieee80211_ibss_timer,
852 (unsigned long) sdata); 851 (unsigned long) sdata);
853} 852}
@@ -890,7 +889,7 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
890 case IEEE80211_STYPE_PROBE_REQ: 889 case IEEE80211_STYPE_PROBE_REQ:
891 case IEEE80211_STYPE_AUTH: 890 case IEEE80211_STYPE_AUTH:
892 skb_queue_tail(&sdata->skb_queue, skb); 891 skb_queue_tail(&sdata->skb_queue, skb);
893 ieee80211_queue_work(&local->hw, &sdata->u.ibss.work); 892 ieee80211_queue_work(&local->hw, &sdata->work);
894 return RX_QUEUED; 893 return RX_QUEUED;
895 } 894 }
896 895
@@ -956,7 +955,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
956 ieee80211_recalc_idle(sdata->local); 955 ieee80211_recalc_idle(sdata->local);
957 956
958 set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); 957 set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
959 ieee80211_queue_work(&sdata->local->hw, &sdata->u.ibss.work); 958 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
960 959
961 return 0; 960 return 0;
962} 961}
@@ -967,7 +966,7 @@ int ieee80211_ibss_leave(struct ieee80211_sub_if_data *sdata)
967 966
968 del_timer_sync(&sdata->u.ibss.timer); 967 del_timer_sync(&sdata->u.ibss.timer);
969 clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); 968 clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
970 cancel_work_sync(&sdata->u.ibss.work); 969 cancel_work_sync(&sdata->work);
971 clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); 970 clear_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
972 971
973 sta_info_flush(sdata->local, sdata); 972 sta_info_flush(sdata->local, sdata);
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 3cc3867c5418..2873f6374d1a 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -325,7 +325,6 @@ struct ieee80211_if_managed {
325 struct timer_list conn_mon_timer; 325 struct timer_list conn_mon_timer;
326 struct timer_list bcn_mon_timer; 326 struct timer_list bcn_mon_timer;
327 struct timer_list chswitch_timer; 327 struct timer_list chswitch_timer;
328 struct work_struct work;
329 struct work_struct monitor_work; 328 struct work_struct monitor_work;
330 struct work_struct chswitch_work; 329 struct work_struct chswitch_work;
331 struct work_struct beacon_connection_loss_work; 330 struct work_struct beacon_connection_loss_work;
@@ -384,7 +383,6 @@ enum ieee80211_ibss_request {
384 383
385struct ieee80211_if_ibss { 384struct ieee80211_if_ibss {
386 struct timer_list timer; 385 struct timer_list timer;
387 struct work_struct work;
388 386
389 unsigned long request; 387 unsigned long request;
390 unsigned long last_scan_completed; 388 unsigned long last_scan_completed;
@@ -412,7 +410,6 @@ struct ieee80211_if_ibss {
412}; 410};
413 411
414struct ieee80211_if_mesh { 412struct ieee80211_if_mesh {
415 struct work_struct work;
416 struct timer_list housekeeping_timer; 413 struct timer_list housekeeping_timer;
417 struct timer_list mesh_path_timer; 414 struct timer_list mesh_path_timer;
418 struct timer_list mesh_path_root_timer; 415 struct timer_list mesh_path_root_timer;
@@ -512,6 +509,7 @@ struct ieee80211_sub_if_data {
512 509
513 u16 sequence_number; 510 u16 sequence_number;
514 511
512 struct work_struct work;
515 struct sk_buff_head skb_queue; 513 struct sk_buff_head skb_queue;
516 514
517 /* 515 /*
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 56167a3d872d..de7ddc303a5f 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -460,17 +460,14 @@ static int ieee80211_stop(struct net_device *dev)
460 * whether the interface is running, which, at this point, 460 * whether the interface is running, which, at this point,
461 * it no longer is. 461 * it no longer is.
462 */ 462 */
463 cancel_work_sync(&sdata->u.mgd.work);
464 cancel_work_sync(&sdata->u.mgd.chswitch_work); 463 cancel_work_sync(&sdata->u.mgd.chswitch_work);
465 cancel_work_sync(&sdata->u.mgd.monitor_work); 464 cancel_work_sync(&sdata->u.mgd.monitor_work);
466 cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work); 465 cancel_work_sync(&sdata->u.mgd.beacon_connection_loss_work);
467 466
468 /* fall through */ 467 /* fall through */
469 case NL80211_IFTYPE_ADHOC: 468 case NL80211_IFTYPE_ADHOC:
470 if (sdata->vif.type == NL80211_IFTYPE_ADHOC) { 469 if (sdata->vif.type == NL80211_IFTYPE_ADHOC)
471 del_timer_sync(&sdata->u.ibss.timer); 470 del_timer_sync(&sdata->u.ibss.timer);
472 cancel_work_sync(&sdata->u.ibss.work);
473 }
474 /* fall through */ 471 /* fall through */
475 case NL80211_IFTYPE_MESH_POINT: 472 case NL80211_IFTYPE_MESH_POINT:
476 if (ieee80211_vif_is_mesh(&sdata->vif)) { 473 if (ieee80211_vif_is_mesh(&sdata->vif)) {
@@ -485,6 +482,7 @@ static int ieee80211_stop(struct net_device *dev)
485 } 482 }
486 /* fall through */ 483 /* fall through */
487 default: 484 default:
485 cancel_work_sync(&sdata->work);
488 /* 486 /*
489 * When we get here, the interface is marked down. 487 * When we get here, the interface is marked down.
490 * Call synchronize_rcu() to wait for the RX path 488 * Call synchronize_rcu() to wait for the RX path
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 065533a37abe..be9aa980e941 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -54,7 +54,7 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data)
54 return; 54 return;
55 } 55 }
56 56
57 ieee80211_queue_work(&local->hw, &ifmsh->work); 57 ieee80211_queue_work(&local->hw, &sdata->work);
58} 58}
59 59
60/** 60/**
@@ -345,7 +345,7 @@ static void ieee80211_mesh_path_timer(unsigned long data)
345 return; 345 return;
346 } 346 }
347 347
348 ieee80211_queue_work(&local->hw, &ifmsh->work); 348 ieee80211_queue_work(&local->hw, &sdata->work);
349} 349}
350 350
351static void ieee80211_mesh_path_root_timer(unsigned long data) 351static void ieee80211_mesh_path_root_timer(unsigned long data)
@@ -362,7 +362,7 @@ static void ieee80211_mesh_path_root_timer(unsigned long data)
362 return; 362 return;
363 } 363 }
364 364
365 ieee80211_queue_work(&local->hw, &ifmsh->work); 365 ieee80211_queue_work(&local->hw, &sdata->work);
366} 366}
367 367
368void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh) 368void ieee80211_mesh_root_setup(struct ieee80211_if_mesh *ifmsh)
@@ -484,9 +484,6 @@ void ieee80211_mesh_quiesce(struct ieee80211_sub_if_data *sdata)
484{ 484{
485 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 485 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
486 486
487 /* might restart the timer but that doesn't matter */
488 cancel_work_sync(&ifmsh->work);
489
490 /* use atomic bitops in case both timers fire at the same time */ 487 /* use atomic bitops in case both timers fire at the same time */
491 488
492 if (del_timer_sync(&ifmsh->housekeeping_timer)) 489 if (del_timer_sync(&ifmsh->housekeeping_timer))
@@ -518,7 +515,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
518 515
519 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags); 516 set_bit(MESH_WORK_HOUSEKEEPING, &ifmsh->wrkq_flags);
520 ieee80211_mesh_root_setup(ifmsh); 517 ieee80211_mesh_root_setup(ifmsh);
521 ieee80211_queue_work(&local->hw, &ifmsh->work); 518 ieee80211_queue_work(&local->hw, &sdata->work);
522 sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL; 519 sdata->vif.bss_conf.beacon_int = MESH_DEFAULT_BEACON_INTERVAL;
523 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | 520 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
524 BSS_CHANGED_BEACON_ENABLED | 521 BSS_CHANGED_BEACON_ENABLED |
@@ -536,7 +533,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
536 * whether the interface is running, which, at this point, 533 * whether the interface is running, which, at this point,
537 * it no longer is. 534 * it no longer is.
538 */ 535 */
539 cancel_work_sync(&sdata->u.mesh.work); 536 cancel_work_sync(&sdata->work);
540} 537}
541 538
542static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, 539static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
@@ -630,7 +627,7 @@ static void ieee80211_mesh_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
630static void ieee80211_mesh_work(struct work_struct *work) 627static void ieee80211_mesh_work(struct work_struct *work)
631{ 628{
632 struct ieee80211_sub_if_data *sdata = 629 struct ieee80211_sub_if_data *sdata =
633 container_of(work, struct ieee80211_sub_if_data, u.mesh.work); 630 container_of(work, struct ieee80211_sub_if_data, work);
634 struct ieee80211_local *local = sdata->local; 631 struct ieee80211_local *local = sdata->local;
635 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 632 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
636 struct sk_buff *skb; 633 struct sk_buff *skb;
@@ -669,7 +666,7 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
669 rcu_read_lock(); 666 rcu_read_lock();
670 list_for_each_entry_rcu(sdata, &local->interfaces, list) 667 list_for_each_entry_rcu(sdata, &local->interfaces, list)
671 if (ieee80211_vif_is_mesh(&sdata->vif)) 668 if (ieee80211_vif_is_mesh(&sdata->vif))
672 ieee80211_queue_work(&local->hw, &sdata->u.mesh.work); 669 ieee80211_queue_work(&local->hw, &sdata->work);
673 rcu_read_unlock(); 670 rcu_read_unlock();
674} 671}
675 672
@@ -677,7 +674,7 @@ void ieee80211_mesh_init_sdata(struct ieee80211_sub_if_data *sdata)
677{ 674{
678 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; 675 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
679 676
680 INIT_WORK(&ifmsh->work, ieee80211_mesh_work); 677 INIT_WORK(&sdata->work, ieee80211_mesh_work);
681 setup_timer(&ifmsh->housekeeping_timer, 678 setup_timer(&ifmsh->housekeeping_timer,
682 ieee80211_mesh_housekeeping_timer, 679 ieee80211_mesh_housekeeping_timer,
683 (unsigned long) sdata); 680 (unsigned long) sdata);
@@ -726,7 +723,6 @@ ieee80211_rx_result
726ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb) 723ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
727{ 724{
728 struct ieee80211_local *local = sdata->local; 725 struct ieee80211_local *local = sdata->local;
729 struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
730 struct ieee80211_mgmt *mgmt; 726 struct ieee80211_mgmt *mgmt;
731 u16 fc; 727 u16 fc;
732 728
@@ -741,7 +737,7 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
741 case IEEE80211_STYPE_PROBE_RESP: 737 case IEEE80211_STYPE_PROBE_RESP:
742 case IEEE80211_STYPE_BEACON: 738 case IEEE80211_STYPE_BEACON:
743 skb_queue_tail(&sdata->skb_queue, skb); 739 skb_queue_tail(&sdata->skb_queue, skb);
744 ieee80211_queue_work(&local->hw, &ifmsh->work); 740 ieee80211_queue_work(&local->hw, &sdata->work);
745 return RX_QUEUED; 741 return RX_QUEUED;
746 } 742 }
747 743
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index 0705018d8d1e..829e08a657d0 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -805,14 +805,14 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
805 spin_unlock(&ifmsh->mesh_preq_queue_lock); 805 spin_unlock(&ifmsh->mesh_preq_queue_lock);
806 806
807 if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata))) 807 if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
808 ieee80211_queue_work(&sdata->local->hw, &ifmsh->work); 808 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
809 809
810 else if (time_before(jiffies, ifmsh->last_preq)) { 810 else if (time_before(jiffies, ifmsh->last_preq)) {
811 /* avoid long wait if did not send preqs for a long time 811 /* avoid long wait if did not send preqs for a long time
812 * and jiffies wrapped around 812 * and jiffies wrapped around
813 */ 813 */
814 ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; 814 ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
815 ieee80211_queue_work(&sdata->local->hw, &ifmsh->work); 815 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
816 } else 816 } else
817 mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq + 817 mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq +
818 min_preq_int_jiff(sdata)); 818 min_preq_int_jiff(sdata));
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 181ffd6efd81..349e466cf08b 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -315,7 +315,7 @@ int mesh_path_add(u8 *dst, struct ieee80211_sub_if_data *sdata)
315 read_unlock(&pathtbl_resize_lock); 315 read_unlock(&pathtbl_resize_lock);
316 if (grow) { 316 if (grow) {
317 set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags); 317 set_bit(MESH_WORK_GROW_MPATH_TABLE, &ifmsh->wrkq_flags);
318 ieee80211_queue_work(&local->hw, &ifmsh->work); 318 ieee80211_queue_work(&local->hw, &sdata->work);
319 } 319 }
320 return 0; 320 return 0;
321 321
@@ -425,7 +425,7 @@ int mpp_path_add(u8 *dst, u8 *mpp, struct ieee80211_sub_if_data *sdata)
425 read_unlock(&pathtbl_resize_lock); 425 read_unlock(&pathtbl_resize_lock);
426 if (grow) { 426 if (grow) {
427 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags); 427 set_bit(MESH_WORK_GROW_MPP_TABLE, &ifmsh->wrkq_flags);
428 ieee80211_queue_work(&local->hw, &ifmsh->work); 428 ieee80211_queue_work(&local->hw, &sdata->work);
429 } 429 }
430 return 0; 430 return 0;
431 431
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 854ef4ed2cfa..75b896d47ea1 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1653,7 +1653,7 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
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->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->work);
1657 return RX_QUEUED; 1657 return RX_QUEUED;
1658 } 1658 }
1659 1659
@@ -1779,13 +1779,13 @@ static void ieee80211_sta_timer(unsigned long data)
1779 return; 1779 return;
1780 } 1780 }
1781 1781
1782 ieee80211_queue_work(&local->hw, &ifmgd->work); 1782 ieee80211_queue_work(&local->hw, &sdata->work);
1783} 1783}
1784 1784
1785static void ieee80211_sta_work(struct work_struct *work) 1785static void ieee80211_sta_work(struct work_struct *work)
1786{ 1786{
1787 struct ieee80211_sub_if_data *sdata = 1787 struct ieee80211_sub_if_data *sdata =
1788 container_of(work, struct ieee80211_sub_if_data, u.mgd.work); 1788 container_of(work, struct ieee80211_sub_if_data, work);
1789 struct ieee80211_local *local = sdata->local; 1789 struct ieee80211_local *local = sdata->local;
1790 struct ieee80211_if_managed *ifmgd; 1790 struct ieee80211_if_managed *ifmgd;
1791 struct sk_buff *skb; 1791 struct sk_buff *skb;
@@ -1906,8 +1906,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
1906 ieee80211_queue_work(&sdata->local->hw, 1906 ieee80211_queue_work(&sdata->local->hw,
1907 &sdata->u.mgd.monitor_work); 1907 &sdata->u.mgd.monitor_work);
1908 /* and do all the other regular work too */ 1908 /* and do all the other regular work too */
1909 ieee80211_queue_work(&sdata->local->hw, 1909 ieee80211_queue_work(&sdata->local->hw, &sdata->work);
1910 &sdata->u.mgd.work);
1911 } 1910 }
1912} 1911}
1913 1912
@@ -1922,7 +1921,6 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
1922 * time -- the code here is properly synchronised. 1921 * time -- the code here is properly synchronised.
1923 */ 1922 */
1924 1923
1925 cancel_work_sync(&ifmgd->work);
1926 cancel_work_sync(&ifmgd->beacon_connection_loss_work); 1924 cancel_work_sync(&ifmgd->beacon_connection_loss_work);
1927 if (del_timer_sync(&ifmgd->timer)) 1925 if (del_timer_sync(&ifmgd->timer))
1928 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running); 1926 set_bit(TMR_RUNNING_TIMER, &ifmgd->timers_running);
@@ -1954,7 +1952,7 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
1954 struct ieee80211_if_managed *ifmgd; 1952 struct ieee80211_if_managed *ifmgd;
1955 1953
1956 ifmgd = &sdata->u.mgd; 1954 ifmgd = &sdata->u.mgd;
1957 INIT_WORK(&ifmgd->work, ieee80211_sta_work); 1955 INIT_WORK(&sdata->work, ieee80211_sta_work);
1958 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work); 1956 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
1959 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); 1957 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
1960 INIT_WORK(&ifmgd->beacon_connection_loss_work, 1958 INIT_WORK(&ifmgd->beacon_connection_loss_work,
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index e145a949b820..d287fde0431d 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -64,6 +64,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
64 64
65 /* remove all interfaces */ 65 /* remove all interfaces */
66 list_for_each_entry(sdata, &local->interfaces, list) { 66 list_for_each_entry(sdata, &local->interfaces, list) {
67 cancel_work_sync(&sdata->work);
68
67 switch(sdata->vif.type) { 69 switch(sdata->vif.type) {
68 case NL80211_IFTYPE_STATION: 70 case NL80211_IFTYPE_STATION:
69 ieee80211_sta_quiesce(sdata); 71 ieee80211_sta_quiesce(sdata);