aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/wl12xx/wl1271_event.c
diff options
context:
space:
mode:
authorJuuso Oikarinen <juuso.oikarinen@nokia.com>2009-11-02 13:22:11 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-11-02 15:43:34 -0500
commit19ad0715d8d9acc259ef02f83df767df2cf1eafe (patch)
tree330fff898975a7f3a17106046e939c4049200e68 /drivers/net/wireless/wl12xx/wl1271_event.c
parent3b775b4b27818130291e7716f3ce1e24664004c9 (diff)
wl1271: Add retry implementation for PSM entries
PSM entries can fail (transmitting the corresponding null-func may not be heard by the AP.) Previously, this scenario was not detected, and out-of-sync between STA and AP could occur. Add retry implementation for the entries to recover from the situation. Signed-off-by: Juuso Oikarinen <juuso.oikarinen@nokia.com> Reviewed-by: Luciano Coelho <luciano.coelho@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/wireless/wl12xx/wl1271_event.c')
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_event.c53
1 files changed, 53 insertions, 0 deletions
diff --git a/drivers/net/wireless/wl12xx/wl1271_event.c b/drivers/net/wireless/wl12xx/wl1271_event.c
index 31d396ba9188..e135d894b42a 100644
--- a/drivers/net/wireless/wl12xx/wl1271_event.c
+++ b/drivers/net/wireless/wl12xx/wl1271_event.c
@@ -68,6 +68,40 @@ static int wl1271_event_scan_complete(struct wl1271 *wl,
68 return 0; 68 return 0;
69} 69}
70 70
71static int wl1271_event_ps_report(struct wl1271 *wl,
72 struct event_mailbox *mbox,
73 bool *beacon_loss)
74{
75 int ret = 0;
76
77 wl1271_debug(DEBUG_EVENT, "ps_status: 0x%x", mbox->ps_status);
78
79 switch (mbox->ps_status) {
80 case EVENT_ENTER_POWER_SAVE_FAIL:
81 if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {
82 wl->psm_entry_retry++;
83 wl1271_error("PSM entry failed, retrying %d\n",
84 wl->psm_entry_retry);
85 ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);
86 } else {
87 wl->psm_entry_retry = 0;
88 *beacon_loss = true;
89 }
90 break;
91 case EVENT_ENTER_POWER_SAVE_SUCCESS:
92 wl->psm_entry_retry = 0;
93 break;
94 case EVENT_EXIT_POWER_SAVE_FAIL:
95 wl1271_info("PSM exit failed");
96 break;
97 case EVENT_EXIT_POWER_SAVE_SUCCESS:
98 default:
99 break;
100 }
101
102 return ret;
103}
104
71static void wl1271_event_mbox_dump(struct event_mailbox *mbox) 105static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
72{ 106{
73 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:"); 107 wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -79,6 +113,7 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
79{ 113{
80 int ret; 114 int ret;
81 u32 vector; 115 u32 vector;
116 bool beacon_loss = false;
82 117
83 wl1271_event_mbox_dump(mbox); 118 wl1271_event_mbox_dump(mbox);
84 119
@@ -101,7 +136,25 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
101 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT"); 136 wl1271_debug(DEBUG_EVENT, "BSS_LOSE_EVENT");
102 137
103 /* indicate to the stack, that beacons have been lost */ 138 /* indicate to the stack, that beacons have been lost */
139 beacon_loss = true;
140 }
141
142 if (vector & PS_REPORT_EVENT_ID) {
143 wl1271_debug(DEBUG_EVENT, "PS_REPORT_EVENT");
144 ret = wl1271_event_ps_report(wl, mbox, &beacon_loss);
145 if (ret < 0)
146 return ret;
147 }
148
149 if (beacon_loss) {
150 /* Obviously, it's dangerous to release the mutex while
151 we are holding many of the variables in the wl struct.
152 That's why it's done last in the function, and care must
153 be taken that nothing more is done after this function
154 returns. */
155 mutex_unlock(&wl->mutex);
104 ieee80211_beacon_loss(wl->vif); 156 ieee80211_beacon_loss(wl->vif);
157 mutex_lock(&wl->mutex);
105 } 158 }
106 159
107 return 0; 160 return 0;