.. | .. |
---|
1 | 1 | /* |
---|
2 | | - * Marvell Wireless LAN device driver: AP TX and RX data handling |
---|
| 2 | + * NXP Wireless LAN device driver: AP TX and RX data handling |
---|
3 | 3 | * |
---|
4 | | - * Copyright (C) 2012-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., |
---|
.. | .. |
---|
71 | 71 | */ |
---|
72 | 72 | static void mwifiex_uap_cleanup_tx_queues(struct mwifiex_private *priv) |
---|
73 | 73 | { |
---|
74 | | - unsigned long flags; |
---|
75 | 74 | struct list_head *ra_list; |
---|
76 | 75 | int i; |
---|
77 | 76 | |
---|
78 | | - spin_lock_irqsave(&priv->wmm.ra_list_spinlock, flags); |
---|
| 77 | + spin_lock_bh(&priv->wmm.ra_list_spinlock); |
---|
79 | 78 | |
---|
80 | 79 | for (i = 0; i < MAX_NUM_TID; i++, priv->del_list_idx++) { |
---|
81 | 80 | if (priv->del_list_idx == MAX_NUM_TID) |
---|
.. | .. |
---|
87 | 86 | } |
---|
88 | 87 | } |
---|
89 | 88 | |
---|
90 | | - spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); |
---|
| 89 | + spin_unlock_bh(&priv->wmm.ra_list_spinlock); |
---|
91 | 90 | } |
---|
92 | 91 | |
---|
93 | 92 | |
---|
.. | .. |
---|
113 | 112 | "Tx: Bridge packet limit reached. Drop packet!\n"); |
---|
114 | 113 | kfree_skb(skb); |
---|
115 | 114 | mwifiex_uap_cleanup_tx_queues(priv); |
---|
| 115 | + return; |
---|
| 116 | + } |
---|
| 117 | + |
---|
| 118 | + if (sizeof(*rx_pkt_hdr) + |
---|
| 119 | + le16_to_cpu(uap_rx_pd->rx_pkt_offset) > skb->len) { |
---|
| 120 | + mwifiex_dbg(adapter, ERROR, |
---|
| 121 | + "wrong rx packet offset: len=%d,rx_pkt_offset=%d\n", |
---|
| 122 | + skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset)); |
---|
| 123 | + priv->stats.rx_dropped++; |
---|
| 124 | + dev_kfree_skb_any(skb); |
---|
116 | 125 | return; |
---|
117 | 126 | } |
---|
118 | 127 | |
---|
.. | .. |
---|
256 | 265 | |
---|
257 | 266 | if (is_multicast_ether_addr(ra)) { |
---|
258 | 267 | skb_uap = skb_copy(skb, GFP_ATOMIC); |
---|
259 | | - mwifiex_uap_queue_bridged_pkt(priv, skb_uap); |
---|
| 268 | + if (likely(skb_uap)) { |
---|
| 269 | + mwifiex_uap_queue_bridged_pkt(priv, skb_uap); |
---|
| 270 | + } else { |
---|
| 271 | + mwifiex_dbg(adapter, ERROR, |
---|
| 272 | + "failed to copy skb for uAP\n"); |
---|
| 273 | + priv->stats.rx_dropped++; |
---|
| 274 | + dev_kfree_skb_any(skb); |
---|
| 275 | + return -1; |
---|
| 276 | + } |
---|
260 | 277 | } else { |
---|
261 | 278 | if (mwifiex_get_sta_entry(priv, ra)) { |
---|
262 | 279 | /* Requeue Intra-BSS packet */ |
---|
.. | .. |
---|
351 | 368 | skb->truesize += (skb->len - MWIFIEX_RX_DATA_BUF_SIZE); |
---|
352 | 369 | |
---|
353 | 370 | /* Forward multicast/broadcast packet to upper layer*/ |
---|
354 | | - if (in_interrupt()) |
---|
355 | | - netif_rx(skb); |
---|
356 | | - else |
---|
357 | | - netif_rx_ni(skb); |
---|
358 | | - |
---|
| 371 | + netif_rx_any_context(skb); |
---|
359 | 372 | return 0; |
---|
360 | 373 | } |
---|
361 | 374 | |
---|
.. | .. |
---|
378 | 391 | struct rx_packet_hdr *rx_pkt_hdr; |
---|
379 | 392 | u16 rx_pkt_type; |
---|
380 | 393 | u8 ta[ETH_ALEN], pkt_type; |
---|
381 | | - unsigned long flags; |
---|
382 | 394 | struct mwifiex_sta_node *node; |
---|
383 | 395 | |
---|
384 | 396 | uap_rx_pd = (struct uap_rxpd *)(skb->data); |
---|
385 | 397 | rx_pkt_type = le16_to_cpu(uap_rx_pd->rx_pkt_type); |
---|
386 | 398 | rx_pkt_hdr = (void *)uap_rx_pd + le16_to_cpu(uap_rx_pd->rx_pkt_offset); |
---|
| 399 | + |
---|
| 400 | + if (le16_to_cpu(uap_rx_pd->rx_pkt_offset) + |
---|
| 401 | + sizeof(rx_pkt_hdr->eth803_hdr) > skb->len) { |
---|
| 402 | + mwifiex_dbg(adapter, ERROR, |
---|
| 403 | + "wrong rx packet for struct ethhdr: len=%d, offset=%d\n", |
---|
| 404 | + skb->len, le16_to_cpu(uap_rx_pd->rx_pkt_offset)); |
---|
| 405 | + priv->stats.rx_dropped++; |
---|
| 406 | + dev_kfree_skb_any(skb); |
---|
| 407 | + return 0; |
---|
| 408 | + } |
---|
387 | 409 | |
---|
388 | 410 | ether_addr_copy(ta, rx_pkt_hdr->eth803_hdr.h_source); |
---|
389 | 411 | |
---|
.. | .. |
---|
413 | 435 | |
---|
414 | 436 | |
---|
415 | 437 | if (rx_pkt_type != PKT_TYPE_BAR && uap_rx_pd->priority < MAX_NUM_TID) { |
---|
416 | | - spin_lock_irqsave(&priv->sta_list_spinlock, flags); |
---|
| 438 | + spin_lock_bh(&priv->sta_list_spinlock); |
---|
417 | 439 | node = mwifiex_get_sta_entry(priv, ta); |
---|
418 | 440 | if (node) |
---|
419 | 441 | node->rx_seq[uap_rx_pd->priority] = |
---|
420 | 442 | le16_to_cpu(uap_rx_pd->seq_num); |
---|
421 | | - spin_unlock_irqrestore(&priv->sta_list_spinlock, flags); |
---|
| 443 | + spin_unlock_bh(&priv->sta_list_spinlock); |
---|
422 | 444 | } |
---|
423 | 445 | |
---|
424 | 446 | if (!priv->ap_11n_enabled || |
---|