15e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/*
25e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Marvell Wireless LAN device driver: generic TX/RX data handling
35e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao *
465da33f5557f0ed3f1227063bcf1f25248d456e5Xinming Hu * Copyright (C) 2011-2014, Marvell International Ltd.
55e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao *
65e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This software file (the "File") is distributed by Marvell International
75e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Ltd. under the terms of the GNU General Public License Version 2, June 1991
85e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * (the "License").  You may use, redistribute and/or modify this File in
95e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * accordance with the terms and conditions of the License, a copy of which
105e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * is available by writing to the Free Software Foundation, Inc.,
115e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA or on the
125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * worldwide web at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.
135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao *
145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE
155e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE
165e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * ARE EXPRESSLY DISCLAIMED.  The License provides additional details about
175e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * this warranty disclaimer.
185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */
195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
205e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "decl.h"
215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "ioctl.h"
225e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "util.h"
235e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "fw.h"
245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "main.h"
255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao#include "wmm.h"
265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/*
285e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function processes the received buffer.
295e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao *
305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Main responsibility of this function is to parse the RxPD to
315e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * identify the correct interface this packet is headed for and
325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * forwarding it to the associated handling function, where the
335e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * packet will be further processed and sent to kernel/upper layer
345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * if required.
355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */
365e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint mwifiex_handle_rx_packet(struct mwifiex_adapter *adapter,
375e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao			     struct sk_buff *skb)
385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{
395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	struct mwifiex_private *priv =
405e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	struct rxpd *local_rx_pd;
425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
43ca8d6dfc929ad6e59eb523e7c057804b55e5673eUjjal Roy	int ret;
445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	local_rx_pd = (struct rxpd *) (skb->data);
465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	/* Get the BSS number from rxpd, get corresponding priv */
475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	priv = mwifiex_get_priv_by_id(adapter, local_rx_pd->bss_num &
485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao				      BSS_NUM_MASK, local_rx_pd->bss_type);
495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	if (!priv)
505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_ANY);
515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
52f3b369e40a0fbf975ab0e39c2104f184e188afc3Avinash Patil	if (!priv) {
53f3b369e40a0fbf975ab0e39c2104f184e188afc3Avinash Patil		dev_err(adapter->dev, "data: priv not found. Drop RX packet\n");
54f3b369e40a0fbf975ab0e39c2104f184e188afc3Avinash Patil		dev_kfree_skb_any(skb);
55f3b369e40a0fbf975ab0e39c2104f184e188afc3Avinash Patil		return -1;
56f3b369e40a0fbf975ab0e39c2104f184e188afc3Avinash Patil	}
57f3b369e40a0fbf975ab0e39c2104f184e188afc3Avinash Patil
58701a9e619347ac06d59481db14bbc4df99763270Amitkumar Karwar	memset(rx_info, 0, sizeof(*rx_info));
599da9a3b29ba6a9a98e437f24576f13cbe259997bYogesh Ashok Powar	rx_info->bss_num = priv->bss_num;
609da9a3b29ba6a9a98e437f24576f13cbe259997bYogesh Ashok Powar	rx_info->bss_type = priv->bss_type;
615e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
62838e4f44929782a2163c7bc95a7cd2da5d8b47f9Avinash Patil	if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
63ca8d6dfc929ad6e59eb523e7c057804b55e5673eUjjal Roy		ret = mwifiex_process_uap_rx_packet(priv, skb);
64ca8d6dfc929ad6e59eb523e7c057804b55e5673eUjjal Roy	else
65ca8d6dfc929ad6e59eb523e7c057804b55e5673eUjjal Roy		ret = mwifiex_process_sta_rx_packet(priv, skb);
66838e4f44929782a2163c7bc95a7cd2da5d8b47f9Avinash Patil
67ca8d6dfc929ad6e59eb523e7c057804b55e5673eUjjal Roy	/* Decrement RX pending counter for each packet */
68ca8d6dfc929ad6e59eb523e7c057804b55e5673eUjjal Roy	if (adapter->if_ops.data_complete)
69ca8d6dfc929ad6e59eb523e7c057804b55e5673eUjjal Roy		adapter->if_ops.data_complete(adapter);
70ca8d6dfc929ad6e59eb523e7c057804b55e5673eUjjal Roy
71ca8d6dfc929ad6e59eb523e7c057804b55e5673eUjjal Roy	return ret;
725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao}
735e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing ZhaoEXPORT_SYMBOL_GPL(mwifiex_handle_rx_packet);
745e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
755e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/*
765e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * This function sends a packet to device.
775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao *
785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * It processes the packet to add the TxPD, checks condition and
795e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * sends the processed packet to firmware for transmission.
805e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao *
815e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * On successful completion, the function calls the completion callback
825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * and logs the time.
835e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */
845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
855e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		       struct mwifiex_tx_param *tx_param)
865e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{
875e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	int ret = -1;
885e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	struct mwifiex_adapter *adapter = priv->adapter;
89270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar	u8 *head_ptr;
905e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	struct txpd *local_tx_pd = NULL;
915e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
924ac8764ab2290fd83c21b4183ca6a0f279dab277Avinash Patil	if (priv->bss_role == MWIFIEX_BSS_ROLE_UAP)
934ac8764ab2290fd83c21b4183ca6a0f279dab277Avinash Patil		head_ptr = mwifiex_process_uap_txpd(priv, skb);
944ac8764ab2290fd83c21b4183ca6a0f279dab277Avinash Patil	else
954ac8764ab2290fd83c21b4183ca6a0f279dab277Avinash Patil		head_ptr = mwifiex_process_sta_txpd(priv, skb);
964ac8764ab2290fd83c21b4183ca6a0f279dab277Avinash Patil
975e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	if (head_ptr) {
985e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
995e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao			local_tx_pd =
1005e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao				(struct txpd *) (head_ptr + INTF_HEADER_LEN);
1014daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar		if (adapter->iface_type == MWIFIEX_USB) {
1024daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar			adapter->data_sent = true;
1034daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar			skb_pull(skb, INTF_HEADER_LEN);
1044daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar			ret = adapter->if_ops.host_to_card(adapter,
1054daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar							   MWIFIEX_USB_EP_DATA,
1064daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar							   skb, NULL);
1074daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar		} else {
1084daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar			ret = adapter->if_ops.host_to_card(adapter,
1094daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar							   MWIFIEX_TYPE_DATA,
1104daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar							   skb, tx_param);
1114daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar		}
1125e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	}
1135e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
1145e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	switch (ret) {
1154daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar	case -ENOSR:
116bd2a864a14ebd0ffa2166c0d8005e44437436713Ujjal Roy		dev_dbg(adapter->dev, "data: -ENOSR is returned\n");
1174daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar		break;
1185e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	case -EBUSY:
1195e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
120c65a30f35f938b421ac67c34a9e70b0e49e6019aYogesh Ashok Powar		    (adapter->pps_uapsd_mode) && (adapter->tx_lock_flag)) {
1215e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao				priv->adapter->tx_lock_flag = false;
1223d82de0fa584fbe73cf74a3bbc906c8710c523b8Yogesh Ashok Powar				if (local_tx_pd)
1233d82de0fa584fbe73cf74a3bbc906c8710c523b8Yogesh Ashok Powar					local_tx_pd->flags = 0;
1245e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		}
1255e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
1265e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		break;
1275e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	case -1:
128e7f767a7d9f809c494bfffffeda2bbdbfec110b4Avinash Patil		if (adapter->iface_type != MWIFIEX_PCIE)
129e7f767a7d9f809c494bfffffeda2bbdbfec110b4Avinash Patil			adapter->data_sent = false;
1305e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
131c65a30f35f938b421ac67c34a9e70b0e49e6019aYogesh Ashok Powar			ret);
1325e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		adapter->dbg.num_tx_host_to_card_failure++;
13347411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil		mwifiex_write_data_complete(adapter, skb, 0, ret);
1345e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		break;
1355e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	case -EINPROGRESS:
136e7f767a7d9f809c494bfffffeda2bbdbfec110b4Avinash Patil		if (adapter->iface_type != MWIFIEX_PCIE)
137e7f767a7d9f809c494bfffffeda2bbdbfec110b4Avinash Patil			adapter->data_sent = false;
1385e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		break;
1395e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	case 0:
14047411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil		mwifiex_write_data_complete(adapter, skb, 0, ret);
1415e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		break;
1425e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	default:
1435e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		break;
1445e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	}
1455e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
1465e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	return ret;
1475e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao}
1485e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
1495e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao/*
1505e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * Packet send completion callback handler.
1515e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao *
1525e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * It either frees the buffer directly or forwards it to another
1535e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * completion callback which checks conditions, updates statistics,
1545e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao * wakes up stalled traffic queue if required, and then frees the buffer.
1555e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao */
1565e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaoint mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
15747411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil				struct sk_buff *skb, int aggr, int status)
1585e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao{
15947411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil	struct mwifiex_private *priv;
160270e58e8898c8be40451ebee45b6c9b5bd5db04bYogesh Ashok Powar	struct mwifiex_txinfo *tx_info;
16147411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil	struct netdev_queue *txq;
16247411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil	int index;
1635e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
1645e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	if (!skb)
1655e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		return 0;
1665e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
1675e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	tx_info = MWIFIEX_SKB_TXCB(skb);
1689da9a3b29ba6a9a98e437f24576f13cbe259997bYogesh Ashok Powar	priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
169c65a30f35f938b421ac67c34a9e70b0e49e6019aYogesh Ashok Powar				      tx_info->bss_type);
1705e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	if (!priv)
1715e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		goto done;
1725e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
1734daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar	if (adapter->iface_type == MWIFIEX_USB)
1744daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar		adapter->data_sent = false;
1754daffe3543667419294b6f22901b7255cbdebdf4Amitkumar Karwar
176bbea3bc432dc5c08d09ca5c80afdd82515470688Avinash Patil	mwifiex_set_trans_start(priv->netdev);
1775e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	if (!status) {
1785e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		priv->stats.tx_packets++;
179a1ed484960066c413712cd9c4d50a350cf67eba3Ujjal Roy		priv->stats.tx_bytes += tx_info->pkt_len;
1808908c7d5392671610a2d80107845d4aeee92d9c1Ashok Nagarajan		if (priv->tx_timeout_cnt)
1818908c7d5392671610a2d80107845d4aeee92d9c1Ashok Nagarajan			priv->tx_timeout_cnt = 0;
1825e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	} else {
1835e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao		priv->stats.tx_errors++;
1845e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	}
18562a5b7dcee00c8e64e61ed98541c95fd38583116Marc Yang
186838e4f44929782a2163c7bc95a7cd2da5d8b47f9Avinash Patil	if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT)
187838e4f44929782a2163c7bc95a7cd2da5d8b47f9Avinash Patil		atomic_dec_return(&adapter->pending_bridged_pkts);
18847411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil
18947411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil	if (aggr)
19047411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil		/* For skb_aggr, do not wake up tx queue */
19162a5b7dcee00c8e64e61ed98541c95fd38583116Marc Yang		goto done;
1925e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
19347411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil	atomic_dec(&adapter->tx_pending);
1945e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
19547411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil	index = mwifiex_1d_to_wmm_queue[skb->priority];
19647411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil	if (atomic_dec_return(&priv->wmm_tx_pending[index]) < LOW_TX_PENDING) {
19747411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil		txq = netdev_get_tx_queue(priv->netdev, index);
19847411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil		if (netif_tx_queue_stopped(txq)) {
19947411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil			netif_tx_wake_queue(txq);
20047411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil			dev_dbg(adapter->dev, "wake queue: %d\n", index);
20147411a06c0c44b3c9dc2feffb0d97785ec9aaa68Avinash Patil		}
2025e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	}
2035e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhaodone:
2045e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	dev_kfree_skb_any(skb);
2055e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
2065e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao	return 0;
2075e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao}
2084daffe3543667419294b6f22901b7255cbdebdf4Amitkumar KarwarEXPORT_SYMBOL_GPL(mwifiex_write_data_complete);
2095e6e3a92b9a4c9416b17f468fa5c7fa2233b8b4eBing Zhao
210