aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2009-10-08 14:56:21 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-10-27 16:47:49 -0400
commit37b70a81855e4a2e66716804ae55ff717520e7fb (patch)
treeaa6c7c9ea6928542d1124a3fd8c6c4010caa10a6 /drivers/net
parent1e2b79761d551c545225e1fa6e7d144f7e804898 (diff)
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 <juuso.oikarinen@nokia.com> Reviewed-by: Vidhya Govindan <vidhya.govindan@nokia.com> Signed-off-by: Luciano Coelho <luciano.coelho@nokia.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271.h1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_main.c1
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.c46
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_ps.h2
4 files changed, 35 insertions, 15 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271.h b/drivers/net/wireless/wl12xx/wl1271.h
index e575dcc9df27..c455dcbae524 100644
--- a/drivers/net/wireless/wl12xx/wl1271.h
+++ b/drivers/net/wireless/wl12xx/wl1271.h
@@ -373,6 +373,7 @@ struct wl1271 {
373 bool elp; 373 bool elp;
374 374
375 struct completion *elp_compl; 375 struct completion *elp_compl;
376 struct delayed_work elp_work;
376 377
377 /* we can be in psm, but not in elp, we have to differentiate */ 378 /* we can be in psm, but not in elp, we have to differentiate */
378 bool psm; 379 bool psm;
diff --git a/drivers/net/wireless/wl12xx/wl1271_main.c b/drivers/net/wireless/wl12xx/wl1271_main.c
index 3d629daf2246..cc5c3285deac 100644
--- a/drivers/net/wireless/wl12xx/wl1271_main.c
+++ b/drivers/net/wireless/wl12xx/wl1271_main.c
@@ -1226,6 +1226,7 @@ static int __devinit wl1271_probe(struct spi_device *spi)
1226 skb_queue_head_init(&wl->tx_queue); 1226 skb_queue_head_init(&wl->tx_queue);
1227 1227
1228 INIT_WORK(&wl->filter_work, wl1271_filter_work); 1228 INIT_WORK(&wl->filter_work, wl1271_filter_work);
1229 INIT_DELAYED_WORK(&wl->elp_work, wl1271_elp_work);
1229 wl->channel = WL1271_DEFAULT_CHANNEL; 1230 wl->channel = WL1271_DEFAULT_CHANNEL;
1230 wl->scanning = false; 1231 wl->scanning = false;
1231 wl->default_key = 0; 1232 wl->default_key = 0;
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.c b/drivers/net/wireless/wl12xx/wl1271_ps.c
index 1dc74b0c7736..0f6ea16cae83 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.c
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.c
@@ -27,25 +27,43 @@
27 27
28#define WL1271_WAKEUP_TIMEOUT 500 28#define WL1271_WAKEUP_TIMEOUT 500
29 29
30/* Routines to toggle sleep mode while in ELP */ 30void wl1271_elp_work(struct work_struct *work)
31void wl1271_ps_elp_sleep(struct wl1271 *wl)
32{ 31{
32 struct delayed_work *dwork;
33 struct wl1271 *wl;
34
35 dwork = container_of(work, struct delayed_work, work);
36 wl = container_of(dwork, struct wl1271, elp_work);
37
38 wl1271_debug(DEBUG_PSM, "elp work");
39
40 mutex_lock(&wl->mutex);
41
33 /* 42 /*
34 * FIXME: due to a problem in the firmware (causing a firmware 43 * FIXME: below, by means of the "true", ELP has been disabled for now
35 * crash), ELP entry is prevented below. Remove the "true" to 44 * to work around a firmware bug. To be enabled upon receiving a new
36 * re-enable ELP entry. 45 * firmware version.
37 */ 46 */
38 if (true || wl->elp || !wl->psm) 47 if (true || wl->elp || !wl->psm)
39 return; 48 goto out;
40 49
41 /* 50 wl1271_debug(DEBUG_PSM, "chip to elp");
42 * Go to ELP unless there is work already pending - pending work 51 wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP);
43 * will immediately wakeup the chipset anyway. 52 wl->elp = true;
44 */ 53
45 if (!work_pending(&wl->irq_work) && !work_pending(&wl->tx_work)) { 54out:
46 wl1271_debug(DEBUG_PSM, "chip to elp"); 55 mutex_unlock(&wl->mutex);
47 wl1271_write32(wl, HW_ACCESS_ELP_CTRL_REG_ADDR, ELPCTRL_SLEEP); 56}
48 wl->elp = true; 57
58#define ELP_ENTRY_DELAY 5
59
60/* Routines to toggle sleep mode while in ELP */
61void wl1271_ps_elp_sleep(struct wl1271 *wl)
62{
63 if (wl->psm) {
64 cancel_delayed_work(&wl->elp_work);
65 ieee80211_queue_delayed_work(wl->hw, &wl->elp_work,
66 msecs_to_jiffies(ELP_ENTRY_DELAY));
49 } 67 }
50} 68}
51 69
diff --git a/drivers/net/wireless/wl12xx/wl1271_ps.h b/drivers/net/wireless/wl12xx/wl1271_ps.h
index de2bd3c7dc9c..779653d0ae85 100644
--- a/drivers/net/wireless/wl12xx/wl1271_ps.h
+++ b/drivers/net/wireless/wl12xx/wl1271_ps.h
@@ -30,6 +30,6 @@
30int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode); 30int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode);
31void wl1271_ps_elp_sleep(struct wl1271 *wl); 31void wl1271_ps_elp_sleep(struct wl1271 *wl);
32int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake); 32int wl1271_ps_elp_wakeup(struct wl1271 *wl, bool chip_awake);
33 33void wl1271_elp_work(struct work_struct *work);
34 34
35#endif /* __WL1271_PS_H__ */ 35#endif /* __WL1271_PS_H__ */