aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c14
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif-ops.h5
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.h1
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c35
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c26
6 files changed, 82 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
index b2b70e6618f..9128aa3c2b6 100644
--- a/drivers/net/wireless/ath/ath6kl/cfg80211.c
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -17,6 +17,7 @@
17#include "core.h" 17#include "core.h"
18#include "cfg80211.h" 18#include "cfg80211.h"
19#include "debug.h" 19#include "debug.h"
20#include "hif-ops.h"
20 21
21#define RATETAB_ENT(_rate, _rateid, _flags) { \ 22#define RATETAB_ENT(_rate, _rateid, _flags) { \
22 .bitrate = (_rate), \ 23 .bitrate = (_rate), \
@@ -1424,6 +1425,16 @@ static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1424 return 0; 1425 return 0;
1425} 1426}
1426 1427
1428#ifdef CONFIG_PM
1429static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
1430 struct cfg80211_wowlan *wow)
1431{
1432 struct ath6kl *ar = wiphy_priv(wiphy);
1433
1434 return ath6kl_hif_suspend(ar);
1435}
1436#endif
1437
1427static struct cfg80211_ops ath6kl_cfg80211_ops = { 1438static struct cfg80211_ops ath6kl_cfg80211_ops = {
1428 .change_virtual_intf = ath6kl_cfg80211_change_iface, 1439 .change_virtual_intf = ath6kl_cfg80211_change_iface,
1429 .scan = ath6kl_cfg80211_scan, 1440 .scan = ath6kl_cfg80211_scan,
@@ -1443,6 +1454,9 @@ static struct cfg80211_ops ath6kl_cfg80211_ops = {
1443 .set_pmksa = ath6kl_set_pmksa, 1454 .set_pmksa = ath6kl_set_pmksa,
1444 .del_pmksa = ath6kl_del_pmksa, 1455 .del_pmksa = ath6kl_del_pmksa,
1445 .flush_pmksa = ath6kl_flush_pmksa, 1456 .flush_pmksa = ath6kl_flush_pmksa,
1457#ifdef CONFIG_PM
1458 .suspend = ar6k_cfg80211_suspend,
1459#endif
1446}; 1460};
1447 1461
1448struct wireless_dev *ath6kl_cfg80211_init(struct device *dev) 1462struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
index a1aa2ef398f..4405ab56bb8 100644
--- a/drivers/net/wireless/ath/ath6kl/core.h
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -544,6 +544,7 @@ void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);
544 544
545void ath6kl_dtimexpiry_event(struct ath6kl *ar); 545void ath6kl_dtimexpiry_event(struct ath6kl *ar);
546void ath6kl_disconnect(struct ath6kl *ar); 546void ath6kl_disconnect(struct ath6kl *ar);
547void ath6kl_deep_sleep_enable(struct ath6kl *ar);
547void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid); 548void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid);
548void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no, 549void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
549 u8 win_sz); 550 u8 win_sz);
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h
index c923979776a..d6c898f3d0b 100644
--- a/drivers/net/wireless/ath/ath6kl/hif-ops.h
+++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h
@@ -69,4 +69,9 @@ static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar)
69 return ar->hif_ops->cleanup_scatter(ar); 69 return ar->hif_ops->cleanup_scatter(ar);
70} 70}
71 71
72static inline int ath6kl_hif_suspend(struct ath6kl *ar)
73{
74 return ar->hif_ops->suspend(ar);
75}
76
72#endif 77#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
index 5ceff54775a..797e2d1d9bf 100644
--- a/drivers/net/wireless/ath/ath6kl/hif.h
+++ b/drivers/net/wireless/ath/ath6kl/hif.h
@@ -202,6 +202,7 @@ struct ath6kl_hif_ops {
202 int (*scat_req_rw) (struct ath6kl *ar, 202 int (*scat_req_rw) (struct ath6kl *ar,
203 struct hif_scatter_req *scat_req); 203 struct hif_scatter_req *scat_req);
204 void (*cleanup_scatter)(struct ath6kl *ar); 204 void (*cleanup_scatter)(struct ath6kl *ar);
205 int (*suspend)(struct ath6kl *ar);
205}; 206};
206 207
207#endif 208#endif
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
index 868838bb6b8..b64b2a35756 100644
--- a/drivers/net/wireless/ath/ath6kl/main.c
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -795,6 +795,41 @@ void ath6kl_disconnect(struct ath6kl *ar)
795 } 795 }
796} 796}
797 797
798void ath6kl_deep_sleep_enable(struct ath6kl *ar)
799{
800 switch (ar->sme_state) {
801 case SME_CONNECTING:
802 cfg80211_connect_result(ar->net_dev, ar->bssid, NULL, 0,
803 NULL, 0,
804 WLAN_STATUS_UNSPECIFIED_FAILURE,
805 GFP_KERNEL);
806 break;
807 case SME_CONNECTED:
808 default:
809 /*
810 * FIXME: oddly enough smeState is in DISCONNECTED during
811 * suspend, why? Need to send disconnected event in that
812 * state.
813 */
814 cfg80211_disconnected(ar->net_dev, 0, NULL, 0, GFP_KERNEL);
815 break;
816 }
817
818 if (test_bit(CONNECTED, &ar->flag) ||
819 test_bit(CONNECT_PEND, &ar->flag))
820 ath6kl_wmi_disconnect_cmd(ar->wmi);
821
822 ar->sme_state = SME_DISCONNECTED;
823
824 /* disable scanning */
825 if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0, 0,
826 0, 0) != 0)
827 printk(KERN_WARNING "ath6kl: failed to disable scan "
828 "during suspend\n");
829
830 ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
831}
832
798/* WMI Event handlers */ 833/* WMI Event handlers */
799 834
800static const char *get_hw_id_string(u32 id) 835static const char *get_hw_id_string(u32 id)
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
index f393090ecef..852a0ccc803 100644
--- a/drivers/net/wireless/ath/ath6kl/sdio.c
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -726,6 +726,31 @@ static int ath6kl_sdio_enable_scatter(struct ath6kl *ar)
726 return 0; 726 return 0;
727} 727}
728 728
729static int ath6kl_sdio_suspend(struct ath6kl *ar)
730{
731 struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
732 struct sdio_func *func = ar_sdio->func;
733 mmc_pm_flag_t flags;
734 int ret;
735
736 flags = sdio_get_host_pm_caps(func);
737
738 if (!(flags & MMC_PM_KEEP_POWER))
739 /* as host doesn't support keep power we need to bail out */
740 return -EINVAL;
741
742 ret = sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER);
743 if (ret) {
744 printk(KERN_ERR "ath6kl: set sdio pm flags failed: %d\n",
745 ret);
746 return ret;
747 }
748
749 ath6kl_deep_sleep_enable(ar);
750
751 return 0;
752}
753
729static const struct ath6kl_hif_ops ath6kl_sdio_ops = { 754static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
730 .read_write_sync = ath6kl_sdio_read_write_sync, 755 .read_write_sync = ath6kl_sdio_read_write_sync,
731 .write_async = ath6kl_sdio_write_async, 756 .write_async = ath6kl_sdio_write_async,
@@ -736,6 +761,7 @@ static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
736 .enable_scatter = ath6kl_sdio_enable_scatter, 761 .enable_scatter = ath6kl_sdio_enable_scatter,
737 .scat_req_rw = ath6kl_sdio_async_rw_scatter, 762 .scat_req_rw = ath6kl_sdio_async_rw_scatter,
738 .cleanup_scatter = ath6kl_sdio_cleanup_scatter, 763 .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
764 .suspend = ath6kl_sdio_suspend,
739}; 765};
740 766
741static int ath6kl_sdio_probe(struct sdio_func *func, 767static int ath6kl_sdio_probe(struct sdio_func *func,