diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2009-11-17 11:48:37 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-18 17:09:20 -0500 |
commit | d5da79ac1f5050cccaa68d814ccce292371f25fa (patch) | |
tree | 2774979009bbc0a4efd5ea3d3a4bb5c03287c6c6 /drivers/net/wireless/wl12xx/wl1251_ps.c | |
parent | 6b21a2cd315e2e56a1748bd3ef9d910fe4f2e711 (diff) |
wl1251: Implement delayed entry into ELP mode
Implement (slightly) delayed entry into ELP. This will cure several
problems:
- It works around a firmware race condition if ELP is entered too fast
after commands (resulting in ELP timeout -traces)
- It will reduce the number of sleep-wake cycles between already
scheduled events such as interrupts and tx, hence improving
performance (less delay in switching between RX and TX)
Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com>
Reviewed-by: Vidhya Govindan <vidhya.govindan@nokia.com>
Signed-off-by: Kalle Valo <kalle.valo@nokia.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1251_ps.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/wl1251_ps.c | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1251_ps.c b/drivers/net/wireless/wl12xx/wl1251_ps.c index c3e348a12322..9931b197ff77 100644 --- a/drivers/net/wireless/wl12xx/wl1251_ps.c +++ b/drivers/net/wireless/wl12xx/wl1251_ps.c | |||
@@ -28,17 +28,41 @@ | |||
28 | 28 | ||
29 | #define WL1251_WAKEUP_TIMEOUT 2000 | 29 | #define WL1251_WAKEUP_TIMEOUT 2000 |
30 | 30 | ||
31 | /* Routines to toggle sleep mode while in ELP */ | 31 | void wl1251_elp_work(struct work_struct *work) |
32 | void wl1251_ps_elp_sleep(struct wl1251 *wl) | ||
33 | { | 32 | { |
33 | struct delayed_work *dwork; | ||
34 | struct wl1251 *wl; | ||
35 | |||
36 | dwork = container_of(work, struct delayed_work, work); | ||
37 | wl = container_of(dwork, struct wl1251, elp_work); | ||
38 | |||
39 | wl1251_debug(DEBUG_PSM, "elp work"); | ||
40 | |||
41 | mutex_lock(&wl->mutex); | ||
42 | |||
34 | if (wl->elp || !wl->psm) | 43 | if (wl->elp || !wl->psm) |
35 | return; | 44 | goto out; |
36 | 45 | ||
37 | wl1251_debug(DEBUG_PSM, "chip to elp"); | 46 | wl1251_debug(DEBUG_PSM, "chip to elp"); |
38 | |||
39 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); | 47 | wl1251_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); |
40 | |||
41 | wl->elp = true; | 48 | wl->elp = true; |
49 | |||
50 | out: | ||
51 | mutex_unlock(&wl->mutex); | ||
52 | } | ||
53 | |||
54 | #define ELP_ENTRY_DELAY 5 | ||
55 | |||
56 | /* Routines to toggle sleep mode while in ELP */ | ||
57 | void wl1251_ps_elp_sleep(struct wl1251 *wl) | ||
58 | { | ||
59 | unsigned long delay; | ||
60 | |||
61 | if (wl->psm) { | ||
62 | cancel_delayed_work(&wl->elp_work); | ||
63 | delay = msecs_to_jiffies(ELP_ENTRY_DELAY); | ||
64 | ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, delay); | ||
65 | } | ||
42 | } | 66 | } |
43 | 67 | ||
44 | int wl1251_ps_elp_wakeup(struct wl1251 *wl) | 68 | int wl1251_ps_elp_wakeup(struct wl1251 *wl) |