blob: 5cfe3d1a57deb4cfbde775e814ed083db06408f6 [file] [log] [blame]
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08001/*
Anurag Chouhan754fbd82016-02-19 17:00:08 +05302 * Copyright (c) 2014-2016 The Linux Foundation. All rights reserved.
Prakash Dhavali7090c5f2015-11-02 17:55:19 -08003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/*
23 * This file was originally distributed by Qualcomm Atheros, Inc.
24 * under proprietary terms before Copyright ownership was assigned
25 * to the Linux Foundation.
26 */
27
28/*========================================================================
29
30 \file epping_main.c
31
32 \brief WLAN End Point Ping test tool implementation
33
34 ========================================================================*/
35
36/*--------------------------------------------------------------------------
37 Include Files
38 ------------------------------------------------------------------------*/
39#include <cds_api.h>
40#include <cds_sched.h>
41#include <linux/etherdevice.h>
42#include <linux/firmware.h>
43#include <wni_api.h>
44#include <wlan_ptt_sock_svc.h>
45#include <linux/wireless.h>
46#include <net/cfg80211.h>
47#include <linux/rtnetlink.h>
48#include <linux/semaphore.h>
49#include <linux/ctype.h>
50#include "epping_main.h"
51#include "epping_internal.h"
52#include "epping_test.h"
53
54#define TX_RETRY_TIMEOUT_IN_MS 1
55
Anurag Chouhan754fbd82016-02-19 17:00:08 +053056static bool enb_tx_dump;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080057
58void epping_tx_dup_pkt(epping_adapter_t *pAdapter,
Nirav Shahcbc6d722016-03-01 16:24:53 +053059 HTC_ENDPOINT_ID eid, qdf_nbuf_t skb)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080060{
61 struct epping_cookie *cookie = NULL;
62 int skb_len, ret;
Nirav Shahcbc6d722016-03-01 16:24:53 +053063 qdf_nbuf_t new_skb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080064
65 cookie = epping_alloc_cookie(pAdapter->pEpping_ctx);
66 if (cookie == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053067 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080068 "%s: epping_alloc_cookie returns no resource\n",
69 __func__);
70 return;
71 }
Nirav Shahcbc6d722016-03-01 16:24:53 +053072 new_skb = qdf_nbuf_copy(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080073 if (!new_skb) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053074 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Nirav Shahcbc6d722016-03-01 16:24:53 +053075 "%s: qdf_nbuf_copy returns no resource\n", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080076 epping_free_cookie(pAdapter->pEpping_ctx, cookie);
77 return;
78 }
79 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
Nirav Shahcbc6d722016-03-01 16:24:53 +053080 cookie, qdf_nbuf_data(skb),
81 qdf_nbuf_len(new_skb), eid, 0);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080082 SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, new_skb);
Nirav Shahcbc6d722016-03-01 16:24:53 +053083 skb_len = (int)qdf_nbuf_len(new_skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080084 /* send the packet */
85 ret = htc_send_pkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt);
86 if (ret != A_OK) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +053087 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080088 "%s: htc_send_pkt failed, ret = %d\n", __func__, ret);
89 epping_free_cookie(pAdapter->pEpping_ctx, cookie);
Nirav Shahcbc6d722016-03-01 16:24:53 +053090 qdf_nbuf_free(new_skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -080091 return;
92 }
93 pAdapter->stats.tx_bytes += skb_len;
94 ++pAdapter->stats.tx_packets;
95 if (((pAdapter->stats.tx_packets +
96 pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 &&
97 (pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) {
98 epping_log_stats(pAdapter, __func__);
99 }
100}
101
Nirav Shahcbc6d722016-03-01 16:24:53 +0530102static int epping_tx_send_int(qdf_nbuf_t skb, epping_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800103{
Nirav Shahcbc6d722016-03-01 16:24:53 +0530104 EPPING_HEADER *eppingHdr = (EPPING_HEADER *) qdf_nbuf_data(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800105 HTC_ENDPOINT_ID eid = ENDPOINT_UNUSED;
106 struct epping_cookie *cookie = NULL;
107 A_UINT8 ac = 0;
108 A_STATUS ret = A_OK;
109 int skb_len;
110 EPPING_HEADER tmpHdr = *eppingHdr;
111
112 /* allocate resource for this packet */
113 cookie = epping_alloc_cookie(pAdapter->pEpping_ctx);
114 /* no resource */
115 if (cookie == NULL) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530116 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800117 "%s: epping_alloc_cookie returns no resource\n",
118 __func__);
119 return -1;
120 }
121
122 if (enb_tx_dump)
123 epping_hex_dump((void *)eppingHdr, skb->len, __func__);
124 /*
125 * a quirk of linux, the payload of the frame is 32-bit aligned and thus
126 * the addition of the HTC header will mis-align the start of the HTC
127 * frame, so we add some padding which will be stripped off in the target
128 */
129 if (EPPING_ALIGNMENT_PAD > 0) {
130 A_NETBUF_PUSH(skb, EPPING_ALIGNMENT_PAD);
131 }
132 /* prepare ep/HTC information */
133 ac = eppingHdr->StreamNo_h;
134 eid = pAdapter->pEpping_ctx->EppingEndpoint[ac];
135 if (eid < 0 || eid >= EPPING_MAX_NUM_EPIDS) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530136 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800137 "%s: invalid eid = %d, ac = %d\n", __func__, eid,
138 ac);
139 return -1;
140 }
141 if (tmpHdr.Cmd_h == EPPING_CMD_RESET_RECV_CNT ||
142 tmpHdr.Cmd_h == EPPING_CMD_CONT_RX_START) {
143 epping_set_kperf_flag(pAdapter, eid, tmpHdr.CmdBuffer_t[0]);
144 }
145 SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt,
Nirav Shahcbc6d722016-03-01 16:24:53 +0530146 cookie, qdf_nbuf_data(skb), qdf_nbuf_len(skb),
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800147 eid, 0);
148 SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, skb);
149 skb_len = skb->len;
150 /* send the packet */
151 ret = htc_send_pkt(pAdapter->pEpping_ctx->HTCHandle, &cookie->HtcPkt);
152 epping_log_packet(pAdapter, &tmpHdr, ret, __func__);
153 if (ret != A_OK) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530154 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800155 "%s: htc_send_pkt failed, status = %d\n", __func__,
156 ret);
157 epping_free_cookie(pAdapter->pEpping_ctx, cookie);
158 return -1;
159 }
160 pAdapter->stats.tx_bytes += skb_len;
161 ++pAdapter->stats.tx_packets;
162 if (((pAdapter->stats.tx_packets +
163 pAdapter->stats.tx_dropped) % EPPING_STATS_LOG_COUNT) == 0 &&
164 (pAdapter->stats.tx_packets || pAdapter->stats.tx_dropped)) {
165 epping_log_stats(pAdapter, __func__);
166 }
167
168 return 0;
169}
170
171void epping_tx_timer_expire(epping_adapter_t *pAdapter)
172{
Nirav Shahcbc6d722016-03-01 16:24:53 +0530173 qdf_nbuf_t nodrop_skb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800174
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530175 EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: queue len: %d\n", __func__,
Nirav Shahcbc6d722016-03-01 16:24:53 +0530176 qdf_nbuf_queue_len(&pAdapter->nodrop_queue));
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800177
Nirav Shahcbc6d722016-03-01 16:24:53 +0530178 if (!qdf_nbuf_queue_len(&pAdapter->nodrop_queue)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800179 /* nodrop queue is empty so no need to arm timer */
180 pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
181 return;
182 }
183
184 /* try to flush nodrop queue */
Nirav Shahcbc6d722016-03-01 16:24:53 +0530185 while ((nodrop_skb = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue))) {
gbian7288cf52016-09-30 16:58:31 +0800186 htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800187 if (epping_tx_send_int(nodrop_skb, pAdapter)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530188 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800189 "%s: nodrop: %p xmit fail in timer\n",
190 __func__, nodrop_skb);
191 /* fail to xmit so put the nodrop packet to the nodrop queue */
Nirav Shahcbc6d722016-03-01 16:24:53 +0530192 qdf_nbuf_queue_insert_head(&pAdapter->nodrop_queue,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800193 nodrop_skb);
194 break;
195 } else {
gbian7288cf52016-09-30 16:58:31 +0800196 htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, false);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530197 EPPING_LOG(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800198 "%s: nodrop: %p xmit ok in timer\n",
199 __func__, nodrop_skb);
200 }
201 }
202
203 /* if nodrop queue is not empty, continue to arm timer */
204 if (nodrop_skb) {
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530205 qdf_spin_lock_bh(&pAdapter->data_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800206 /* if nodrop queue is not empty, continue to arm timer */
207 if (pAdapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) {
208 pAdapter->epping_timer_state = EPPING_TX_TIMER_RUNNING;
Anurag Chouhan754fbd82016-02-19 17:00:08 +0530209 qdf_timer_mod(&pAdapter->epping_timer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800210 TX_RETRY_TIMEOUT_IN_MS);
211 }
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530212 qdf_spin_unlock_bh(&pAdapter->data_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800213 } else {
214 pAdapter->epping_timer_state = EPPING_TX_TIMER_STOPPED;
215 }
216}
217
Nirav Shahcbc6d722016-03-01 16:24:53 +0530218int epping_tx_send(qdf_nbuf_t skb, epping_adapter_t *pAdapter)
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800219{
Nirav Shahcbc6d722016-03-01 16:24:53 +0530220 qdf_nbuf_t nodrop_skb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800221 EPPING_HEADER *eppingHdr;
222 A_UINT8 ac = 0;
223
Nirav Shahcbc6d722016-03-01 16:24:53 +0530224 eppingHdr = (EPPING_HEADER *) qdf_nbuf_data(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800225
226 if (!IS_EPPING_PACKET(eppingHdr)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530227 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800228 "%s: Recived non endpoint ping packets\n", __func__);
229 /* no packet to send, cleanup */
Nirav Shahcbc6d722016-03-01 16:24:53 +0530230 qdf_nbuf_free(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800231 return -ENOMEM;
232 }
233
234 /* the stream ID is mapped to an access class */
235 ac = eppingHdr->StreamNo_h;
236 /* hard coded two ep ids */
237 if (ac != 0 && ac != 1) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530238 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800239 "%s: ac %d is not mapped to mboxping service\n",
240 __func__, ac);
Nirav Shahcbc6d722016-03-01 16:24:53 +0530241 qdf_nbuf_free(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800242 return -ENOMEM;
243 }
244
245 /*
246 * some EPPING packets cannot be dropped no matter what access class
247 * it was sent on. A special care has been taken:
248 * 1. when there is no TX resource, queue the control packets to
249 * a special queue
250 * 2. when there is TX resource, send the queued control packets first
251 * and then other packets
252 * 3. a timer launches to check if there is queued control packets and
253 * flush them
254 */
255
256 /* check the nodrop queue first */
Nirav Shahcbc6d722016-03-01 16:24:53 +0530257 while ((nodrop_skb = qdf_nbuf_queue_remove(&pAdapter->nodrop_queue))) {
gbian7288cf52016-09-30 16:58:31 +0800258 htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, true);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800259 if (epping_tx_send_int(nodrop_skb, pAdapter)) {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530260 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800261 "%s: nodrop: %p xmit fail\n", __func__,
262 nodrop_skb);
263 /* fail to xmit so put the nodrop packet to the nodrop queue */
Nirav Shahcbc6d722016-03-01 16:24:53 +0530264 qdf_nbuf_queue_insert_head(&pAdapter->nodrop_queue,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800265 nodrop_skb);
266 /* no cookie so free the current skb */
267 goto tx_fail;
268 } else {
gbian7288cf52016-09-30 16:58:31 +0800269 htc_set_nodrop_pkt(pAdapter->pEpping_ctx->HTCHandle, false);
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530270 EPPING_LOG(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800271 "%s: nodrop: %p xmit ok\n", __func__,
272 nodrop_skb);
273 }
274 }
275
276 /* send the original packet */
277 if (epping_tx_send_int(skb, pAdapter))
278 goto tx_fail;
279
280 return 0;
281
282tx_fail:
283 if (!IS_EPING_PACKET_NO_DROP(eppingHdr)) {
284 /* allow to drop the skb so drop it */
Nirav Shahcbc6d722016-03-01 16:24:53 +0530285 qdf_nbuf_free(skb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800286 ++pAdapter->stats.tx_dropped;
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530287 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800288 "%s: Tx skb %p dropped, stats.tx_dropped = %ld\n",
289 __func__, skb, pAdapter->stats.tx_dropped);
290 return -ENOMEM;
291 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530292 EPPING_LOG(QDF_TRACE_LEVEL_FATAL,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800293 "%s: nodrop: %p queued\n", __func__, skb);
Nirav Shahcbc6d722016-03-01 16:24:53 +0530294 qdf_nbuf_queue_add(&pAdapter->nodrop_queue, skb);
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530295 qdf_spin_lock_bh(&pAdapter->data_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800296 if (pAdapter->epping_timer_state != EPPING_TX_TIMER_RUNNING) {
297 pAdapter->epping_timer_state = EPPING_TX_TIMER_RUNNING;
Anurag Chouhan754fbd82016-02-19 17:00:08 +0530298 qdf_timer_mod(&pAdapter->epping_timer,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800299 TX_RETRY_TIMEOUT_IN_MS);
300 }
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530301 qdf_spin_unlock_bh(&pAdapter->data_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800302 }
303
304 return 0;
305}
306
307#ifdef HIF_SDIO
308HTC_SEND_FULL_ACTION epping_tx_queue_full(void *Context, HTC_PACKET *pPacket)
309{
gbian7288cf52016-09-30 16:58:31 +0800310 /*
311 * Call netif_stop_queue frequently will impact the mboxping tx t-put.
312 * Return HTC_SEND_FULL_KEEP directly in epping_tx_queue_full to avoid.
313 */
314 return HTC_SEND_FULL_KEEP;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800315}
316#endif /* HIF_SDIO */
317void epping_tx_complete_multiple(void *ctx, HTC_PACKET_QUEUE *pPacketQueue)
318{
319 epping_context_t *pEpping_ctx = (epping_context_t *) ctx;
320 epping_adapter_t *pAdapter = pEpping_ctx->epping_adapter;
321 struct net_device *dev = pAdapter->dev;
322 A_STATUS status;
323 HTC_ENDPOINT_ID eid;
Nirav Shahcbc6d722016-03-01 16:24:53 +0530324 qdf_nbuf_t pktSkb;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800325 struct epping_cookie *cookie;
326 A_BOOL flushing = false;
Nirav Shahcbc6d722016-03-01 16:24:53 +0530327 qdf_nbuf_queue_t skb_queue;
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800328 HTC_PACKET *htc_pkt;
329
Nirav Shahcbc6d722016-03-01 16:24:53 +0530330 qdf_nbuf_queue_init(&skb_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800331
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530332 qdf_spin_lock_bh(&pAdapter->data_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800333
334 while (!HTC_QUEUE_EMPTY(pPacketQueue)) {
335 htc_pkt = htc_packet_dequeue(pPacketQueue);
336 if (htc_pkt == NULL)
337 break;
338 status = htc_pkt->Status;
339 eid = htc_pkt->Endpoint;
340 pktSkb = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt);
341 cookie = htc_pkt->pPktContext;
342
Himanshu Agarwal5e302a72016-07-19 16:27:21 +0530343 if (!pktSkb) {
344 EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
Himanshu Agarwalf03f8102016-09-08 18:54:47 +0530345 "%s: NULL skb from hc packet", __func__);
346 QDF_BUG(0);
Himanshu Agarwal5e302a72016-07-19 16:27:21 +0530347 } else {
348 if (htc_pkt->pBuffer != qdf_nbuf_data(pktSkb)) {
349 EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
350 "%s: htc_pkt buffer not equal to skb->data",
351 __func__);
Himanshu Agarwalf03f8102016-09-08 18:54:47 +0530352 QDF_BUG(0);
Himanshu Agarwal5e302a72016-07-19 16:27:21 +0530353 }
354 /* add this to the list, use faster non-lock API */
355 qdf_nbuf_queue_add(&skb_queue, pktSkb);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800356
Himanshu Agarwal5e302a72016-07-19 16:27:21 +0530357 if (A_SUCCESS(status)) {
358 if (htc_pkt->ActualLength !=
359 qdf_nbuf_len(pktSkb)) {
360 EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
361 "%s: htc_pkt length not equal to skb->len",
362 __func__);
Himanshu Agarwalf03f8102016-09-08 18:54:47 +0530363 QDF_BUG(0);
Himanshu Agarwal5e302a72016-07-19 16:27:21 +0530364 }
365 }
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800366 }
Himanshu Agarwal5e302a72016-07-19 16:27:21 +0530367
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530368 EPPING_LOG(QDF_TRACE_LEVEL_INFO,
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800369 "%s skb=%p data=%p len=0x%x eid=%d ",
370 __func__, pktSkb, htc_pkt->pBuffer,
371 htc_pkt->ActualLength, eid);
372
373 if (A_FAILED(status)) {
374 if (status == A_ECANCELED) {
375 /* a packet was flushed */
376 flushing = true;
377 }
378 if (status != A_NO_RESOURCE) {
379 printk("%s() -TX ERROR, status: 0x%x\n",
380 __func__, status);
381 }
382 } else {
Anurag Chouhanb2dc16f2016-02-25 11:47:37 +0530383 EPPING_LOG(QDF_TRACE_LEVEL_INFO, "%s: OK\n", __func__);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800384 flushing = false;
385 }
386
387 epping_free_cookie(pAdapter->pEpping_ctx, cookie);
388 }
389
Anurag Chouhana37b5b72016-02-21 14:53:42 +0530390 qdf_spin_unlock_bh(&pAdapter->data_lock);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800391
392 /* free all skbs in our local list */
Nirav Shahcbc6d722016-03-01 16:24:53 +0530393 while (qdf_nbuf_queue_len(&skb_queue)) {
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800394 /* use non-lock version */
Nirav Shahcbc6d722016-03-01 16:24:53 +0530395 pktSkb = qdf_nbuf_queue_remove(&skb_queue);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800396 if (pktSkb == NULL)
397 break;
Rajeev Kumar8044ede2016-04-14 16:08:05 -0700398 qdf_nbuf_tx_free(pktSkb, QDF_NBUF_PKT_ERROR);
Prakash Dhavali7090c5f2015-11-02 17:55:19 -0800399 pEpping_ctx->total_tx_acks++;
400 }
401
402 if (!flushing) {
403 netif_wake_queue(dev);
404 }
405}