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