diff options
author | Juuso Oikarinen <juuso.oikarinen@nokia.com> | 2009-11-02 13:22:11 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-02 15:43:34 -0500 |
commit | 19ad0715d8d9acc259ef02f83df767df2cf1eafe (patch) | |
tree | 330fff898975a7f3a17106046e939c4049200e68 /drivers/net/wireless/wl12xx/wl1271_event.c | |
parent | 3b775b4b27818130291e7716f3ce1e24664004c9 (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.c | 53 |
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 | ||
71 | static 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 | |||
71 | static void wl1271_event_mbox_dump(struct event_mailbox *mbox) | 105 | static 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; |