From 37b70a81855e4a2e66716804ae55ff717520e7fb Mon Sep 17 00:00:00 2001 From: Juuso Oikarinen Date: Thu, 8 Oct 2009 21:56:21 +0300 Subject: wl1271: Implement delayed entry into ELP Implement delayed entry into ELP. This will promote the following: - Less redundant sleep/wake cycles (better perf) - Avoids known firmware issues with going to ELP too fast after an operation Signed-off-by: Juuso Oikarinen Reviewed-by: Vidhya Govindan Signed-off-by: Luciano Coelho Signed-off-by: John W. Linville --- drivers/net/wireless/wl12xx/wl1271_ps.c | 46 +++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 14 deletions(-) (limited to 'drivers/net/wireless/wl12xx/wl1271_ps.c') diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c index 1dc74b0c773..0f6ea16cae8 100644 --- a/drivers/net/wireless/wl12xx/wl1271_ps.c +++ b/drivers/net/wireless/wl12xx/wl1271_ps.c @@ -27,25 +27,43 @@ #define WL1271_WAKEUP_TIMEOUT 500 -/* Routines to toggle sleep mode while in ELP */ -void wl1271_ps_elp_sleep(struct wl1271 *wl) +void wl1271_elp_work(struct work_struct *work) { + struct delayed_work *dwork; + struct wl1271 *wl; + + dwork = container_of(work, struct delayed_work, work); + wl = container_of(dwork, struct wl1271, elp_work); + + wl1271_debug(DEBUG_PSM, "elp work"); + + mutex_lock(&wl->mutex); + /* - * FIXME: due to a problem in the firmware (causing a firmware - * crash), ELP entry is prevented below. Remove the "true" to - * re-enable ELP entry. + * FIXME: below, by means of the "true", ELP has been disabled for now + * to work around a firmware bug. To be enabled upon receiving a new + * firmware version. */ if (true || wl->elp || !wl->psm) - return; + goto out; - /* - * Go to ELP unless there is work already pending - pending work - * will immediately wakeup the chipset anyway. - */ - if (!work_pending(&wl->irq_work) && !work_pending(&wl->tx_work)) { - wl1271_debug(DEBUG_PSM, "chip to elp"); - wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); - wl->elp = true; + wl1271_debug(DEBUG_PSM, "chip to elp"); + wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); + wl->elp = true; + +out: + mutex_unlock(&wl->mutex); +} + +#define ELP_ENTRY_DELAY 5 + +/* Routines to toggle sleep mode while in ELP */ +void wl1271_ps_elp_sleep(struct wl1271 *wl) +{ + if (wl->psm) { + cancel_delayed_work(&wl->elp_work); + ieee80211_queue_delayed_work(wl->hw, &wl->elp_work, + msecs_to_jiffies(ELP_ENTRY_DELAY)); } } -- cgit v1.2.3