aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1271_event.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/wl12xx/wl1271_event.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index ca52cdec7a8f..15f6b86f81a2 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -28,6 +28,63 @@
28#include "wl1271_ps.h" 28#include "wl1271_ps.h"
29#include "wl12xx_80211.h" 29#include "wl12xx_80211.h"
30 30
31void wl1271_pspoll_work(struct work_struct *work)
32{
33 struct delayed_work *dwork;
34 struct wl1271 *wl;
35
36 dwork = container_of(work, struct delayed_work, work);
37 wl = container_of(dwork, struct wl1271, pspoll_work);
38
39 wl1271_debug(DEBUG_EVENT, "pspoll work");
40
41 mutex_lock(&wl->mutex);
42
43 if (!test_and_clear_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags))
44 goto out;
45
46 if (!test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags))
47 goto out;
48
49 /*
50 * if we end up here, then we were in powersave when the pspoll
51 * delivery failure occurred, and no-one changed state since, so
52 * we should go back to powersave.
53 */
54 wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE, true);
55
56out:
57 mutex_unlock(&wl->mutex);
58};
59
60static void wl1271_event_pspoll_delivery_fail(struct wl1271 *wl)
61{
62 int delay = wl->conf.conn.ps_poll_recovery_period;
63 int ret;
64
65 wl->ps_poll_failures++;
66 if (wl->ps_poll_failures == 1)
67 wl1271_info("AP with dysfunctional ps-poll, "
68 "trying to work around it.");
69
70 /* force active mode receive data from the AP */
71 if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {
72 ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE, true);
73 if (ret < 0)
74 return;
75 set_bit(WL1271_FLAG_PSPOLL_FAILURE, &wl->flags);
76 ieee80211_queue_delayed_work(wl->hw, &wl->pspoll_work,
77 msecs_to_jiffies(delay));
78 }
79
80 /*
81 * If already in active mode, lets we should be getting data from
82 * the AP right away. If we enter PSM too fast after this, and data
83 * remains on the AP, we will get another event like this, and we'll
84 * go into active once more.
85 */
86}
87
31static int wl1271_event_scan_complete(struct wl1271 *wl, 88static int wl1271_event_scan_complete(struct wl1271 *wl,
32 struct event_mailbox *mbox) 89 struct event_mailbox *mbox)
33{ 90{
@@ -191,6 +248,9 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
191 return ret; 248 return ret;
192 } 249 }
193 250
251 if (vector & PSPOLL_DELIVERY_FAILURE_EVENT_ID)
252 wl1271_event_pspoll_delivery_fail(wl);
253
194 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) { 254 if (vector & RSSI_SNR_TRIGGER_0_EVENT_ID) {
195 wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT"); 255 wl1271_debug(DEBUG_EVENT, "RSSI_SNR_TRIGGER_0_EVENT");
196 if (wl->vif) 256 if (wl->vif)