diff options
author | Yair Shapira | 2013-05-05 10:57:04 -0500 |
---|---|---|
committer | Yaniv Machani | 2015-08-04 06:29:42 -0500 |
commit | a9ee010e1c3b73b3e3f7feb4c0b83488cdc93386 (patch) | |
tree | 933558e0f59e42d3ad26005a939b90d7a66e86a8 | |
parent | b1aeee39eb6f8316848934d342986e3b1c62054b (diff) | |
download | kernel-audio-a9ee010e1c3b73b3e3f7feb4c0b83488cdc93386.tar.gz kernel-audio-a9ee010e1c3b73b3e3f7feb4c0b83488cdc93386.tar.xz kernel-audio-a9ee010e1c3b73b3e3f7feb4c0b83488cdc93386.zip |
wlcore: Add RX_BA_WIN_SIZE_CHANGE_EVENT event
This event is used by the Firmware to limit the RX BA win size
for a specific link.
The event handler updates the new size in the driver's link struct
and in the mac's sta->sta struct accordingly and closes all active BA
sessions for that link.
Conseqent BA sessions opened for that link will use the new restricted
win_size. This limitation remains until a new update is received or
until the link is closed.
This solves an IOP bug with APs that don't respect the max subframes in
a single-frame and uses the max win_size instead. In these cases the FW
recovers by sending this event to decrease the win_size to use the single
frame limitation.
Update the min fw version accordingly to 8.6.0.0.1
Signed-off-by: Yair Shapira <yair.shapira@ti.com>
Signed-off-by: Igal Chernobelsky <igalc@ti.com>
-rw-r--r-- | drivers/net/wireless/ti/wl18xx/event.c | 61 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl18xx/event.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/ti/wl18xx/main.c | 1 |
3 files changed, 63 insertions, 0 deletions
diff --git a/drivers/net/wireless/ti/wl18xx/event.c b/drivers/net/wireless/ti/wl18xx/event.c index 09c7e098f460..e0bc8a22f98e 100644 --- a/drivers/net/wireless/ti/wl18xx/event.c +++ b/drivers/net/wireless/ti/wl18xx/event.c | |||
@@ -206,5 +206,66 @@ int wl18xx_process_mailbox_events(struct wl1271 *wl) | |||
206 | mbox->sc_pwd_len, | 206 | mbox->sc_pwd_len, |
207 | mbox->sc_pwd); | 207 | mbox->sc_pwd); |
208 | 208 | ||
209 | if (vector & RX_BA_WIN_SIZE_CHANGE_EVENT_ID) { | ||
210 | struct wl12xx_vif *wlvif; | ||
211 | struct ieee80211_vif *vif; | ||
212 | u8 role_id = mbox->rx_ba_role_id; | ||
213 | u8 link_id = mbox->rx_ba_link_id; | ||
214 | u8 win_size = mbox->rx_ba_win_size; | ||
215 | int prev_win_size; | ||
216 | |||
217 | wl1271_debug(DEBUG_EVENT, | ||
218 | "%s. role_id=%u link_id=%u win_size=%u", | ||
219 | "RX_BA_WIN_SIZE_CHANGE_EVENT_ID", | ||
220 | role_id, link_id, win_size); | ||
221 | |||
222 | wlvif = wl->links[link_id].wlvif; | ||
223 | if (unlikely(!wlvif)) { | ||
224 | wl1271_error("%s. link_id wlvif is null", | ||
225 | "RX_BA_WIN_SIZE_CHANGE_EVENT_ID"); | ||
226 | |||
227 | goto out_event; | ||
228 | } | ||
229 | |||
230 | if (unlikely(wlvif->role_id != role_id)) { | ||
231 | wl1271_error("%s. wlvif has different role_id=%d", | ||
232 | "RX_BA_WIN_SIZE_CHANGE_EVENT_ID", | ||
233 | wlvif->role_id); | ||
234 | |||
235 | goto out_event; | ||
236 | } | ||
237 | |||
238 | prev_win_size = wlcore_rx_ba_max_subframes(wl, link_id); | ||
239 | if (unlikely(prev_win_size < 0)) { | ||
240 | wl1271_error("%s. cannot get link rx_ba_max_subframes", | ||
241 | "RX_BA_WIN_SIZE_CHANGE_EVENT_ID"); | ||
242 | |||
243 | goto out_event; | ||
244 | } | ||
245 | |||
246 | if ((u8)prev_win_size <= win_size) { | ||
247 | /* This not supposed to happen unless a FW bug */ | ||
248 | wl1271_error("%s. prev_win_size(%d) <= win_size(%d)", | ||
249 | "RX_BA_WIN_SIZE_CHANGE_EVENT_ID", | ||
250 | prev_win_size, win_size); | ||
251 | |||
252 | goto out_event; | ||
253 | } | ||
254 | |||
255 | /* | ||
256 | * Call MAC routine to update win_size and stop all link active | ||
257 | * BA sessions. This routine returns 0 on failure or previous | ||
258 | * win_size on success | ||
259 | */ | ||
260 | vif = wl12xx_wlvif_to_vif(wlvif); | ||
261 | ieee80211_change_rx_ba_max_subframes(vif, | ||
262 | (wlvif->bss_type != BSS_TYPE_AP_BSS ? | ||
263 | vif->bss_conf.bssid : | ||
264 | wl->links[link_id].addr), | ||
265 | win_size); | ||
266 | } | ||
267 | |||
268 | out_event: | ||
269 | |||
209 | return 0; | 270 | return 0; |
210 | } | 271 | } |
diff --git a/drivers/net/wireless/ti/wl18xx/event.h b/drivers/net/wireless/ti/wl18xx/event.h index f3d4f13379cb..9495fadc8093 100644 --- a/drivers/net/wireless/ti/wl18xx/event.h +++ b/drivers/net/wireless/ti/wl18xx/event.h | |||
@@ -38,6 +38,7 @@ enum { | |||
38 | REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID = BIT(18), | 38 | REMAIN_ON_CHANNEL_COMPLETE_EVENT_ID = BIT(18), |
39 | DFS_CHANNELS_CONFIG_COMPLETE_EVENT = BIT(19), | 39 | DFS_CHANNELS_CONFIG_COMPLETE_EVENT = BIT(19), |
40 | PERIODIC_SCAN_REPORT_EVENT_ID = BIT(20), | 40 | PERIODIC_SCAN_REPORT_EVENT_ID = BIT(20), |
41 | RX_BA_WIN_SIZE_CHANGE_EVENT_ID = BIT(21), | ||
41 | SMART_CONFIG_SYNC_EVENT_ID = BIT(22), | 42 | SMART_CONFIG_SYNC_EVENT_ID = BIT(22), |
42 | SMART_CONFIG_DECODE_EVENT_ID = BIT(23), | 43 | SMART_CONFIG_DECODE_EVENT_ID = BIT(23), |
43 | TIME_SYNC_EVENT_ID = BIT(24), | 44 | TIME_SYNC_EVENT_ID = BIT(24), |
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index b5908ffc0f98..da1a3d034526 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c | |||
@@ -1005,6 +1005,7 @@ static int wl18xx_boot(struct wl1271 *wl) | |||
1005 | DFS_CHANNELS_CONFIG_COMPLETE_EVENT | | 1005 | DFS_CHANNELS_CONFIG_COMPLETE_EVENT | |
1006 | SMART_CONFIG_SYNC_EVENT_ID | | 1006 | SMART_CONFIG_SYNC_EVENT_ID | |
1007 | SMART_CONFIG_DECODE_EVENT_ID | | 1007 | SMART_CONFIG_DECODE_EVENT_ID | |
1008 | RX_BA_WIN_SIZE_CHANGE_EVENT_ID | | ||
1008 | TIME_SYNC_EVENT_ID; | 1009 | TIME_SYNC_EVENT_ID; |
1009 | 1010 | ||
1010 | wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID; | 1011 | wl->ap_event_mask = MAX_TX_FAILURE_EVENT_ID; |