aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1251_ps.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /drivers/net/wireless/wl12xx/wl1251_ps.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (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.c53
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 */ 32void wl1251_elp_work(struct work_struct *work)
32void 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
51out:
52 mutex_unlock(&wl->mutex);
53}
54
55#define ELP_ENTRY_DELAY 5
56
57/* Routines to toggle sleep mode while in ELP */
58void 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
44int wl1251_ps_elp_wakeup(struct wl1251 *wl) 69int 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);