diff options
author | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
---|---|---|
committer | Andrea Bastoni <bastoni@cs.unc.edu> | 2010-05-30 19:16:45 -0400 |
commit | ada47b5fe13d89735805b566185f4885f5a3f750 (patch) | |
tree | 644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/wl12xx/wl1251_ps.c | |
parent | 43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff) | |
parent | 3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff) |
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1251_ps.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_ps.c | 53 |
1 files changed, 44 insertions, 9 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c index c53e28727ed4..851dfb65e474 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.c +++ b/drivers/net/wireless/wl12xx/wl1251_ps.c | |||
@@ -26,24 +26,49 @@ | |||
26 | #include "wl1251_cmd.h" | 26 | #include "wl1251_cmd.h" |
27 | #include "wl1251_io.h" | 27 | #include "wl1251_io.h" |
28 | 28 | ||
29 | #define WL1251_WAKEUP_TIMEOUT 2000 | 29 | /* in ms */ |
30 | #define WL1251_WAKEUP_TIMEOUT 100 | ||
30 | 31 | ||
31 | /* Routines to toggle sleep mode while in ELP */ | 32 | void wl1251_elp_work(struct work_struct *work) |
32 | void wl1251_ps_elp_sleep(struct wl1251 *wl) | ||
33 | { | 33 | { |
34 | struct delayed_work *dwork; | ||
35 | struct wl1251 *wl; | ||
36 | |||
37 | dwork = container_of(work, struct delayed_work, work); | ||
38 | wl = container_of(dwork, struct wl1251, elp_work); | ||
39 | |||
40 | wl1251_debug(DEBUG_PSM, "elp work"); | ||
41 | |||
42 | mutex_lock(&wl->mutex); | ||
43 | |||
34 | if (wl->elp || !wl->psm) | 44 | if (wl->elp || !wl->psm) |
35 | return; | 45 | goto out; |
36 | 46 | ||
37 | wl1251_debug(DEBUG_PSM, "chip to elp"); | 47 | wl1251_debug(DEBUG_PSM, "chip to elp"); |
38 | |||
39 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); | 48 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); |
40 | |||
41 | wl->elp = true; | 49 | wl->elp = true; |
50 | |||
51 | out: | ||
52 | mutex_unlock(&wl->mutex); | ||
53 | } | ||
54 | |||
55 | #define ELP_ENTRY_DELAY 5 | ||
56 | |||
57 | /* Routines to toggle sleep mode while in ELP */ | ||
58 | void wl1251_ps_elp_sleep(struct wl1251 *wl) | ||
59 | { | ||
60 | unsigned long delay; | ||
61 | |||
62 | if (wl->psm) { | ||
63 | cancel_delayed_work(&wl->elp_work); | ||
64 | delay = msecs_to_jiffies(ELP_ENTRY_DELAY); | ||
65 | ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay); | ||
66 | } | ||
42 | } | 67 | } |
43 | 68 | ||
44 | int wl1251_ps_elp_wakeup(struct wl1251 *wl) | 69 | int wl1251_ps_elp_wakeup(struct wl1251 *wl) |
45 | { | 70 | { |
46 | unsigned long timeout; | 71 | unsigned long timeout, start; |
47 | u32 elp_reg; | 72 | u32 elp_reg; |
48 | 73 | ||
49 | if (!wl->elp) | 74 | if (!wl->elp) |
@@ -51,6 +76,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl) | |||
51 | 76 | ||
52 | wl1251_debug(DEBUG_PSM, "waking up chip from elp"); | 77 | wl1251_debug(DEBUG_PSM, "waking up chip from elp"); |
53 | 78 | ||
79 | start = jiffies; | ||
54 | timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT); | 80 | timeout = jiffies + msecs_to_jiffies(WL1251_WAKEUP_TIMEOUT); |
55 | 81 | ||
56 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); | 82 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_WAKE_UP); |
@@ -71,8 +97,7 @@ int wl1251_ps_elp_wakeup(struct wl1251 *wl) | |||
71 | } | 97 | } |
72 | 98 | ||
73 | wl1251_debug(DEBUG_PSM, "wakeup time: %u ms", | 99 | wl1251_debug(DEBUG_PSM, "wakeup time: %u ms", |
74 | jiffies_to_msecs(jiffies) - | 100 | jiffies_to_msecs(jiffies - start)); |
75 | (jiffies_to_msecs(timeout) - WL1251_WAKEUP_TIMEOUT)); | ||
76 | 101 | ||
77 | wl->elp = false; | 102 | wl->elp = false; |
78 | 103 | ||
@@ -119,6 +144,11 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) | |||
119 | case STATION_POWER_SAVE_MODE: | 144 | case STATION_POWER_SAVE_MODE: |
120 | wl1251_debug(DEBUG_PSM, "entering psm"); | 145 | wl1251_debug(DEBUG_PSM, "entering psm"); |
121 | 146 | ||
147 | /* enable beacon filtering */ | ||
148 | ret = wl1251_acx_beacon_filter_opt(wl, true); | ||
149 | if (ret < 0) | ||
150 | return ret; | ||
151 | |||
122 | ret = wl1251_acx_wake_up_conditions(wl, | 152 | ret = wl1251_acx_wake_up_conditions(wl, |
123 | WAKE_UP_EVENT_DTIM_BITMAP, | 153 | WAKE_UP_EVENT_DTIM_BITMAP, |
124 | wl->listen_int); | 154 | wl->listen_int); |
@@ -142,6 +172,11 @@ int wl1251_ps_set_mode(struct wl1251 *wl, enum wl1251_cmd_ps_mode mode) | |||
142 | if (ret < 0) | 172 | if (ret < 0) |
143 | return ret; | 173 | return ret; |
144 | 174 | ||
175 | /* disable beacon filtering */ | ||
176 | ret = wl1251_acx_beacon_filter_opt(wl, false); | ||
177 | if (ret < 0) | ||
178 | return ret; | ||
179 | |||
145 | ret = wl1251_acx_wake_up_conditions(wl, | 180 | ret = wl1251_acx_wake_up_conditions(wl, |
146 | WAKE_UP_EVENT_DTIM_BITMAP, | 181 | WAKE_UP_EVENT_DTIM_BITMAP, |
147 | wl->listen_int); | 182 | wl->listen_int); |