diff options
Diffstat (limited to 'drivers/net/wireless/wl12xx/event.c')
-rw-r--r-- | drivers/net/wireless/wl12xx/event.c | 70 |
1 files changed, 23 insertions, 47 deletions
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c index d7be3aec6fc3..c3c554cd6580 100644 --- a/drivers/net/wireless/wl12xx/event.c +++ b/drivers/net/wireless/wl12xx/event.c | |||
@@ -135,6 +135,13 @@ static int wl1271_event_ps_report(struct wl1271 *wl, | |||
135 | 135 | ||
136 | /* enable beacon early termination */ | 136 | /* enable beacon early termination */ |
137 | ret = wl1271_acx_bet_enable(wl, true); | 137 | ret = wl1271_acx_bet_enable(wl, true); |
138 | if (ret < 0) | ||
139 | break; | ||
140 | |||
141 | if (wl->ps_compl) { | ||
142 | complete(wl->ps_compl); | ||
143 | wl->ps_compl = NULL; | ||
144 | } | ||
138 | break; | 145 | break; |
139 | default: | 146 | default: |
140 | break; | 147 | break; |
@@ -174,8 +181,6 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | |||
174 | u32 vector; | 181 | u32 vector; |
175 | bool beacon_loss = false; | 182 | bool beacon_loss = false; |
176 | bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); | 183 | bool is_ap = (wl->bss_type == BSS_TYPE_AP_BSS); |
177 | bool disconnect_sta = false; | ||
178 | unsigned long sta_bitmap = 0; | ||
179 | 184 | ||
180 | wl1271_event_mbox_dump(mbox); | 185 | wl1271_event_mbox_dump(mbox); |
181 | 186 | ||
@@ -190,6 +195,22 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | |||
190 | wl1271_scan_stm(wl); | 195 | wl1271_scan_stm(wl); |
191 | } | 196 | } |
192 | 197 | ||
198 | if (vector & PERIODIC_SCAN_REPORT_EVENT_ID) { | ||
199 | wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_REPORT_EVENT " | ||
200 | "(status 0x%0x)", mbox->scheduled_scan_status); | ||
201 | |||
202 | wl1271_scan_sched_scan_results(wl); | ||
203 | } | ||
204 | |||
205 | if (vector & PERIODIC_SCAN_COMPLETE_EVENT_ID) { | ||
206 | wl1271_debug(DEBUG_EVENT, "PERIODIC_SCAN_COMPLETE_EVENT " | ||
207 | "(status 0x%0x)", mbox->scheduled_scan_status); | ||
208 | if (wl->sched_scanning) { | ||
209 | wl1271_scan_sched_scan_stop(wl); | ||
210 | ieee80211_sched_scan_stopped(wl->hw); | ||
211 | } | ||
212 | } | ||
213 | |||
193 | /* disable dynamic PS when requested by the firmware */ | 214 | /* disable dynamic PS when requested by the firmware */ |
194 | if (vector & SOFT_GEMINI_SENSE_EVENT_ID && | 215 | if (vector & SOFT_GEMINI_SENSE_EVENT_ID && |
195 | wl->bss_type == BSS_TYPE_STA_BSS) { | 216 | wl->bss_type == BSS_TYPE_STA_BSS) { |
@@ -237,54 +258,9 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox) | |||
237 | wl1271_tx_dummy_packet(wl); | 258 | wl1271_tx_dummy_packet(wl); |
238 | } | 259 | } |
239 | 260 | ||
240 | /* | ||
241 | * "TX retries exceeded" has a different meaning according to mode. | ||
242 | * In AP mode the offending station is disconnected. In STA mode we | ||
243 | * report connection loss. | ||
244 | */ | ||
245 | if (vector & MAX_TX_RETRY_EVENT_ID) { | ||
246 | wl1271_debug(DEBUG_EVENT, "MAX_TX_RETRY_EVENT_ID"); | ||
247 | if (is_ap) { | ||
248 | sta_bitmap |= le16_to_cpu(mbox->sta_tx_retry_exceeded); | ||
249 | disconnect_sta = true; | ||
250 | } else { | ||
251 | beacon_loss = true; | ||
252 | } | ||
253 | } | ||
254 | |||
255 | if ((vector & INACTIVE_STA_EVENT_ID) && is_ap) { | ||
256 | wl1271_debug(DEBUG_EVENT, "INACTIVE_STA_EVENT_ID"); | ||
257 | sta_bitmap |= le16_to_cpu(mbox->sta_aging_status); | ||
258 | disconnect_sta = true; | ||
259 | } | ||
260 | |||
261 | if (wl->vif && beacon_loss) | 261 | if (wl->vif && beacon_loss) |
262 | ieee80211_connection_loss(wl->vif); | 262 | ieee80211_connection_loss(wl->vif); |
263 | 263 | ||
264 | if (is_ap && disconnect_sta) { | ||
265 | u32 num_packets = wl->conf.tx.max_tx_retries; | ||
266 | struct ieee80211_sta *sta; | ||
267 | const u8 *addr; | ||
268 | int h; | ||
269 | |||
270 | for (h = find_first_bit(&sta_bitmap, AP_MAX_LINKS); | ||
271 | h < AP_MAX_LINKS; | ||
272 | h = find_next_bit(&sta_bitmap, AP_MAX_LINKS, h+1)) { | ||
273 | if (!wl1271_is_active_sta(wl, h)) | ||
274 | continue; | ||
275 | |||
276 | addr = wl->links[h].addr; | ||
277 | |||
278 | rcu_read_lock(); | ||
279 | sta = ieee80211_find_sta(wl->vif, addr); | ||
280 | if (sta) { | ||
281 | wl1271_debug(DEBUG_EVENT, "remove sta %d", h); | ||
282 | ieee80211_report_low_ack(sta, num_packets); | ||
283 | } | ||
284 | rcu_read_unlock(); | ||
285 | } | ||
286 | } | ||
287 | |||
288 | return 0; | 264 | return 0; |
289 | } | 265 | } |
290 | 266 | ||