.. | .. |
---|
1 | 1 | /* |
---|
2 | | - * Marvell Wireless LAN device driver: 802.11n RX Re-ordering |
---|
| 2 | + * NXP Wireless LAN device driver: 802.11n RX Re-ordering |
---|
3 | 3 | * |
---|
4 | | - * Copyright (C) 2011-2014, Marvell International Ltd. |
---|
| 4 | + * Copyright 2011-2020 NXP |
---|
5 | 5 | * |
---|
6 | | - * This software file (the "File") is distributed by Marvell International |
---|
7 | | - * Ltd. under the terms of the GNU General Public License Version 2, June 1991 |
---|
| 6 | + * This software file (the "File") is distributed by NXP |
---|
| 7 | + * under the terms of the GNU General Public License Version 2, June 1991 |
---|
8 | 8 | * (the "License"). You may use, redistribute and/or modify this File in |
---|
9 | 9 | * accordance with the terms and conditions of the License, a copy of which |
---|
10 | 10 | * is available by writing to the Free Software Foundation, Inc., |
---|
.. | .. |
---|
76 | 76 | /* This function will process the rx packet and forward it to kernel/upper |
---|
77 | 77 | * layer. |
---|
78 | 78 | */ |
---|
79 | | -static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, void *payload) |
---|
| 79 | +static int mwifiex_11n_dispatch_pkt(struct mwifiex_private *priv, |
---|
| 80 | + struct sk_buff *payload) |
---|
80 | 81 | { |
---|
81 | 82 | |
---|
82 | 83 | int ret; |
---|
.. | .. |
---|
109 | 110 | struct mwifiex_rx_reorder_tbl *tbl, |
---|
110 | 111 | int start_win) |
---|
111 | 112 | { |
---|
| 113 | + struct sk_buff_head list; |
---|
| 114 | + struct sk_buff *skb; |
---|
112 | 115 | int pkt_to_send, i; |
---|
113 | | - void *rx_tmp_ptr; |
---|
114 | | - unsigned long flags; |
---|
| 116 | + |
---|
| 117 | + __skb_queue_head_init(&list); |
---|
| 118 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
115 | 119 | |
---|
116 | 120 | pkt_to_send = (start_win > tbl->start_win) ? |
---|
117 | 121 | min((start_win - tbl->start_win), tbl->win_size) : |
---|
118 | 122 | tbl->win_size; |
---|
119 | 123 | |
---|
120 | 124 | for (i = 0; i < pkt_to_send; ++i) { |
---|
121 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
122 | | - rx_tmp_ptr = NULL; |
---|
123 | 125 | if (tbl->rx_reorder_ptr[i]) { |
---|
124 | | - rx_tmp_ptr = tbl->rx_reorder_ptr[i]; |
---|
| 126 | + skb = tbl->rx_reorder_ptr[i]; |
---|
| 127 | + __skb_queue_tail(&list, skb); |
---|
125 | 128 | tbl->rx_reorder_ptr[i] = NULL; |
---|
126 | 129 | } |
---|
127 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
128 | | - if (rx_tmp_ptr) |
---|
129 | | - mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr); |
---|
130 | 130 | } |
---|
131 | 131 | |
---|
132 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
133 | 132 | /* |
---|
134 | 133 | * We don't have a circular buffer, hence use rotation to simulate |
---|
135 | 134 | * circular buffer |
---|
.. | .. |
---|
140 | 139 | } |
---|
141 | 140 | |
---|
142 | 141 | tbl->start_win = start_win; |
---|
143 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
| 142 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
| 143 | + |
---|
| 144 | + while ((skb = __skb_dequeue(&list))) |
---|
| 145 | + mwifiex_11n_dispatch_pkt(priv, skb); |
---|
144 | 146 | } |
---|
145 | 147 | |
---|
146 | 148 | /* |
---|
.. | .. |
---|
155 | 157 | mwifiex_11n_scan_and_dispatch(struct mwifiex_private *priv, |
---|
156 | 158 | struct mwifiex_rx_reorder_tbl *tbl) |
---|
157 | 159 | { |
---|
| 160 | + struct sk_buff_head list; |
---|
| 161 | + struct sk_buff *skb; |
---|
158 | 162 | int i, j, xchg; |
---|
159 | | - void *rx_tmp_ptr; |
---|
160 | | - unsigned long flags; |
---|
| 163 | + |
---|
| 164 | + __skb_queue_head_init(&list); |
---|
| 165 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
161 | 166 | |
---|
162 | 167 | for (i = 0; i < tbl->win_size; ++i) { |
---|
163 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
164 | | - if (!tbl->rx_reorder_ptr[i]) { |
---|
165 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, |
---|
166 | | - flags); |
---|
| 168 | + if (!tbl->rx_reorder_ptr[i]) |
---|
167 | 169 | break; |
---|
168 | | - } |
---|
169 | | - rx_tmp_ptr = tbl->rx_reorder_ptr[i]; |
---|
| 170 | + skb = tbl->rx_reorder_ptr[i]; |
---|
| 171 | + __skb_queue_tail(&list, skb); |
---|
170 | 172 | tbl->rx_reorder_ptr[i] = NULL; |
---|
171 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
172 | | - mwifiex_11n_dispatch_pkt(priv, rx_tmp_ptr); |
---|
173 | 173 | } |
---|
174 | 174 | |
---|
175 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
176 | 175 | /* |
---|
177 | 176 | * We don't have a circular buffer, hence use rotation to simulate |
---|
178 | 177 | * circular buffer |
---|
.. | .. |
---|
185 | 184 | } |
---|
186 | 185 | } |
---|
187 | 186 | tbl->start_win = (tbl->start_win + i) & (MAX_TID_VALUE - 1); |
---|
188 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
| 187 | + |
---|
| 188 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
| 189 | + |
---|
| 190 | + while ((skb = __skb_dequeue(&list))) |
---|
| 191 | + mwifiex_11n_dispatch_pkt(priv, skb); |
---|
189 | 192 | } |
---|
190 | 193 | |
---|
191 | 194 | /* |
---|
.. | .. |
---|
198 | 201 | mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv, |
---|
199 | 202 | struct mwifiex_rx_reorder_tbl *tbl) |
---|
200 | 203 | { |
---|
201 | | - unsigned long flags; |
---|
202 | 204 | int start_win; |
---|
203 | 205 | |
---|
204 | 206 | if (!tbl) |
---|
205 | 207 | return; |
---|
206 | 208 | |
---|
207 | | - spin_lock_irqsave(&priv->adapter->rx_proc_lock, flags); |
---|
| 209 | + spin_lock_bh(&priv->adapter->rx_proc_lock); |
---|
208 | 210 | priv->adapter->rx_locked = true; |
---|
209 | 211 | if (priv->adapter->rx_processing) { |
---|
210 | | - spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags); |
---|
| 212 | + spin_unlock_bh(&priv->adapter->rx_proc_lock); |
---|
211 | 213 | flush_workqueue(priv->adapter->rx_workqueue); |
---|
212 | 214 | } else { |
---|
213 | | - spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags); |
---|
| 215 | + spin_unlock_bh(&priv->adapter->rx_proc_lock); |
---|
214 | 216 | } |
---|
215 | 217 | |
---|
216 | 218 | start_win = (tbl->start_win + tbl->win_size) & (MAX_TID_VALUE - 1); |
---|
.. | .. |
---|
219 | 221 | del_timer_sync(&tbl->timer_context.timer); |
---|
220 | 222 | tbl->timer_context.timer_is_set = false; |
---|
221 | 223 | |
---|
222 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
| 224 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
223 | 225 | list_del(&tbl->list); |
---|
224 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
| 226 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
225 | 227 | |
---|
226 | 228 | kfree(tbl->rx_reorder_ptr); |
---|
227 | 229 | kfree(tbl); |
---|
228 | 230 | |
---|
229 | | - spin_lock_irqsave(&priv->adapter->rx_proc_lock, flags); |
---|
| 231 | + spin_lock_bh(&priv->adapter->rx_proc_lock); |
---|
230 | 232 | priv->adapter->rx_locked = false; |
---|
231 | | - spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags); |
---|
| 233 | + spin_unlock_bh(&priv->adapter->rx_proc_lock); |
---|
232 | 234 | |
---|
233 | 235 | } |
---|
234 | 236 | |
---|
.. | .. |
---|
240 | 242 | mwifiex_11n_get_rx_reorder_tbl(struct mwifiex_private *priv, int tid, u8 *ta) |
---|
241 | 243 | { |
---|
242 | 244 | struct mwifiex_rx_reorder_tbl *tbl; |
---|
243 | | - unsigned long flags; |
---|
244 | 245 | |
---|
245 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
| 246 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
246 | 247 | list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list) { |
---|
247 | 248 | if (!memcmp(tbl->ta, ta, ETH_ALEN) && tbl->tid == tid) { |
---|
248 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, |
---|
249 | | - flags); |
---|
| 249 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
250 | 250 | return tbl; |
---|
251 | 251 | } |
---|
252 | 252 | } |
---|
253 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
| 253 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
254 | 254 | |
---|
255 | 255 | return NULL; |
---|
256 | 256 | } |
---|
.. | .. |
---|
261 | 261 | void mwifiex_11n_del_rx_reorder_tbl_by_ta(struct mwifiex_private *priv, u8 *ta) |
---|
262 | 262 | { |
---|
263 | 263 | struct mwifiex_rx_reorder_tbl *tbl, *tmp; |
---|
264 | | - unsigned long flags; |
---|
265 | 264 | |
---|
266 | 265 | if (!ta) |
---|
267 | 266 | return; |
---|
268 | 267 | |
---|
269 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
| 268 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
270 | 269 | list_for_each_entry_safe(tbl, tmp, &priv->rx_reorder_tbl_ptr, list) { |
---|
271 | 270 | if (!memcmp(tbl->ta, ta, ETH_ALEN)) { |
---|
272 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, |
---|
273 | | - flags); |
---|
| 271 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
274 | 272 | mwifiex_del_rx_reorder_entry(priv, tbl); |
---|
275 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
| 273 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
276 | 274 | } |
---|
277 | 275 | } |
---|
278 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
| 276 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
279 | 277 | |
---|
280 | 278 | return; |
---|
281 | 279 | } |
---|
.. | .. |
---|
289 | 287 | { |
---|
290 | 288 | struct mwifiex_rx_reorder_tbl *rx_reorder_tbl_ptr = ctx->ptr; |
---|
291 | 289 | struct mwifiex_private *priv = ctx->priv; |
---|
292 | | - unsigned long flags; |
---|
293 | 290 | int i; |
---|
294 | 291 | |
---|
295 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
| 292 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
296 | 293 | for (i = rx_reorder_tbl_ptr->win_size - 1; i >= 0; --i) { |
---|
297 | 294 | if (rx_reorder_tbl_ptr->rx_reorder_ptr[i]) { |
---|
298 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, |
---|
299 | | - flags); |
---|
| 295 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
300 | 296 | return i; |
---|
301 | 297 | } |
---|
302 | 298 | } |
---|
303 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
| 299 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
304 | 300 | |
---|
305 | 301 | return -1; |
---|
306 | 302 | } |
---|
.. | .. |
---|
348 | 344 | int i; |
---|
349 | 345 | struct mwifiex_rx_reorder_tbl *tbl, *new_node; |
---|
350 | 346 | u16 last_seq = 0; |
---|
351 | | - unsigned long flags; |
---|
352 | 347 | struct mwifiex_sta_node *node; |
---|
353 | 348 | |
---|
354 | 349 | /* |
---|
.. | .. |
---|
372 | 367 | new_node->init_win = seq_num; |
---|
373 | 368 | new_node->flags = 0; |
---|
374 | 369 | |
---|
375 | | - spin_lock_irqsave(&priv->sta_list_spinlock, flags); |
---|
| 370 | + spin_lock_bh(&priv->sta_list_spinlock); |
---|
376 | 371 | if (mwifiex_queuing_ra_based(priv)) { |
---|
377 | 372 | if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) { |
---|
378 | 373 | node = mwifiex_get_sta_entry(priv, ta); |
---|
.. | .. |
---|
386 | 381 | else |
---|
387 | 382 | last_seq = priv->rx_seq[tid]; |
---|
388 | 383 | } |
---|
389 | | - spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); |
---|
| 384 | + spin_unlock_bh(&priv->sta_list_spinlock); |
---|
390 | 385 | |
---|
391 | 386 | mwifiex_dbg(priv->adapter, INFO, |
---|
392 | 387 | "info: last_seq=%d start_win=%d\n", |
---|
.. | .. |
---|
403 | 398 | new_node->rx_reorder_ptr = kcalloc(win_size, sizeof(void *), |
---|
404 | 399 | GFP_KERNEL); |
---|
405 | 400 | if (!new_node->rx_reorder_ptr) { |
---|
406 | | - kfree((u8 *) new_node); |
---|
| 401 | + kfree(new_node); |
---|
407 | 402 | mwifiex_dbg(priv->adapter, ERROR, |
---|
408 | 403 | "%s: failed to alloc reorder_ptr\n", __func__); |
---|
409 | 404 | return; |
---|
.. | .. |
---|
418 | 413 | for (i = 0; i < win_size; ++i) |
---|
419 | 414 | new_node->rx_reorder_ptr[i] = NULL; |
---|
420 | 415 | |
---|
421 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
| 416 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
422 | 417 | list_add_tail(&new_node->list, &priv->rx_reorder_tbl_ptr); |
---|
423 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
| 418 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
424 | 419 | } |
---|
425 | 420 | |
---|
426 | 421 | static void |
---|
.. | .. |
---|
476 | 471 | u32 rx_win_size = priv->add_ba_param.rx_win_size; |
---|
477 | 472 | u8 tid; |
---|
478 | 473 | int win_size; |
---|
479 | | - unsigned long flags; |
---|
480 | 474 | uint16_t block_ack_param_set; |
---|
481 | 475 | |
---|
482 | 476 | if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) && |
---|
483 | 477 | ISSUPP_TDLS_ENABLED(priv->adapter->fw_cap_info) && |
---|
484 | 478 | priv->adapter->is_hw_11ac_capable && |
---|
485 | 479 | memcmp(priv->cfg_bssid, cmd_addba_req->peer_mac_addr, ETH_ALEN)) { |
---|
486 | | - spin_lock_irqsave(&priv->sta_list_spinlock, flags); |
---|
| 480 | + spin_lock_bh(&priv->sta_list_spinlock); |
---|
487 | 481 | sta_ptr = mwifiex_get_sta_entry(priv, |
---|
488 | 482 | cmd_addba_req->peer_mac_addr); |
---|
489 | 483 | if (!sta_ptr) { |
---|
490 | | - spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); |
---|
| 484 | + spin_unlock_bh(&priv->sta_list_spinlock); |
---|
491 | 485 | mwifiex_dbg(priv->adapter, ERROR, |
---|
492 | 486 | "BA setup with unknown TDLS peer %pM!\n", |
---|
493 | 487 | cmd_addba_req->peer_mac_addr); |
---|
.. | .. |
---|
495 | 489 | } |
---|
496 | 490 | if (sta_ptr->is_11ac_enabled) |
---|
497 | 491 | rx_win_size = MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE; |
---|
498 | | - spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); |
---|
| 492 | + spin_unlock_bh(&priv->sta_list_spinlock); |
---|
499 | 493 | } |
---|
500 | 494 | |
---|
501 | 495 | cmd->command = cpu_to_le16(HostCmd_CMD_11N_ADDBA_RSP); |
---|
.. | .. |
---|
682 | 676 | struct mwifiex_tx_ba_stream_tbl *ptx_tbl; |
---|
683 | 677 | struct mwifiex_ra_list_tbl *ra_list; |
---|
684 | 678 | u8 cleanup_rx_reorder_tbl; |
---|
685 | | - unsigned long flags; |
---|
686 | 679 | int tid_down; |
---|
687 | 680 | |
---|
688 | 681 | if (type == TYPE_DELBA_RECEIVE) |
---|
.. | .. |
---|
716 | 709 | ra_list->amsdu_in_ampdu = false; |
---|
717 | 710 | ra_list->ba_status = BA_SETUP_NONE; |
---|
718 | 711 | } |
---|
719 | | - spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); |
---|
| 712 | + spin_lock_bh(&priv->tx_ba_stream_tbl_lock); |
---|
720 | 713 | mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, ptx_tbl); |
---|
721 | | - spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); |
---|
| 714 | + spin_unlock_bh(&priv->tx_ba_stream_tbl_lock); |
---|
722 | 715 | } |
---|
723 | 716 | } |
---|
724 | 717 | |
---|
.. | .. |
---|
804 | 797 | void mwifiex_11n_cleanup_reorder_tbl(struct mwifiex_private *priv) |
---|
805 | 798 | { |
---|
806 | 799 | struct mwifiex_rx_reorder_tbl *del_tbl_ptr, *tmp_node; |
---|
807 | | - unsigned long flags; |
---|
808 | 800 | |
---|
809 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
| 801 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
810 | 802 | list_for_each_entry_safe(del_tbl_ptr, tmp_node, |
---|
811 | 803 | &priv->rx_reorder_tbl_ptr, list) { |
---|
812 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
| 804 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
813 | 805 | mwifiex_del_rx_reorder_entry(priv, del_tbl_ptr); |
---|
814 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, flags); |
---|
| 806 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
815 | 807 | } |
---|
816 | 808 | INIT_LIST_HEAD(&priv->rx_reorder_tbl_ptr); |
---|
817 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, flags); |
---|
| 809 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
818 | 810 | |
---|
819 | 811 | mwifiex_reset_11n_rx_seq_num(priv); |
---|
820 | 812 | } |
---|
.. | .. |
---|
826 | 818 | { |
---|
827 | 819 | struct mwifiex_private *priv; |
---|
828 | 820 | struct mwifiex_rx_reorder_tbl *tbl; |
---|
829 | | - unsigned long lock_flags; |
---|
830 | 821 | int i; |
---|
831 | 822 | |
---|
832 | 823 | for (i = 0; i < adapter->priv_num; i++) { |
---|
.. | .. |
---|
834 | 825 | if (!priv) |
---|
835 | 826 | continue; |
---|
836 | 827 | |
---|
837 | | - spin_lock_irqsave(&priv->rx_reorder_tbl_lock, lock_flags); |
---|
| 828 | + spin_lock_bh(&priv->rx_reorder_tbl_lock); |
---|
838 | 829 | list_for_each_entry(tbl, &priv->rx_reorder_tbl_ptr, list) |
---|
839 | 830 | tbl->flags = flags; |
---|
840 | | - spin_unlock_irqrestore(&priv->rx_reorder_tbl_lock, lock_flags); |
---|
| 831 | + spin_unlock_bh(&priv->rx_reorder_tbl_lock); |
---|
841 | 832 | } |
---|
842 | 833 | |
---|
843 | 834 | return; |
---|
.. | .. |
---|
986 | 977 | } |
---|
987 | 978 | } |
---|
988 | 979 | |
---|
989 | | - tlv_buf_left -= (sizeof(*tlv_rxba) + tlv_len); |
---|
990 | | - tmp = (u8 *)tlv_rxba + tlv_len + sizeof(*tlv_rxba); |
---|
| 980 | + tlv_buf_left -= (sizeof(tlv_rxba->header) + tlv_len); |
---|
| 981 | + tmp = (u8 *)tlv_rxba + sizeof(tlv_rxba->header) + tlv_len; |
---|
991 | 982 | tlv_rxba = (struct mwifiex_ie_types_rxba_sync *)tmp; |
---|
992 | 983 | } |
---|
993 | 984 | } |
---|