aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHamad Kadmany <qca_hkadmany@qca.qualcomm.com>2015-12-16 10:51:45 -0500
committerKalle Valo <kvalo@qca.qualcomm.com>2016-01-07 08:00:32 -0500
commitdea16eddb4753129dbcd8dc8d1a58ff0cc4ea38c (patch)
tree18a24f72f258d3aac65ad46dc9ffc04e0d4fcf49
parente33a99e227e430a788467e5a85dc29f6df16b983 (diff)
wil6210: fix kernel OOPS when stopping interface during Rx traffic
When network interface is stopping, some resources may be already released by the network stack, and Rx frames cause kernel OOPS (observed one is in netfilter code) Proper solution is to drop packets pending in reorder buffer. Signed-off-by: Hamad Kadmany <qca_hkadmany@qca.qualcomm.com> Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com> Signed-off-by: Maya Erez <qca_merez@qca.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index e3d1be82f314..32031e7a11d5 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -261,9 +261,19 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
261void wil_tid_ampdu_rx_free(struct wil6210_priv *wil, 261void wil_tid_ampdu_rx_free(struct wil6210_priv *wil,
262 struct wil_tid_ampdu_rx *r) 262 struct wil_tid_ampdu_rx *r)
263{ 263{
264 int i;
265
264 if (!r) 266 if (!r)
265 return; 267 return;
266 wil_release_reorder_frames(wil, r, r->head_seq_num + r->buf_size); 268
269 /* Do not pass remaining frames to the network stack - it may be
270 * not expecting to get any more Rx. Rx from here may lead to
271 * kernel OOPS since some per-socket accounting info was already
272 * released.
273 */
274 for (i = 0; i < r->buf_size; i++)
275 kfree_skb(r->reorder_buf[i]);
276
267 kfree(r->reorder_buf); 277 kfree(r->reorder_buf);
268 kfree(r->reorder_time); 278 kfree(r->reorder_time);
269 kfree(r); 279 kfree(r);