summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/marvell/mwifiex/txrx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/marvell/mwifiex/txrx.c')
-rw-r--r--drivers/net/wireless/marvell/mwifiex/txrx.c70
1 files changed, 32 insertions, 38 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/txrx.c b/drivers/net/wireless/marvell/mwifiex/txrx.c
index d848933466d9..f44e22f24511 100644
--- a/drivers/net/wireless/marvell/mwifiex/txrx.c
+++ b/drivers/net/wireless/marvell/mwifiex/txrx.c
@@ -1,20 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
- * Marvell Wireless LAN device driver: generic TX/RX data handling
+ * NXP Wireless LAN device driver: generic TX/RX data handling
*
- * Copyright (C) 2011-2014, Marvell International Ltd.
- *
- * This software file (the "File") is distributed by Marvell International
- * Ltd. under the terms of the GNU General Public License Version 2, June 1991
- * (the "License"). You may use, redistribute and/or modify this File in
- * accordance with the terms and conditions of the License, a copy of which
- * is available by writing to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
- * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
- *
- * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
- * ARE EXPRESSLY DISCLAIMED. The License provides additional details about
- * this warranty disclaimer.
+ * Copyright 2011-2020 NXP
*/
#include "decl.h"
@@ -36,8 +24,7 @@
int mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
struct sk_buff *skb)
{
- struct mwifiex_private *priv =
- mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
+ struct mwifiex_private *priv;
struct rxpd *local_rx_pd;
struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
int ret;
@@ -84,13 +71,18 @@ EXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
struct mwifiex_tx_param *tx_param)
{
- int hroom, ret = -1;
+ int hroom, ret;
struct mwifiex_adapter *adapter = priv->adapter;
- u8 *head_ptr;
struct txpd *local_tx_pd = NULL;
struct mwifiex_sta_node *dest_node;
struct ethhdr *hdr = (void *)skb->data;
+ if (unlikely(!skb->len ||
+ skb_headroom(skb) < MWIFIEX_MIN_DATA_HEADER_LEN)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
hroom = adapter->intf_hdr_len;
if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP) {
@@ -100,33 +92,31 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
dest_node->stats.tx_packets++;
}
- head_ptr = mwifiex_process_uap_txpd(priv, skb);
+ mwifiex_process_uap_txpd(priv, skb);
} else {
- head_ptr = mwifiex_process_sta_txpd(priv, skb);
+ mwifiex_process_sta_txpd(priv, skb);
}
- if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) {
+ if (adapter->data_sent || adapter->tx_lock_flag) {
skb_queue_tail(&adapter->tx_data_q, skb);
atomic_inc(&adapter->tx_queued);
return 0;
}
- if (head_ptr) {
- if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
- local_tx_pd = (struct txpd *)(head_ptr + hroom);
- if (adapter->iface_type == MWIFIEX_USB) {
- ret = adapter->if_ops.host_to_card(adapter,
- priv->usb_port,
- skb, tx_param);
- } else {
- ret = adapter->if_ops.host_to_card(adapter,
- MWIFIEX_TYPE_DATA,
- skb, tx_param);
- }
+ if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
+ local_tx_pd = (struct txpd *)(skb->data + hroom);
+ if (adapter->iface_type == MWIFIEX_USB) {
+ ret = adapter->if_ops.host_to_card(adapter,
+ priv->usb_port,
+ skb, tx_param);
+ } else {
+ ret = adapter->if_ops.host_to_card(adapter,
+ MWIFIEX_TYPE_DATA,
+ skb, tx_param);
}
mwifiex_dbg_dump(adapter, DAT_D, "tx pkt:", skb->data,
min_t(size_t, skb->len, DEBUG_DUMP_DATA_MAX_LEN));
-
+out:
switch (ret) {
case -ENOSR:
mwifiex_dbg(adapter, DATA, "data: -ENOSR is returned\n");
@@ -149,6 +139,11 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
break;
case -EINPROGRESS:
break;
+ case -EINVAL:
+ mwifiex_dbg(adapter, ERROR,
+ "malformed skb (length: %u, headroom: %u)\n",
+ skb->len, skb_headroom(skb));
+ fallthrough;
case 0:
mwifiex_write_data_complete(adapter, skb, 0, ret);
break;
@@ -334,15 +329,14 @@ void mwifiex_parse_tx_status_event(struct mwifiex_private *priv,
{
struct tx_status_event *tx_status = (void *)priv->adapter->event_body;
struct sk_buff *ack_skb;
- unsigned long flags;
struct mwifiex_txinfo *tx_info;
if (!tx_status->tx_token_id)
return;
- spin_lock_irqsave(&priv->ack_status_lock, flags);
+ spin_lock_bh(&priv->ack_status_lock);
ack_skb = idr_remove(&priv->ack_status_frames, tx_status->tx_token_id);
- spin_unlock_irqrestore(&priv->ack_status_lock, flags);
+ spin_unlock_bh(&priv->ack_status_lock);
if (ack_skb) {
tx_info = MWIFIEX_SKB_TXCB(ack_skb);