aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYair Shapira2013-05-05 10:57:04 -0500
committerYaniv Machani2015-08-04 06:29:42 -0500
commita9ee010e1c3b73b3e3f7feb4c0b83488cdc93386 (patch)
tree933558e0f59e42d3ad26005a939b90d7a66e86a8
parentb1aeee39eb6f8316848934d342986e3b1c62054b (diff)
downloadkernel-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.c61
-rw-r--r--drivers/net/wireless/ti/wl18xx/event.h1
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c1
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
268out_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;