aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c93
2 files changed, 5 insertions, 89 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 2a9909dd551d..d0a825638188 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -575,7 +575,6 @@ enum rt2x00_flags {
575 DEVICE_STATE_REGISTERED_HW, 575 DEVICE_STATE_REGISTERED_HW,
576 DEVICE_STATE_INITIALIZED, 576 DEVICE_STATE_INITIALIZED,
577 DEVICE_STATE_STARTED, 577 DEVICE_STATE_STARTED,
578 DEVICE_STATE_STARTED_SUSPEND,
579 DEVICE_STATE_ENABLED_RADIO, 578 DEVICE_STATE_ENABLED_RADIO,
580 DEVICE_STATE_DISABLED_RADIO_HW, 579 DEVICE_STATE_DISABLED_RADIO_HW,
581 580
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index cd4447502d8b..e1b40545a9be 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -881,23 +881,17 @@ EXPORT_SYMBOL_GPL(rt2x00lib_remove_dev);
881#ifdef CONFIG_PM 881#ifdef CONFIG_PM
882int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state) 882int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
883{ 883{
884 int retval;
885
886 NOTICE(rt2x00dev, "Going to sleep.\n"); 884 NOTICE(rt2x00dev, "Going to sleep.\n");
887 885
888 /* 886 /*
889 * Only continue if mac80211 has open interfaces. 887 * Prevent mac80211 from accessing driver while suspended.
890 */ 888 */
891 if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags) || 889 if (!test_and_clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
892 !test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) 890 return 0;
893 goto exit;
894
895 set_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags);
896 891
897 /* 892 /*
898 * Disable radio. 893 * Cleanup as much as possible.
899 */ 894 */
900 rt2x00lib_stop(rt2x00dev);
901 rt2x00lib_uninitialize(rt2x00dev); 895 rt2x00lib_uninitialize(rt2x00dev);
902 896
903 /* 897 /*
@@ -906,7 +900,6 @@ int rt2x00lib_suspend(struct rt2x00_dev *rt2x00dev, pm_message_t state)
906 rt2x00leds_suspend(rt2x00dev); 900 rt2x00leds_suspend(rt2x00dev);
907 rt2x00debug_deregister(rt2x00dev); 901 rt2x00debug_deregister(rt2x00dev);
908 902
909exit:
910 /* 903 /*
911 * Set device mode to sleep for power management, 904 * Set device mode to sleep for power management,
912 * on some hardware this call seems to consistently fail. 905 * on some hardware this call seems to consistently fail.
@@ -918,8 +911,7 @@ exit:
918 * the radio and the other components already disabled the 911 * the radio and the other components already disabled the
919 * device is as good as disabled. 912 * device is as good as disabled.
920 */ 913 */
921 retval = rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP); 914 if (rt2x00dev->ops->lib->set_device_state(rt2x00dev, STATE_SLEEP))
922 if (retval)
923 WARNING(rt2x00dev, "Device failed to enter sleep state, " 915 WARNING(rt2x00dev, "Device failed to enter sleep state, "
924 "continue suspending.\n"); 916 "continue suspending.\n");
925 917
@@ -927,34 +919,8 @@ exit:
927} 919}
928EXPORT_SYMBOL_GPL(rt2x00lib_suspend); 920EXPORT_SYMBOL_GPL(rt2x00lib_suspend);
929 921
930static void rt2x00lib_resume_intf(void *data, u8 *mac,
931 struct ieee80211_vif *vif)
932{
933 struct rt2x00_dev *rt2x00dev = data;
934 struct rt2x00_intf *intf = vif_to_intf(vif);
935
936 spin_lock(&intf->lock);
937
938 rt2x00lib_config_intf(rt2x00dev, intf,
939 vif->type, intf->mac, intf->bssid);
940
941
942 /*
943 * AP, Ad-hoc, and Mesh Point mode require a new beacon update.
944 */
945 if (vif->type == NL80211_IFTYPE_AP ||
946 vif->type == NL80211_IFTYPE_ADHOC ||
947 vif->type == NL80211_IFTYPE_MESH_POINT ||
948 vif->type == NL80211_IFTYPE_WDS)
949 intf->delayed_flags |= DELAYED_UPDATE_BEACON;
950
951 spin_unlock(&intf->lock);
952}
953
954int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev) 922int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
955{ 923{
956 int retval;
957
958 NOTICE(rt2x00dev, "Waking up.\n"); 924 NOTICE(rt2x00dev, "Waking up.\n");
959 925
960 /* 926 /*
@@ -964,60 +930,11 @@ int rt2x00lib_resume(struct rt2x00_dev *rt2x00dev)
964 rt2x00leds_resume(rt2x00dev); 930 rt2x00leds_resume(rt2x00dev);
965 931
966 /* 932 /*
967 * Only continue if mac80211 had open interfaces.
968 */
969 if (!test_and_clear_bit(DEVICE_STATE_STARTED_SUSPEND, &rt2x00dev->flags))
970 return 0;
971
972 /*
973 * Reinitialize device and all active interfaces.
974 */
975 retval = rt2x00lib_start(rt2x00dev);
976 if (retval)
977 goto exit;
978
979 /*
980 * Reconfigure device.
981 */
982 retval = rt2x00mac_config(rt2x00dev->hw, ~0);
983 if (retval)
984 goto exit;
985
986 /*
987 * Iterator over each active interface to
988 * reconfigure the hardware.
989 */
990 ieee80211_iterate_active_interfaces(rt2x00dev->hw,
991 rt2x00lib_resume_intf, rt2x00dev);
992
993 /*
994 * We are ready again to receive requests from mac80211. 933 * We are ready again to receive requests from mac80211.
995 */ 934 */
996 set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); 935 set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags);
997 936
998 /*
999 * It is possible that during that mac80211 has attempted
1000 * to send frames while we were suspending or resuming.
1001 * In that case we have disabled the TX queue and should
1002 * now enable it again
1003 */
1004 ieee80211_wake_queues(rt2x00dev->hw);
1005
1006 /*
1007 * During interface iteration we might have changed the
1008 * delayed_flags, time to handles the event by calling
1009 * the work handler directly.
1010 */
1011 rt2x00lib_intf_scheduled(&rt2x00dev->intf_work);
1012
1013 return 0; 937 return 0;
1014
1015exit:
1016 rt2x00lib_stop(rt2x00dev);
1017 rt2x00lib_uninitialize(rt2x00dev);
1018 rt2x00debug_deregister(rt2x00dev);
1019
1020 return retval;
1021} 938}
1022EXPORT_SYMBOL_GPL(rt2x00lib_resume); 939EXPORT_SYMBOL_GPL(rt2x00lib_resume);
1023#endif /* CONFIG_PM */ 940#endif /* CONFIG_PM */